# Compatibility > Blocks install into any shadcn/ui project, whichever style, component library and icon library it was created with. [shadcn/create](https://ui.shadcn.com/create) lets you pick a style, a component library and an icon library for your project. Every block works with all of them, and installs without edits. Use **Customize** in the sidebar to preview blocks with your setup. The preview, the code and the install command all follow your choice. ## Styles [#styles] Vega, Nova, Maia, Lyra, Mira, Luma, Sera and Rhea all work. Blocks are built from your own `card`, `button`, `badge` and other components, so they pick up your style's spacing, radius and density. Blocks only set the layout and colours that belong to them. ## Colours [#colours] Charts, meters and other data use your theme's chart colours, starting at `--chart-2` and ending with `--chart-1`, the lightest, so they follow the chart colour you picked in shadcn/create. Status has fixed colours, the same in every block: emerald for success, amber for warnings, red for errors and sky for information, with orange between amber and red in longer severity scales. Status always has an icon or a label as well. ## Component libraries [#component-libraries] Base UI, Radix UI and React Aria are all supported. Where the libraries differ, for example Base UI's `render` prop and Radix's `asChild`, each block is published once per library. Install blocks by name, and the shadcn CLI picks the build for your component library: ```bash npx shadcn@latest add @dashboardblocks/kpi-01 ``` `@dashboardblocks` is listed in the [shadcn registry directory](https://ui.shadcn.com/docs/directory), so there's nothing to set up. The first install adds the registry to your `components.json`: ```json title="components.json" { "registries": { "@dashboardblocks": "https://www.dashboardblocks.com/r/{style}/{name}.json" } } ``` The CLI fills in `{style}` from your project. On an older version of the CLI that doesn't read the directory, add these lines yourself. Blocks need version 4.7 of the CLI or later. Older versions write the files into folders named `@components`, `@lib` and `@hooks` instead of your own. ### Registry URLs [#registry-urls] You can also install a block from its URL: | Library | Registry URL | | ---------- | ----------------------------------------------------- | | Base UI | `https://www.dashboardblocks.com/r/base/{name}.json` | | Radix UI | `https://www.dashboardblocks.com/r/radix/{name}.json` | | React Aria | `https://www.dashboardblocks.com/r/aria/{name}.json` | URLs without a library, such as `https://www.dashboardblocks.com/r/kpi-01.json`, are Base UI. ## Routers [#routers] By default, the links in the App Shell, Page Header, Notifications and Onboarding blocks are plain `` elements, so blocks work in any React app. With a client-side router, pass its link to `LinkProvider` once, near the root, and those links navigate without reloading the page. `LinkProvider` comes with the blocks that need it. Next.js's `Link` takes `href`, so pass it as it is, from a client component: ```tsx title="app/providers.tsx" 'use client' import NextLink from 'next/link' import { LinkProvider } from '@/components/dashboardblocks/link' export function Providers({ children }: { children: React.ReactNode }) { return {children} } ``` With `typedRoutes` on, Next.js's `Link` only takes known routes, so wrap it and pass `href` as a `Route`: ```tsx title="app/providers.tsx" 'use client' import type { Route } from 'next' import NextLink from 'next/link' import { type LinkProps, LinkProvider } from '@/components/dashboardblocks/link' function Link({ href, ...props }: LinkProps) { return } export function Providers({ children }: { children: React.ReactNode }) { return {children} } ``` For a router whose link takes `to`, such as React Router, wrap it so it takes `href`: ```tsx import { Link as RouterLink } from 'react-router' import { type LinkProps, LinkProvider } from '@/components/dashboardblocks/link' function Link({ href, ...props }: LinkProps) { return } export function Providers({ children }: { children: React.ReactNode }) { return {children} } ``` The App Shell and Page Header mark the current page from the `pathname` you pass them. Pass your router's, such as Next.js's `usePathname()`, so the active link follows navigation. The mobile sidebar and the notifications panel close when one of their links is followed. With React Aria, the App Shell's sidebar, menu and breadcrumb links are React Aria links, which navigate through its [`RouterProvider`](https://react-spectrum.adobe.com/react-aria/routing.html). Wrap your app in both. ## Icon libraries [#icon-libraries] Lucide, Tabler Icons, HugeIcons, Phosphor Icons and Remix Icon all work. Blocks name each icon in every library, and the shadcn CLI keeps the one in your `components.json`. Blocks don't add an icon package: they use the one your project already has. Blocks that take an icon as a prop, such as `Icon` or the usage meters, take an element, so pass one from any library: ```tsx } size='sm' /> ``` # Introduction > Open-source dashboard blocks for shadcn/ui. Install them with the shadcn CLI and own the code. Dashboardblocks is a set of open-source dashboard blocks built on [shadcn/ui](https://ui.shadcn.com). The shadcn CLI copies each block's source into your project, so you add only the blocks you use and can edit every line. ## How it works [#how-it-works] - Each block installs on its own with the shadcn CLI, along with the components and other blocks it needs. - Blocks use your project's own `card`, `button`, `badge` and other components, so they take on your style. - Every block works with Base UI, Radix UI and React Aria, and with all five icon libraries. See [Compatibility](/docs/compatibility). ## Dashboards [#dashboards] Full dashboards composed from the blocks, with header filters that scope every block below them. Each dashboard is a single component you can install and adapt. Its header controls one query: the date range, comparison and filters. Every block below re-renders from that query, so the numbers always agree. While new data loads, the blocks stay in place, dimmed, instead of flashing skeletons. The data comes from one function in each file (`buildStoreData`, `buildSaasData`, `buildAnalyticsData`, `buildCrmData` and `buildOpsData`). Replace it with your own queries; the blocks only need their props. ### Store [#store] Revenue, orders, average order value and conversion, with revenue over time, revenue by channel, top products, a checkout funnel, month-to-date revenue against its target and low stock. Filter by date range and region, and compare with the previous period. [Open the store dashboard](/docs/dashboards/store) ```bash npx shadcn@latest add @dashboardblocks/dashboard-01 ``` ### SaaS [#saas] MRR, active accounts, churn and NPS as metric tabs, an activity heatmap, MRR by region, MRR movement, retention milestones and live service status. Filter by date range and plan. [Open the SaaS dashboard](/docs/dashboards/saas) ```bash npx shadcn@latest add @dashboardblocks/dashboard-02 ``` ### Web Analytics [#web-analytics] Visitors, page views and bounce rate as metric tabs, visitors right now, a traffic flow from source to outcome, top pages, top countries and browsers. Filter by date range and device. [Open the web analytics dashboard](/docs/dashboards/web-analytics) ```bash npx shadcn@latest add @dashboardblocks/dashboard-03 ``` ### CRM [#crm] Bookings, win rate, deal size and sales cycle with sparklines, open pipeline by stage, monthly bookings, lead conversion, a quarter forecast by rep against quota, deal activity and stuck deals. Filter by date range and segment. [Open the CRM dashboard](/docs/dashboards/crm) ```bash npx shadcn@latest add @dashboardblocks/dashboard-04 ``` ### DevOps [#devops] Live throughput, delivery performance against the DORA bands, response time percentiles, open alerts, 90-day uptime, build health and recent deployments. Filter by service; the date range scopes delivery performance and response times. [Open the DevOps dashboard](/docs/dashboards/devops) ```bash npx shadcn@latest add @dashboardblocks/dashboard-05 ``` # MCP server > Let your coding agent find and install blocks through shadcn's MCP server. shadcn's MCP server lets a coding agent browse the blocks, search them, read their code and install them in your project. It reads the registries in your `components.json`, so add `@dashboardblocks` there once. ## Set up [#set-up] Run both commands in your project, where `components.json` is. Add the registry: ```bash npx shadcn@latest registry add @dashboardblocks ``` Connect the MCP server to your agent. Pick your client: `claude`, `cursor`, `vscode`, `codex` or `opencode`. ```bash npx shadcn@latest mcp init --client claude ``` This adds `shadcn` to your dev dependencies and writes the server to the client's config file: `.mcp.json` for Claude Code, `.cursor/mcp.json` for Cursor, `.vscode/mcp.json` for VS Code and `opencode.json` for OpenCode. For Codex, it prints the lines to add to `~/.codex/config.toml` yourself. Restart the agent, or reload its MCP servers, so it picks up the server. ## Ask for blocks [#ask-for-blocks] Name the registry in your request, so the agent searches it: - Show me the KPI blocks in @dashboardblocks. - Find a block in @dashboardblocks for a checkout funnel and add it to the home page. - Add the store dashboard from @dashboardblocks and replace its data with my orders query. Blocks you can drop into a page end in a number, such as `kpi-01` and `funnel-02`. Each one's description says what it shows, so a search for what you need finds them. Items without a number, such as `kpi` and `funnel`, hold the parts those blocks are built from. Some blocks share files, such as `block-state.tsx`. When the agent installs a block next to one you already have, the CLI may ask whether to overwrite a shared file, which an agent can't answer. Ask it to run the add command with `--overwrite`. # Activity Feed > Activity feeds grouped by day, a record's history as a timeline, notifications with unread state, a weekly digest and social activity. Activity feeds show who did what, and when. Times are relative, like "5 min ago" or "yesterday", with the full date and time on hover, and days are headed "Today" and "Yesterday". Both take a fixed `now` and a time zone, so they render the same on the server and in the browser. Avatars show initials on a tint of your chart colours, picked from the name, when there's no photo. Icons for each kind of activity are decorative, and the sentence next to them says what happened. ### Recent Activity [#recent-activity] What people did across a workspace, newest first and grouped by day. ### Record History [#record-history] The history of one record as a timeline, oldest first, with changes shown from one value to the next and comments quoted in full. ### Notifications [#notifications] Notifications with All, Mentions and Unread tabs. Open one to mark it read, or mark them all at once. ### Weekly Digest [#weekly-digest] A week of activity by kind, with the change on the week before and the most active people. ### Social Activity [#social-activity] Slack and GitHub activity in one timeline, with quoted messages and actions such as starting a review. # AI Assistant > A chat panel docked beside a page, a conversation with code and feedback, questions about a usage card with the cost of each answer, and a failed reply with retry. The assistant works with any model and any API. Messages are plain objects with an `id`, a `role` of `user` or `assistant`, and `content` text, and `status` is `ready`, `submitted`, `streaming` or `error`: the same shapes as the [AI SDK](https://ai-sdk.dev)'s `useChat`. Replies are formatted safely, with no HTML, for paragraphs, lists, **bold**, `code` and fenced code blocks. A new question moves to the top of the log and its reply grows below it, so it reads from the start; a saved conversation opens at its last question. When you're at the bottom the log follows the reply, until you scroll up or select text. Screen readers hear the whole reply once it's done, not every word. The examples stream canned replies; see [Usage](#usage) to connect your own. It's built on shadcn's [Message](https://ui.shadcn.com/docs/components/message), [Bubble](https://ui.shadcn.com/docs/components/bubble), [Marker](https://ui.shadcn.com/docs/components/marker), [Attachment](https://ui.shadcn.com/docs/components/attachment), [Code Block](https://ui.shadcn.com/docs/components/code-block) and [Message Scroller](https://ui.shadcn.com/docs/components/message-scroller), which install with it, so it matches the rest of your chat in your style. Code Block adds the `shiki` package, which colours the code in a reply as it streams, and Message Scroller adds `@shadcn/react`. The typing indicator's shimmer comes from the `shadcn` package's Tailwind CSS: if it doesn't show, update `shadcn` and Tailwind CSS. ### Side Panel [#side-panel] An assistant docked beside the page, with suggested prompts to start from, the page as context, and new chat and close buttons. On narrow screens it covers the page. ### Conversation [#conversation] A conversation with a list and a SQL query. Copy a reply or its code, rate it, regenerate the last one, or pick a follow-up question. ### Ask About Data [#ask-about-data] Questions about an [AI Usage](/docs/blocks/ai-usage) card, with the tokens and cost of each answer. ### Retry [#retry] A reply that failed, kept in the conversation with a button to try again. ## Usage [#usage] The examples run on `useChatStream`, a small hook in the primitives. Give it `onSend`, a function that streams the reply to the conversation so far as chunks of text, and it keeps the messages and status, and handles stop, regenerate and new chat. Stop aborts the `signal`. ```tsx async function* onSend(messages: ChatMessageData[], signal: AbortSignal) { const response = await fetch('/api/chat', { body: JSON.stringify({ messages }), method: 'POST', signal, }) const reader = response.body!.pipeThrough(new TextDecoderStream()).getReader() while (true) { const { done, value } = await reader.read() if (done) return yield value } } const chat = useChatStream({ onSend }) ``` With the AI SDK, use `useChat` instead and pass its values to the same primitives. Its messages keep text in `parts`, so join those into `content`: ```tsx const { messages, regenerate, sendMessage, status, stop } = useChat() const chatMessages = messages.flatMap((message) => message.role === 'system' ? [] : [ { content: message.parts.map((part) => (part.type === 'text' ? part.text : '')).join(''), id: message.id, role: message.role, }, ], ) {chatMessages.map((message) => ( ))} sendMessage({ text })} onStop={stop} /> ``` Render each `ChatMessage` inside `ChatMessages`, and pass `ChatMessages` the `status`: the log places each question at the top when the status turns `submitted`. Put the typing indicator, an error or follow-up suggestions inside it too, after the messages. # AI Usage > Tokens by model, cost by feature, model latency and errors, and prompt caching savings. AI usage blocks track what language models cost and how they perform. Costs come from token counts at per-million prices, with cached input tokens billed at their own, lower rate. Models keep their colour in a fixed order across blocks. Prices and model names in the examples are placeholders; pass your own. ### Token Usage [#token-usage] Tokens per day stacked by model, with the total cost and the cost per million tokens. ### Cost by Feature [#cost-by-feature] Model spend by product feature, with each feature's input, cached and output tokens and its cost per thousand requests. ### Model Performance [#model-performance] Requests, time to first token at the median and 95th percentile, output speed and error rate for each model. ### Prompt Caching [#prompt-caching] The share of input tokens served from the cache, what it saved and what tokens would have cost without it. # Alerts > Alert inboxes, threshold breaches, alert rules and severity summaries. Severity colours are reserved for alerts, and every severity comes with an icon and a label, so colour never carries it alone. Relative times take a fixed `now`, so they render the same on the server and in the browser. ### Inbox [#inbox] Open alerts, most recent first, each with an acknowledge action. ### Threshold Breach [#threshold-breach] The metric over the last hour against its threshold, with the current value, the peak and actions. ### Rules [#rules] Alert rules with their conditions, severities and channels. Pause or resume each one with its switch. ### Summary [#summary] A compact strip with open alerts by severity and the latest one, for the top of a dashboard. # App Shell > The frame around every page, built on the shadcn sidebar. Navigation from data, a workspace switcher, a user menu, breadcrumbs, search and notifications. The sidebar layouts use shadcn's [Sidebar](https://ui.shadcn.com/docs/components/sidebar), so collapsing, the mobile sheet, ⌘B and theming all work as documented there. These blocks add what goes in it. Navigation comes from data and marks the active link from the current path. App Shell also installs its own `hooks/use-mobile.ts`, which replaces the one that comes with the sidebar: it reads the screen width without setting state in an effect, so `react-hooks/set-state-in-effect` passes in a new Vite project. Running `shadcn add --overwrite sidebar` on its own brings the original back. Add an App Shell block again with `--overwrite` to restore this one. Links are plain `` elements. For client-side navigation, pass your router's link to `LinkProvider`. See [Routers](/docs/compatibility#routers). ### Sidebar [#sidebar] A workspace switcher, navigation sections with count badges and a user menu. The top bar holds breadcrumbs, search on ⌘K and notifications. ### Icon Sidebar [#icon-sidebar] Collapses to icons with tooltips, using the trigger, the rail or ⌘B. Sections with child links open when one of them is the current page. Help and settings are pinned to the bottom. ### Inset [#inset] The page sits in a card beside the sidebar. Plan usage with an upgrade link sits above the user menu. ### Top Navigation [#top-navigation] No sidebar. Page links sit under the top bar and scroll sideways on small screens. The user menu is an avatar. # Auth > Accepting an invite, choosing a workspace, a two-factor code at sign-in and verifying an email address. These are the auth pages that are specific to a dashboard with workspaces. For sign-in and sign-up forms, use [shadcn's login blocks](https://ui.shadcn.com/blocks/login). Each page is built on `AuthLayout`: your brand, then one narrow column that stays readable on a phone. Codes go in `OtpInput`, one box per digit. Typing moves to the next box, Backspace goes back, and a pasted or autofilled code fills every box and submits. Every step that waits on the server shows that it's working, and says what to do when it fails. Try `123456` as the code. ### Accept Invite [#accept-invite] The workspace, who invited you, the role you'll get and who's already there. When you're signed in with a different address from the invite, it asks you to switch account instead of joining the wrong one. Pass `expired` for an invite that can't be used. ### Workspace Picker [#workspace-picker] Every workspace you're in, with your role, pending invites you can join from the list, and a search once there are more than five. ### Two-Factor Code [#two-factor-code] The 6-digit code from an authenticator app, with a recovery code instead, the tries left, and trusting the device for a while. ### Verify Email [#verify-email] A code sent by email, a resend that waits a minute between emails, and a way to fix a mistyped address. # Billing > MRR movement, the current plan, changing plans and seats, invoices and revenue metrics for subscription businesses. MRR movement always adds up: starting MRR plus new and expansion, minus contraction and churn, gives ending MRR. Movements are small next to the totals, so the waterfall's axis starts below the lowest running total, the total bars show a break, and the axis says where it starts. Amounts go through one currency formatter, and dates are formatted in UTC so they render the same on the server and in the browser. Increases, decreases and invoice statuses each come with a sign, an icon or a label, so colour never carries them alone. ### MRR Movement [#mrr-movement] Starting to ending MRR as a waterfall, with net new MRR and net revenue retention for the month. ### Current Plan [#current-plan] The plan and its price, when it renews, the next invoice and the payment method on file, with actions to manage them. ### Invoices [#invoices] Recent invoices with their status and amount, what's outstanding, and a PDF download for each. ### Revenue Summary [#revenue-summary] MRR, ARR, ARPU and net revenue retention, each with its change from the previous month. ### Change Plan [#change-plan] Plans side by side, monthly or yearly, with seats. Shows what's due today with credit for the rest of the period, and what a downgrade takes away. Upgrades start today and downgrades at renewal. Plans without a price go to sales. # Breakdown > Part-to-whole views that show how a total splits into categories. ### Segmented Bar [#segmented-bar] A single 100% bar with each category's value and share listed below. ### Composition by Group [#composition-by-group] Compare the mix across groups, with one category's share labelled on every row. ### Waffle [#waffle] A 10×10 grid where each square is 1% of the total. ### Share Shift [#share-shift] How each category's share moved between two periods. # Calendar > Month and week calendars with events, a planner that switches between them, and a day of meeting rooms. Full-size calendars built on plain dates, with no calendar library. The month grid draws timed events as chips, all-day and multi-day events as bars across the days they cover, and "+N more" when a day is full; in narrow containers each day shows dots instead, so pair it with the selected day's events. The week and room views place events on an hour axis, side by side when they overlap, with a line at the current time. Every date takes a fixed `now` and a time zone (UTC unless you pass one), so days and times render the same on the server and in the browser. The date helpers and the day's event list come from [Schedule](/docs/blocks/schedule). ### Month [#month] A month of team events, launches, travel and holidays. Select a day or an event to list the day beside the grid, or move between days with the arrow keys. ### Week [#week] A week on an hour axis that opens at working hours, with overlapping meetings side by side, all-day events at the top and the details of the selected event. ### Planner [#planner] A content calendar that switches between month and week, with each calendar shown or hidden from the sidebar and the selected event's details below it. ### Rooms [#rooms] A day of meeting room bookings, a column per room with whether it's free right now. # Chart Panel > Full-size chart cards with headline figures, legends, tooltips and an accessible data table. ### Period Comparison [#period-comparison] This period against the previous one, with the previous line muted so the current trend leads. ### Metric Tabs [#metric-tabs] Switch between related metrics, each tab showing its total and change. ### Stacked Bars [#stacked-bars] Monthly totals split by category, with a legend and gaps between segments. ### Highlighted Bar [#highlighted-bar] A single series with the latest period highlighted and labelled. ### Breakdown Donut [#breakdown-donut] Part-to-whole at a glance, with values and shares listed beside the donut. ### Percentiles [#percentiles] Ordered series share one hue from light to full strength, labelled at the line ends. # Checklist > Onboarding checklists, setup steppers, progress cards and task lists. Every step is done, in progress, to do or skipped, and each state has its own marker shape and a text label, so colour never carries it alone. Skipped steps are left out of the total, so skipping an optional step doesn't hold progress back. Use these for steps people tick off; for numeric targets, use Goals. ### Onboarding [#onboarding] Setup steps with a progress ring. Each step expands to show what it involves, with the action on the current step and a skip button on optional ones. ### Stepper [#stepper] The stages of a multi-stage setup, side by side on wide cards and stacked on narrow ones. ### Progress Card [#progress-card] A compact card with how many steps are done and the next one, to bring people back to setup. ### Task List [#task-list] Tasks grouped by team, with due dates and checkboxes. Overdue and due-today tasks are flagged with an icon and text. # Command Menu > A search dialog for pages, actions and records, opened from a button or ⌘K. Built on shadcn Command. Built on shadcn's [Command](https://ui.shadcn.com/docs/components/command). Pass groups of items, and the menu filters them as the user types, matching labels, descriptions and keywords. To search your API instead, pass `query` and `onQueryChange`, and the menu shows the groups you give it. Items either go to an `href`, through `onNavigate` for your router, or run `onSelect`. ### Pages and Actions [#pages-and-actions] Jump to a page or run an action, with shortcuts shown beside actions. It opens on ⌘K by default. This preview uses ⌘/, because ⌘K opens this site's search. ### Record Search [#record-search] Recently viewed records before you type, then customers and orders fetched as you type, with a searching state. Try "jonas" or "1042". # Comments > Discussion threads with replies and reactions, a composer that mentions people, review comments you resolve, and a ticket conversation with internal notes. Type @ in any comment box to suggest people: Up and Down choose, Enter or Tab inserts the name, and Escape closes the list. ⌘ or Ctrl + Enter posts. Mentions are highlighted in the posted text. Reactions toggle on and off, and the smiley button opens a row of emoji to add one. Your own comments have a menu to edit or delete them, and a resolved thread collapses to one line you can expand or reopen. Times are relative, with the full date on hover, and take a fixed `now` so they render the same on the server and in the browser. They come from the [Activity Feed](/docs/blocks/activity-feed) primitives. ### Discussion [#discussion] Threads with replies, reactions and a resolved thread, and a box to start a new one. Replying to a reply mentions its author. ### Update [#update] A composer with a preview of how mentions will look and who will be notified, above the latest updates. ### Review [#review] Comments on a document in a column beside it, each quoting the words it's about. Resolve a comment to move it to Resolved, and reopen it from there. ### Ticket [#ticket] A support ticket's conversation, with replies emailed to the customer and internal notes only the team sees. Pairs with [Record Detail: Ticket](/docs/blocks/record-detail#ticket). # Comparison > Compare periods, variants and segments, and show what changed. ### Period over Period [#period-over-period] Each metric this period and last, with the difference and the change. Metrics where a decrease is good are coloured the other way round. ### A/B Test [#ab-test] Lift for a variant over the control, with a 95% confidence interval drawn against zero. The interval uses a normal approximation, which is fine for a dashboard summary; use a stats library when deciding a test. ### What Changed [#what-changed] The change in each segment, as bars either side of zero, sorted from the biggest gain to the biggest drop. ### Before and After [#before-and-after] Two values per row on a shared scale: a hollow dot for before and a filled dot for after. # Dashboard Header > A title with date range presets, a compare switch, filter chips and an export menu, in one row above the dashboard. ### Full Header [#full-header] Title, date range presets, compare switch, removable filter chips, an add filter menu and export. The date line under the title follows the selected range and comparison. ### Compact [#compact] A title with a date range menu and export. ### Segmented Presets [#segmented-presets] Date range presets as a segmented control, with a compare switch and a filter chip. ### Last Updated [#last-updated] A description, the time of the last update and a refresh button, beside the date range and export. # Data Table > Tables for dashboards built on TanStack Table, with sorting, search, filters, row selection and pagination. Rows restack into labelled cards on narrow screens. ### Full Featured [#full-featured] Search, status and plan filters with counts, a column menu and page sizes. Select rows to export them as CSV or email them. Shift-click a header to sort by more than one column. ### Sortable [#sortable] Select a column header to sort by it, and again to reverse the order. On narrow screens, where the headers are hidden, use the sort menu instead. ### Inline Bars [#inline-bars] Revenue by product, with a bar scaled to the top product and each product's share of the total. ### Trends [#trends] Campaign conversions and cost per conversion with their change, plus a 14-day sparkline. ### Status [#status] Services with their status, latency and error rate. Sorted by status, worst first. ### Pagination [#pagination] Recent orders, five to a page. ## Usage [#usage] `useDataTable` creates a [TanStack Table](https://tanstack.com/table) instance with sorting, filtering, search, pagination, row selection and column visibility. It takes every TanStack Table option. `DataTableContent` renders it, laying out each cell from its column's `meta`. ```tsx title="components/orders-table.tsx" const columnHelper = createDataTableColumnHelper() const columns = columnHelper.columns([ createDataTableSelectColumn({ getRowLabel: (row) => row.customer }), columnHelper.accessor('customer', { header: 'Customer', meta: { primary: true } }), columnHelper.accessor('status', { header: 'Status' }), columnHelper.accessor('amount', { cell: ({ getValue }) => `$${getValue().toFixed(2)}`, header: 'Amount', meta: { align: 'end' }, }), ]) function Orders({ orders }: { orders: Order[] }) { const table = useDataTable({ columns, data: orders, pageSize: 10 }) return (
) } ``` `createDataTableSelectColumn` adds a checkbox to each row. Its `getRowLabel` names each checkbox after the row ("Select Northwind"), so a screen reader can tell the rows apart; without it, or for an empty label, the checkbox reads "Select row". Keep `data` and `columns` stable between renders, at module scope or in `useMemo`. Without `pageSize`, or pagination in `initialState` or `state`, the table shows every row. For server-side data, pass `manualSorting`, `manualFiltering` and `manualPagination` with `rowCount`, and control the state with `state` and its `on[State]Change` callbacks. ### Column meta [#column-meta] | Option | Description | | ---------------------- | -------------------------------------------------------------------------------------------- | | `label` | Names the column in menus and labels its values when stacked. Defaults to a string `header`. | | `align` | `'end'` right-aligns the column, for numbers. | | `primary` | The row's title: spans the full width when stacked, without a label. | | `truncate` | Fills the spare width and truncates long text. | | `cellClassName` | Classes for the column's cells. | | `headerClassName` | Classes for the column's header. | | `hideLabelWhenStacked` | Leaves its values without a label when stacked, for a column of row actions. | The layout primitives, `DataTable`, `DataTableRow`, `DataTableCell` and friends, still render static tables without TanStack Table, as in the Inline Bars and Trends examples. # Deployments > Recent deploys, environments and what is waiting to ship, DORA metrics and build health. Deployment blocks show what shipped, where it's running and how healthy the pipeline is. Statuses (ready, failed, running, queued and rolled back) each have an icon and a label, and the running spinner stops for reduced motion. DORA metrics are rated against the widely used elite, high, medium and low bands; bands differ between reports, so adjust `getDoraLevels` to yours. Pass fixed dates, so the blocks render the same on the server and in the browser. ### Recent Deployments [#recent-deployments] The latest builds with their commit, environment, author, how long they took and their status. ### Environments [#environments] What each environment is running and how many commits are waiting to be promoted to the next. ### Delivery Performance [#delivery-performance] The four DORA metrics with their band and the change on the period before, in the direction that's better. ### Build Health [#build-health] The last runs of each pipeline as a strip, with the pass rate and median duration. # Distribution > Histograms with percentiles, box plots by group, spread summaries and before and after comparisons. Distributions show the shape of a metric, not just its average: where most values sit, how far the tail reaches and whether a few large values pull the mean up. Blocks take binned counts, such as histogram buckets from a metrics backend, a summary of percentiles or raw values. Percentiles from bins assume values are spread evenly within each bin, so they are estimates. Every chart comes with a table of the same values for screen readers. ### Histogram [#histogram] Response times in buckets that widen as times grow, with p50, p95 and p99 lines and the buckets over the SLO in red. Hover a bar to read its count. ### Box Plots [#box-plots] One box and whiskers per group on a shared axis: the box spans the middle half, the line is the median and the whiskers reach the 5th and 95th percentiles. ### Spread [#spread] The median, mean and percentiles of raw values, with a note when a long tail pulls the mean away from the median. ### Before and After [#before-and-after] This week's distribution against last week's outline, as shares so weeks of different sizes compare fairly, with both medians and the change at the median and p90. # Error Pages > Not found, no access, something went wrong, down for maintenance and an ended session, each with a way forward. Error pages say what happened in plain words, whose fault it was, and what to do next, so nobody is left on a dead end. Each one is a full page built on `ErrorPageLayout`: your brand at the top, a centred message, then actions. Leave out `brand` to use one inside an [app shell](/docs/blocks/app-shell). Pass `focusOnMount` when the page is a route, so focus moves to the title and screen readers announce the error after a client-side navigation. Times are shown in UTC, and anything that waits on the server shows that it's working and says when it fails again. ### Not Found [#not-found] The path that wasn't found, so a typo is easy to spot, a search, and the places people usually look for. ### No Access [#no-access] Who can give access, a request with an optional message, and the account you're signed in with, since the wrong account is the most common cause. ### Something Went Wrong [#something-went-wrong] Try again, with a count of failed retries, an error ID to copy for support, and the technical details folded away. The details are a shadcn [Code Block](https://ui.shadcn.com/docs/components/code-block), which installs with this page and adds the `shiki` package to your project. ### Maintenance [#maintenance] What's being done, when it'll be back, progress through the planned window, the latest updates, and an email when it's over. When it runs late, it says so instead of showing a time that has passed. ### Session Ended [#session-ended] Why the session ended, whether unsaved work was kept, and a sign-in link that goes back to the same page. # Feedback > Rating breakdowns, sentiment by topic, recent reviews and CSAT over time. Feedback blocks summarise what customers say. Ratings average from the count of each star, and CSAT is the share rating 4 or 5 out of 5, as it's usually reported. Sentiment uses red for negative, grey for neutral and green for positive, always with a legend and the numbers as text. Stars fill to fractions, with the rating read out for screen readers. ### Ratings [#ratings] The average rating with stars, the number of ratings and the share of each star, with the change on the last period. ### Sentiment by Topic [#sentiment-by-topic] Negative and positive mentions either side of a centre line for each topic, on one scale, sorted by net sentiment. ### Recent Reviews [#recent-reviews] The latest reviews with their rating and source, flagging low ratings that are still waiting for a reply. ### Customer Satisfaction [#customer-satisfaction] Weekly CSAT against a target, with the change on the week before and how many weeks met it. # Files > File uploads with progress, cancel and retry, a file table, storage by kind with the largest files, and a folder browser. The dropzone wraps a real file input, so it opens the file picker on click, on tap and from the keyboard, and takes files dragged onto it. It checks type, size and count before anything is sent, and lists files it turns away with the reason. `useFileUploads` works with any storage: pass an `upload` function that sends one file, reports progress and stops when its signal aborts. Uploads run three at a time by default. File icons and colours come from the name or MIME type, sizes count in steps of 1,024, and times take a fixed `now` so they render the same on the server and in the browser. ### Upload [#upload] A dropzone with the accepted types and size limit, and each upload's progress. Cancel an upload while it runs, retry one that failed, or remove it. The example fails every third upload once, to show retry. ### File Table [#file-table] Files with their type, owner, last change and size. Search, filter by type, sort, and download or delete a selection. Each row has a menu to download, copy a link or delete. Built on the [Data Table](/docs/blocks/data-table). ### Storage [#storage] Storage used against the plan, split by kind of file, with the largest files to clean up. Deleting one frees its space. Builds on the [Usage Meter](/docs/blocks/usage-meter) primitives. ### Folder Browser [#folder-browser] Folders and files in a grid, with a path back to the top. Open a folder to go into it; each file has a menu. ## Usage [#usage] ```tsx // fetch can't report upload progress, so this uses XMLHttpRequest. const upload: UploadFn = (file, { onProgress, signal }) => new Promise((resolve, reject) => { const request = new XMLHttpRequest() request.open('POST', '/api/files') request.upload.onprogress = (event) => onProgress(event.loaded / event.total) request.onload = () => request.status < 300 ? resolve() : reject(new Error('Upload failed. Try again.')) request.onerror = () => reject(new Error('Connection lost. Try again.')) signal.addEventListener('abort', () => request.abort()) const body = new FormData() body.append('file', file) request.send(body) }) function Attachments() { const { add, cancel, remove, retry, uploads } = useFileUploads({ upload }) return ( <> {uploads.map((item) => ( ))} ) } ``` `upload` resolves when the file is stored, optionally with its `url`, and rejects with an `Error` whose message the row shows. For S3, R2 or another store, upload to a signed URL the same way, or call your storage SDK and pass its progress to `onProgress`. # Flow > Sankey diagrams for traffic and user paths, income flows and the most common routes. Flows show how a total splits and moves between stages. Nodes sit in columns and bands between them are as wide as the flow. A node's value is the larger of what flows in and out. Downstream nodes take the colour of their largest source, so a flow keeps its hue, and drop-offs are drawn muted. Hover a node or band to highlight what it connects. Each chart comes with a table of its links for screen readers, and scrolls sideways in narrow cards to keep labels legible. ### Traffic Flow [#traffic-flow] Sessions from each source, through the landing page, to signing up, browsing on or bouncing. ### User Paths [#user-paths] Where visitors go in their first pages after landing, with the ones who left at each step. ### Income Flow [#income-flow] Revenue streams into revenue, then out to costs and profit, with each part's share of revenue. ### Top Paths [#top-paths] The most common routes as steps, ranked by how many took them, with how often each reaches the goal. # Forecast > Actuals running into forecasts, dates to target, run-rates and scenarios. Forecasts are a straight-line fit through the actuals, with a prediction interval that widens the further ahead it looks. It's a normal approximation, good enough to show uncertainty on a dashboard but not to plan on. Actuals are solid and forecasts dashed in the same hue, with a shaded range and a label, so a forecast never relies on colour to stand apart. Pass fixed dates, so the blocks render the same on the server and in the browser. ### Actual and Forecast [#actual-and-forecast] Weekly actuals continuing into a dashed forecast with a shaded 80% range and a today marker. ### Date to Target [#date-to-target] When the trend reaches a target, with an 80% range of dates, against the deadline. ### Run-Rate [#run-rate] Month to date, projected to the end of the month at the daily run-rate, with what's needed per day to hit the target. ### Scenarios [#scenarios] Low, base and high growth scenarios from the last actual, as a chart and a table with when each one reaches the target. # Forms > Settings sections with a save bar, a form in a side sheet, a multi-step wizard and inline editing. Built on shadcn Field, with no form library. The fields use shadcn's [Field](https://ui.shadcn.com/docs/components/field). State lives in `useSimpleForm`, a small hook in the primitives. It validates a field when it loses focus with a value in it, and the whole form on submit, focuses the first invalid field, and shows errors your server returns. To use React Hook Form or TanStack Form instead, keep the layout and swap `useSimpleForm` for your library's hook. The fields take the same `id`, `name`, `value`, `onChange`, `onBlur` and `aria-invalid` props. ### Sections [#sections] Fields grouped into titled sections. A save bar appears while there are unsaved changes. Try the URL "acme" to see an error from the server. ### Sheet [#sheet] Create a record in a panel that slides in from the side. Try the email "taken@example.com" to see an error from the server. ### Wizard [#wizard] A form in steps. Next checks the current step before moving on, and the last step reviews everything before it's created. ### Inline Edit [#inline-edit] Edit one value at a time, in place. Enter saves and Escape cancels. # Funnel > Conversion funnels with step and overall conversion, drop-off and segment comparison. ### Stage Bars [#stage-bars] Each stage sized against the first, with step conversion and overall conversion. ### Columns [#columns] Vertical stages with the lost share shown as the track above each column. ### Steps [#steps] A vertical stepper that calls out the step with the biggest drop-off. ### Segment Comparison [#segment-comparison] Two segments side by side at every stage, as a share of their first step. # Gauge > NPS, health scores, system load and scores against a target, on radial gauges. A gauge is for one number on a known scale, where the bands or the target matter as much as the value. Each gauge is a `meter` with its range and a text value for screen readers, and every band comes with a label and an icon, so colour never carries it alone. Bands sit on the track when you mark the value with a knob, or as a thin scale inside the track when the value is a fill. The fill animates in once, and not at all with reduced motion. ### Net Promoter Score [#net-promoter-score] NPS on its full −100 to 100 scale, filled from zero, with the split of promoters, passives and detractors behind it. ### Health Score [#health-score] An account health score weighted from its contributing factors, marked on poor, fair and good bands. ### System Load [#system-load] CPU, memory and disk as small gauges. Each fill takes the colour of its band, and the warning and critical thresholds show as a scale inside the track. ### Score Card [#score-card] A satisfaction score with a target tick on the arc, the change since last period and the gap to target. # Geo > State tile maps, dotted world maps, top countries and regional splits. The maps need no map library or data files: US states are a grid of equal square tiles, so small states are as easy to read as large ones, and the world map is a dotted land mask of about 1.3 KB embedded in the component. Hover, focus or tap a tile or marker to read it under the map; with the keyboard, Tab into the map and use the arrow keys, Home and End. Every map has a legend and gives screen readers its data as a table. Flags are emoji, which some platforms, such as Windows, draw as two letters. ### State Tile Map [#state-tile-map] Revenue by state on a single-hue scale, with the total and the top five states. ### Top Countries [#top-countries] The leading countries with flags, values and shares, and the rest summed into one row. ### Dotted World Map [#dotted-world-map] Active users by city right now, with markers sized by value. ### Region Split [#region-split] Revenue split across regions, each with its share and change on the previous quarter. # Goals > Progress towards targets, with pace against where you should be by now. Pace compares progress with a straight line from zero to the target over the period. Within 5% of that line counts as on track. Use it for values that build up over the period, such as revenue or deals closed, not for rates. ### Target [#target] One target with an expected-by-today marker, what's left and a projection at the current pace. ### Goal List [#goal-list] Several goals for the same period, each with its own pace. ### Projection [#projection] Cumulative progress this month, projected to the end of the month at the current daily rate, against the target line. ### Daily Rings [#daily-rings] Small daily goals as rings, with a check mark once a goal is met. # Heatmap > Grids of cells coloured by value, for patterns over time and across groups. Hover a cell to read it in the line under the grid. With the keyboard, Tab into the grid and use the arrow keys, Home and End to move between cells; screen readers announce each cell with its row, column and value. ### Weekday by Hour [#weekday-by-hour] When visitors arrive, by day of the week and hour of the day. ### Cohort Retention [#cohort-retention] The share of each weekly signup cohort still active in each week after signup. ### Calendar [#calendar] A year of daily values. On narrow screens the grid scrolls sideways and starts at the most recent weeks. ### Hot Spots [#hot-spots] p95 latency by endpoint over the last 24 hours, darker where it's slower. # Insights > Plain-language insights, anomaly callouts, key drivers and weekly digests. Insights explain what the data shows in a sentence, with the numbers that matter highlighted inline. Each insight has a kind (positive, negative, neutral or anomaly) that describes the outcome, not the direction, so churn falling is positive. Every kind comes with an icon and a label, and highlighted metrics say their direction in words, so colour never carries the meaning alone. The blocks render the text you pass them: generate it however you like, on the server or ahead of time. ### Feed [#feed] A list of insights, each with its kind, the topic, the sentence with its metrics highlighted, an optional "why" line of drivers and a link to explore. ### Anomaly Callout [#anomaly-callout] An unusual reading against the range it was expected to fall in, with the days outside it highlighted, the explanation and the likely causes. ### Key Drivers [#key-drivers] What contributed to a change, as bars either side of zero. The summary sentence is built from the numbers: the change, the biggest driver and the biggest drag. ### Weekly Digest [#weekly-digest] A headline, three takeaways and helpful or not helpful buttons. The buttons are toggles: press one again to take the feedback back. # Inventory > Low stock with what to reorder, warehouse capacity, stock health and a stock projection. Inventory blocks show what's running low and what to do about it. An item is low at or below its reorder point and out of stock at zero, and each status has an icon and a label. Days of cover is stock on hand over daily demand. The reorder quantity covers the lead time plus a target number of days, less what's on hand and on order. Pass a fixed date, so the blocks render the same on the server and in the browser. ### Low Stock [#low-stock] Items at or near their reorder point, soonest to run out first, with how much to order and which will run out before an order arrives. ### Warehouse Capacity [#warehouse-capacity] Units stored against capacity in each warehouse, with what arrives this week and which will be nearly full. ### Stock Health [#stock-health] Every SKU by status, with the value of stock on hand and how many times a year it turns over. ### Stock Projection [#stock-projection] One item's stock day by day at its current demand, with incoming orders, the reorder point and when it runs out. # Invoice > Invoices, receipts, quotes and packing slips that print cleanly, with totals that add up to the cent. Totals are worked out in cents, or the currency's smallest unit, so the subtotal, discount, tax, shipping and total always add up. A discount is shared across tax rates in proportion to their lines, and tax is rounded once per rate. Dates are formatted in UTC so they render the same on the server and in the browser, and amounts, statuses and dates come from [Billing](/docs/blocks/billing). Printing uses Tailwind's `print:` variants, so there's no stylesheet to add. The toolbar and other screen-only controls hide, the card fills the paper, and dark mode prints black on white. Rows, totals and notes don't split across pages, and the table header repeats on each page. Your app's own sidebar and header print too, so add `print:hidden` to them. The previews on this page print the whole docs page. ### Invoice [#invoice] An overdue invoice with a discount, sales tax, a deposit and the balance due, how to pay online or by bank transfer, and a reminder you can send. ### Receipt [#receipt] A paid receipt with the payment method, a partial refund and the net amount paid. Narrow tables show quantity and unit price under each item. ### Quote [#quote] Optional items to tick before accepting, with totals that follow, and an expiry date. The printed copy has a signature block instead of the buttons. ### Packing Slip [#packing-slip] Items with their SKU and bin, a checkbox for each one picked, and a scannable barcode of the order number. No prices, so it can go in a gift. # Kanban > Boards you can edit, for sprints, deals and support tickets. Drag cards between columns with a mouse, a finger or the keyboard. Drag a card to another column or to a new place in its own. On a touch screen, press and hold a card to pick it up, so a swipe still scrolls the board. With a keyboard, focus a card's title and press Space or Enter to pick it up, the arrow keys to move it between columns and up and down, then Space or Enter to drop it or Escape to put it back. Every step is announced to screen readers, and each card also has a Move menu. Near the edges the board scrolls under the card. Columns can set a WIP limit, shown as "3 / 4" beside the title. By default a column can go over its limit and turns red; set `wipLimitMode='block'` to refuse cards instead. The board reports each move as `onMove(id, column, index)`, and `moveItem` applies it to your array. Due dates take a fixed `now`, so they render the same on the server and in the browser. For a read-only view of work by stage, see [Pipeline](/docs/blocks/pipeline). ### Sprint Board [#sprint-board] Issues with labels, assignees, due dates, priorities, comments and subtasks. In progress and In review have WIP limits that warn when they're passed. ### Deals [#deals] A sales board with each column's total value, which updates as deals move, and the next step on every deal. The Lost column collapses to a strip that still takes drops. ### Support Queue [#support-queue] Tickets with priority and time left to their SLA, paused while waiting on the customer. Add tickets from the first column. Escalated is full, so it refuses more tickets until one moves on. # KPI > KPI cards with the change on the last period, progress to a target, and bar, line and area charts. A KPI card puts one headline number first, with what it means next to it: the change on the previous period, the target it's working towards or the shape of the week behind it. Changes come from the value and the previous value, in percent or in percentage points for rates, and keep their arrow and sign so colour never carries them alone. Use `goodDirection` for metrics like churn, where a drop is good. Values count up once in view, and screen readers get the final value. Numbers use named formats in `en-US`, so the server and the browser render the same, and every chart has a text alternative. ### Headline [#headline] A value with its change and what it's compared with. ### Change Badge [#change-badge] A value with its change as a badge beside the label. ### Previous Value [#previous-value] A rate with its previous value underneath and the change in percentage points. ### Target Pace [#target-pace] Progress to a monthly target, with a tick where an even pace would be by today and the total you're on pace for. ### Status Breakdown [#status-breakdown] The share of work done, with a bar for each status. ### Goal Ring [#goal-ring] A count against a goal as a ring, with how many are left to go. ### Bar Chart [#bar-chart] The week's total with a bar for each day and the change on the week before. ### Actual vs Goal [#actual-vs-goal] Each day's value next to its goal, with the share of the goal reached and how many days met it. ### Line Chart [#line-chart] This week against the same days last week, drawn as a solid and a dashed line. ### Area Chart [#area-chart] Gross profit with its margin, and revenue and profit by day as stacked areas. ### Background Chart [#background-chart] A total with an area chart behind it, for a hero card at the top of a dashboard. # Leaderboard > Ranked lists for top pages, products, people, and regions. ### Share Bars [#share-bars] Ranked rows with a background bar sized relative to the leader. ### Team Ranking [#team-ranking] People ranked by revenue with top-three rank badges and period-over-period trend. ### Podium [#podium] Top three on a staged podium, with the rest of the field listed below. ### Rank Movement [#rank-movement] Products ranked by revenue with change in position since the last period. ### Sortable [#sortable] Reverse the sort order and expand the list to show every entry. # Metric List > Many metrics in one card, one row each, with their change, sparkline or target. A metric list is lighter than a data table and denser than a stat group: one row per metric, with the value and change in fixed columns so rows line up. Green and red follow whether a rise is good, so a drop in latency reads as good, and every change keeps its arrow and sign. Values use named formats in `en-US`, so the server and the browser render the same. ### Sparklines [#sparklines] Metrics with their change and a 14-day sparkline. On narrow cards the change moves under the value. ### Sections [#sections] Metrics grouped into sections, each with a header and how many of its metrics improved. ### Targets [#targets] Metrics against their targets, each with a bar, a tick at the target and a status. Targets can be floors or ceilings. ### Watchlist [#watchlist] Select a metric to chart it in the same card. The list is a radio group, so it works with the arrow keys. # Notifications > A bell with an unread count that opens the latest notifications, requests you can approve from the panel, and a full inbox. Clicking anywhere on a notification opens it and marks it read. Buttons inside a notification, like Approve, work on their own. Times are relative, with the full date on hover, and take a fixed `now` so they render the same on the server and in the browser. The rows build on the [Activity Feed](/docs/blocks/activity-feed) primitives. For a notifications card inside a dashboard, see [Activity Feed: Notifications](/docs/blocks/activity-feed#notifications). Links are plain `
` elements. For client-side navigation, pass your router's link to `LinkProvider`. See [Routers](/docs/compatibility#routers). ### Bell [#bell] The latest notifications in a panel, with mark all as read and a link to the inbox. ### Requests [#requests] Notifications that ask for a decision, such as a request to join or a refund, with a tab of the ones still waiting. ### Inbox [#inbox] Every notification grouped by day, filtered by unread and mentions. Mark each read or unread, or archive it. # Onboarding > A first-run setup wizard, a welcome page for an empty workspace, a data source picker and a short personalisation step. Choice cards are native radio buttons and checkboxes, so Tab reaches each group, the arrow keys move between options and they work in any form. When a step changes, focus moves to its title, so keyboard and screen reader users start from the top. The wizard's fields use `useSimpleForm` from [Forms](/docs/blocks/forms), and setup progress uses the [Checklist](/docs/blocks/checklist) primitives. For a getting-started checklist inside a dashboard, see [Checklist: Onboarding](/docs/blocks/checklist#onboarding). Links are plain `` elements. For client-side navigation, pass your router's link to `LinkProvider`. See [Routers](/docs/compatibility#routers). The wizard's Sign out stays a plain ``, since signing out usually needs a full request. ### Setup Wizard [#setup-wizard] Name the workspace and pick its URL, say what it's for, then invite the team. Each step checks its own fields, and the URL is checked with the server before moving on. Try `acme` to see a taken URL. Paste a list of addresses into an email field to fill a row for each. ### Welcome [#welcome] The first page of an empty workspace: quick starts, an empty dashboards list with a way in, setup progress and help. ### Connect a Source [#connect-a-source] Search and filter the sources, pick one, then follow it through connecting to connected. Snowflake fails, to show the error state. ### Personalise [#personalise] A role, a team size and up to three goals, turned into the dashboards set up for them. # Page Header > The top of a page. A heading with actions, section tabs, a record's header with a back link and facts, and a list page's search. The heading is the page's `

