import * as react_jsx_runtime from 'react/jsx-runtime'; import { HTMLAttributes, ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, RefObject, CSSProperties, ElementType } from 'react'; interface AvatarProps extends Omit, "children"> { /** Name used for initials and the image alt text. */ name: string; /** Optional image URL; falls back to initials when absent or on error. */ src?: string; /** Diameter in px. Default 28. */ size?: number; } declare function Avatar({ name, src, size, style, ...rest }: AvatarProps): react_jsx_runtime.JSX.Element; type BadgeTone = "neutral" | "accent" | "success" | "warning" | "danger" | "processing"; interface BadgeProps extends HTMLAttributes { tone?: BadgeTone; children?: ReactNode; } declare function Badge({ tone, style, children, ...rest }: BadgeProps): react_jsx_runtime.JSX.Element; interface Crumb { label: string; /** Omit on the current step. A crumb with no handler renders as plain text. */ onClick?: () => void; } interface BreadcrumbProps extends Omit, "children"> { crumbs: Crumb[]; /** The glyph between steps. */ separator?: string; } declare function Breadcrumb({ crumbs, separator, style, ...rest }: BreadcrumbProps): react_jsx_runtime.JSX.Element; /** * `danger` is for the verb that destroys something — Delete, Remove, Forget. It is * filled like `primary`, so it is never the quiet option beside one, and red so the * difference reads before the label does. */ type Variant = "primary" | "secondary" | "ghost" | "danger"; type Size = "sm" | "md"; interface ButtonProps extends ButtonHTMLAttributes { variant?: Variant; size?: Size; children?: ReactNode; } declare function Button({ variant, size, style, className, children, ...rest }: ButtonProps): react_jsx_runtime.JSX.Element; interface TextLinkProps extends ButtonHTMLAttributes { /** Resting tone. Hover always moves toward `accent` (or `danger`). */ tone?: "muted" | "default" | "danger"; children?: ReactNode; } /** A chrome-less text button — for back / delete / retry affordances. */ declare function TextLink({ tone, style, className, children, ...rest }: TextLinkProps): react_jsx_runtime.JSX.Element; interface CardProps extends HTMLAttributes { /** Inner padding (CSS length or px number). Default `0.875rem`. */ padding?: number | string; /** Lift on hover — for clickable cards. */ interactive?: boolean; children?: ReactNode; } declare function Card({ padding, interactive, style, className, children, ...rest }: CardProps): react_jsx_runtime.JSX.Element; interface ConfirmDialogProps { open: boolean; /** Every dismissal path — Escape, the scrim, Cancel — calls this with `false`. */ onOpenChange: (open: boolean) => void; /** Names the dialog (`aria-labelledby`). */ title: ReactNode; /** One line under the title. Becomes the dialog's accessible description. */ description?: ReactNode; /** What the action will do, and any control that shapes it. */ children?: ReactNode; confirmLabel?: string; cancelLabel?: string; /** Confirm's label while `onConfirm` is in flight. Defaults to `confirmLabel`. */ pendingLabel?: string; /** Render Confirm as a `danger` button, and open with focus on Cancel. */ destructive?: boolean; /** Resolve to close. Throw to stay open with the error's message shown. */ onConfirm: () => void | Promise; } declare function ConfirmDialog({ open, onOpenChange, title, description, children, confirmLabel, cancelLabel, pendingLabel, destructive, onConfirm, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element | null; type Side$1 = "left" | "right" | "bottom"; interface DrawerProps extends Omit, "onClick"> { open: boolean; /** Called by the scrim and the Header close button. */ onClose: () => void; /** Called on Escape. Defaults to `onClose` — override to do something else * (e.g. pop one level of a panel stack before closing). */ onEscape?: () => void; side?: Side$1; /** Panel width (ignored for `side="bottom"`, which is full width). Default 480. */ width?: number | string; children?: ReactNode; } declare function DrawerRoot({ open, onClose, onEscape, side, width, style, children, ...rest }: DrawerProps): react_jsx_runtime.JSX.Element | null; interface HeaderProps extends Omit, "title"> { /** * Heading text — rendered as an `

` and wired as the drawer's accessible * name. Renders **instead of** `children` (pass one or the other, not both). */ title?: ReactNode; /** Show a leading back button (e.g. pop one level of a panel stack). */ onBack?: () => void; /** Trailing controls placed before the close button. */ actions?: ReactNode; /** Show a close button that calls this. */ onClose?: () => void; children?: ReactNode; } declare function Header$1({ title, onBack, actions, onClose, style, children, ...rest }: HeaderProps): react_jsx_runtime.JSX.Element; declare function Body$1({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; declare function Footer$1({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; /** `Drawer` with `.Header`, `.Body`, `.Footer` slots. */ declare const Drawer: typeof DrawerRoot & { Header: typeof Header$1; Body: typeof Body$1; Footer: typeof Footer$1; }; interface EmptyStateProps extends Omit, "title"> { icon?: ReactNode; title?: ReactNode; description?: ReactNode; action?: ReactNode; } declare function EmptyState({ icon, title, description, action, style, ...rest }: EmptyStateProps): react_jsx_runtime.JSX.Element; interface ListRowProps extends Omit, "title"> { title: ReactNode; /** Secondary line under the title. */ meta?: ReactNode; /** Leading slot — e.g. a StatusDot or Avatar. */ leading?: ReactNode; /** Trailing slot — e.g. a timestamp or actions. */ trailing?: ReactNode; /** Enables pointer cursor + hover tint. */ interactive?: boolean; } declare function ListRow({ title, meta, leading, trailing, interactive, style, className, ...rest }: ListRowProps): react_jsx_runtime.JSX.Element; interface PageHeaderProps extends Omit, "title"> { /** The trail. Omit on a top-level page, which has nothing above it to name. */ crumbs?: Crumb[]; title: ReactNode; /** Sits beside the title — typically a `Badge`. */ status?: ReactNode; /** Sits at the far end of the title's row. Buttons, a menu. */ actions?: ReactNode; description?: ReactNode; /** Lines the description is clamped to before ellipsis. `0` removes the clamp. */ descriptionLines?: number; } declare function PageHeader({ crumbs, title, status, actions, description, descriptionLines, style, ...rest }: PageHeaderProps): react_jsx_runtime.JSX.Element; interface PaginationProps extends Omit, "onChange"> { /** Current page, 1-based. */ page: number; /** Total number of pages. */ pageCount: number; onChange: (page: number) => void; } declare function Pagination({ page, pageCount, onChange, style, ...rest }: PaginationProps): react_jsx_runtime.JSX.Element; interface ProseProps extends Omit, "children" | "dangerouslySetInnerHTML"> { /** Trusted, pre-sanitized HTML string. */ html?: string; children?: ReactNode; } declare function Prose({ html, children, className, ...rest }: ProseProps): react_jsx_runtime.JSX.Element; interface SearchFieldProps extends InputHTMLAttributes { variant?: "underline" | "boxed"; } declare function SearchField({ variant, style, className, type, ...rest }: SearchFieldProps): react_jsx_runtime.JSX.Element; interface Option { label: string; value: T; } interface SegmentedControlProps extends Omit, "onChange"> { options: Option[]; value: T; onChange: (value: T) => void; } declare function SegmentedControl({ options, value, onChange, style, className, ...rest }: SegmentedControlProps): react_jsx_runtime.JSX.Element; interface SpinnerProps extends HTMLAttributes { /** Diameter in px. Default 16. */ size?: number; /** Arc color. Defaults to the accent token. */ color?: string; } declare function Spinner({ size, color, style, className, ...rest }: SpinnerProps): react_jsx_runtime.JSX.Element; type Status = "working" | "completed" | "failed" | "idle"; interface StatusDotProps extends Omit, "color"> { status?: Status; /** Override the dot color (any CSS color / token). */ color?: string; /** Diameter in px. Default 8. */ size?: number; } declare function StatusDot({ status, color, size, style, className, ...rest }: StatusDotProps): react_jsx_runtime.JSX.Element; type Align$1 = "left" | "right" | "center"; interface Column { /** Stable column id. */ key: string; header: ReactNode; /** Cell content for a row. */ render: (row: T, index: number) => ReactNode; align?: Align$1; /** * Column width (`"40%"`, `220`, `"12rem"`). Declaring one on any column switches * the table to `table-layout: fixed`, and columns without a width then divide the * remainder equally. Required on any column whose cell truncates — see the note on * the module above. */ width?: number | string; } interface TableProps extends Omit, "children"> { data: T[]; columns: Column[]; /** Stable key per row. */ rowKey: (row: T, index: number) => string | number; onRowClick?: (row: T, index: number) => void; /** Shown when `data` is empty. */ empty?: ReactNode; /** * The narrowest this table stays readable, and the switch that turns scrolling on. * * A fixed-layout table has no lower bound of its own, so seven columns in a 400px pane * become seven clipped headers and a badge overflowing its cell. Below this width the * table scrolls inside its own container instead of crushing — and setting the floor is * the only way to ask for that, because a scroller with no floor has no defined moment to * engage: under fixed layout the table always fits its container, and under auto layout it * engages at whatever width the content happens to reach. * * The cost is the sticky header. An `overflow-x` container captures the stickiness * `position: sticky` resolves against the page's own scroller, and CSS gives no way to * scroll one axis while leaving the other visible — so a table without a floor keeps its * sticky header, and one with a floor trades it. */ minWidth?: number | string; } declare function Table({ data, columns, rowKey, onRowClick, empty, minWidth, style, className, ...rest }: TableProps): react_jsx_runtime.JSX.Element; interface Tab { label: string; value: T; /** A small trailing count. Rendered muted, and omitted entirely when undefined. */ count?: number; } interface TabsProps extends Omit, "onChange"> { tabs: Tab[]; value: T; onChange: (value: T) => void; /** Accessible name for the tab set — what these are facets OF. */ label?: string; } declare function Tabs({ tabs, value, onChange, label, style, className, onKeyDown: callerKeyDown, ...rest }: TabsProps): react_jsx_runtime.JSX.Element; type ContentWidth = "reading" | "full"; interface AppFrameProps extends HTMLAttributes { contentWidth?: ContentWidth; children?: ReactNode; } declare function AppFrameRoot({ contentWidth, style, children, ...rest }: AppFrameProps): react_jsx_runtime.JSX.Element; declare function Header({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; interface BodyProps extends HTMLAttributes { /** * Host a full-bleed body layout (SidebarLayout, BoardLayout) edge-to-edge: * no padding, no reading column, and the body itself doesn't scroll — the * layout's panes manage their own scroll. Leave off for plain content * (lists, forms), which get the padded reading/full column. */ bleed?: boolean; } declare function Body({ bleed, style, children, ...rest }: BodyProps): react_jsx_runtime.JSX.Element; declare function Footer({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; /** `AppFrame` with `.Header`, `.Body`, `.Footer` slots. */ declare const AppFrame: typeof AppFrameRoot & { Header: typeof Header; Body: typeof Body; Footer: typeof Footer; }; interface ListDetailState { collapsed: boolean; selected: boolean; listWidth: number | string; onBack?: () => void; } /** Read the list/detail responsive state — for custom back affordances. */ declare function useListDetail(): ListDetailState; interface ListDetailLayoutProps extends HTMLAttributes { /** Is a detail open? Drives which pane shows on a narrow layout. */ selected?: boolean; /** Called by `Back` (and custom triggers) to return to the list when narrow. */ onBack?: () => void; /** Master list width when side-by-side. Default 320. */ listWidth?: number | string; /** Collapse to one-at-a-time below this layout width (px). Default 720. */ breakpoint?: number; children?: ReactNode; } declare function ListDetailLayoutRoot({ selected, onBack, listWidth, breakpoint, style, children, ...rest }: ListDetailLayoutProps): react_jsx_runtime.JSX.Element; declare function List({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element | null; declare function Detail({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element | null; interface BackProps { children?: ReactNode; style?: React.CSSProperties; } /** "← Back" affordance — renders only on a narrow pane with a detail open. */ declare function Back({ children, style }: BackProps): react_jsx_runtime.JSX.Element | null; /** `ListDetailLayout` with `.List`, `.Detail`, and `.Back` slots. */ declare const ListDetailLayout: typeof ListDetailLayoutRoot & { List: typeof List; Detail: typeof Detail; Back: typeof Back; }; interface PageLayoutProps extends Omit, "title"> { /** The trail. Omit at the top level, which has nothing above it to name. */ crumbs?: Crumb[]; title: ReactNode; /** Beside the title — typically a `Badge`. */ status?: ReactNode; /** The far end of the title's row. */ actions?: ReactNode; description?: ReactNode; /** Lines the description is clamped to. `0` removes the clamp. */ descriptionLines?: number; /** * ONE tab bar, of the facets of whatever the title names. A `Tabs`. * * A slot rather than typed props because `Tabs` already has an API worth having, and * wrapping it here would mean maintaining a second copy of it that drifts. What the layout * owns is the bar's POSITION — under the header, above the content — which is the part * apps get wrong. */ tabs?: ReactNode; /** * Controls that narrow the content below: a search field, a status filter, a view toggle. * * Distinct from `tabs` on purpose. A tab changes which facet of one entity is shown; a * toolbar reshapes a set within that facet. Rendering them as one row is how an app ends up * with two identical-looking control strips whose difference nobody can see. */ toolbar?: ReactNode; children?: ReactNode; } declare function PageLayout({ crumbs, title, status, actions, description, descriptionLines, tabs, toolbar, children, style, ...rest }: PageLayoutProps): react_jsx_runtime.JSX.Element; type CollapseMode = "reflow" | "drawer"; type Side = "left" | "right"; interface SidebarState { collapsed: boolean; mode: CollapseMode; side: Side; width: number | string; open: boolean; setOpen: (open: boolean) => void; } /** Read the sidebar's responsive state — for custom triggers or nav re-orientation. */ declare function useSidebar(): SidebarState; interface SidebarLayoutProps extends HTMLAttributes { side?: Side; /** Expanded rail / drawer width. Default 240. */ width?: number | string; /** Collapse below this pane width (px). Default 640. */ breakpoint?: number; collapseMode?: CollapseMode; children?: ReactNode; } declare function SidebarLayoutRoot({ side, width, breakpoint, collapseMode, style, children, ...rest }: SidebarLayoutProps): react_jsx_runtime.JSX.Element; declare function Sidebar({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; declare function Main({ style, children, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; interface TriggerProps extends ButtonHTMLAttributes { /** Override the default hamburger glyph. */ children?: ReactNode; } /** * Hamburger that opens the drawer. Renders only when collapsed in `drawer` * mode, and only when it can see a `SidebarLayout` context — so it's safe to * place anywhere inside the layout subtree (it no-ops elsewhere). Note: in v1 * the context lives on `SidebarLayout` itself, so the trigger must sit inside * it (e.g. a toolbar in `Main`), not in a sibling `AppFrame.Header`. */ declare function Trigger({ children, style, onClick, ...rest }: TriggerProps): react_jsx_runtime.JSX.Element | null; /** `SidebarLayout` with `.Sidebar`, `.Main`, and `.Trigger` slots. */ declare const SidebarLayout: typeof SidebarLayoutRoot & { Sidebar: typeof Sidebar; Main: typeof Main; Trigger: typeof Trigger; }; /** * `useBreakpoint` — responsive hook keyed to an element's OWN width, not the * device viewport. Synapse apps render in an iframe pane whose width the host * controls (fullscreen, split, or a narrow sidebar), so layouts must react to * the space they're actually given. * * Attach the returned `ref` to the element whose width drives the decision. * Width is measured synchronously on mount (no first-frame flash) and kept live * via `ResizeObserver`. SSR/test-safe: without a DOM/`ResizeObserver` it simply * reports `isNarrow: false`. */ declare function useBreakpoint(breakpoint: number): { ref: RefObject; isNarrow: boolean; }; type Align = "start" | "center" | "end" | "stretch" | "baseline"; type Justify = "start" | "center" | "end" | "between" | "around"; interface FlexProps extends HTMLAttributes { gap?: number | string; align?: Align; justify?: Justify; wrap?: boolean; children?: ReactNode; } /** Vertical flex container with `gap`. Defaults to `align: stretch`. */ declare function Stack({ gap, align, justify, wrap, style, children, ...rest }: FlexProps): react_jsx_runtime.JSX.Element; /** Horizontal flex container with `gap`. Defaults to `align: center`. */ declare function Inline({ gap, align, justify, wrap, style, children, ...rest }: FlexProps): react_jsx_runtime.JSX.Element; /** Flexible gap that pushes siblings apart inside a `Stack`/`Inline`. */ declare function Spacer({ style, ...rest }: HTMLAttributes): react_jsx_runtime.JSX.Element; interface DividerProps extends HTMLAttributes { orientation?: "horizontal" | "vertical"; } /** A hairline rule using the border token. Horizontal by default. Decorative * (`aria-hidden`) — it's a visual divider, not a focusable/valued separator. */ declare function Divider({ orientation, style, ...rest }: DividerProps): react_jsx_runtime.JSX.Element; /** * The token contract for `@nimblebrain/synapse/ui`. * * Values are NOT brand hexes — they are `var(--token, fallback)` references to * the CSS custom properties the host injects into the app iframe (the MCP * ext-apps `hostContext.styles.variables`). Because styling resolves through * CSS variables, theme changes (including light↔dark) reflect automatically * with no React re-render: the host swaps the `:root` vars and every `var()` * re-resolves. * * The fallbacks are deliberately **unbranded** — system fonts, neutral grays, a * generic blue, and generic semantic hues for the status channels. NOT * NimbleBrain brand. Brand arrives by injection when the app runs inside the * NimbleBrain host; standalone/static renders get a sane * unbranded default. This keeps the library host-agnostic. * `__tests__/ui/tokens.test.ts` holds the line: every hex in these fallbacks * must be in the sanctioned set, same as `theme-defaults.ts`. * * Components import the static `tokens` object and style with CSS `var()`, so * theming (incl. light/dark) resolves in CSS with no re-render. */ /** Resolved design tokens as CSS `var()` references with neutral fallbacks. */ declare const tokens: { readonly bg: "var(--color-background-primary, #ffffff)"; readonly bgRaised: "var(--color-background-secondary, #fafafa)"; readonly bgSubtle: "var(--color-background-tertiary, #f3f4f6)"; readonly fg: "var(--color-text-primary, #111827)"; readonly fgMuted: "var(--color-text-secondary, #6b7280)"; readonly fgFaint: "var(--color-text-tertiary, #9ca3af)"; readonly accent: "var(--color-text-accent, #2563eb)"; readonly accentFg: "var(--nb-color-accent-foreground, #ffffff)"; readonly border: "var(--color-border-primary, #e5e7eb)"; readonly borderStrong: "var(--color-border-secondary, #d1d5db)"; readonly ring: "var(--color-ring-primary, #2563eb)"; readonly danger: "var(--nb-color-danger, #dc2626)"; readonly dangerFg: "var(--nb-color-danger-foreground, #ffffff)"; readonly success: "var(--nb-color-success, #059669)"; readonly warning: "var(--nb-color-warning, #f59e0b)"; readonly processing: "var(--nb-color-processing, #7c3aed)"; readonly processingLight: "var(--nb-color-processing-light, #f3eeff)"; readonly infoLight: "var(--nb-color-info-light, #eef4ff)"; readonly fontSans: "var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, sans-serif)"; readonly fontMono: "var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)"; readonly fontHeading: "var(--nb-font-heading, system-ui, -apple-system, BlinkMacSystemFont, sans-serif)"; readonly weightNormal: "var(--font-weight-normal, 400)"; readonly weightMedium: "var(--font-weight-medium, 500)"; readonly weightSemibold: "var(--font-weight-semibold, 600)"; readonly weightBold: "var(--font-weight-bold, 700)"; readonly textXsSize: "var(--font-text-xs-size, 0.75rem)"; readonly textXsLine: "var(--font-text-xs-line-height, 1rem)"; readonly textSmSize: "var(--font-text-sm-size, 0.875rem)"; readonly textSmLine: "var(--font-text-sm-line-height, 1.25rem)"; readonly textBaseSize: "var(--font-text-base-size, 1rem)"; readonly textBaseLine: "var(--font-text-base-line-height, 1.5rem)"; readonly textLgSize: "var(--font-text-lg-size, 1.125rem)"; readonly textLgLine: "var(--font-text-lg-line-height, 1.75rem)"; readonly headingSmSize: "var(--font-heading-sm-size, 1.25rem)"; readonly headingSmLine: "var(--font-heading-sm-line-height, 1.75rem)"; readonly headingMdSize: "var(--font-heading-md-size, 1.5rem)"; readonly headingMdLine: "var(--font-heading-md-line-height, 2rem)"; readonly headingLgSize: "var(--font-heading-lg-size, 2rem)"; readonly headingLgLine: "var(--font-heading-lg-line-height, 2.5rem)"; readonly radiusXs: "var(--border-radius-xs, 0.25rem)"; readonly radiusSm: "var(--border-radius-sm, 0.5rem)"; readonly radiusMd: "var(--border-radius-md, 0.75rem)"; readonly radiusLg: "var(--border-radius-lg, 1rem)"; readonly radiusXl: "var(--border-radius-xl, 1.5rem)"; readonly borderWidth: "var(--border-width-regular, 1px)"; readonly shadowHairline: "var(--shadow-hairline, 0 0 0 1px rgba(0,0,0,0.06))"; readonly shadowSm: "var(--shadow-sm, 0 1px 2px rgba(0,0,0,0.05))"; readonly shadowMd: "var(--shadow-md, 0 4px 6px -1px rgba(0,0,0,0.1))"; readonly shadowLg: "var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1))"; }; type Tokens = typeof tokens; /** Body text sizes. */ type TextSize = "xs" | "sm" | "base" | "lg"; /** Heading sizes. */ type HeadingSize = "sm" | "md" | "lg"; /** `{ fontSize, lineHeight }` for a body-text level. */ declare function textStyle(size: TextSize): CSSProperties; /** `{ fontSize, lineHeight }` for a heading level. */ declare function headingStyle(size: HeadingSize): CSSProperties; type Tone = "default" | "muted" | "faint" | "accent" | "danger" | "success"; type Weight = "normal" | "medium" | "semibold" | "bold"; interface TextProps extends Omit, "color"> { size?: TextSize; weight?: Weight; tone?: Tone; mono?: boolean; /** * Single-line ellipsis truncation. * * Sets `display: block` alongside the ellipsis rules, and that is load-bearing rather * than incidental: `overflow` and `text-overflow` do not apply to a non-replaced INLINE * box, so on the default `` the only declaration that survived was * `white-space: nowrap` — and the prop did the exact opposite of its name, making text * unwrappable instead of clipping it. Inside an auto-layout `` that widened the * column to the full string and pushed every later column off the pane. * * `min-width: 0` comes with it so the box can actually shrink as a flex item; without it * a truncating `Text` inside `Inline`/`Stack` refuses to go below its content width and * pushes its container instead, which is the same bug one layer out. * * A truncating cell in a `Table` also needs its column to declare a `width` — see * `Column.width`. Auto table layout sizes to content, so the ellipsis has nothing to * clip against until some column is pinned. */ truncate?: boolean; as?: ElementType; children?: ReactNode; } /** Body text. Defaults to base size, normal weight, primary tone, sans font. */ declare function Text({ size, weight, tone, mono, truncate, as: As, style, children, ...rest }: TextProps): react_jsx_runtime.JSX.Element; interface HeadingProps extends Omit, "color"> { size?: HeadingSize; weight?: Weight; tone?: Tone; as?: ElementType; children?: ReactNode; } /** Display heading using the heading font slot. Defaults to md, semibold. */ declare function Heading({ size, weight, tone, as: As, style, children, ...rest }: HeadingProps): react_jsx_runtime.JSX.Element; export { AppFrame, Avatar, Badge, type BadgeTone, Breadcrumb, Button, Card, type Column, ConfirmDialog, type Crumb, Divider, Drawer, EmptyState, Heading, type HeadingSize, Inline, ListDetailLayout, ListRow, PageHeader, PageLayout, Pagination, Prose, SearchField, SegmentedControl, SidebarLayout, Spacer, Spinner, Stack, type Status, StatusDot, Table, Tabs, Text, TextLink, type TextSize, type Tokens, headingStyle, textStyle, tokens, useBreakpoint, useListDetail, useSidebar };