@agg-build/ui
v4.7.4
Published
Pre-built React component library for the AGG prediction market aggregator. Tailwind-based, themeable, with primitives, event surfaces, trading flows, full pages, and modals.
Readme
@agg-build/ui
Pre-built React component library for the AGG prediction market aggregator. Tailwind-based styles, themeable CSS tokens, and components grouped into primitives, event surfaces, trading flows, full pages, and modals.
See every component live in the AGG Storybook.
What it is
@agg-build/ui ships the UI you'd have to build yourself: event cards, market detail pages, orderbook
and chart primitives, order entry forms, deposit/withdraw/onboarding modals, and opinionated page
layouts. Components are built on top of @agg-build/hooks
and expect an <AggProvider> above them in the tree. Styling is Tailwind v4 + CSS custom
properties so you can theme everything from your own stylesheet.
This package intentionally contains no wallet code and no auth adapters — the modular
connect/sign-in UI lives in @agg-build/auth. That keeps
@agg-build/ui free of wagmi, @solana/*, and related peers.
When to use this package
- You want production-ready AGG trading UI without wiring every view from scratch.
- You plan to render a full AGG home/event/market/profile surface inside your app.
- You want themeable primitives (Button, Card, Modal, Chart, Tooltip, etc.) consistent with the rest of the AGG surfaces.
If you only need the underlying logic, install @agg-build/sdk
and @agg-build/hooks and build your own UI.
Install
npm install @agg-build/sdk @agg-build/hooks @agg-build/ui livelineliveline is the charting engine used by Chart / LineChart and is declared as a peer
dependency.
Quick start
import "@agg-build/ui/styles.css";
import { QueryClient, QueryClientProvider } from "@agg-build/hooks";
import { createAggClient } from "@agg-build/sdk";
import { AggProvider } from "@agg-build/ui";
import { HomePage } from "@agg-build/ui/pages";
const client = createAggClient({
baseUrl: "https://api.agg.market",
appId: "your-app-id",
wsUrl: "wss://ws.agg.market",
});
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<AggProvider
client={client}
config={{
general: { locale: "en-US", theme: "dark" },
features: { enableAnimations: true, enableLiveUpdates: true, showFeesBreakdown: true },
}}
>
<HomePage withHeader />
</AggProvider>
</QueryClientProvider>
);
}Set config.features.enableEventDiscoveryUrlPersistence to true to persist the primary
HomePage section's category, repeated subcategory, venue, and sort filters in browser
history. It is disabled by default and preserves unrelated query parameters such as search.
Styling
Import the default theme once at your app entrypoint:
import "@agg-build/ui/styles.css";The UI-level AggProvider adds AGG's toast surface to the hooks provider. It still requires the
same client prop and QueryClientProvider ancestor shown above. Override theme tokens with CSS
variables on the .agg-root container (automatically applied by AggProvider):
.agg-root {
--agg-color-primary: #ed8200;
--agg-color-foreground: #1a1a1a;
--agg-radius-md: 8px;
--agg-font-family-sans: "Your Font", ui-sans-serif, system-ui, sans-serif;
}You can also set --agg-font-family-sans on :root; a value on .agg-root wins because it is
scoped closer to the AGG UI tree.
With Next.js next/font, expose the generated font variable on an ancestor, then map it into the
AGG token on .agg-root:
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
});
export default function App() {
return (
<div className={inter.variable}>
<QueryClientProvider client={queryClient}>
<AggProvider client={client}>
<AggApp />
</AggProvider>
</QueryClientProvider>
</div>
);
}.agg-root {
--agg-font-family-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}If you already use Tailwind v4 in your app and want the AGG preset to merge with your config,
import @agg-build/ui/tailwind.css instead of (or alongside) styles.css.
Tree-shaking
Import from the grouped subpaths to keep your bundle narrow:
// Preferred
import { Button, Card } from "@agg-build/ui/primitives";
import { HomePage, EventMarketPage } from "@agg-build/ui/pages";
import { DepositModal, OnboardingModal } from "@agg-build/ui/modals";
import { PlaceOrder } from "@agg-build/ui/trading";
// Wider than necessary
import { Button } from "@agg-build/ui";Using a full page
The HomePage and EventMarketPage components take partner-owned navigation callbacks. In the
demo app we wire them to Next.js router.push:
"use client";
import { HomePage } from "@agg-build/ui/pages";
import { useRouter } from "next/navigation";
export function Home() {
const router = useRouter();
const getMarketHref = (event, market, outcome) =>
`/events/${event.id}?marketId=${market.id}&outcomeId=${outcome.id}`;
const getEventHref = (event) => `/events/${event.id}`;
return (
<HomePage
withHeader={false}
onEventClick={(event) => router.push(getEventHref(event))}
onMarketClick={(event, market, outcome) => router.push(getMarketHref(event, market, outcome))}
getEventHref={getEventHref}
getMarketHref={getMarketHref}
stickyOrderPanel={{ enabled: true, top: 80 }}
/>
);
}Components
Primitives — @agg-build/ui/primitives
| Component | Description |
| -------------------- | ---------------------------- |
| AggErrorBoundary | Error boundary wrapper |
| AggLogo | AGG wordmark |
| AutocompleteSelect | Combobox with async results |
| Badge | Status badge |
| Button | Base button primitive |
| Card | Content card |
| Chart | Price chart (liveline-based) |
| CurrencyInput | Locale-aware money input |
| Footer | Site footer |
| Header | Site header with search |
| Icon | AGG icon set |
| InlineAlert | Error/warning inline alert |
| LoadingIcon | Spinner |
| Modal | Dialog/modal |
| NumberValue | Formatted, animated numbers |
| RemoteImage | Image with loading/error |
| Search | Search input |
| Select | Dropdown select |
| Skeleton | Loading placeholder |
| StateMessage | Empty / error state display |
| SwitchButton | Binary toggle switch |
| Tabs | Tab navigation |
| Tooltip | Hover / focus tooltip |
| Typography | Text scale primitives |
| VenueLogo | Venue icon / logo |
Events — @agg-build/ui/events
| Component | Description |
| --------------- | ------------------------------------- |
| EventList | Grid/list of prediction market events |
| EventListItem | Single event row / card |
| ItemDetails | Per-market detail block |
| MarketDetails | Full market detail view |
| Orderbook | Orderbook depth view |
Trading — @agg-build/ui/trading
| Component | Description |
| ------------------- | -------------------------------------- |
| PlaceOrder | Order entry form (managed execution) |
| Settlement | Settlement status card |
| SettlementDetails | Expanded settlement detail |
| TradingContext | Event/market/outcome selection context |
Pages — @agg-build/ui/pages
| Component | Description |
| ----------------- | -------------------------------------- |
| HomePage | Full home page with tabs, search, grid |
| EventMarketPage | Full event/market detail page |
| UserProfilePage | User profile page with tabs |
Modals — @agg-build/ui/modals
| Component | Description |
| ----------------- | --------------------------------------- |
| DepositModal | Deposit flow (managed wallets + chains) |
| WithdrawModal | Withdraw flow |
| OnboardingModal | User onboarding flow |
| ProfileModal | Profile edit + linked accounts |
| GeoBlockModal | Geo-restriction modal |
| GeoBlockBanner | Persistent geo-block banner |
classNames overrides
Most components accept a classNames compound prop so partners can target sub-elements:
<Modal.Header
title="Place order"
classNames={{
root: "custom-header",
title: "custom-title",
close: "custom-close-btn",
}}
/>Key component props
HomePage
| Prop | Type | Description |
| --------------------- | ------------------------------------ | --------------------------------------------------- |
| tabs | HomePageTab[] | Custom tab definitions |
| eventSectionItems | HomePageEventSectionItem[] | Custom event section configuration |
| categoriesLimit | number | Max number of category tabs to show |
| allCategoryTabLabel | string | Label for the "All" category tab |
| actions | ReactNode | Slot for header actions (e.g., <ConnectButton />) |
| withHeader | boolean (default true) | Render the built-in Header with search + logo |
| onEventClick | (event) => void | Called when an event card is clicked |
| onMarketClick | (event, market, outcome) => void | Called when an outcome price is clicked |
| getEventHref | (event) => string | Provide href for SSR-friendly links |
| getMarketHref | (event, market, outcome) => string | Provide href for market links |
| stickyOrderPanel | { enabled: boolean; top?: number } | Stick the order panel when scrolling |
| classNames | HomePageClassNames | Style overrides |
EventMarketPage
Renders the full event page with trading context. Requires <AggProvider> and uses
EventTradingContext internally. Access selection state with useEventTradingContext() from
@agg-build/hooks.
PlaceOrder
Order entry form. Renders inside EventMarketPage or standalone — requires an active
EventTradingContext with a selected market and outcome. Integrates with the managed execution
hooks from @agg-build/hooks.
Entrypoints
| Entry | Purpose |
| ---------------------------- | ---------------------------------------------------------- |
| @agg-build/ui | Root export (re-exports every subpath) |
| @agg-build/ui/primitives | Buttons, Modal, Chart, Tooltip, etc. |
| @agg-build/ui/events | EventList, EventListItem, MarketDetails, Orderbook |
| @agg-build/ui/trading | PlaceOrder, Settlement, trading context utilities |
| @agg-build/ui/pages | HomePage, EventMarketPage, UserProfilePage |
| @agg-build/ui/modals | Deposit/Withdraw/Onboarding/Profile/GeoBlock modals |
| @agg-build/ui/styles.css | Default theme stylesheet (import once at app entry) |
| @agg-build/ui/tailwind.css | Tailwind preset if you run Tailwind v4 yourself |
Peer dependencies
@agg-build/sdk@agg-build/hooksreact^18.0.0 or ^19.0.0react-dom^18.0.0 or ^19.0.0liveline^0.0.7 — charting engine used byChart/LineChart
No wallet packages required. Wallet-backed auth lives in
@agg-build/auth.
Links
- Documentation — https://docs.agg.market/
- Storybook — https://storybook.agg.market/
- Demo app — https://demo.agg.market/
- Vanilla SDK —
@agg-build/sdk - React hooks —
@agg-build/hooks - Connect / sign-in UX —
@agg-build/auth
License
MIT
