@cueplusplus/ui 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +705 -0
- package/dist/brand/_chassis.d.ts +54 -0
- package/dist/brand/_chassis.js +81 -0
- package/dist/brand/_geometry.js +41 -0
- package/dist/brand/cue-logotype.d.ts +29 -0
- package/dist/brand/cue-logotype.js +60 -0
- package/dist/brand/cue-mark.d.ts +30 -0
- package/dist/brand/cue-mark.js +61 -0
- package/dist/brand/index.d.ts +5 -0
- package/dist/brand/plussie.d.ts +67 -0
- package/dist/brand/plussie.js +125 -0
- package/dist/chat/agent-pile.js +1 -1
- package/dist/chat/ask-box.js +2 -2
- package/dist/chat/delegation-card.js +1 -1
- package/dist/chat/message.js +2 -2
- package/dist/chrome/_edge-scroller.d.ts +45 -0
- package/dist/chrome/_edge-scroller.js +149 -0
- package/dist/chrome/_glyphs.js +19 -1
- package/dist/chrome/_tabs-scroll.d.ts +13 -8
- package/dist/chrome/_tabs-scroll.js +13 -8
- package/dist/chrome/app-bar.d.ts +103 -0
- package/dist/chrome/app-bar.js +175 -0
- package/dist/chrome/app-shell.d.ts +125 -0
- package/dist/chrome/app-shell.js +167 -0
- package/dist/chrome/footer.d.ts +75 -0
- package/dist/chrome/footer.js +68 -0
- package/dist/chrome/index.d.ts +5 -1
- package/dist/chrome/index.js +4 -1
- package/dist/chrome/navigation-menu.js +1 -1
- package/dist/chrome/page-shell.d.ts +1 -1
- package/dist/chrome/page-shell.js +15 -5
- package/dist/chrome/segmented-control.d.ts +19 -0
- package/dist/chrome/segmented-control.js +40 -21
- package/dist/chrome/tabs.js +21 -65
- package/dist/chrome/toolbar.d.ts +22 -0
- package/dist/chrome/toolbar.js +26 -5
- package/dist/configurator/_overrides.js +22 -8
- package/dist/configurator/configurator.js +1 -1
- package/dist/configurator/panel-sections.js +10 -4
- package/dist/dmx/channel-matrix.js +1 -1
- package/dist/forms/otp-field.js +1 -1
- package/dist/index.d.ts +18 -9
- package/dist/index.js +16 -10
- package/dist/instruments/data-table.js +1 -1
- package/dist/instruments/index.d.ts +2 -2
- package/dist/instruments/index.js +2 -2
- package/dist/instruments/table.d.ts +14 -1
- package/dist/instruments/table.js +20 -1
- package/dist/layout/carousel.js +1 -1
- package/dist/layout/container.d.ts +1 -1
- package/dist/layout/container.js +6 -3
- package/dist/layout/index.d.ts +3 -3
- package/dist/layout/index.js +3 -3
- package/dist/layout/pagination.js +1 -1
- package/dist/layout/sidebar.d.ts +23 -3
- package/dist/layout/sidebar.js +18 -7
- package/dist/midi/spectrum-visualizer.js +1 -1
- package/dist/midi/timeline-ruler.js +1 -1
- package/dist/overlays/command-palette.js +1 -1
- package/dist/overlays/dialog.js +1 -1
- package/dist/overlays/dropdown-menu.js +2 -2
- package/dist/overlays/hover-card.js +1 -1
- package/dist/overlays/index.js +1 -1
- package/dist/overlays/popover.js +1 -1
- package/dist/overlays/sheet.js +1 -1
- package/dist/overlays/toast.js +1 -1
- package/dist/primitives/chip.d.ts +1 -1
- package/dist/primitives/index.d.ts +1 -1
- package/dist/primitives/index.js +1 -1
- package/dist/primitives/status-dot.d.ts +7 -0
- package/dist/primitives/status-dot.js +8 -1
- package/dist/styles.css +58 -2
- package/dist/system/density.d.ts +4 -1
- package/dist/system/density.js +12 -4
- package/dist/system/index.d.ts +4 -4
- package/dist/system/portal.d.ts +5 -5
- package/dist/system/portal.js +30 -11
- package/dist/system/prepaint.d.ts +34 -9
- package/dist/system/prepaint.js +48 -25
- package/dist/system/theme-provider.d.ts +48 -11
- package/dist/system/theme-provider.js +109 -35
- package/dist/system/use-density.d.ts +3 -3
- package/dist/system/use-density.js +16 -6
- package/dist/system/use-theme.d.ts +4 -2
- package/dist/system/use-theme.js +4 -2
- package/dist/theming/_presets.js +133 -5
- package/dist/theming/create-theme.d.ts +2 -2
- package/dist/theming/create-theme.js +37 -19
- package/dist/theming/serialize.d.ts +1 -1
- package/dist/theming/serialize.js +25 -1
- package/manifest/components/accordion.json +154 -0
- package/manifest/components/agent-pile.json +116 -0
- package/manifest/components/alert-dialog.json +190 -0
- package/manifest/components/app-bar.json +244 -0
- package/manifest/components/app-shell.json +291 -0
- package/manifest/components/app-window-frame.json +102 -0
- package/manifest/components/ask-box.json +209 -0
- package/manifest/components/autocomplete.json +197 -0
- package/manifest/components/avatar-group.json +72 -0
- package/manifest/components/avatar.json +95 -0
- package/manifest/components/breadcrumb.json +74 -0
- package/manifest/components/button-group.json +74 -0
- package/manifest/components/button.json +125 -0
- package/manifest/components/calendar.json +65 -0
- package/manifest/components/card.json +140 -0
- package/manifest/components/carousel.json +200 -0
- package/manifest/components/channel-matrix.json +173 -0
- package/manifest/components/chart-container.json +111 -0
- package/manifest/components/chart-ramp.json +72 -0
- package/manifest/components/chart-swatch.json +65 -0
- package/manifest/components/chart-tooltip-content.json +114 -0
- package/manifest/components/checkbox-group.json +68 -0
- package/manifest/components/checkbox.json +93 -0
- package/manifest/components/chip.json +132 -0
- package/manifest/components/collapsible.json +120 -0
- package/manifest/components/color-area.json +59 -0
- package/manifest/components/color-field.json +79 -0
- package/manifest/components/color-picker.json +175 -0
- package/manifest/components/color-slider.json +75 -0
- package/manifest/components/color-swatch.json +68 -0
- package/manifest/components/colors-section.json +66 -0
- package/manifest/components/combobox.json +198 -0
- package/manifest/components/command-palette.json +177 -0
- package/manifest/components/composer.json +176 -0
- package/manifest/components/container.json +60 -0
- package/manifest/components/context-menu.json +121 -0
- package/manifest/components/copy-button.json +93 -0
- package/manifest/components/cue-logotype.json +96 -0
- package/manifest/components/cue-mark.json +97 -0
- package/manifest/components/cue-portal-frame.json +55 -0
- package/manifest/components/data-table-pagination.json +83 -0
- package/manifest/components/data-table-toolbar.json +104 -0
- package/manifest/components/date-field.json +80 -0
- package/manifest/components/date-picker.json +191 -0
- package/manifest/components/date-range-picker.json +191 -0
- package/manifest/components/delegation-card.json +144 -0
- package/manifest/components/density.json +58 -0
- package/manifest/components/description-list.json +84 -0
- package/manifest/components/dialog.json +198 -0
- package/manifest/components/disclosure.json +109 -0
- package/manifest/components/dmx-bar.json +94 -0
- package/manifest/components/dmx-strip.json +101 -0
- package/manifest/components/drawer.json +179 -0
- package/manifest/components/dropdown-menu.json +229 -0
- package/manifest/components/empty-state.json +90 -0
- package/manifest/components/env-var-input.json +150 -0
- package/manifest/components/export-dialog.json +84 -0
- package/manifest/components/eyebrow.json +56 -0
- package/manifest/components/field-description.json +63 -0
- package/manifest/components/field-error.json +77 -0
- package/manifest/components/field-label.json +63 -0
- package/manifest/components/field.json +79 -0
- package/manifest/components/file-upload.json +159 -0
- package/manifest/components/flow-background.json +50 -0
- package/manifest/components/flow-controls.json +50 -0
- package/manifest/components/footer.json +112 -0
- package/manifest/components/grid.json +81 -0
- package/manifest/components/group-bar.json +102 -0
- package/manifest/components/hover-card.json +151 -0
- package/manifest/components/icon-button.json +88 -0
- package/manifest/components/info-tip.json +98 -0
- package/manifest/components/input-group.json +91 -0
- package/manifest/components/input.json +89 -0
- package/manifest/components/item.json +129 -0
- package/manifest/components/kbd.json +52 -0
- package/manifest/components/link.json +81 -0
- package/manifest/components/log-viewer.json +139 -0
- package/manifest/components/menubar.json +157 -0
- package/manifest/components/message-list.json +100 -0
- package/manifest/components/message.json +116 -0
- package/manifest/components/meter.json +114 -0
- package/manifest/components/multi-select.json +190 -0
- package/manifest/components/musical-time-input.json +113 -0
- package/manifest/components/navigation-menu.json +226 -0
- package/manifest/components/node-card.json +109 -0
- package/manifest/components/node-handle.json +69 -0
- package/manifest/components/number-field.json +107 -0
- package/manifest/components/otp-field.json +128 -0
- package/manifest/components/page-shell.json +96 -0
- package/manifest/components/pagination.json +92 -0
- package/manifest/components/panel-header.json +77 -0
- package/manifest/components/panel.json +71 -0
- package/manifest/components/password-input.json +119 -0
- package/manifest/components/piano-keyboard.json +120 -0
- package/manifest/components/plussie.json +111 -0
- package/manifest/components/popover.json +193 -0
- package/manifest/components/preset-section.json +73 -0
- package/manifest/components/progress.json +95 -0
- package/manifest/components/radio-group.json +73 -0
- package/manifest/components/radio.json +80 -0
- package/manifest/components/rating.json +141 -0
- package/manifest/components/resizable.json +88 -0
- package/manifest/components/row.json +109 -0
- package/manifest/components/scroll-area.json +91 -0
- package/manifest/components/scrollable-tabs-list.json +83 -0
- package/manifest/components/scrub-input.json +200 -0
- package/manifest/components/seam-cell.json +75 -0
- package/manifest/components/seam-grid.json +75 -0
- package/manifest/components/seam-list.json +56 -0
- package/manifest/components/search-input.json +134 -0
- package/manifest/components/section-header.json +112 -0
- package/manifest/components/segmented-control.json +138 -0
- package/manifest/components/select.json +194 -0
- package/manifest/components/separator.json +53 -0
- package/manifest/components/shape-section.json +66 -0
- package/manifest/components/sheet.json +186 -0
- package/manifest/components/sidebar.json +198 -0
- package/manifest/components/signal-edge.json +56 -0
- package/manifest/components/skeleton.json +46 -0
- package/manifest/components/slider.json +89 -0
- package/manifest/components/sparkline.json +76 -0
- package/manifest/components/spectrum-visualizer.json +115 -0
- package/manifest/components/spinner.json +61 -0
- package/manifest/components/stack.json +96 -0
- package/manifest/components/stat.json +87 -0
- package/manifest/components/status-bar.json +58 -0
- package/manifest/components/status-dot.json +78 -0
- package/manifest/components/stepper.json +89 -0
- package/manifest/components/switch.json +87 -0
- package/manifest/components/table-scroll-region.json +69 -0
- package/manifest/components/table.json +155 -0
- package/manifest/components/tabs.json +145 -0
- package/manifest/components/tags-input.json +190 -0
- package/manifest/components/terminal-frame.json +119 -0
- package/manifest/components/textarea.json +76 -0
- package/manifest/components/theme-configurator.json +124 -0
- package/manifest/components/theme-provider.json +134 -0
- package/manifest/components/threshold-rail.json +160 -0
- package/manifest/components/time-field.json +80 -0
- package/manifest/components/timeline-ruler.json +139 -0
- package/manifest/components/timeline.json +115 -0
- package/manifest/components/title-bar.json +82 -0
- package/manifest/components/toast.json +130 -0
- package/manifest/components/toggle-group.json +106 -0
- package/manifest/components/toggle.json +109 -0
- package/manifest/components/token-editor.json +90 -0
- package/manifest/components/toolbar.json +163 -0
- package/manifest/components/tooltip.json +164 -0
- package/manifest/components/tree-visibility-toggle.json +84 -0
- package/manifest/components/tree.json +140 -0
- package/manifest/components/two-step-button.json +113 -0
- package/manifest/components/universe-grid.json +127 -0
- package/manifest/components/usage-chart.json +124 -0
- package/manifest/manifest.json +2142 -0
- package/manifest/tokens.json +138 -0
- package/package.json +13 -5
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "FlowControls",
|
|
3
|
+
"slug": "flow-controls",
|
|
4
|
+
"group": "flow",
|
|
5
|
+
"importPath": "@cueplusplus/ui/flow",
|
|
6
|
+
"peerDependencies": [
|
|
7
|
+
"@xyflow/react"
|
|
8
|
+
],
|
|
9
|
+
"clientOnly": true,
|
|
10
|
+
"description": "The zoom / fit / lock capsule, restyled as an overlay surface.\n\nShape is inline for the same reason the colours are: `border-radius` and\n`overflow` have no `--xy-*` hook, and the library's own rule would otherwise\nwin. `overflow: hidden` is what makes the first and last buttons take the\ncapsule's corners instead of squaring them off.",
|
|
11
|
+
"props": [],
|
|
12
|
+
"typeReferences": [
|
|
13
|
+
"React.ComponentProps<typeof Controls>"
|
|
14
|
+
],
|
|
15
|
+
"subcomponents": [],
|
|
16
|
+
"parts": [],
|
|
17
|
+
"variants": {},
|
|
18
|
+
"defaultVariants": {},
|
|
19
|
+
"tokensUsed": [
|
|
20
|
+
"--cue-border-overlay",
|
|
21
|
+
"--cue-radius-overlay"
|
|
22
|
+
],
|
|
23
|
+
"summary": "The zoom / fit / lock capsule, restyled as an overlay surface.",
|
|
24
|
+
"examples": [
|
|
25
|
+
{
|
|
26
|
+
"title": "Usage",
|
|
27
|
+
"code": "<ReactFlow …><FlowControls /></ReactFlow>",
|
|
28
|
+
"language": "tsx"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"status": "todo-docs",
|
|
32
|
+
"url": "/docs/components/flow-controls",
|
|
33
|
+
"mdUrl": "/docs/components/flow-controls.md",
|
|
34
|
+
"jsonUrl": "/r/components/flow-controls.json",
|
|
35
|
+
"specimens": [
|
|
36
|
+
{
|
|
37
|
+
"title": "useFlowTheme / FlowControls / FlowBackground / SignalEdge",
|
|
38
|
+
"group": "flow",
|
|
39
|
+
"components": [
|
|
40
|
+
"FlowControls",
|
|
41
|
+
"FlowBackground",
|
|
42
|
+
"SignalEdge"
|
|
43
|
+
],
|
|
44
|
+
"code": "<div className=\"h-[24rem] w-full overflow-hidden rounded-(--radius-surface) border border-border\">\n <ReactFlow\n nodes={NODES}\n edges={EDGES}\n nodeTypes={NODE_TYPES}\n edgeTypes={theme.edgeTypes}\n defaultEdgeOptions={theme.defaultEdgeOptions}\n colorMode={theme.colorMode}\n style={theme.style}\n fitView\n proOptions={{ hideAttribution: true }}\n >\n <FlowBackground />\n <FlowControls />\n </ReactFlow>\n</div>",
|
|
45
|
+
"note": "The hook returns the `--xy-*` token map plus stable `edgeTypes` and `defaultEdgeOptions` identities. Every part also publishes the map on its own root, so the group is correct before flow.css is imported and correct again after.",
|
|
46
|
+
"interaction": "the controls capsule is an overlay surface; a live wire animates its dash overlay and stops under prefers-reduced-motion."
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"todo": true
|
|
50
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Footer",
|
|
3
|
+
"slug": "footer",
|
|
4
|
+
"group": "chrome",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": false,
|
|
8
|
+
"description": "The `contentinfo` landmark at the bottom of a document: a hairline, a\nmeasure, and room for whatever a page ends with.\n\nDeliberately **not** a link-list component. A \"complex footer\" in this system\nis `Grid` + `Stack` + `Link` inside this one — components that already exist\nand already carry the density ladder — and a `Grid` with `minItemWidth` fills\nthe row with as many columns as fit, so the footer is responsive without a\nbreakpoint and without a prop for how many columns to draw. What is left over\nis what a footer actually needs and nothing else has: the landmark, the rule\nthat separates it from the page, the measure that lines it up with the page,\nand the second rule above the fine print.\n\nThe band is full-bleed and the column inside it is centred, which is why the\nhairline runs edge to edge while the links stop at the measure. The column is\nset in the bar's register — mono, at the UI size — because a footer is\nfurniture. It paints no ground of its own: a footer is the end of the page,\nnot a bar, and the seam is the hairline. Give it `className=\"bg-surface-1\"`\nwhere a distinct band is wanted.\n\nInside `AppShell` this is a child of `AppShell.Scroller`, at the end of the\ncontent column — so it scrolls with the page and its full bleed is the\ncontent column's width, not the window's. A footer placed *beside* the\nnavigation column instead (after `AppShell.Body`) runs under the navigation\nand reads as chrome it is not. It coexists with `StatusBar`, which is the\nopposite object: a strip of the frame, always on screen, never scrolled.\n\nStatic markup — no `\"use client\"`.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "width",
|
|
12
|
+
"type": "\"narrow\" | \"wide\" | \"broad\" | \"full\"",
|
|
13
|
+
"required": false,
|
|
14
|
+
"defaultValue": "broad",
|
|
15
|
+
"description": "Which measure the footer's column takes. Defaults to `\"broad\"`.\n\nThe same four rungs `Container` and `PageShell` offer, so a footer lines up\nwith the page above it by naming the same width — `broad` rather than\n`narrow` by default because a footer is usually the widest thing on a page,\nand a row of columns inside a 42rem reading measure is four squeezed lists."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "meta",
|
|
19
|
+
"type": "ReactNode",
|
|
20
|
+
"required": false,
|
|
21
|
+
"defaultValue": null,
|
|
22
|
+
"description": "The fine print, under a hairline of its own: copyright, a licence, a build\nnumber.\n\nA slot rather than a component, because that row is a sentence and a couple\nof links — but it is a *separated* sentence, and hand-rolling the rule and\nthe space above it in every app is exactly the kind of repetition this\ncomponent exists to end."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "columnClassName",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "Extra classes for the centred column inside the landmark."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "children",
|
|
33
|
+
"type": "ReactNode",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": null,
|
|
36
|
+
"description": "The footer's body — normally a `Grid` of `Stack`s of `Link`s."
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"typeReferences": [
|
|
40
|
+
"React.ComponentPropsWithoutRef<\"footer\">"
|
|
41
|
+
],
|
|
42
|
+
"subcomponents": [],
|
|
43
|
+
"parts": [],
|
|
44
|
+
"variants": {},
|
|
45
|
+
"defaultVariants": {},
|
|
46
|
+
"tokensUsed": [
|
|
47
|
+
"--cue-border",
|
|
48
|
+
"--cue-fg-subtle",
|
|
49
|
+
"--cue-font-mono",
|
|
50
|
+
"--cue-space-3",
|
|
51
|
+
"--cue-space-5",
|
|
52
|
+
"--cue-space-6",
|
|
53
|
+
"--cue-space-7",
|
|
54
|
+
"--cue-text-label",
|
|
55
|
+
"--cue-text-ui"
|
|
56
|
+
],
|
|
57
|
+
"summary": "The contentinfo landmark at the bottom of a document: a full-bleed hairline, a centred measure, and a fine-print row under a rule of its own.",
|
|
58
|
+
"examples": [
|
|
59
|
+
{
|
|
60
|
+
"title": "A complex footer is components you already have",
|
|
61
|
+
"code": "<Footer\n width=\"broad\"\n meta={\n <>\n <span>© 2026 CUE++</span>\n <Link href=\"/legal\">Legal</Link>\n </>\n }\n>\n <Grid minItemWidth=\"12rem\" gap={5}>\n <Stack gap={2}>\n <Eyebrow>Docs</Eyebrow>\n <Link href=\"/docs\">Getting started</Link>\n <Link href=\"/docs/theming\">Theming</Link>\n </Stack>\n <Stack gap={2}>\n <Eyebrow>Surfaces</Eyebrow>\n <Link href=\"/kitchen-sink\">Kitchen sink</Link>\n <Link href=\"/gallery\">Gallery</Link>\n </Stack>\n </Grid>\n</Footer>",
|
|
62
|
+
"language": "tsx"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"title": "Wiring it once",
|
|
66
|
+
"code": "<div className=\"flex min-h-dvh flex-col\">\n <SiteHeader />\n <main className=\"min-w-0 flex-1\">{children}</main>\n <SiteFooter />\n</div>",
|
|
67
|
+
"language": "tsx"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"title": "Inside `AppShell`: the content column, never the frame",
|
|
71
|
+
"code": "<AppShell.Content>\n <AppShell.Scroller padded={false} className=\"flex flex-col\">\n <div className=\"flex-1\">{children}</div>\n <Footer meta={…}>…</Footer>\n </AppShell.Scroller>\n</AppShell.Content>",
|
|
72
|
+
"language": "tsx"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"title": "Usage",
|
|
76
|
+
"code": "<Footer meta={<><span>© 2026 CUE++</span><Link href=\"/legal\">Legal</Link></>}>\n <Grid minItemWidth=\"12rem\" gap={5}>\n <Stack gap={2}>\n <Eyebrow>Docs</Eyebrow>\n <Link href=\"/docs\">Getting started</Link>\n <Link href=\"/docs/theming\">Theming</Link>\n </Stack>\n <Stack gap={2}>\n <Eyebrow>Surfaces</Eyebrow>\n <Link href=\"/kitchen-sink\">Kitchen sink</Link>\n </Stack>\n </Grid>\n</Footer>",
|
|
77
|
+
"language": "tsx"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"status": "stable",
|
|
81
|
+
"url": "/docs/components/footer",
|
|
82
|
+
"mdUrl": "/docs/components/footer.md",
|
|
83
|
+
"jsonUrl": "/r/components/footer.json",
|
|
84
|
+
"whenToUse": [
|
|
85
|
+
"The end of any document that scrolls: a site, a documentation page, a marketing page, the signed-out half of a console.",
|
|
86
|
+
"Whenever a page ends with a hand-rolled `<footer>` carrying its own `border-t`, its own `max-w-*` and its own gutters. Those three are the component.",
|
|
87
|
+
"As the frame for a complex footer — a row of link columns, a status line, a licence — with `Grid` and `Stack` doing the layout inside it."
|
|
88
|
+
],
|
|
89
|
+
"whenNotToUse": [
|
|
90
|
+
"As the bottom strip of a console. That is `StatusBar`: one chrome rung tall, always on screen, tone-inked readouts. A footer scrolls away, and should. The two can coexist — see below.",
|
|
91
|
+
"As a sibling of the navigation column. Inside a shell a footer belongs to the content scroller; one placed beside `AppShell.Sidebar`, or after `AppShell.Body`, stretches under the navigation and pretends to be part of the frame.",
|
|
92
|
+
"As a place to put a link list component. There isn't one, and there does not need to be — see below."
|
|
93
|
+
],
|
|
94
|
+
"commonMistakes": [
|
|
95
|
+
"Reaching for a column count. Use `Grid` with `minItemWidth`: it fills the row with as many columns as fit, so the footer is responsive with no breakpoint and no prop for how many columns to draw.",
|
|
96
|
+
"Setting a width that disagrees with the page above it. `Footer` takes the same four measures as `Container` and `PageShell` — name the same rung and the columns line up with the content.",
|
|
97
|
+
"Hand-rolling the fine-print rule. That is what `meta` is: it draws the hairline and the space above it so every app does not.",
|
|
98
|
+
"Painting a ground on it by reflex. A footer is the end of the page, not a bar; the seam is the hairline. Pass `className=\"bg-surface-1\"` only when a distinct band is actually wanted."
|
|
99
|
+
],
|
|
100
|
+
"specimens": [
|
|
101
|
+
{
|
|
102
|
+
"title": "Footer",
|
|
103
|
+
"group": "chrome",
|
|
104
|
+
"components": [
|
|
105
|
+
"Footer"
|
|
106
|
+
],
|
|
107
|
+
"code": "<div className=\"w-full overflow-hidden rounded-(--radius-surface) border border-border bg-bg\">\n <Footer\n width=\"wide\"\n meta={\n <>\n <span>© 2026 CUE++</span>\n <Link href=\"#legal\">Legal</Link>\n </>\n }\n >\n <Grid minItemWidth=\"9rem\" gap={5}>\n <Stack gap={2}>\n <Eyebrow>Docs</Eyebrow>\n <Link href=\"#getting-started\">Getting started</Link>\n <Link href=\"#theming\">Theming</Link>\n </Stack>\n <Stack gap={2}>\n <Eyebrow>Surfaces</Eyebrow>\n <Link href=\"#kitchen-sink\">Kitchen sink</Link>\n <Link href=\"#gallery\">Gallery</Link>\n </Stack>\n <Stack gap={2}>\n <Eyebrow>Elsewhere</Eyebrow>\n <Link external href=\"https://skills.cueplusplus.com\">\n Skills\n </Link>\n </Stack>\n </Grid>\n </Footer>\n</div>",
|
|
108
|
+
"note": "The contentinfo landmark: a full-bleed hairline, a centred measure off the same ladder Container and PageShell use, and a fine-print row under a rule of its own. The columns are Grid + Stack + Link — there is no link-list component here, because none is needed.",
|
|
109
|
+
"interaction": "none; the links inside are ordinary links."
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Grid",
|
|
3
|
+
"slug": "grid",
|
|
4
|
+
"group": "layout",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": false,
|
|
8
|
+
"description": "Two-dimensional layout: equal columns, or as many as fit.\n\nSame bargain as `Stack` — the gap is a rung of the density ladder rather than\na hand-picked pixel value, so a card grid tightens with the rest of the\nconsole when the user asks for ultra-compact.\n\nStatic markup — no `\"use client\"`.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "cols",
|
|
12
|
+
"type": "4 | 1 | 2 | 3 | 5 | 6",
|
|
13
|
+
"required": false,
|
|
14
|
+
"defaultValue": "1",
|
|
15
|
+
"description": "How many equal columns. Defaults to `1`. Ignored when `minItemWidth` is set."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "gap",
|
|
19
|
+
"type": "0 | 4 | 8 | 1 | 2 | 3 | 5 | 6 | 7",
|
|
20
|
+
"required": false,
|
|
21
|
+
"defaultValue": "4",
|
|
22
|
+
"description": "Which rung of the density space ladder to spend between cells. Defaults to `4`."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "minItemWidth",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "Fill the row with as many columns of at least this width as fit, instead of\na fixed count. Any CSS length (`\"12rem\"`, `\"200px\"`).\n\nPrefer this over a column count wherever the content has a natural minimum\nmeasure — it is responsive without a single breakpoint."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "align",
|
|
33
|
+
"type": "\"center\" | \"end\" | \"baseline\" | \"start\" | \"stretch\"",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": null,
|
|
36
|
+
"description": "Cross-axis alignment of the cells."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "justify",
|
|
40
|
+
"type": "\"center\" | \"end\" | \"start\" | \"between\"",
|
|
41
|
+
"required": false,
|
|
42
|
+
"defaultValue": null,
|
|
43
|
+
"description": "Main-axis distribution of the tracks."
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"typeReferences": [
|
|
47
|
+
"React.ComponentPropsWithoutRef<\"div\">"
|
|
48
|
+
],
|
|
49
|
+
"subcomponents": [],
|
|
50
|
+
"parts": [],
|
|
51
|
+
"variants": {},
|
|
52
|
+
"defaultVariants": {},
|
|
53
|
+
"tokensUsed": [
|
|
54
|
+
"--cue-grid-min"
|
|
55
|
+
],
|
|
56
|
+
"summary": "Two-dimensional layout: equal columns, or as many as fit.",
|
|
57
|
+
"examples": [
|
|
58
|
+
{
|
|
59
|
+
"title": "Usage",
|
|
60
|
+
"code": "<Grid cols={3} gap={5}>{cards}</Grid>\n<Grid minItemWidth=\"14rem\" gap={4}>{cards}</Grid>",
|
|
61
|
+
"language": "tsx"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"status": "todo-docs",
|
|
65
|
+
"url": "/docs/components/grid",
|
|
66
|
+
"mdUrl": "/docs/components/grid.md",
|
|
67
|
+
"jsonUrl": "/r/components/grid.json",
|
|
68
|
+
"specimens": [
|
|
69
|
+
{
|
|
70
|
+
"title": "Grid",
|
|
71
|
+
"group": "layout",
|
|
72
|
+
"components": [
|
|
73
|
+
"Grid"
|
|
74
|
+
],
|
|
75
|
+
"code": "<div className=\"flex w-full flex-col gap-(--cue-space-5)\">\n <Grid cols={4} gap={3}>\n {[\"1\", \"2\", \"3\", \"4\"].map((cell) => (\n <Panel\n key={cell}\n className=\"p-(--cue-space-4) text-center font-mono text-(length:--cue-text-label) text-fg-subtle\"\n >\n {cell}\n </Panel>\n ))}\n </Grid>\n <Grid minItemWidth=\"12rem\" gap={3}>\n {[\"auto\", \"fit\", \"from\", \"12rem\"].map((cell) => (\n <Panel\n key={cell}\n className=\"p-(--cue-space-4) text-center font-mono text-(length:--cue-text-label) text-fg-subtle\"\n >\n {cell}\n </Panel>\n ))}\n </Grid>\n</div>",
|
|
76
|
+
"note": "Fixed columns, or auto-fit from a minimum item width.",
|
|
77
|
+
"interaction": "none."
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"todo": true
|
|
81
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "GroupBar",
|
|
3
|
+
"slug": "group-bar",
|
|
4
|
+
"group": "instruments",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": false,
|
|
8
|
+
"description": "The distribution strip: one flex cell per group, weighted by its value.\n\nA stacked bar with no axis and no numbers — the shape *is* the reading. Three\nrules keep it honest:\n\n1. **Empty groups get no cell.** A minimum width is what makes a two-pixel\n sliver visible, and a minimum width on a zero would draw a group that is\n not there.\n2. **The percentages add to 100.** Shares are rounded by largest remainder,\n so the legend never sums to 99 and never to 101.\n3. **Colour is never the only channel.** The strip is a `role=\"img\"` whose\n accessible name spells the whole distribution out (WCAG 1.4.1); the legend\n repeats it in text when there is room for one.\n\nThe cells are divided by the same 1px seam as `SeamList`, so a distribution\nstrip and a seam list sitting in the same panel share one hairline language.\n\nStatic markup — no `\"use client\"`.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "items",
|
|
12
|
+
"type": "readonly GroupBarItem[]",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "The slices, in display order."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "height",
|
|
19
|
+
"type": "number",
|
|
20
|
+
"required": false,
|
|
21
|
+
"defaultValue": "6",
|
|
22
|
+
"description": "Strip height in px at the 16px root, emitted as `rem`. Defaults to `6`."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "label",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "What the distribution is *of*. Required in practice — it names the graphic."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "legend",
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": "false",
|
|
36
|
+
"description": "List the slices with their shares underneath the strip."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "formatShare",
|
|
40
|
+
"type": "((share: number, item: GroupBarItem) => string)",
|
|
41
|
+
"required": false,
|
|
42
|
+
"defaultValue": "(share) => `${share}%`",
|
|
43
|
+
"description": "Format one share for the summary and the legend. Defaults to `\"42%\"`."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "emptyLabel",
|
|
47
|
+
"type": "string",
|
|
48
|
+
"required": false,
|
|
49
|
+
"defaultValue": "no data",
|
|
50
|
+
"description": "What to say when every slice is empty. Defaults to `\"no data\"`."
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"typeReferences": [
|
|
54
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
|
|
55
|
+
],
|
|
56
|
+
"subcomponents": [],
|
|
57
|
+
"parts": [],
|
|
58
|
+
"variants": {},
|
|
59
|
+
"defaultVariants": {},
|
|
60
|
+
"tokensUsed": [
|
|
61
|
+
"--cue-accent",
|
|
62
|
+
"--cue-border",
|
|
63
|
+
"--cue-busy",
|
|
64
|
+
"--cue-danger",
|
|
65
|
+
"--cue-fg-muted",
|
|
66
|
+
"--cue-fg-subtle",
|
|
67
|
+
"--cue-font-mono",
|
|
68
|
+
"--cue-info",
|
|
69
|
+
"--cue-ok",
|
|
70
|
+
"--cue-radius-control",
|
|
71
|
+
"--cue-space-2",
|
|
72
|
+
"--cue-space-3",
|
|
73
|
+
"--cue-space-5",
|
|
74
|
+
"--cue-text-label",
|
|
75
|
+
"--cue-warn"
|
|
76
|
+
],
|
|
77
|
+
"summary": "The distribution strip: one flex cell per group, weighted by its value.",
|
|
78
|
+
"examples": [
|
|
79
|
+
{
|
|
80
|
+
"title": "Usage",
|
|
81
|
+
"code": "<GroupBar\n label=\"Universe load\"\n items={[\n { label: \"dimmers\", value: 212, tone: \"accent\" },\n { label: \"movers\", value: 96, tone: \"info\" },\n { label: \"free\", value: 204 },\n ]}\n legend\n/>",
|
|
82
|
+
"language": "tsx"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"status": "todo-docs",
|
|
86
|
+
"url": "/docs/components/group-bar",
|
|
87
|
+
"mdUrl": "/docs/components/group-bar.md",
|
|
88
|
+
"jsonUrl": "/r/components/group-bar.json",
|
|
89
|
+
"specimens": [
|
|
90
|
+
{
|
|
91
|
+
"title": "GroupBar",
|
|
92
|
+
"group": "instruments",
|
|
93
|
+
"components": [
|
|
94
|
+
"GroupBar"
|
|
95
|
+
],
|
|
96
|
+
"code": "<div className=\"flex w-full max-w-[36rem] flex-col gap-(--cue-space-5)\">\n <GroupBar items={GROUP_ITEMS} label=\"Channel allocation by group\" />\n <GroupBar items={[]} label=\"Empty allocation\" emptyLabel={COPY.empty.title} />\n</div>",
|
|
97
|
+
"note": "The distribution strip: one flex cell per item, coloured by tone, with a legend that names each share.",
|
|
98
|
+
"interaction": "none. It is a picture of a breakdown, and the legend is the text version of it."
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"todo": true
|
|
102
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "HoverCard",
|
|
3
|
+
"slug": "hover-card",
|
|
4
|
+
"group": "overlays",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "A richer preview than a tooltip, revealed by hovering a link or a name: the\nfixture behind a profile string, the operator behind an initial.\n\nWraps Base UI's `PreviewCard`, which is the right primitive precisely because\nit is *not* a tooltip: the card is reachable — the pointer can travel into it\nand interact — and its content is not announced as the trigger's description.\n\nHover is the only way in, so the content here must always be a *convenience*.\nAnything a keyboard or touch user genuinely needs belongs in a `Popover`\n(a real trigger) or an `InfoTip` (a focusable badge).",
|
|
9
|
+
"props": [],
|
|
10
|
+
"typeReferences": [],
|
|
11
|
+
"subcomponents": [
|
|
12
|
+
"Root",
|
|
13
|
+
"Trigger",
|
|
14
|
+
"Content"
|
|
15
|
+
],
|
|
16
|
+
"parts": [
|
|
17
|
+
{
|
|
18
|
+
"name": "Root",
|
|
19
|
+
"usage": "HoverCard.Root",
|
|
20
|
+
"description": "Groups the parts of a hover card and owns its open state. Renders no element.",
|
|
21
|
+
"props": [
|
|
22
|
+
{
|
|
23
|
+
"name": "closeOnWheel",
|
|
24
|
+
"type": "boolean",
|
|
25
|
+
"required": false,
|
|
26
|
+
"defaultValue": "true",
|
|
27
|
+
"description": "Close the card when the viewport moves under it — a wheel anywhere outside\nthe popup, or a window resize. Defaults to `true`, for the same reason as\n`Popover`: an anchored popup is placed from its trigger's rect, and a canvas\nthat pans by CSS transform fires no `scroll` event."
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"typeReferences": [
|
|
31
|
+
"BasePreviewCard.Root.Props"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "Trigger",
|
|
36
|
+
"usage": "HoverCard.Trigger",
|
|
37
|
+
"description": "The thing being previewed — an `<a>` by default, because the pattern this\ncomponent exists for is \"what is behind this link\".\n\nDeliberately unstyled: a hover card must never change how the underlying link\nor name looks, or the page grows a second kind of underline.\n\nThe hover intent lives here rather than on the root, because Base UI supports\nseveral triggers sharing one card: `delay` (600ms) is how long the pointer\nmust rest, `closeDelay` (300ms) how long it may wander off before the card\ngoes.",
|
|
38
|
+
"props": [],
|
|
39
|
+
"typeReferences": [
|
|
40
|
+
"BasePreviewCard.Trigger.Props"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "Content",
|
|
45
|
+
"usage": "HoverCard.Content",
|
|
46
|
+
"description": "The card's portal, positioner and popup.\n\nPortalled through {@link useCuePortalProps}, so the surface renders at the\ncaller's theme and density. The hover intent — open delay, close delay, the\nsafe triangle between trigger and popup — is Base UI's.",
|
|
47
|
+
"props": [
|
|
48
|
+
{
|
|
49
|
+
"name": "className",
|
|
50
|
+
"type": "string",
|
|
51
|
+
"required": false,
|
|
52
|
+
"defaultValue": null,
|
|
53
|
+
"description": "Extra classes for the popup surface."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "align",
|
|
57
|
+
"type": "\"center\" | \"end\" | \"start\"",
|
|
58
|
+
"required": false,
|
|
59
|
+
"defaultValue": null,
|
|
60
|
+
"description": "Alignment along that side. Defaults to `\"center\"`."
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "keepMounted",
|
|
64
|
+
"type": "boolean",
|
|
65
|
+
"required": false,
|
|
66
|
+
"defaultValue": null,
|
|
67
|
+
"description": "Keep the popup mounted while closed."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "positionerClassName",
|
|
71
|
+
"type": "string",
|
|
72
|
+
"required": false,
|
|
73
|
+
"defaultValue": null,
|
|
74
|
+
"description": "Extra classes for the positioner that places the popup."
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "sideOffset",
|
|
78
|
+
"type": "number | OffsetFunction",
|
|
79
|
+
"required": false,
|
|
80
|
+
"defaultValue": "4",
|
|
81
|
+
"description": "Gap in px between trigger and popup. Defaults to `4`."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "side",
|
|
85
|
+
"type": "\"left\" | \"right\" | \"top\" | \"bottom\" | \"inline-end\" | \"inline-start\"",
|
|
86
|
+
"required": false,
|
|
87
|
+
"defaultValue": null,
|
|
88
|
+
"description": "Preferred side of the trigger. Defaults to `\"bottom\"`."
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "alignOffset",
|
|
92
|
+
"type": "number | OffsetFunction",
|
|
93
|
+
"required": false,
|
|
94
|
+
"defaultValue": null,
|
|
95
|
+
"description": "Nudge along the alignment axis, in px."
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"typeReferences": [
|
|
99
|
+
"Omit<BasePreviewCard.Popup.Props, \"className\">"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"variants": {},
|
|
104
|
+
"defaultVariants": {},
|
|
105
|
+
"tokensUsed": [
|
|
106
|
+
"--cue-accent-soft",
|
|
107
|
+
"--cue-border",
|
|
108
|
+
"--cue-border-overlay",
|
|
109
|
+
"--cue-control-sm",
|
|
110
|
+
"--cue-fg",
|
|
111
|
+
"--cue-fg-muted",
|
|
112
|
+
"--cue-fg-subtle",
|
|
113
|
+
"--cue-font-mono",
|
|
114
|
+
"--cue-radius-control",
|
|
115
|
+
"--cue-radius-overlay",
|
|
116
|
+
"--cue-scrim",
|
|
117
|
+
"--cue-space-1",
|
|
118
|
+
"--cue-space-2",
|
|
119
|
+
"--cue-space-3",
|
|
120
|
+
"--cue-space-4",
|
|
121
|
+
"--cue-surface-2",
|
|
122
|
+
"--cue-text-emphasis",
|
|
123
|
+
"--cue-text-label",
|
|
124
|
+
"--cue-text-ui"
|
|
125
|
+
],
|
|
126
|
+
"summary": "A richer preview than a tooltip, revealed by hovering a link or a name: the fixture behind a profile string, the operator behind an initial.",
|
|
127
|
+
"examples": [
|
|
128
|
+
{
|
|
129
|
+
"title": "Usage",
|
|
130
|
+
"code": "<HoverCard.Root>\n <HoverCard.Trigger href=\"/fixtures/mac-aura\">MAC Aura XIP</HoverCard.Trigger>\n <HoverCard.Content>\n <Stat label=\"Channels\" value=\"21\" />\n </HoverCard.Content>\n</HoverCard.Root>",
|
|
131
|
+
"language": "tsx"
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"status": "todo-docs",
|
|
135
|
+
"url": "/docs/components/hover-card",
|
|
136
|
+
"mdUrl": "/docs/components/hover-card.md",
|
|
137
|
+
"jsonUrl": "/r/components/hover-card.json",
|
|
138
|
+
"specimens": [
|
|
139
|
+
{
|
|
140
|
+
"title": "HoverCard",
|
|
141
|
+
"group": "overlays",
|
|
142
|
+
"components": [
|
|
143
|
+
"HoverCard"
|
|
144
|
+
],
|
|
145
|
+
"code": "<Specimens>\n <Specimen label=\"default\">\n <HoverCard.Root>\n <HoverCard.Trigger href=\"#front-wash\">Front wash</HoverCard.Trigger>\n <HoverCard.Content className=\"w-[18rem]\">\n <div className=\"flex flex-col gap-(--cue-space-2)\">\n <span className=\"font-mono text-(length:--cue-text-emphasis) text-fg\">\n Front wash\n </span>\n <span className=\"font-mono text-(length:--cue-text-ui) text-fg-muted\">\n 6 × Source Four 26°, universe 1, channels 1 to 48.\n </span>\n <StatusDot tone=\"ok\" label=\"Patched\" />\n </div>\n </HoverCard.Content>\n </HoverCard.Root>\n </Specimen>\n</Specimens>",
|
|
146
|
+
"note": "A preview card: richer than a tooltip, and never the only way to reach the information.",
|
|
147
|
+
"interaction": "opens on hover after a delay and on focus; the card itself is hoverable, so a link inside it is reachable."
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"todo": true
|
|
151
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "IconButton",
|
|
3
|
+
"slug": "icon-button",
|
|
4
|
+
"group": "primitives",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "A square, icon-only button for toolbars, row affordances and panel headers.\n\nDefaults to the `ghost` variant: in a dense console most icon buttons should\nbe invisible until hovered, speaking through text colour rather than a rim.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "aria-label",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "Required. An icon-only control has no text to name it, so the label is not\noptional — the type makes forgetting it a compile error."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "icon",
|
|
19
|
+
"type": "ElementType<any, keyof IntrinsicElements>",
|
|
20
|
+
"required": true,
|
|
21
|
+
"defaultValue": null,
|
|
22
|
+
"description": "The icon component to render (e.g. a lucide icon). Rendered `aria-hidden`\nand sized to the density icon token."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "render",
|
|
26
|
+
"type": "RenderProp<Record<string, unknown>>",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "Replace the rendered element (Base UI render prop)."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "size",
|
|
33
|
+
"type": "\"sm\" | \"md\" | \"lg\"",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": "md",
|
|
36
|
+
"description": ""
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"typeReferences": [
|
|
40
|
+
"Omit<React.ComponentPropsWithoutRef<\"button\">, \"children\">",
|
|
41
|
+
"VariantProps<typeof iconButtonVariants>"
|
|
42
|
+
],
|
|
43
|
+
"subcomponents": [],
|
|
44
|
+
"parts": [],
|
|
45
|
+
"variants": {
|
|
46
|
+
"size": [
|
|
47
|
+
"sm",
|
|
48
|
+
"md",
|
|
49
|
+
"lg"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"defaultVariants": {
|
|
53
|
+
"variant": "ghost",
|
|
54
|
+
"size": "md"
|
|
55
|
+
},
|
|
56
|
+
"tokensUsed": [
|
|
57
|
+
"--cue-control-lg",
|
|
58
|
+
"--cue-control-md",
|
|
59
|
+
"--cue-control-sm",
|
|
60
|
+
"--cue-icon-md",
|
|
61
|
+
"--cue-icon-sm"
|
|
62
|
+
],
|
|
63
|
+
"summary": "A square, icon-only button for toolbars, row affordances and panel headers.",
|
|
64
|
+
"examples": [
|
|
65
|
+
{
|
|
66
|
+
"title": "Usage",
|
|
67
|
+
"code": "<IconButton aria-label=\"Close panel\" icon={X} />\n<IconButton aria-label=\"Delete cue\" icon={Trash} variant=\"danger-outline\" size=\"sm\" />",
|
|
68
|
+
"language": "tsx"
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"status": "todo-docs",
|
|
72
|
+
"url": "/docs/components/icon-button",
|
|
73
|
+
"mdUrl": "/docs/components/icon-button.md",
|
|
74
|
+
"jsonUrl": "/r/components/icon-button.json",
|
|
75
|
+
"specimens": [
|
|
76
|
+
{
|
|
77
|
+
"title": "IconButton",
|
|
78
|
+
"group": "primitives",
|
|
79
|
+
"components": [
|
|
80
|
+
"IconButton"
|
|
81
|
+
],
|
|
82
|
+
"code": "<Specimens>\n {BUTTON_VARIANTS.map((variant) => (\n <Specimen key={variant} label={variant}>\n <IconButton aria-label={`Play, ${variant}`} icon={Play} variant={variant} />\n </Specimen>\n ))}\n <Specimen label=\"disabled\">\n <IconButton aria-label=\"Delete cue\" icon={Trash2} disabled />\n </Specimen>\n {SIZES.map((size) => (\n <Specimen key={size} label={`size ${size}`}>\n <IconButton aria-label={`Pause, ${size}`} icon={Pause} size={size} />\n </Specimen>\n ))}\n</Specimens>",
|
|
83
|
+
"note": "A square button with a required accessible name. There is no unlabelled variant.",
|
|
84
|
+
"interaction": "same ring as Button; the hit target stays at the control height even when the glyph shrinks."
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"todo": true
|
|
88
|
+
}
|