@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
package/dist/theming/_presets.js
CHANGED
|
@@ -453,6 +453,112 @@ const THEME_PRESETS = {
|
|
|
453
453
|
"scrim": "rgba(0,0,0,0.35)"
|
|
454
454
|
},
|
|
455
455
|
fonts: { "font-mono": "\"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" }
|
|
456
|
+
},
|
|
457
|
+
requestport: {
|
|
458
|
+
dark: {
|
|
459
|
+
"bg": "#0a0d0e",
|
|
460
|
+
"sunken": "#07090a",
|
|
461
|
+
"surface-1": "#101416",
|
|
462
|
+
"surface-2": "#151a1d",
|
|
463
|
+
"surface-3": "#1a2024",
|
|
464
|
+
"fg": "#f0eee9",
|
|
465
|
+
"fg-muted": "#a3a6a8",
|
|
466
|
+
"fg-subtle": "#81868a",
|
|
467
|
+
"border": "#293034",
|
|
468
|
+
"border-strong": "#61686d",
|
|
469
|
+
"border-overlay": "#3f484e",
|
|
470
|
+
"accent": "#e66a45",
|
|
471
|
+
"accent-hover": "#f07a53",
|
|
472
|
+
"accent-fg": "#160d09",
|
|
473
|
+
"ok": "#63b482",
|
|
474
|
+
"busy": "#9a8cdb",
|
|
475
|
+
"warn": "#d6a65a",
|
|
476
|
+
"danger": "#dc6d69",
|
|
477
|
+
"info": "#6eb7d9",
|
|
478
|
+
"selection": "rgba(230,106,69,0.18)",
|
|
479
|
+
"focus": "#e66a45",
|
|
480
|
+
"data-ground": "#000000",
|
|
481
|
+
"scrim": "rgba(0,0,0,0.72)"
|
|
482
|
+
},
|
|
483
|
+
light: {
|
|
484
|
+
"bg": "#f4f3ef",
|
|
485
|
+
"sunken": "#e7e6e1",
|
|
486
|
+
"surface-1": "#faf9f6",
|
|
487
|
+
"surface-2": "#ffffff",
|
|
488
|
+
"surface-3": "#deddd8",
|
|
489
|
+
"fg": "#1a1d1e",
|
|
490
|
+
"fg-muted": "#53595c",
|
|
491
|
+
"fg-subtle": "#62696d",
|
|
492
|
+
"border": "#d0d2cf",
|
|
493
|
+
"border-strong": "#7f8689",
|
|
494
|
+
"border-overlay": "#aeb4b5",
|
|
495
|
+
"accent": "#b8492b",
|
|
496
|
+
"accent-hover": "#963b23",
|
|
497
|
+
"accent-fg": "#ffffff",
|
|
498
|
+
"ok": "#247746",
|
|
499
|
+
"busy": "#604aaa",
|
|
500
|
+
"warn": "#8a5b00",
|
|
501
|
+
"danger": "#aa2f2b",
|
|
502
|
+
"info": "#1d6587",
|
|
503
|
+
"selection": "rgba(184,73,43,0.18)",
|
|
504
|
+
"focus": "#b8492b",
|
|
505
|
+
"data-ground": "#000000",
|
|
506
|
+
"scrim": "rgba(20,18,15,0.45)"
|
|
507
|
+
},
|
|
508
|
+
fonts: { "font-mono": "\"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" }
|
|
509
|
+
},
|
|
510
|
+
quotamate: {
|
|
511
|
+
dark: {
|
|
512
|
+
"bg": "#0e0e12",
|
|
513
|
+
"sunken": "#09090c",
|
|
514
|
+
"surface-1": "#15151a",
|
|
515
|
+
"surface-2": "#212127",
|
|
516
|
+
"surface-3": "#2b2b31",
|
|
517
|
+
"fg": "#f4f4f6",
|
|
518
|
+
"fg-muted": "#8b8b95",
|
|
519
|
+
"fg-subtle": "#62626b",
|
|
520
|
+
"border": "#2b2b31",
|
|
521
|
+
"border-strong": "#3d3d45",
|
|
522
|
+
"border-overlay": "#3d3d45",
|
|
523
|
+
"accent": "#00e5e5",
|
|
524
|
+
"accent-hover": "#33ffff",
|
|
525
|
+
"accent-fg": "#0e0e12",
|
|
526
|
+
"ok": "#22d967",
|
|
527
|
+
"busy": "#00e5e5",
|
|
528
|
+
"warn": "#ffab1a",
|
|
529
|
+
"danger": "#e13d3d",
|
|
530
|
+
"info": "#4a9eff",
|
|
531
|
+
"selection": "rgba(0,229,229,0.18)",
|
|
532
|
+
"focus": "#00e5e5",
|
|
533
|
+
"data-ground": "#000000",
|
|
534
|
+
"scrim": "rgba(0,0,0,0.55)"
|
|
535
|
+
},
|
|
536
|
+
light: {
|
|
537
|
+
"bg": "#fcfcfd",
|
|
538
|
+
"sunken": "#f1f1f4",
|
|
539
|
+
"surface-1": "#ffffff",
|
|
540
|
+
"surface-2": "#f4f4f6",
|
|
541
|
+
"surface-3": "#e7e7ec",
|
|
542
|
+
"fg": "#18181b",
|
|
543
|
+
"fg-muted": "#6e6e78",
|
|
544
|
+
"fg-subtle": "#9a9aa4",
|
|
545
|
+
"border": "#e2e2e8",
|
|
546
|
+
"border-strong": "#c9c9d2",
|
|
547
|
+
"border-overlay": "#c9c9d2",
|
|
548
|
+
"accent": "#0d7d7d",
|
|
549
|
+
"accent-hover": "#0a6767",
|
|
550
|
+
"accent-fg": "#ffffff",
|
|
551
|
+
"ok": "#17914a",
|
|
552
|
+
"busy": "#0d7d7d",
|
|
553
|
+
"warn": "#b46a00",
|
|
554
|
+
"danger": "#c22d2d",
|
|
555
|
+
"info": "#1f6fd4",
|
|
556
|
+
"selection": "rgba(13,125,125,0.16)",
|
|
557
|
+
"focus": "#0d7d7d",
|
|
558
|
+
"data-ground": "#ffffff",
|
|
559
|
+
"scrim": "rgba(0,0,0,0.55)"
|
|
560
|
+
},
|
|
561
|
+
fonts: { "font-mono": "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace" }
|
|
456
562
|
}
|
|
457
563
|
};
|
|
458
564
|
/**
|
|
@@ -461,11 +567,16 @@ const THEME_PRESETS = {
|
|
|
461
567
|
* has to beat, and `:root` carries the *default* theme's font override. A silent
|
|
462
568
|
* theme would inherit cue's JetBrains Mono instead of the base stack, so every
|
|
463
569
|
* block says what it owns. Mirrors `build.mjs`'s `THEME_FONTS` handling.
|
|
570
|
+
*
|
|
571
|
+
* Every entry is a generic or a face the platform ships. The sans stack named
|
|
572
|
+
* `Geist` until 2026-08-19 and no webfont was ever loaded to make it resolve, so
|
|
573
|
+
* it was a name most visitors silently fell straight past; Geist is now the head
|
|
574
|
+
* of the `geist` font pairing, which an app can actually deliver.
|
|
464
575
|
*/
|
|
465
576
|
const BASE_FONT_STACKS = {
|
|
466
|
-
"font-sans": "
|
|
577
|
+
"font-sans": "ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", \"Helvetica Neue\", sans-serif",
|
|
467
578
|
"font-mono": "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
468
|
-
"font-display": "
|
|
579
|
+
"font-display": "ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif"
|
|
469
580
|
};
|
|
470
581
|
/**
|
|
471
582
|
* The radius multiplier each density level contributes.
|
|
@@ -478,10 +589,27 @@ const BASE_FONT_STACKS = {
|
|
|
478
589
|
*/
|
|
479
590
|
const DENSITY_RADIUS_SCALE = {
|
|
480
591
|
"ultra-compact": .75,
|
|
592
|
+
"compact": 1,
|
|
481
593
|
"normal": 1,
|
|
482
|
-
"large": 1
|
|
594
|
+
"large": 1,
|
|
595
|
+
"ultra-large": 1
|
|
483
596
|
};
|
|
484
597
|
/** The default density, whose radius scale the uncrossed theme block carries. */
|
|
485
|
-
const DEFAULT_DENSITY_LEVEL = "
|
|
598
|
+
const DEFAULT_DENSITY_LEVEL = "compact";
|
|
599
|
+
/**
|
|
600
|
+
* What every theme block sets `--cue-font-mono` to.
|
|
601
|
+
*
|
|
602
|
+
* Neither the theme axis nor the font axis writes the shared token: each
|
|
603
|
+
* publishes its own half (`--cue-font-theme-mono` and `--cue-font-pairing-mono`)
|
|
604
|
+
* and this is the resolution, pairing first. It has to be a `var()` chain rather
|
|
605
|
+
* than a value because the two attributes land on different elements — a
|
|
606
|
+
* provider stamps `data-theme` on a `<div>` inside the `<html>` the pre-paint
|
|
607
|
+
* script stamped `data-font` on, and for an inherited property the nearer
|
|
608
|
+
* declaration would otherwise win whatever the stylesheet's order is.
|
|
609
|
+
*
|
|
610
|
+
* Mirrors `packages/tokens/build.mjs`'s `RESOLVED_MONO`, and
|
|
611
|
+
* `test/theming/presets.test.ts` fails when the two drift.
|
|
612
|
+
*/
|
|
613
|
+
const RESOLVED_MONO = "var(--cue-font-pairing-mono, var(--cue-font-theme-mono))";
|
|
486
614
|
//#endregion
|
|
487
|
-
export { BASE_FONT_STACKS, DEFAULT_DENSITY_LEVEL, DENSITY_RADIUS_SCALE, THEME_COLOR_TOKENS, THEME_PRESETS };
|
|
615
|
+
export { BASE_FONT_STACKS, DEFAULT_DENSITY_LEVEL, DENSITY_RADIUS_SCALE, RESOLVED_MONO, THEME_COLOR_TOKENS, THEME_PRESETS };
|
|
@@ -30,7 +30,7 @@ declare const DEFAULT_THEME_BASE: ThemeName;
|
|
|
30
30
|
/**
|
|
31
31
|
* How far the sunken ground sits below the page, in oklch lightness.
|
|
32
32
|
*
|
|
33
|
-
* Small on purpose: sunken is a well, not a second theme. Across the
|
|
33
|
+
* Small on purpose: sunken is a well, not a second theme. Across the ten
|
|
34
34
|
* shipped presets the authored gap runs −0.011 to −0.031.
|
|
35
35
|
*/
|
|
36
36
|
declare const SUNKEN_LIGHTNESS_STEP = -0.02;
|
|
@@ -75,7 +75,7 @@ declare const ACCENT_FG_MINIMUM = 4.5;
|
|
|
75
75
|
* extreme rather than to the arithmetic mirror: `1 − L` of a 0.16 near-black is a
|
|
76
76
|
* 0.84 mid-grey, which is not a page. Compressing instead maps the ladder of
|
|
77
77
|
* dark grounds onto a narrow paper band — a deeper dark theme gets a cleaner
|
|
78
|
-
* white page — and lands within 0.01 of all
|
|
78
|
+
* white page — and lands within 0.01 of all ten authored light presets.
|
|
79
79
|
*/
|
|
80
80
|
declare const LIGHT_GROUND_COMPRESSION = 0.1;
|
|
81
81
|
interface ThemeAnchors {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { formatColorString } from "../color/_convert.js";
|
|
2
|
-
import { BASE_FONT_STACKS, DEFAULT_DENSITY_LEVEL, DENSITY_RADIUS_SCALE, THEME_COLOR_TOKENS, THEME_PRESETS } from "./_presets.js";
|
|
2
|
+
import { BASE_FONT_STACKS, DEFAULT_DENSITY_LEVEL, DENSITY_RADIUS_SCALE, RESOLVED_MONO, THEME_COLOR_TOKENS, THEME_PRESETS } from "./_presets.js";
|
|
3
3
|
import { WCAG_AA_TEXT, contrastRatio, contrastReport } from "./contrast.js";
|
|
4
|
-
import { assertCssValue, assertThemeName, derivedTokens, serializeThemeCss, themeSelector, tokenProperty } from "./serialize.js";
|
|
4
|
+
import { assertCssValue, assertThemeName, derivedTokens, serializeSystemModeAliases, serializeThemeCss, themeSelector, tokenProperty } from "./serialize.js";
|
|
5
5
|
import { clampChroma, converter, formatHex, inGamut, parse } from "culori";
|
|
6
6
|
//#region src/theming/create-theme.ts
|
|
7
7
|
/**
|
|
@@ -32,7 +32,7 @@ const DEFAULT_THEME_BASE = "cue";
|
|
|
32
32
|
/**
|
|
33
33
|
* How far the sunken ground sits below the page, in oklch lightness.
|
|
34
34
|
*
|
|
35
|
-
* Small on purpose: sunken is a well, not a second theme. Across the
|
|
35
|
+
* Small on purpose: sunken is a well, not a second theme. Across the ten
|
|
36
36
|
* shipped presets the authored gap runs −0.011 to −0.031.
|
|
37
37
|
*/
|
|
38
38
|
const SUNKEN_LIGHTNESS_STEP = -.02;
|
|
@@ -81,7 +81,7 @@ const ACCENT_FG_MINIMUM = WCAG_AA_TEXT;
|
|
|
81
81
|
* extreme rather than to the arithmetic mirror: `1 − L` of a 0.16 near-black is a
|
|
82
82
|
* 0.84 mid-grey, which is not a page. Compressing instead maps the ladder of
|
|
83
83
|
* dark grounds onto a narrow paper band — a deeper dark theme gets a cleaner
|
|
84
|
-
* white page — and lands within 0.01 of all
|
|
84
|
+
* white page — and lands within 0.01 of all ten authored light presets.
|
|
85
85
|
*/
|
|
86
86
|
const LIGHT_GROUND_COMPRESSION = .1;
|
|
87
87
|
/** Lightness a derived light colour steps down by while hunting for contrast. */
|
|
@@ -321,14 +321,23 @@ function resolveLight(dark, preset) {
|
|
|
321
321
|
provisional
|
|
322
322
|
};
|
|
323
323
|
}
|
|
324
|
-
/**
|
|
324
|
+
/**
|
|
325
|
+
* The font declarations a theme block carries.
|
|
326
|
+
*
|
|
327
|
+
* The monospace lands on `--cue-font-theme-mono`, not on `--cue-font-mono`, and
|
|
328
|
+
* the shared token is restated as the resolution of the two axes' halves —
|
|
329
|
+
* exactly what a shipped preset's block does. A generated theme that wrote the
|
|
330
|
+
* shared token directly would beat a `[data-font]` pairing stamped on any
|
|
331
|
+
* ancestor, purely by sitting nearer to the text, and a consumer's own preset
|
|
332
|
+
* would be the one preset in the system the typeface picker could not move.
|
|
333
|
+
*/
|
|
325
334
|
function resolveFonts(anchors, preset) {
|
|
326
335
|
const fonts = anchors.fonts ?? {};
|
|
327
336
|
const declared = [];
|
|
328
337
|
if (fonts.sans !== void 0) declared.push(["font-sans", fonts.sans]);
|
|
329
|
-
declared.push(["font-mono", fonts.mono ?? lookup(preset, "font-mono") ?? BASE_FONT_STACKS["font-mono"]]);
|
|
338
|
+
declared.push(["font-theme-mono", fonts.mono ?? lookup(preset, "font-mono") ?? BASE_FONT_STACKS["font-mono"]]);
|
|
330
339
|
if (fonts.display !== void 0) declared.push(["font-display", fonts.display]);
|
|
331
|
-
return declared.map(([name, value]) => [tokenProperty(name), assertCssValue(name, value)]);
|
|
340
|
+
return [...declared.map(([name, value]) => [tokenProperty(name), assertCssValue(name, value)]), [tokenProperty("font-mono"), RESOLVED_MONO]];
|
|
332
341
|
}
|
|
333
342
|
/** Round a product of two scales to something a stylesheet can print. */
|
|
334
343
|
const scaled = (a, b) => String(Number((a * b).toFixed(4)));
|
|
@@ -391,7 +400,7 @@ function createTheme(anchors) {
|
|
|
391
400
|
const derived = Object.entries(derivedTokens());
|
|
392
401
|
const fonts = resolveFonts(anchors, preset.fonts);
|
|
393
402
|
const radius = anchors.radiusScale === void 0 ? null : radiusBlocks(name, anchors.radiusScale);
|
|
394
|
-
const
|
|
403
|
+
const darkPaletteSections = [
|
|
395
404
|
{ declarations: colorDeclarations(dark.colors) },
|
|
396
405
|
{
|
|
397
406
|
comment: DERIVED_COMMENT,
|
|
@@ -400,25 +409,26 @@ function createTheme(anchors) {
|
|
|
400
409
|
{
|
|
401
410
|
comment: FONT_COMMENT,
|
|
402
411
|
declarations: fonts
|
|
403
|
-
}
|
|
404
|
-
...radius === null ? [] : [{
|
|
405
|
-
comment: SHAPE_COMMENT,
|
|
406
|
-
declarations: radius.base
|
|
407
|
-
}]
|
|
412
|
+
}
|
|
408
413
|
];
|
|
414
|
+
const darkSections = [...darkPaletteSections, ...radius === null ? [] : [{
|
|
415
|
+
comment: SHAPE_COMMENT,
|
|
416
|
+
declarations: radius.base
|
|
417
|
+
}]];
|
|
418
|
+
const lightSections = light === null ? null : [{ declarations: colorDeclarations(light.colors) }, {
|
|
419
|
+
comment: DERIVED_COMMENT,
|
|
420
|
+
declarations: derived
|
|
421
|
+
}];
|
|
409
422
|
const blocks = [
|
|
410
423
|
{
|
|
411
424
|
selector: themeSelector(name),
|
|
412
425
|
colorScheme: "dark",
|
|
413
426
|
sections: darkSections
|
|
414
427
|
},
|
|
415
|
-
...
|
|
428
|
+
...lightSections === null ? [] : [{
|
|
416
429
|
selector: themeSelector(name, { mode: "light" }),
|
|
417
430
|
colorScheme: "light",
|
|
418
|
-
sections:
|
|
419
|
-
comment: DERIVED_COMMENT,
|
|
420
|
-
declarations: derived
|
|
421
|
-
}]
|
|
431
|
+
sections: lightSections
|
|
422
432
|
}],
|
|
423
433
|
...radius?.blocks ?? []
|
|
424
434
|
];
|
|
@@ -432,7 +442,15 @@ function createTheme(anchors) {
|
|
|
432
442
|
}]];
|
|
433
443
|
return {
|
|
434
444
|
name,
|
|
435
|
-
css: serializeThemeCss(blocks, { banner: `@cueplusplus/ui — theme "${name}"` }),
|
|
445
|
+
css: `${serializeThemeCss(blocks, { banner: `@cueplusplus/ui — theme "${name}"` }).trimEnd()}\n\n${serializeSystemModeAliases(name, [{
|
|
446
|
+
mode: "dark",
|
|
447
|
+
colorScheme: "light dark",
|
|
448
|
+
sections: darkPaletteSections
|
|
449
|
+
}, {
|
|
450
|
+
mode: "light",
|
|
451
|
+
colorScheme: "light dark",
|
|
452
|
+
sections: lightSections ?? darkPaletteSections
|
|
453
|
+
}])}\n`,
|
|
436
454
|
tokens: Object.fromEntries(darkSections.flatMap((section) => section.declarations)),
|
|
437
455
|
light: light === null ? null : Object.fromEntries([...colorDeclarations(light.colors), ...derived]),
|
|
438
456
|
report: contrastReport(inputs)
|
|
@@ -110,7 +110,7 @@ interface ThemeBlock {
|
|
|
110
110
|
/** The selector the rule declares under. */
|
|
111
111
|
selector: string;
|
|
112
112
|
/** Emitted as `color-scheme`, ahead of the custom properties. Omit to skip it. */
|
|
113
|
-
colorScheme?: "dark" | "light";
|
|
113
|
+
colorScheme?: "dark" | "light" | "light dark";
|
|
114
114
|
/** The declarations, grouped into commented sections. */
|
|
115
115
|
sections: readonly ThemeBlockSection[];
|
|
116
116
|
}
|
|
@@ -148,6 +148,30 @@ function serializeThemeBlock(block) {
|
|
|
148
148
|
}
|
|
149
149
|
return `${block.selector} {\n${lines.join("\n")}\n}`;
|
|
150
150
|
}
|
|
151
|
+
/** Indent a complete rule once so it can live inside an at-rule. */
|
|
152
|
+
function indentRule(rule) {
|
|
153
|
+
return rule.split("\n").map((line) => ` ${line}`).join("\n");
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Alias resolved dark/light palettes onto the preserved logical `system` mode.
|
|
157
|
+
*
|
|
158
|
+
* Both `createTheme()` and the configurator call this function. Keeping the
|
|
159
|
+
* selector and media-query spelling here prevents exported overrides from
|
|
160
|
+
* drifting away from generated custom themes.
|
|
161
|
+
*
|
|
162
|
+
* @internal Used by package-owned theme serializers; not part of the public
|
|
163
|
+
* `@cueplusplus/ui/theming` barrel.
|
|
164
|
+
*/
|
|
165
|
+
function serializeSystemModeAliases(theme, aliases) {
|
|
166
|
+
const name = assertThemeName(theme);
|
|
167
|
+
return aliases.map(({ mode, colorScheme, sections }) => {
|
|
168
|
+
return `@media (prefers-color-scheme: ${mode}) {\n${indentRule(serializeThemeBlock({
|
|
169
|
+
selector: `[data-theme="${name}"][data-mode="system"]`,
|
|
170
|
+
colorScheme,
|
|
171
|
+
sections
|
|
172
|
+
}))}\n}`;
|
|
173
|
+
}).join("\n\n");
|
|
174
|
+
}
|
|
151
175
|
/**
|
|
152
176
|
* A whole generated stylesheet: banner, then one rule per block.
|
|
153
177
|
*
|
|
@@ -162,4 +186,4 @@ function serializeThemeCss(blocks, options = {}) {
|
|
|
162
186
|
return `${[...options.banner === void 0 ? [] : [`/*! ${options.banner}\n * Generated by createTheme(). Do not edit by hand.\n */`], ...rules].join("\n\n")}\n`;
|
|
163
187
|
}
|
|
164
188
|
//#endregion
|
|
165
|
-
export { CUE_TOKEN_PREFIX, DERIVED_TOKEN_TEMPLATES, THEME_NAME_PATTERN, assertCssValue, assertThemeName, derivedTokens, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty };
|
|
189
|
+
export { CUE_TOKEN_PREFIX, DERIVED_TOKEN_TEMPLATES, THEME_NAME_PATTERN, assertCssValue, assertThemeName, derivedTokens, serializeSystemModeAliases, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Accordion",
|
|
3
|
+
"slug": "accordion",
|
|
4
|
+
"group": "layout",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "A stack of sections, one (or several) open at a time.\n\nWraps Base UI's `Accordion`, so the disclosure ARIA, keyboard handling and\nopen-state bookkeeping are the primitive's. This layer adds the console skin:\nhairline separation, mono summary rows on the control ladder, and a height\ntransition that respects `prefers-reduced-motion`.",
|
|
9
|
+
"props": [],
|
|
10
|
+
"typeReferences": [],
|
|
11
|
+
"subcomponents": [
|
|
12
|
+
"Root",
|
|
13
|
+
"Item",
|
|
14
|
+
"Header",
|
|
15
|
+
"Trigger",
|
|
16
|
+
"Panel"
|
|
17
|
+
],
|
|
18
|
+
"parts": [
|
|
19
|
+
{
|
|
20
|
+
"name": "Root",
|
|
21
|
+
"usage": "Accordion.Root",
|
|
22
|
+
"description": "Groups the sections and owns which of them are open.",
|
|
23
|
+
"props": [
|
|
24
|
+
{
|
|
25
|
+
"name": "className",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "Extra classes for the accordion frame."
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"typeReferences": [
|
|
33
|
+
"Omit<BaseAccordion.Root.Props, \"className\">"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "Item",
|
|
38
|
+
"usage": "Accordion.Item",
|
|
39
|
+
"description": "One section.\n\nSeparation is a hairline the section draws above itself, dropped on the first\none — so a stack shows rules *between* sections and none against the rim of\nwhatever contains them. Same rule as `Row`, for the same reason.",
|
|
40
|
+
"props": [
|
|
41
|
+
{
|
|
42
|
+
"name": "className",
|
|
43
|
+
"type": "string",
|
|
44
|
+
"required": false,
|
|
45
|
+
"defaultValue": null,
|
|
46
|
+
"description": "Extra classes for the section."
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"typeReferences": [
|
|
50
|
+
"Omit<BaseAccordion.Item.Props, \"className\">"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "Header",
|
|
55
|
+
"usage": "Accordion.Header",
|
|
56
|
+
"description": "The heading that labels a section's panel. An `<h3>` with no type of its own.",
|
|
57
|
+
"props": [
|
|
58
|
+
{
|
|
59
|
+
"name": "className",
|
|
60
|
+
"type": "string",
|
|
61
|
+
"required": false,
|
|
62
|
+
"defaultValue": null,
|
|
63
|
+
"description": "Extra classes for the heading."
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"typeReferences": [
|
|
67
|
+
"Omit<BaseAccordion.Header.Props, \"className\">"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "Trigger",
|
|
72
|
+
"usage": "Accordion.Trigger",
|
|
73
|
+
"description": "The summary row that opens a section.\n\nA mono row on the control ladder, padded to the same gutters as a `Row`, with\na caret that rotates off the trigger's own `data-panel-open` — nothing in\nReact has to know the section is open for the arrow to turn.",
|
|
74
|
+
"props": [
|
|
75
|
+
{
|
|
76
|
+
"name": "className",
|
|
77
|
+
"type": "string",
|
|
78
|
+
"required": false,
|
|
79
|
+
"defaultValue": null,
|
|
80
|
+
"description": "Extra classes for the summary row."
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"typeReferences": [
|
|
84
|
+
"Omit<BaseAccordion.Trigger.Props, \"className\">"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "Panel",
|
|
89
|
+
"usage": "Accordion.Panel",
|
|
90
|
+
"description": "A section's body.\n\nHeight is animated from `--accordion-panel-height`, which Base UI measures.\nThe animating element carries no padding — padding is part of the box height,\nso it would be counted into the `0 → measured` transition and make the panel\njump at both ends — hence the inner body element.",
|
|
91
|
+
"props": [
|
|
92
|
+
{
|
|
93
|
+
"name": "className",
|
|
94
|
+
"type": "string",
|
|
95
|
+
"required": false,
|
|
96
|
+
"defaultValue": null,
|
|
97
|
+
"description": "Extra classes for the animating box. Padding belongs on `bodyClassName`."
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "bodyClassName",
|
|
101
|
+
"type": "string",
|
|
102
|
+
"required": false,
|
|
103
|
+
"defaultValue": null,
|
|
104
|
+
"description": "Extra classes for the padded body inside it."
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"typeReferences": [
|
|
108
|
+
"Omit<BaseAccordion.Panel.Props, \"className\">"
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"variants": {},
|
|
113
|
+
"defaultVariants": {},
|
|
114
|
+
"tokensUsed": [
|
|
115
|
+
"--cue-accent",
|
|
116
|
+
"--cue-border",
|
|
117
|
+
"--cue-control-md",
|
|
118
|
+
"--cue-fg",
|
|
119
|
+
"--cue-fg-muted",
|
|
120
|
+
"--cue-fg-subtle",
|
|
121
|
+
"--cue-font-mono",
|
|
122
|
+
"--cue-icon-sm",
|
|
123
|
+
"--cue-pad-row-x",
|
|
124
|
+
"--cue-space-1",
|
|
125
|
+
"--cue-space-3",
|
|
126
|
+
"--cue-space-4",
|
|
127
|
+
"--cue-text-ui"
|
|
128
|
+
],
|
|
129
|
+
"summary": "A stack of sections, one (or several) open at a time.",
|
|
130
|
+
"examples": [
|
|
131
|
+
{
|
|
132
|
+
"title": "Usage",
|
|
133
|
+
"code": "<Accordion.Root>\n <Accordion.Item value=\"routing\">\n <Accordion.Header><Accordion.Trigger>routing</Accordion.Trigger></Accordion.Header>\n <Accordion.Panel>…</Accordion.Panel>\n </Accordion.Item>\n</Accordion.Root>\n<Accordion.Root multiple defaultValue={[\"routing\"]}>…</Accordion.Root>",
|
|
134
|
+
"language": "tsx"
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"status": "todo-docs",
|
|
138
|
+
"url": "/docs/components/accordion",
|
|
139
|
+
"mdUrl": "/docs/components/accordion.md",
|
|
140
|
+
"jsonUrl": "/r/components/accordion.json",
|
|
141
|
+
"specimens": [
|
|
142
|
+
{
|
|
143
|
+
"title": "Accordion",
|
|
144
|
+
"group": "layout",
|
|
145
|
+
"components": [
|
|
146
|
+
"Accordion"
|
|
147
|
+
],
|
|
148
|
+
"code": "<Accordion.Root className=\"w-full max-w-[36rem]\" defaultValue={[\"patch\"]}>\n <Accordion.Item value=\"patch\">\n <Accordion.Header>\n <Accordion.Trigger>Patch</Accordion.Trigger>\n </Accordion.Header>\n <Accordion.Panel>48 fixtures across 4 universes.</Accordion.Panel>\n </Accordion.Item>\n <Accordion.Item value=\"cues\">\n <Accordion.Header>\n <Accordion.Trigger>Cues</Accordion.Trigger>\n </Accordion.Header>\n <Accordion.Panel>12 cues, last edited 4 minutes ago.</Accordion.Panel>\n </Accordion.Item>\n <Accordion.Item value=\"network\" disabled>\n <Accordion.Header>\n <Accordion.Trigger>Network</Accordion.Trigger>\n </Accordion.Header>\n <Accordion.Panel>Art-Net on 10.0.0.42.</Accordion.Panel>\n </Accordion.Item>\n</Accordion.Root>",
|
|
149
|
+
"note": "Hairline-separated items with mono summary rows. Several can be open at once.",
|
|
150
|
+
"interaction": "the whole header row is the trigger; the panel animates its height and stills under prefers-reduced-motion."
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"todo": true
|
|
154
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "AgentPile",
|
|
3
|
+
"slug": "agent-pile",
|
|
4
|
+
"group": "chat",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "The roster of agents working on a thread, stacked into one object.\n\nThree states ride on each avatar, and none of them is colour-only: the\norchestrator wears a crown, a working agent gets a spinning arc, and an agent\nwaiting on the user gets a `?` badge — each of them also spelled into the\navatar's accessible name, so a screen reader hears \"Researcher · working\"\nrather than nothing at all.\n\nAvatars are outlined in the agent's colour rather than filled with it. A fill\nwould put arbitrary-hue ink on an arbitrary-hue ground at 20px; the outline\ntreatment is the same tinted-chip recipe the rest of the system uses and\nstays legible on every theme.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "agents",
|
|
12
|
+
"type": "readonly AgentPileEntry[]",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "The roster, in the order it should read. Renders nothing when empty."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "root",
|
|
19
|
+
"type": "string",
|
|
20
|
+
"required": false,
|
|
21
|
+
"defaultValue": null,
|
|
22
|
+
"description": "Slug of the orchestrator: takes the theme accent and wears the crown."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "selected",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "Slug of the lane currently open — that avatar gets a ring."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "onSelect",
|
|
33
|
+
"type": "((slug: string) => void)",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": null,
|
|
36
|
+
"description": "Called with a slug when an avatar is pressed. Omit for a read-only pile."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "max",
|
|
40
|
+
"type": "number",
|
|
41
|
+
"required": false,
|
|
42
|
+
"defaultValue": null,
|
|
43
|
+
"description": "Show at most this many; the rest collapse into a `+N` chip."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "fanned",
|
|
47
|
+
"type": "boolean",
|
|
48
|
+
"required": false,
|
|
49
|
+
"defaultValue": null,
|
|
50
|
+
"description": "Force the fan open or shut. Omit to let hover and focus decide."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "size",
|
|
54
|
+
"type": "\"sm\" | \"md\" | \"lg\"",
|
|
55
|
+
"required": false,
|
|
56
|
+
"defaultValue": "md",
|
|
57
|
+
"description": "Rung of the control ladder. Defaults to `\"md\"`."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "aria-label",
|
|
61
|
+
"type": "string",
|
|
62
|
+
"required": false,
|
|
63
|
+
"defaultValue": null,
|
|
64
|
+
"description": "Accessible name for the group. Required in practice — name the roster."
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"typeReferences": [
|
|
68
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"onSelect\">"
|
|
69
|
+
],
|
|
70
|
+
"subcomponents": [],
|
|
71
|
+
"parts": [],
|
|
72
|
+
"variants": {},
|
|
73
|
+
"defaultVariants": {},
|
|
74
|
+
"tokensUsed": [
|
|
75
|
+
"--cue-accent",
|
|
76
|
+
"--cue-accent-fg",
|
|
77
|
+
"--cue-bg",
|
|
78
|
+
"--cue-border",
|
|
79
|
+
"--cue-control-lg",
|
|
80
|
+
"--cue-control-md",
|
|
81
|
+
"--cue-control-sm",
|
|
82
|
+
"--cue-fg-muted",
|
|
83
|
+
"--cue-font-mono",
|
|
84
|
+
"--cue-icon-sm",
|
|
85
|
+
"--cue-surface-2",
|
|
86
|
+
"--cue-surface-3",
|
|
87
|
+
"--cue-text-label",
|
|
88
|
+
"--cue-text-micro",
|
|
89
|
+
"--cue-text-ui"
|
|
90
|
+
],
|
|
91
|
+
"summary": "The roster of agents working on a thread, stacked into one object.",
|
|
92
|
+
"examples": [
|
|
93
|
+
{
|
|
94
|
+
"title": "Usage",
|
|
95
|
+
"code": "<AgentPile aria-label=\"Agents\" agents={roster} root=\"chief\" onSelect={openLane} />\n<AgentPile aria-label=\"Agents\" agents={roster} max={5} fanned />",
|
|
96
|
+
"language": "tsx"
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"status": "todo-docs",
|
|
100
|
+
"url": "/docs/components/agent-pile",
|
|
101
|
+
"mdUrl": "/docs/components/agent-pile.md",
|
|
102
|
+
"jsonUrl": "/r/components/agent-pile.json",
|
|
103
|
+
"specimens": [
|
|
104
|
+
{
|
|
105
|
+
"title": "AgentPile",
|
|
106
|
+
"group": "chat",
|
|
107
|
+
"components": [
|
|
108
|
+
"AgentPile"
|
|
109
|
+
],
|
|
110
|
+
"code": "<Specimens>\n {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n <Specimen key={size} label={size}>\n <AgentPile agents={AGENTS} root=\"orchestrator\" size={size} />\n </Specimen>\n ))}\n <Specimen label=\"max 4\">\n <AgentPile agents={AGENTS} root=\"orchestrator\" max={4} />\n </Specimen>\n <Specimen label=\"not fanned\">\n <AgentPile agents={AGENTS} root=\"orchestrator\" fanned={false} />\n </Specimen>\n <Specimen label=\"selected\">\n <AgentPile agents={AGENTS} root=\"orchestrator\" selected=\"patcher\" />\n </Specimen>\n</Specimens>",
|
|
111
|
+
"note": "Faces at −12px overlap, fanning to +4px on hover. The crown marks the orchestrator, an arc marks work in flight and a `?` marks an agent waiting on an answer.",
|
|
112
|
+
"interaction": "every face is a button with the agent's name; the pile is one tab stop and arrow keys move inside it."
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"todo": true
|
|
116
|
+
}
|