/** * UI primitives for `cursor/canvas`. Styling follows the Cursor dark theme; no extra packages required. */ import { type CSSProperties, type JSX, type ReactNode } from "react"; /** * Shallow-merge style objects with `override` taking precedence. * * Use for small tweaks on built-in components (e.g. extra padding or width). * **Do not** use this to build elaborate custom chrome — prefer the built-in * components and flat solid token colors. No gradients, no box-shadows. * * @example * ```tsx * // Good — minor override on a built-in component * * * // Bad — hand-rolled decorative styling *
* ``` */ export declare function mergeStyle(base: CSSProperties, override?: CSSProperties): CSSProperties; export type StackProps = { children?: ReactNode; gap?: number; style?: CSSProperties; }; /** * Vertical flex column. Use as the top-level page wrapper or to stack cards/sections. * * @example * ```tsx * *

Dashboard

* * *
* ``` */ export declare function Stack({ children, gap, style }: StackProps): JSX.Element; export type RowProps = { children?: ReactNode; gap?: number; align?: "start" | "center" | "end" | "stretch"; justify?: "start" | "center" | "end" | "space-between"; wrap?: boolean; style?: CSSProperties; }; /** * Horizontal flex row. Use for inline groups of buttons, badges, or metadata. * * @example * ```tsx * * * * * ``` */ export declare function Row({ children, gap, align, justify, wrap, style }: RowProps): JSX.Element; /** * CSS Grid with tokenized gap. Prefer this over `Row` + `wrap` when you need a * fixed number of equal-width columns: wrapped flex items can land on their * own row and grow to full width (`flex-grow`), which is often surprising for * boards and dashboards. */ export type GridProps = { children?: ReactNode; /** * Equal columns: pass a number (uses `repeat(n, minmax(0, 1fr))`), or a CSS * `grid-template-columns` string (e.g. `"1fr 2fr"` or `"minmax(0, 200px) 1fr"`). */ columns: number | string; gap?: number; align?: "start" | "center" | "end" | "stretch"; style?: CSSProperties; }; export declare function Grid({ children, columns, gap, align, style }: GridProps): JSX.Element; export type DividerProps = { style?: CSSProperties; }; /** * Horizontal line for visually separating sections. Uses `stroke.tertiary` * to match the Card/Table hairline weight. * * @example * ```tsx * * Section one * * Section two * * ``` */ export declare function Divider({ style }: DividerProps): JSX.Element; /** * Flex spacer that pushes siblings apart. Place inside a `Row` to push * trailing content to the right edge. * * @example * ```tsx * * Title * * * * ``` */ export declare function Spacer(): JSX.Element; /** Horizontal alignment for a table column. */ export type TableColumnAlign = "left" | "center" | "right"; /** Semantic tone for a table row — renders a translucent tinted background. */ export type TableRowTone = "success" | "danger" | "warning" | "info" | "neutral"; export type TableProps = { /** Column titles, left to right. Column count is fixed by this array. */ headers: ReactNode[]; /** * Body rows. Each row is an array of cells in the same order as `headers`. * Shorter rows are padded with empty cells; extra cells are ignored. */ rows: ReactNode[][]; /** Optional alignment per column index (headers/rows). Defaults to left. */ columnAlign?: Array; /** * Optional semantic tone per row index. Applies a translucent tinted * background — use for status highlighting (e.g. failing services, warnings). * Sparse: `undefined` entries are uncolored. */ rowTone?: Array; /** When true (default), bordered rounded shell with horizontal scroll if needed. */ framed?: boolean; /** Alternate subtle fill on even rows for easier scanning in large tables. */ striped?: boolean; /** Stick the header row when the framed container scrolls vertically. */ stickyHeader?: boolean; style?: CSSProperties; /** Shown in a single spanning cell when `rows` is empty. */ emptyMessage?: ReactNode; }; /** * Data table with column headers and rows. Framed by default with its own * bordered container — **do not wrap in a Card** unless the card itself is * a named entity that happens to contain a table. Render directly under a * heading in the normal case. * * @example * ```tsx * // Good — table directly under a heading *

Active services

* * * // Allowed — table inside a named-entity card * * billing-service *
* * ``` */ export declare function Table({ headers, rows, columnAlign, rowTone, framed, striped, stickyHeader, style, emptyMessage }: TableProps): JSX.Element; export type TextWeight = "normal" | "medium" | "semibold" | "bold"; export type TextProps = { children?: ReactNode; tone?: "primary" | "secondary" | "tertiary" | "quaternary"; size?: "body" | "small"; /** * Element tag to render. Defaults to `"p"` for top-level body copy and * automatically switches to `"span"` when nested inside another typography * container so inline emphasis stays valid HTML. */ as?: "p" | "span"; /** Font weight. Default is `"normal"` (400). Use `"semibold"` or `"bold"` for emphasis. */ weight?: TextWeight; /** Render as italic. */ italic?: boolean; /** * Truncate overflowing text with an ellipsis on a single line. * - `true` / `"end"` — ellipsis at the end (default truncation). * - `"start"` — ellipsis at the start. Useful for file paths where the * filename matters more than the directory prefix. * * Requires the parent to have a bounded width (flex child with * `minWidth: 0`, fixed width, etc.) — otherwise the text just expands * and never overflows. */ truncate?: boolean | "start" | "end"; style?: CSSProperties; }; /** * Body text with tone, size, weight, and italic variants. * * Top-level `Text` renders a `

`. Nested `Text` automatically renders a * `` so inline emphasis like `Use this` * does not emit invalid nested paragraphs. Use `as` to override when needed. * * Compose with `` for inline code and `` for hyperlinks inside * the text flow. * * @example * ```tsx * Primary body text. * Important note. * Supplementary remark. * Run npm install to get started. * See the docs for details. * ``` */ export declare function Text({ children, tone, size, as, weight, italic, truncate, style }: TextProps): JSX.Element; export type H1Props = { children?: ReactNode; style?: CSSProperties; }; /** * Page-level heading. Use once at the top of a canvas. * **Do not** place inside `CardHeader` — card headers use their own label. * * @example * ```tsx * *

Performance Report

* * * ``` */ export declare function H1({ children, style }: H1Props): JSX.Element; export type H2Props = { children?: ReactNode; style?: CSSProperties; }; /** * Section heading. Use between groups of cards or sections. * **Do not** place inside `CardHeader` — card headers use their own label. * * @example * ```tsx * *

Recent activity

* * *
* ``` */ export declare function H2({ children, style }: H2Props): JSX.Element; export type H3Props = { children?: ReactNode; style?: CSSProperties; }; /** * Sub-section heading. Use below `H2` for finer hierarchy. * * @example * ```tsx * *

API Reference

*

Authentication

* All requests require a bearer token. *
* ``` */ export declare function H3({ children, style }: H3Props): JSX.Element; export type CodeProps = { children?: ReactNode; style?: CSSProperties; }; /** * Inline `` span for identifiers, file names, or short snippets. * Uses `0.92em` so it scales with surrounding text (headings, body, etc.). * * Prefer writing backtick markdown inside `Text` — e.g. `` Run `npm install` `` — * which is automatically parsed. Use `` only when you need an explicit element. * * @example * ```tsx * Run npm install to get started. * ``` */ export declare function Code({ children, style }: CodeProps): JSX.Element; export type LinkProps = { children?: ReactNode; href: string; style?: CSSProperties; }; /** * Inline link that opens in the user's default browser. * * Prefer writing markdown links inside `Text` — e.g. `See the [docs](url)` — * which are automatically parsed. Use `` when you need an explicit anchor * outside of a text flow or when composing with other elements. * * @example * ```tsx * View documentation * ``` */ export declare function Link({ children, href, style }: LinkProps): JSX.Element; export type CardSize = "base" | "lg"; export type CardVariant = "default" | "borderless"; /** * Inline chevron SVG used by disclosure-style controls (collapsible cards, * expandable list items, etc.). Shared by `Card` and `todo-list.tsx` so * every disclosure in the canvas SDK uses the same glyph. */ export declare function CanvasChevron({ expanded }: { expanded: boolean; }): JSX.Element; export type CardProps = { children?: ReactNode; /** Default: bordered surface with radius; `borderless` removes both. */ variant?: CardVariant; /** `lg` uses a taller header and roomier title padding (matches packages/ui). */ size?: CardSize; /** * When true, the header uses `position: sticky` so it stays visible while * the card body scrolls. Requires the card (or a parent) to have a * constrained height and `overflow: auto` — the canvas host controls this, * so sticky behavior depends on the host viewport. */ stickyHeader?: boolean; /** * Make the card collapsible. The header becomes a clickable toggle with * a leading chevron; `CardBody` renders nothing while the card is closed. */ collapsible?: boolean; /** Initial open state in uncontrolled mode. Ignored when `open` is set. */ defaultOpen?: boolean; /** Controlled open state. Pair with `onOpenChange`. */ open?: boolean; /** Fires on every toggle with the next open state. */ onOpenChange?: (open: boolean) => void; style?: CSSProperties; }; /** * Bordered surface for a **labeled, self-contained unit** — a file, a service, * a config block, or a table with a title. Compose with `CardHeader` + `CardBody`. * * **When to use Card:** * - Displaying a named entity (file path, service name, resource). * - Wrapping a `
` or `` that needs a title. * - A distinct, bounded section the user might scan by header label. * * **When NOT to use Card:** * - General text sections — use `

` + `` instead. Not every section * needs a border. * - Page-level layout — use `` with headings. A canvas should not be a * wall of stacked cards. * - Nesting — do not put cards inside cards. Use `` within a card body. * * Pass **plain text** as `CardHeader` children — the header provides its own * 12px font. Do **not** put `

` or `

` inside a card header. * * Set `collapsible` to make the header a toggle that shows/hides `CardBody`. * * @example * ```tsx * // Card wraps a titled diff * * }> * src/utils.ts * * * * * * * // Collapsible card * * deploy-service.ts * Service handles rolling deployments across regions. * * * // Bad — card wrapping plain text that should just be a heading * // Use

Overview

instead. * ``` */ export declare function Card({ children, variant, size, stickyHeader, collapsible, defaultOpen, open: openProp, onOpenChange, style }: CardProps): JSX.Element; export type CardHeaderProps = { /** Plain text title. Do **not** pass headings, buttons, pills, or layout rows. */ children?: ReactNode; /** Small trailing content aligned to the right edge — a status label, a * single pill, or a short metadata string. Keep it compact. */ trailing?: ReactNode; style?: CSSProperties; }; /** * 28px header row (32px at `size="lg"`). A compact label for the card. * * **`children`** — plain text only. This is a 12px label, not a toolbar. * Do **not** pass `

`, `

`, ``, ``, * ` * * * * ``` */ export declare function Button({ children, variant, disabled, type, style, onClick }: ButtonProps): JSX.Element; export type PillTone = "neutral" | "added" | "deleted" | "renamed" | "success" | "warning" | "info"; export type PillSize = "sm" | "md"; export type PillProps = { children?: ReactNode; /** Whether the pill is in its selected/active state (filled background). */ active?: boolean; /** * Semantic tone. Recolors the border and text. When `active` is also * set, fills the background with the tone color at low opacity. * Defaults to `neutral` (current stroke/text tokens). */ tone?: PillTone; /** * Visual size. `"md"` (default) is the standard pill. `"sm"` is a * compact variant with smaller text, tighter padding, and no border — * designed for tight spaces like `CardHeader` trailing slots. */ size?: PillSize; /** Shown before the label (icon, emoji, etc.). */ leadingContent?: ReactNode; /** e.g. shortcut hint — matches ui `Pill` ghost keyboard hint (muted primary). */ keyboardHint?: string; disabled?: boolean; title?: string; style?: CSSProperties; onClick?: () => void; }; /** * Pill-shaped label or toggle button. Use for tab bars, filter groups, or * action suggestions. Set `active` for the selected state (filled background). * * @example * ```tsx * // Tab-style selector * * {tabs.map(tab => ( * setSelected(tab)}> * {tab} * * ))} * * * // Action suggestion with shortcut hint * Plan new idea * ``` */ export declare function Pill({ children, active, tone, size, leadingContent, keyboardHint, disabled, title, style, onClick }: PillProps): JSX.Element; export type StatTone = "success" | "danger" | "warning" | "info"; export type StatProps = { /** The primary metric value (number, percentage, short string). */ value: ReactNode; /** Label below the value. */ label: string; /** Semantic color for the value. Omit for default primary text. */ tone?: StatTone; style?: CSSProperties; }; /** * Single metric display — a large value with a compact label beneath it. * Use inside `` for dashboard summary strips. * * @example * ```tsx * * * * * * ``` */ export declare function Stat({ value, label, tone, style }: StatProps): JSX.Element; export type CalloutTone = "info" | "success" | "warning" | "danger" | "neutral"; export type CalloutProps = { /** Body content. Plain strings, ``, ``, ``, or short lists. */ children?: ReactNode; /** Semantic tone. Recolors the border, background tint, and title text. */ tone?: CalloutTone; /** Optional bold title line, shown above the body in the tone color. */ title?: ReactNode; /** Optional leading icon (emoji, inline SVG, or short text glyph). */ icon?: ReactNode; style?: CSSProperties; }; /** * Tinted, bordered notice block for warnings, tips, or short status messages * inline within a section. * * @example * ```tsx * * Rolling deploy is in progress. Metrics may be noisy for 10 minutes. * * ``` */ export declare function Callout({ children, tone, title, icon, style }: CalloutProps): JSX.Element; //# sourceMappingURL=ui-primitives.d.ts.map