`. Actions sit beside it on wide headers and wrap under it on narrow ones, measured by the header's own width. Links are plain `` elements. For client-side navigation, pass your router's link to `LinkProvider`. See [Routers](/docs/compatibility#routers). ### Actions [#actions] A title and description with a secondary and a main action. ### Tabs [#tabs] A status badge and links to the page's sections, with counts. ### Record [#record] A back link, an avatar, facts about the record and a menu for less common actions such as delete. ### List [#list] A count beside the title, with search and the main action on the same row. # Pipeline > Work in flight across stages, from sales deals to tickets and hiring. A pipeline shows where work sits right now, not how many people dropped out along the way; for conversion, use the [Funnel](/docs/blocks/funnel). Stages are ordered, so they share one hue that deepens towards the last stage. Each stage can set the days an item is expected to spend in it: items over that turn amber and swap their clock icon, so the state never rests on colour alone. Days in stage take a fixed `now`, so they render the same on the server and in the browser. ### Board [#board] A column per stage with its item count and total value, and a card per item. The columns scroll sideways when they don't fit. There's no drag and drop: move an item from its menu, which works with a keyboard and a screen reader. ### Stage Summary [#stage-summary] A compact strip with each stage as a segment sized by value or by count, for the top of a dashboard. ### Stuck Items [#stuck-items] Items over their expected time in stage, longest over first, with how long they've waited and who owns them. ### Weighted Forecast [#weighted-forecast] Closed plus open deals weighted by the chance their stage closes, per owner, against quota. # Realtime > Active users right now, live throughput, an activity stream and today so far. Realtime blocks show data that keeps changing. Each block takes its first values as props, so it renders the same on the server and in the browser, then updates from state. Set `simulate` to see it move with made-up data, or replace the interval in the block with your own feed, such as a WebSocket or polling. Numbers count to each new value, and the pulse and counting stop for reduced motion. Updates aren't announced to screen readers, which would be noisy every second. ### Right Now [#right-now] Active users, page views per second over the last minute and the pages with the most people on them. ### Throughput [#throughput] Requests per second over the last five minutes, with the peak, the error rate and errors on their own scale. ### Live Activity [#live-activity] Orders, sign-ups, refunds and messages as they arrive, newest first, with a pause button. ### Today So Far [#today-so-far] Running totals since midnight against yesterday at the same time, with orders per hour. # Record Detail > Pages for one customer, order or ticket. Headline numbers, related records, a timeline and a column of properties. A record's page puts the main content first and a narrower column of properties beside it. The column moves below the content when the page is narrow, measured by the page's own width. The headers are built from [Page Header](/docs/blocks/page-header) and the timelines from [Activity Feed](/docs/blocks/activity-feed). ### Customer [#customer] Headline numbers, recent orders, contact details and notes. ### Order [#order] Line items with totals, a timeline of what happened, the customer, and shipping and payment. ### Ticket [#ticket] A description, activity with comments, a comment box, and properties such as status, assignee and labels. # Retention > Cohort tables, retention curves, day 1, 7 and 30 milestones and growth accounting. Retention follows each cohort, such as everyone who signed up in March, from the period they joined. Pass a cohort's size and how many were still active in each period since, starting with period 0. Newer cohorts have fewer periods. Averages are weighted by cohort size, so a small cohort doesn't swing them. Changes are in percentage points, not percent. ### Cohort Table [#cohort-table] A retention triangle with one row per cohort and a weighted average row. Cells are shaded against the best share after period 0, so period 0's 100% doesn't wash out the rest. Hover a cell to read its count. ### Retention Curves [#retention-curves] Every cohort's curve, with one highlighted against the average and where the average levels off. ### Milestones [#milestones] Day 1, 7 and 30 retention for the latest cohort, with the change against the cohort before. ### Growth Accounting [#growth-accounting] Users gained (new and resurrected) above the axis and lost (churned) below it, with the net change and the quick ratio: users gained for each one lost. # Scatter > Correlations with a trend line, 2×2 priority quadrants, bubble charts and a risk matrix. Scatter blocks plot two measures against each other, one dot per item. Series keep their colour in a fixed order, and every point has a tooltip and a row in the table read by screen readers. A correlation is a least-squares line with Pearson's r, described in words, which says how closely two measures move together, not that one causes the other. ### Correlation [#correlation] Pages by load time and conversion rate, grouped by section, with a trend line and how strong the relationship is. ### Quadrants [#quadrants] Features by usage and satisfaction, split at the medians into four labelled quadrants, with each point named. ### Bubbles [#bubbles] Campaigns by cost per acquisition and conversion rate, sized by spend and coloured by channel. ### Risk Matrix [#risk-matrix] Open risks on a likelihood by impact grid, shaded by level. Select a cell to list its risks. # Schedule > Agendas, month calendars, deadlines and the week ahead. What's coming up, the forward-looking counterpart to the activity feed. Every date helper takes a fixed `now` and a time zone (UTC unless you pass one), so days, times and countdowns render the same on the server and in the browser. Each event's colour comes with its calendar name, and urgency comes with an icon and a label, so colour never carries meaning alone. ### Agenda [#agenda] Upcoming events grouped by day, as Today, Tomorrow and then weekdays, with the event in progress marked. ### Calendar [#calendar] A month calendar with a dot for each event. Select a day with the mouse or the keyboard to list its events. ### Deadlines [#deadlines] Deadlines and renewals in date order, each with a countdown and an urgency badge. ### Week Ahead [#week-ahead] The next seven days on a shared time axis, with how many events each day holds and how much of it is booked. # Security > Sign-in activity, an audit log, active sessions, a security posture score, two-factor authentication and single sign-on. Security blocks show who is getting in, what changed and how well the workspace is set up. Severities and check results each have an icon and a label, so colour never carries them alone. Pass fixed dates, so the blocks render the same on the server and in the browser. ### Sign-in Activity [#sign-in-activity] Succeeded, failed and blocked sign-ins per day, with the failure rate, spikes in blocked attempts and MFA coverage. ### Audit Log [#security-audit] Changes to access, keys and settings, newest first, with a toggle to show warnings only. ### Active Sessions [#active-sessions] The devices signed in to an account, with where and when each was last active, and buttons to sign them out. ### Security Posture [#security-posture] A weighted score from workspace checks, with failing checks first and what to do about each. ### Two-Factor Authentication [#two-factor-authentication] Set up an authenticator app with a QR code and a 6-digit code, add security keys and passkeys, and get recovery codes that are shown once. When the workspace requires two-factor, the last method can't be removed. ### Single Sign-On [#single-sign-on] A SAML connection with the details to copy into your identity provider, domains verified by TXT record, and a switch to require SSO once a domain is verified. # Settings > Members and invites, API keys, notification preferences, integrations, webhooks, a danger zone and your profile. Settings blocks are the pages every dashboard needs behind the charts: who can get in, what they can do, where notifications go and what the workspace is connected to. Each block keeps its own state so it works as soon as it's installed, and calls back with every change so you can save it. Roles, connection statuses and webhook deliveries each have a label, and failed deliveries are taller as well as red, so colour never carries them alone. Secrets are only ever shown once, and anything that can't be undone asks for the workspace name first. Pass fixed dates, so the blocks render the same on the server and in the browser. ### Members [#members] Invite people by email with a role, change roles, remove members, and resend or revoke pending invites. Counts seats against the plan, and stops invites when they're all taken. ### API Keys [#api-keys] Keys with their access, when they were last used and who created them, with unused keys flagged. A new key is shown once, with a button to copy it. ### Notifications [#notifications] Each notification against each channel, grouped by topic, with a switch per channel to turn it on or off for everything. ### Integrations [#integrations] Connected and available integrations, with a tab for each, what they do, and ones that need reconnecting. ### Webhooks [#webhooks] Endpoints with the events they receive, their recent deliveries and delivery rate, and a switch to pause each one. An endpoint is failing when its last three deliveries failed. ### Danger Zone [#danger-zone] Transferring, archiving and deleting the workspace. Deleting asks for the workspace name first. ### Profile [#profile] Your photo, name, email, time zone and theme. A new email only takes effect once it's confirmed, and photos over 2 MB are refused before upload. # Spend > Budget against actual, spend by service, monthly variance, and burn and runway. Spend blocks compare what's gone out with what was planned. Pace assumes the budget is spent evenly over the period, so the projection is spend so far divided by the share of the period gone. A status says whether that lands under, on or over budget, with an icon and a label as well as a colour. Pass fixed dates, so the blocks render the same on the server and in the browser. ### Monthly Budget [#monthly-budget] Spend so far against the month's budget, with the projected month end and what's left to spend per day. ### Spend by Service [#spend-by-service] One budget bar per service, each with its own status, and the total underneath. ### Spend vs Budget [#spend-vs-budget] Monthly spend as bars against a stepped budget line, with months over budget in red and the year-to-date variance. ### Burn and Runway [#burn-and-runway] The cash balance, the average net burn and how many months of runway are left, with the balance projected to zero. # Stat Group > A row of related metrics in one card, each with its change vs the previous period. ### Plain Row [#plain-row] Three metrics side by side, each with its change and previous value. The row keeps its columns on narrow screens. ### With Sparklines [#with-sparklines] Each metric with a 14-day sparkline. On narrow screens the sparkline moves beside the value. ### Metric Tabs [#metric-tabs] Select a metric to chart it against the previous period. The tabs work with the arrow keys. ### Compact Strip [#compact-strip] Five metrics in a slim row that wraps to two columns on narrow screens. ### Responsive Grid [#responsive-grid] Four columns, then a 2×2 grid, then a single stack as the card narrows. # States > Loading, refreshing, empty and error states that keep the block's layout. Each block takes a `load` function that returns a promise, and the `useBlockData` hook tracks its status. Use a skeleton only for the first load. When data is already on screen, keep it in place while it refreshes, dimmed, so the layout doesn't jump. ### Skeleton [#skeleton] Placeholders sized to match the loaded stats, so nothing shifts when the data arrives. Select Reload to see them again. ### Refresh [#refresh] The chart stays in place at reduced opacity while it refreshes, with an updating indicator in the header. ### Empty [#empty] A filtered table with no matching rows explains why it's empty and offers a way out. ### Error [#error] When loading fails, the card says what went wrong and offers to try again. This example fails on every other attempt. # Status > Service status, uptime history, incidents and regional health. ### Service List [#service-list] Each service with its current status, and an overall badge for the worst one. ### Uptime Bars [#uptime-bars] Ninety days of daily status per service. Hover a day, or focus the bar and use the arrow keys, to read it. ### Incident [#incident] An active incident with its severity, affected components and update timeline. ### Region Health [#region-health] A grid of regions with status, latency and error rate. ### Service Uptime [#service-uptime] One service's uptime, incident count and downtime, with its daily history and recent incidents. # Team > Member lists with presence, workload against capacity, who is online, on-call rotas, roles and permissions, and sharing. These blocks are about the people on a team, not how they rank. Avatars show initials on a tint of your chart colours picked from the name, so the same person gets the same tint everywhere without needing a photo. Presence always has a label next to its dot, and offline is a hollow dot, so colour never carries it alone. Avatar stacks keep every name for screen readers and on hover, and say how many are hidden behind the "+N". Times take a fixed `now`, and handovers are shown in a named time zone, so they render the same on the server and in the browser. ### Member List [#member-list] Members with their role, presence and when they were last active. ### Workload [#workload] Work assigned to each person against their capacity on a shared scale. Anyone over capacity is flagged and listed first. ### Who's Online [#whos-online] How many people are online, with their avatars, and the team split by presence. ### On Call [#on-call] Who is on call now and until when, who is next, and the rest of the rota. ### Roles and Permissions [#roles-and-permissions] What each role can do, as a grid of permissions by role. Granting a permission also grants what it needs, and revoking one revokes what depends on it. Changes are highlighted until they're saved, and locked roles, like the owner, have everything. ### Share [#share] Invite people to a dashboard with view or edit access, change or remove it, and choose who the link works for. # Timeline > Roadmaps, launch milestones, release cadence and plan against actual. Timelines place work on a calendar. Dates are handled in UTC, so pass fixed dates and a fixed `now`, and the blocks render the same on the server and in the browser. Statuses (done, in progress, planned and at risk) each have an icon and a label, so colour never carries them alone. Wide timelines scroll sideways in narrow cards, with the labels kept in view. ### Roadmap [#roadmap] Projects grouped by team, each a bar from start to end filled to its progress, with a today line. Hover a bar for its dates. ### Milestones [#milestones] A launch plan as a list on a rail, with the next milestone highlighted and how soon, or how late, each one is. ### Release Cadence [#release-cadence] Every release on one line, sized by major, minor and patch, with the median gap and days since the last one. ### Plan vs Actual [#plan-vs-actual] Each phase's plan as a dashed outline and what actually happened as a bar beneath it, with how many days it slipped. # Usage Meter > Usage meters for quotas, storage, metered billing, prepaid credits and plan limits, with projections and upgrade prompts. Usage meters show how much of a limit is used and what happens next. Usage is within limit, nearing it from 80%, critical from 95% and over past 100%, and each status has an icon and a label, so colour never carries it alone. Projections take the average daily rate so far to the end of the period, drawn as a striped segment on the bar. When usage or a projection goes past the limit, the bar extends and the limit shows as a tick. Pass fixed dates, so the blocks render the same on the server and in the browser. ### Quota [#quota] An API quota with its status, when it resets and the usage it's on pace for, with the date it would hit the limit. ### Storage Ring [#storage-ring] Storage used as a ring in its status colour, with the space that's free. ### Metered Billing [#metered-billing] Usage against what the plan includes, with overage past the limit and what it will cost. ### Prepaid Credits [#prepaid-credits] A credit balance with the average daily use, the date it runs out and a strip of recent days. ### Storage Breakdown [#storage-breakdown] Storage by category as one segmented bar, with each category's size and share. ### Plan Limits [#plan-limits] Every limit on a plan, flagging the ones nearly reached and prompting an upgrade. ### Liquid Gauge [#liquid-gauge] What's left as a liquid that drains as usage grows and turns amber, then red. It's a `meter` for screen readers, and the wave stops for reduced motion. # CRM > A full CRM dashboard built from Dashboardblocks, with sales stats, open pipeline, monthly bookings, lead conversion, a quarter forecast by rep, deal activity and stuck deals. ## Blocks used [#blocks-used] Each block installs on its own. Open one to see its code and variants. # DevOps > A full DevOps dashboard built from Dashboardblocks, with live throughput, delivery performance, response time percentiles, open alerts, uptime, build health and recent deployments. ## Blocks used [#blocks-used] Each block installs on its own. Open one to see its code and variants. # SaaS > A full SaaS dashboard built from Dashboardblocks, with metric tabs, an activity heatmap, MRR by region, MRR movement, retention milestones and service status. ## Blocks used [#blocks-used] Each block installs on its own. Open one to see its code and variants. # Store > A full store dashboard built from Dashboardblocks, with header filters, stats, revenue, channels, products, a checkout funnel, month-to-date revenue and low stock. ## Blocks used [#blocks-used] Each block installs on its own. Open one to see its code and variants. # Web Analytics > A full web analytics dashboard built from Dashboardblocks, with traffic tabs, visitors right now, a traffic flow, top pages, countries and browsers. ## Blocks used [#blocks-used] Each block installs on its own. Open one to see its code and variants.