@cueplusplus/ui 0.8.0 → 0.10.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 +457 -0
- package/README.md +131 -0
- package/dist/chat/message-list.js +2 -1
- package/dist/configurator/_export.d.ts +1 -1
- package/dist/configurator/_export.js +53 -13
- package/dist/configurator/_overrides.d.ts +25 -6
- package/dist/configurator/_overrides.js +30 -17
- package/dist/configurator/configurator.js +8 -3
- package/dist/configurator/panel-sections.js +43 -13
- package/dist/elements/command-palette.js +1 -1
- package/dist/elements/flow-graph.js +2 -2
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/surfaces.js +4 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +5 -2
- package/dist/instruments/meter.d.ts +5 -1
- package/dist/layout/bento.d.ts +144 -0
- package/dist/layout/bento.js +266 -0
- package/dist/layout/index.d.ts +3 -2
- package/dist/layout/index.js +3 -2
- package/dist/midi/piano-keyboard.js +5 -1
- package/dist/primitives/button.d.ts +12 -0
- package/dist/styles.css +23 -1
- package/dist/system/density.d.ts +17 -8
- package/dist/system/density.js +39 -16
- package/dist/system/index.d.ts +5 -2
- package/dist/system/index.js +3 -1
- package/dist/system/overrides.d.ts +80 -0
- package/dist/system/overrides.js +277 -0
- package/dist/system/portal.d.ts +4 -2
- package/dist/system/portal.js +34 -3
- package/dist/system/prepaint.d.ts +58 -7
- package/dist/system/prepaint.js +72 -20
- package/dist/system/theme-provider.d.ts +133 -8
- package/dist/system/theme-provider.js +203 -72
- package/dist/system/theme-registry.d.ts +53 -0
- package/dist/system/theme-registry.js +66 -0
- package/dist/system/use-density.d.ts +13 -5
- package/dist/system/use-density.js +142 -13
- package/dist/system/use-theme.d.ts +5 -3
- package/dist/system/use-theme.js +5 -3
- package/dist/system/vocabulary.d.ts +15 -0
- package/dist/system/vocabulary.js +111 -0
- package/dist/theming/contrast.d.ts +2 -122
- package/dist/theming/contrast.js +2 -194
- package/dist/theming/create-theme.d.ts +37 -11
- package/dist/theming/create-theme.js +54 -17
- package/dist/theming/index.d.ts +3 -4
- package/dist/theming/index.js +3 -4
- package/dist/theming/serialize.d.ts +24 -11
- package/dist/theming/serialize.js +16 -18
- package/manifest/components/accordion.json +24 -6
- package/manifest/components/activity-graph.json +20 -5
- package/manifest/components/agent-card.json +37 -9
- package/manifest/components/agent-handoff.json +21 -5
- package/manifest/components/agent-mode-badge.json +22 -4
- package/manifest/components/agent-pile.json +38 -8
- package/manifest/components/agent-plan.json +9 -2
- package/manifest/components/agent-status.json +17 -3
- package/manifest/components/agent-surface.json +26 -11
- package/manifest/components/alert-dialog.json +29 -5
- package/manifest/components/animated-number.json +14 -6
- package/manifest/components/app-bar.json +66 -13
- package/manifest/components/app-shell.json +133 -31
- package/manifest/components/app-window-frame.json +28 -6
- package/manifest/components/approval-card.json +37 -7
- package/manifest/components/artifact-card.json +16 -4
- package/manifest/components/ask-box.json +99 -21
- package/manifest/components/audience-icon.json +1 -7
- package/manifest/components/autocomplete.json +80 -18
- package/manifest/components/avatar-group.json +13 -2
- package/manifest/components/avatar.json +22 -4
- package/manifest/components/background-inbox.json +9 -2
- package/manifest/components/bento.json +306 -0
- package/manifest/components/branch-picker.json +29 -7
- package/manifest/components/breadcrumb.json +13 -3
- package/manifest/components/button-group.json +21 -4
- package/manifest/components/button.json +41 -4
- package/manifest/components/canvas-split-body.json +4 -1
- package/manifest/components/canvas-split-header.json +17 -4
- package/manifest/components/canvas-split-line.json +4 -1
- package/manifest/components/canvas-split-message.json +8 -1
- package/manifest/components/card.json +14 -3
- package/manifest/components/carousel.json +54 -12
- package/manifest/components/catalogue-icon.json +1 -7
- package/manifest/components/channel-beta-icon.json +1 -7
- package/manifest/components/channel-matrix.json +80 -15
- package/manifest/components/channel-released-icon.json +1 -7
- package/manifest/components/chart-container.json +26 -10
- package/manifest/components/chart-ramp.json +13 -3
- package/manifest/components/chart-swatch.json +9 -2
- package/manifest/components/chart-tooltip-content.json +31 -7
- package/manifest/components/chart.json +30 -6
- package/manifest/components/chat-panel-composer.json +9 -2
- package/manifest/components/checkbox-group.json +4 -2
- package/manifest/components/checkbox.json +17 -4
- package/manifest/components/checkpoint-history.json +13 -3
- package/manifest/components/chip.json +35 -5
- package/manifest/components/clamp.json +30 -7
- package/manifest/components/cli-tool-icon.json +1 -7
- package/manifest/components/code-diff.json +20 -5
- package/manifest/components/code-runner.json +32 -6
- package/manifest/components/collapsible.json +16 -4
- package/manifest/components/color-area.json +4 -1
- package/manifest/components/color-field.json +13 -3
- package/manifest/components/color-picker.json +75 -17
- package/manifest/components/color-slider.json +12 -3
- package/manifest/components/color-swatch.json +13 -2
- package/manifest/components/colors-section.json +10 -7
- package/manifest/components/combobox.json +81 -18
- package/manifest/components/command-palette.json +57 -13
- package/manifest/components/compaction-row.json +35 -7
- package/manifest/components/comparison-card.json +17 -4
- package/manifest/components/composer-attachment-chip.json +9 -2
- package/manifest/components/composer-bar.json +4 -1
- package/manifest/components/composer-command-item.json +8 -2
- package/manifest/components/composer-context.json +4 -1
- package/manifest/components/composer-input.json +5 -1
- package/manifest/components/composer-menu-item.json +4 -1
- package/manifest/components/composer-menu.json +12 -2
- package/manifest/components/composer-model-item.json +8 -2
- package/manifest/components/composer-model-trigger.json +8 -2
- package/manifest/components/composer-person-item.json +8 -2
- package/manifest/components/composer-send.json +8 -2
- package/manifest/components/composer-voice-button.json +4 -1
- package/manifest/components/composer-voice.json +8 -2
- package/manifest/components/composer.json +76 -17
- package/manifest/components/computer-use.json +17 -4
- package/manifest/components/confidence-marker.json +13 -3
- package/manifest/components/connection-state.json +23 -4
- package/manifest/components/container.json +14 -2
- package/manifest/components/context-breakdown.json +8 -2
- package/manifest/components/context-menu.json +16 -4
- package/manifest/components/context-usage.json +16 -4
- package/manifest/components/conversation-search.json +22 -5
- package/manifest/components/copy-button.json +32 -7
- package/manifest/components/cost-meter.json +12 -3
- package/manifest/components/cue-logotype.json +17 -3
- package/manifest/components/cue-mark.json +17 -3
- package/manifest/components/cue-portal-frame.json +14 -4
- package/manifest/components/data-row.json +21 -7
- package/manifest/components/data-table-pagination.json +18 -4
- package/manifest/components/data-table-toolbar.json +30 -7
- package/manifest/components/data-tree.json +42 -9
- package/manifest/components/date-field.json +13 -2
- package/manifest/components/date-picker.json +81 -19
- package/manifest/components/date-range-picker.json +81 -19
- package/manifest/components/day-separator.json +4 -1
- package/manifest/components/delegation-card.json +64 -12
- package/manifest/components/density.json +25 -5
- package/manifest/components/description-list.json +8 -1
- package/manifest/components/diagram.json +33 -7
- package/manifest/components/dialog.json +29 -6
- package/manifest/components/disclosure.json +31 -7
- package/manifest/components/dmx-bar.json +16 -4
- package/manifest/components/dmx-strip.json +20 -5
- package/manifest/components/document-reference.json +21 -5
- package/manifest/components/draft-restore.json +18 -4
- package/manifest/components/drawer.json +30 -6
- package/manifest/components/dropdown-menu.json +55 -10
- package/manifest/components/edit-message.json +32 -7
- package/manifest/components/elements-command-palette.json +27 -6
- package/manifest/components/elements-data-table.json +9 -2
- package/manifest/components/elements-timeline.json +8 -2
- package/manifest/components/elicitation-form.json +31 -6
- package/manifest/components/empty-state-composer.json +9 -2
- package/manifest/components/empty-state-suggestion.json +4 -1
- package/manifest/components/empty-state.json +25 -5
- package/manifest/components/end-of-turn-summary.json +16 -4
- package/manifest/components/env-var-input.json +54 -12
- package/manifest/components/error-state.json +17 -4
- package/manifest/components/export-dialog.json +27 -11
- package/manifest/components/eyebrow.json +4 -1
- package/manifest/components/feedback-dialog.json +33 -7
- package/manifest/components/field-description.json +4 -1
- package/manifest/components/field-error.json +13 -3
- package/manifest/components/field-label.json +4 -1
- package/manifest/components/field.json +4 -1
- package/manifest/components/file-tree.json +16 -4
- package/manifest/components/file-upload.json +58 -13
- package/manifest/components/flow-graph.json +12 -3
- package/manifest/components/folder-icon.json +1 -7
- package/manifest/components/footer.json +24 -4
- package/manifest/components/frac.json +10 -2
- package/manifest/components/generation-loader.json +17 -3
- package/manifest/components/generative-ui.json +39 -7
- package/manifest/components/grid.json +56 -5
- package/manifest/components/group-bar.json +25 -6
- package/manifest/components/guardrail-notice.json +22 -5
- package/manifest/components/hover-card.json +45 -8
- package/manifest/components/icon-button.json +22 -4
- package/manifest/components/image-generation.json +8 -2
- package/manifest/components/info-tip.json +42 -7
- package/manifest/components/inline-citation.json +14 -3
- package/manifest/components/input-group.json +24 -5
- package/manifest/components/input.json +13 -3
- package/manifest/components/item.json +42 -8
- package/manifest/components/job-progress.json +25 -6
- package/manifest/components/launcher-bubble.json +32 -7
- package/manifest/components/ledger.json +87 -19
- package/manifest/components/link.json +16 -3
- package/manifest/components/live-region-announcer.json +21 -5
- package/manifest/components/log-viewer.json +42 -10
- package/manifest/components/map-answer.json +17 -4
- package/manifest/components/markdown-text.json +36 -5
- package/manifest/components/math-block.json +12 -3
- package/manifest/components/mcp-server-icon.json +1 -7
- package/manifest/components/mcp-server-panel.json +18 -4
- package/manifest/components/memory-chips.json +9 -2
- package/manifest/components/menubar.json +33 -7
- package/manifest/components/message-actions.json +32 -7
- package/manifest/components/message-attachments.json +9 -2
- package/manifest/components/message-branches.json +14 -3
- package/manifest/components/message-list.json +27 -6
- package/manifest/components/message-pair.json +25 -5
- package/manifest/components/message-queue.json +13 -3
- package/manifest/components/message-timing.json +8 -2
- package/manifest/components/message.json +41 -9
- package/manifest/components/meter.json +43 -7
- package/manifest/components/mobile-composer.json +47 -10
- package/manifest/components/model-picker.json +13 -3
- package/manifest/components/multi-select.json +78 -17
- package/manifest/components/musical-time-input.json +34 -8
- package/manifest/components/navigation-menu.json +54 -12
- package/manifest/components/node-card.json +42 -7
- package/manifest/components/node-handle.json +17 -2
- package/manifest/components/number-field.json +28 -6
- package/manifest/components/number-ticker.json +8 -2
- package/manifest/components/onboarding.json +18 -4
- package/manifest/components/otp-field.json +43 -10
- package/manifest/components/page-shell.json +35 -6
- package/manifest/components/pagination.json +21 -5
- package/manifest/components/panel-header.json +15 -3
- package/manifest/components/password-input.json +38 -8
- package/manifest/components/permission-grant.json +28 -5
- package/manifest/components/permission-scopes.json +57 -12
- package/manifest/components/piano-keyboard.json +38 -9
- package/manifest/components/plussie.json +34 -5
- package/manifest/components/popover.json +45 -8
- package/manifest/components/preset-section.json +14 -8
- package/manifest/components/progress.json +25 -6
- package/manifest/components/prompt-library.json +27 -6
- package/manifest/components/queue-dock.json +36 -8
- package/manifest/components/quota-banner.json +25 -6
- package/manifest/components/quote-reply.json +29 -7
- package/manifest/components/radio-group.json +12 -2
- package/manifest/components/radio.json +17 -3
- package/manifest/components/rating.json +60 -13
- package/manifest/components/read-aloud.json +35 -8
- package/manifest/components/reasoning-effort.json +17 -4
- package/manifest/components/reasoning-panel.json +33 -8
- package/manifest/components/recommendation-card.json +35 -10
- package/manifest/components/regenerate-menu.json +22 -5
- package/manifest/components/replay-player.json +29 -7
- package/manifest/components/research-report.json +12 -3
- package/manifest/components/resizable.json +4 -1
- package/manifest/components/retrieval-chunks.json +16 -4
- package/manifest/components/revert-dock.json +61 -14
- package/manifest/components/reviewable-diff.json +23 -5
- package/manifest/components/risk-badge.json +18 -3
- package/manifest/components/row.json +17 -4
- package/manifest/components/schedule-card.json +25 -6
- package/manifest/components/score-breakdown.json +20 -5
- package/manifest/components/scroll-anchor.json +13 -3
- package/manifest/components/scroll-area.json +31 -8
- package/manifest/components/scrollable-tabs-list.json +12 -4
- package/manifest/components/scrub-input.json +84 -18
- package/manifest/components/seam-cell.json +19 -3
- package/manifest/components/seam-grid.json +12 -3
- package/manifest/components/search-input.json +49 -10
- package/manifest/components/section-header.json +36 -8
- package/manifest/components/segmented-control.json +50 -11
- package/manifest/components/select.json +74 -16
- package/manifest/components/separator.json +4 -1
- package/manifest/components/settings-panel.json +41 -9
- package/manifest/components/shape-section.json +10 -7
- package/manifest/components/shared-conversation.json +21 -5
- package/manifest/components/sheet.json +29 -6
- package/manifest/components/shimmer-label.json +4 -2
- package/manifest/components/sidebar.json +60 -13
- package/manifest/components/skill-icon.json +1 -7
- package/manifest/components/slider.json +22 -5
- package/manifest/components/sources.json +17 -4
- package/manifest/components/sparkline.json +17 -4
- package/manifest/components/speaker-identity.json +4 -1
- package/manifest/components/spec-sheet.json +16 -4
- package/manifest/components/spectrum-visualizer.json +41 -10
- package/manifest/components/spinner.json +12 -2
- package/manifest/components/stack-icon.json +1 -7
- package/manifest/components/stack.json +54 -7
- package/manifest/components/stacks-matrix-icon.json +1 -7
- package/manifest/components/stat.json +28 -4
- package/manifest/components/status-bar.json +50 -9
- package/manifest/components/status-dot.json +23 -4
- package/manifest/components/stepper.json +22 -5
- package/manifest/components/stopped-run.json +19 -4
- package/manifest/components/streaming-text.json +12 -3
- package/manifest/components/subagent-list.json +21 -5
- package/manifest/components/suggestions.json +27 -5
- package/manifest/components/swap-label.json +18 -4
- package/manifest/components/switch.json +18 -3
- package/manifest/components/table-scroll-region.json +4 -1
- package/manifest/components/table.json +54 -11
- package/manifest/components/tabs.json +16 -5
- package/manifest/components/tags-input.json +79 -17
- package/manifest/components/tail-status.json +37 -8
- package/manifest/components/terminal-block.json +25 -5
- package/manifest/components/terminal-frame.json +34 -8
- package/manifest/components/textarea.json +8 -3
- package/manifest/components/theme-configurator.json +47 -14
- package/manifest/components/theme-provider.json +97 -18
- package/manifest/components/thinking-indicator.json +8 -2
- package/manifest/components/thread-list.json +13 -3
- package/manifest/components/thread-search.json +22 -5
- package/manifest/components/threshold-rail.json +77 -14
- package/manifest/components/time-boundary.json +8 -2
- package/manifest/components/time-field.json +13 -2
- package/manifest/components/timeline-ruler.json +51 -12
- package/manifest/components/timeline.json +19 -3
- package/manifest/components/title-bar.json +19 -4
- package/manifest/components/toast.json +12 -3
- package/manifest/components/todo-list.json +8 -2
- package/manifest/components/toggle-group.json +33 -7
- package/manifest/components/toggle.json +23 -4
- package/manifest/components/token-editor.json +26 -10
- package/manifest/components/tool-call-card.json +83 -16
- package/manifest/components/tool-call.json +37 -9
- package/manifest/components/tool-error.json +34 -8
- package/manifest/components/tool-group.json +17 -4
- package/manifest/components/tool-timeline.json +37 -9
- package/manifest/components/toolbar.json +37 -8
- package/manifest/components/tooltip.json +41 -7
- package/manifest/components/trace-waterfall.json +12 -3
- package/manifest/components/tree-visibility-toggle.json +18 -3
- package/manifest/components/tree.json +52 -11
- package/manifest/components/turn-footer.json +36 -8
- package/manifest/components/two-step-button.json +46 -9
- package/manifest/components/typing-indicator.json +8 -1
- package/manifest/components/universe-grid.json +37 -10
- package/manifest/components/unread-divider.json +4 -1
- package/manifest/components/usage-chart.json +46 -9
- package/manifest/components/verdict-row.json +20 -5
- package/manifest/components/voice-conversation.json +37 -7
- package/manifest/components/web-preview.json +23 -5
- package/manifest/components/web-search.json +20 -5
- package/manifest/components/work-collapse.json +30 -7
- package/manifest/fixtures.json +106 -0
- package/manifest/manifest.json +449 -310
- package/manifest/tokens.json +122 -12
- package/package.json +16 -6
- package/dist/theming/_presets.d.ts +0 -11
- package/dist/theming/_presets.js +0 -678
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { SpaceStep } from "./stack.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/layout/bento.d.ts
|
|
4
|
+
/** How many columns the bento resolves to at `lg`. */
|
|
5
|
+
type BentoColumns = 2 | 3 | 4;
|
|
6
|
+
/** How many rows to declare, so a tall tile spans a track that exists. */
|
|
7
|
+
type BentoRows = 1 | 2 | 3 | 4;
|
|
8
|
+
/** How many columns one tile covers, before the container clamps it. */
|
|
9
|
+
type BentoSpan = 1 | 2 | 3 | 4;
|
|
10
|
+
/** How many rows one tile covers. */
|
|
11
|
+
type BentoRowSpan = 1 | 2;
|
|
12
|
+
/** How much height a tile reserves before its content arrives. */
|
|
13
|
+
type BentoMinHeight = "none" | "half" | "hero";
|
|
14
|
+
interface BentoRootProps extends React.ComponentPropsWithoutRef<"div"> {
|
|
15
|
+
/** How many columns at `lg`. Defaults to `3`. Two from `sm`, one below it. */
|
|
16
|
+
cols?: BentoColumns;
|
|
17
|
+
/**
|
|
18
|
+
* How many rows to declare from `sm` up.
|
|
19
|
+
*
|
|
20
|
+
* Only worth setting where a tile spans rows: a `rowSpan` over implicit
|
|
21
|
+
* tracks sizes itself to the tile's own content, which is not a span.
|
|
22
|
+
*/
|
|
23
|
+
rows?: BentoRows;
|
|
24
|
+
/** Pack later tiles into earlier holes instead of leaving them empty. */
|
|
25
|
+
dense?: boolean;
|
|
26
|
+
/** Which rung of the density space ladder to spend between tiles. Defaults to `4`. */
|
|
27
|
+
gap?: SpaceStep;
|
|
28
|
+
/** The tiles. Declared, so the manifest files it as a documented prop. */
|
|
29
|
+
children?: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* What both tile variants share: the geometry, the four slots and the body.
|
|
33
|
+
*
|
|
34
|
+
* An `interface … extends Omit<…>` rather than a type alias over an
|
|
35
|
+
* intersection, for the same reason `PanelHeaderProps` and `ItemProps` are:
|
|
36
|
+
* `children` is a documented prop only where a component *declares* it, and a
|
|
37
|
+
* member of an intersection's object half is attributed to React's own
|
|
38
|
+
* declaration rather than to this file — so the alias form files every other
|
|
39
|
+
* slot and silently drops the body.
|
|
40
|
+
*/
|
|
41
|
+
interface BentoTileBase extends Omit<React.ComponentPropsWithoutRef<"div">, "title"> {
|
|
42
|
+
/** How many columns to cover. Clamped by the container to its own `cols`. */
|
|
43
|
+
span?: BentoSpan;
|
|
44
|
+
/** How many rows to cover. Needs a container that declares them. */
|
|
45
|
+
rowSpan?: BentoRowSpan;
|
|
46
|
+
/** How much height to hold before the content arrives. Defaults to `"none"`. */
|
|
47
|
+
minHeight?: BentoMinHeight;
|
|
48
|
+
/** The qualifier above the name: an import specifier, a family, a device. */
|
|
49
|
+
eyebrow?: React.ReactNode;
|
|
50
|
+
/** The tile's name. Rendered as a `<span>`, never as a heading. */
|
|
51
|
+
title?: React.ReactNode;
|
|
52
|
+
/** The count beside the name — by convention a `<Chip variant="outline">`. */
|
|
53
|
+
meta?: React.ReactNode;
|
|
54
|
+
/** The summary and anything below it. */
|
|
55
|
+
children?: React.ReactNode;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A tile whose whole surface is one `<a>`.
|
|
59
|
+
*
|
|
60
|
+
* Its content is static: no control, no second link. HTML's content model for
|
|
61
|
+
* `<a>` is transparent *but* admits no interactive descendant and no `<a>`
|
|
62
|
+
* descendant, and `inert` changes focus, hit-testing and the accessibility tree
|
|
63
|
+
* while changing that content model not at all.
|
|
64
|
+
*/
|
|
65
|
+
type BentoLinkTileProps = BentoTileBase & {
|
|
66
|
+
/** Where the tile goes. Its presence is what makes the tile a link. */
|
|
67
|
+
href: string;
|
|
68
|
+
/**
|
|
69
|
+
* A router's own link element, cloned to carry the tile's classes and slots.
|
|
70
|
+
*
|
|
71
|
+
* The **element** form only, and never a render function: a function would
|
|
72
|
+
* buy a second calling convention at the price of this component's
|
|
73
|
+
* server-safety, because the hook that reads one is a hook. The element keeps
|
|
74
|
+
* its own `href` — `next/link` declares that prop required, so passing the
|
|
75
|
+
* tile's would make the tile the silent owner of a value the element has to
|
|
76
|
+
* declare anyway. Its own `className` is **merged** with the tile's rather
|
|
77
|
+
* than replaced by it, which is the other half of the same bargain: `href` is
|
|
78
|
+
* a value the element owns outright, and a class is one it adds to.
|
|
79
|
+
*/
|
|
80
|
+
render?: React.ReactElement;
|
|
81
|
+
/** Never on a link tile: an `<a>` may not contain a control. */
|
|
82
|
+
action?: never;
|
|
83
|
+
};
|
|
84
|
+
/** A surface that may hold live children; its link or control is a visible sibling. */
|
|
85
|
+
type BentoPanelTileProps = BentoTileBase & {
|
|
86
|
+
/** Never on a panel tile: `href` is what selects the link variant. */
|
|
87
|
+
href?: never;
|
|
88
|
+
/** Never on a panel tile: `render` belongs to the link variant. */
|
|
89
|
+
render?: never;
|
|
90
|
+
/** The tile's own link or control, rendered beside the count rather than around it. */
|
|
91
|
+
action?: React.ReactNode;
|
|
92
|
+
};
|
|
93
|
+
/** Props for {@link Bento.Tile}: a link tile, or a panel tile with an `action`. */
|
|
94
|
+
type BentoTileProps = BentoLinkTileProps | BentoPanelTileProps;
|
|
95
|
+
/**
|
|
96
|
+
* A grid of unequal tiles: per-item spans, clamped to the container's columns.
|
|
97
|
+
*
|
|
98
|
+
* Where `Grid` lays out cells it never touches, a bento's whole content is
|
|
99
|
+
* per-item — so the span is a prop on the tile, from a closed set, and the
|
|
100
|
+
* container clamps it on the way past. One column below `sm`, two from `sm`,
|
|
101
|
+
* the asked-for count from `lg`; the clamp is per breakpoint and not per
|
|
102
|
+
* `cols`, because every container is two tracks wide in between whatever it
|
|
103
|
+
* was asked for.
|
|
104
|
+
*
|
|
105
|
+
* **Static markup — no hooks, no `"use client"`, and it must stay that way.**
|
|
106
|
+
* A directive is per *module*, so a `Bento` built on `useRender` would open a
|
|
107
|
+
* client boundary in every server page that draws one. That is why the router
|
|
108
|
+
* escape hatch is `render`, an *element* that is cloned, rather than a render
|
|
109
|
+
* function; and why {@link Bento.Tile} is a discriminated union rather than a
|
|
110
|
+
* tile that decides at runtime what it is.
|
|
111
|
+
*
|
|
112
|
+
* `BentoTileProps` omits the native `title` from its `<div>` props, the same
|
|
113
|
+
* omission `PanelHeader` and `Item` make: `React.ComponentPropsWithoutRef<"div">`
|
|
114
|
+
* already declares `title?: string`, and narrowing it to a `ReactNode` without
|
|
115
|
+
* the `Omit` is TS2430.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* <Bento.Root cols={3} rows={2} gap={5}>
|
|
119
|
+
* <Bento.Tile span={2} rowSpan={2} minHeight="hero" title="Kitchen sink">
|
|
120
|
+
* Every component, on one page.
|
|
121
|
+
* </Bento.Tile>
|
|
122
|
+
* <Bento.Tile title="Themes" meta={<Chip variant="outline">10</Chip>} />
|
|
123
|
+
* <Bento.Tile title="Density" meta={<Chip variant="outline">5</Chip>} />
|
|
124
|
+
* </Bento.Root>
|
|
125
|
+
* @example
|
|
126
|
+
* <Bento.Tile
|
|
127
|
+
* href="/docs/components/grid"
|
|
128
|
+
* render={<NextLink href="/docs/components/grid" />}
|
|
129
|
+
* eyebrow="@cueplusplus/ui"
|
|
130
|
+
* title="Grid"
|
|
131
|
+
* >
|
|
132
|
+
* Equal columns, or as many as fit.
|
|
133
|
+
* </Bento.Tile>
|
|
134
|
+
* @example
|
|
135
|
+
* <Bento.Tile title="Signal" action={<Button onClick={apply}>Apply</Button>}>
|
|
136
|
+
* <ThemeSwatches theme="signal" />
|
|
137
|
+
* </Bento.Tile>
|
|
138
|
+
*/
|
|
139
|
+
declare const Bento: {
|
|
140
|
+
Root: React.ForwardRefExoticComponent<BentoRootProps & React.RefAttributes<HTMLDivElement>>;
|
|
141
|
+
Tile: React.ForwardRefExoticComponent<BentoTileProps & React.RefAttributes<HTMLElement>>;
|
|
142
|
+
};
|
|
143
|
+
//#endregion
|
|
144
|
+
export { Bento, BentoColumns, BentoMinHeight, BentoRootProps, BentoRowSpan, BentoRows, BentoSpan, BentoTileProps };
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { GAP_CLASSES } from "./stack.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/layout/bento.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Static class per count — Tailwind scans source text, not computed strings.
|
|
8
|
+
*
|
|
9
|
+
* One column below `sm`, two from `sm`, the asked-for count only from `lg`:
|
|
10
|
+
* three fixed columns at 640 px would be ~200 px per tile, narrower than the
|
|
11
|
+
* `18rem` minimum measure every grid this replaces already declares.
|
|
12
|
+
*/
|
|
13
|
+
const COLUMN_CLASSES = {
|
|
14
|
+
2: "grid-cols-1 sm:grid-cols-2",
|
|
15
|
+
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
16
|
+
4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"
|
|
17
|
+
};
|
|
18
|
+
/** Static class per row count, from `sm` up — below it the bento is one column. */
|
|
19
|
+
const ROW_CLASSES = {
|
|
20
|
+
1: "sm:grid-rows-1",
|
|
21
|
+
2: "sm:grid-rows-2",
|
|
22
|
+
3: "sm:grid-rows-3",
|
|
23
|
+
4: "sm:grid-rows-4"
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Static class per span, clamped at `sm` because every container is two tracks
|
|
27
|
+
* wide between 640 px and 1024 px whatever its `cols`.
|
|
28
|
+
*
|
|
29
|
+
* So there is no `sm:col-span-3` and no `sm:col-span-4` in this table at all,
|
|
30
|
+
* and no unprefixed `col-span-*` either: an unprefixed span in the one-track
|
|
31
|
+
* base grid grows an implicit second column, which is the same defect one
|
|
32
|
+
* breakpoint down. A span of 1 or 2 carries through from `sm` and needs no
|
|
33
|
+
* `lg:` rung.
|
|
34
|
+
*/
|
|
35
|
+
const SPAN_CLASSES = {
|
|
36
|
+
1: "sm:col-span-1",
|
|
37
|
+
2: "sm:col-span-2",
|
|
38
|
+
3: "sm:col-span-2 lg:col-span-3",
|
|
39
|
+
4: "sm:col-span-2 lg:col-span-4"
|
|
40
|
+
};
|
|
41
|
+
/** Static class per row span, from `sm` up for the same reason as the columns. */
|
|
42
|
+
const ROW_SPAN_CLASSES = {
|
|
43
|
+
1: "sm:row-span-1",
|
|
44
|
+
2: "sm:row-span-2"
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Static class per reserved height, spent off the space ladder's top rung so a
|
|
48
|
+
* hero tile shrinks with the rest of the console at ultra-compact.
|
|
49
|
+
*/
|
|
50
|
+
const MIN_HEIGHT_CLASSES = {
|
|
51
|
+
none: "",
|
|
52
|
+
half: "min-h-[calc(var(--cue-space-8)*4)]",
|
|
53
|
+
hero: "min-h-[calc(var(--cue-space-8)*8)]"
|
|
54
|
+
};
|
|
55
|
+
/** The tile surface, shared by both variants so a link tile is not a second look. */
|
|
56
|
+
const TILE_CLASS = "flex flex-col gap-(--cue-space-3) overflow-hidden rounded-(--radius-surface) border border-border bg-surface-1 p-(--cue-space-5)";
|
|
57
|
+
/** What a link tile adds: the hover tint and the focus ring the whole surface takes. */
|
|
58
|
+
const LINK_TILE_CLASS = "no-underline transition-colors duration-150 outline-none hover:bg-surface-2 focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent";
|
|
59
|
+
/** The host elements a link tile may not contain, plus anything carrying `tabIndex`. */
|
|
60
|
+
const INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
61
|
+
"a",
|
|
62
|
+
"button",
|
|
63
|
+
"input",
|
|
64
|
+
"select",
|
|
65
|
+
"textarea"
|
|
66
|
+
]);
|
|
67
|
+
/**
|
|
68
|
+
* The first interactive child a link tile was given, named, or `undefined`.
|
|
69
|
+
*
|
|
70
|
+
* Shallow by design — it walks `React.Children` and not the rendered tree,
|
|
71
|
+
* because it must run in a server render as well as a client one and a hook is
|
|
72
|
+
* not available in either. What it cannot see (a control behind a component
|
|
73
|
+
* boundary) is what each converted grid's own DOM assertion catches.
|
|
74
|
+
*/
|
|
75
|
+
function interactiveChild(children) {
|
|
76
|
+
let found;
|
|
77
|
+
React.Children.forEach(children, (child) => {
|
|
78
|
+
if (found !== void 0 || !React.isValidElement(child)) return;
|
|
79
|
+
const { tabIndex } = child.props;
|
|
80
|
+
if (typeof child.type === "string" && INTERACTIVE_TAGS.has(child.type)) found = child.type;
|
|
81
|
+
else if (tabIndex !== void 0) found = typeof child.type === "string" ? child.type : "child";
|
|
82
|
+
});
|
|
83
|
+
return found;
|
|
84
|
+
}
|
|
85
|
+
/** The tile's name as a log line can carry it, for a `title` that is not a string. */
|
|
86
|
+
function tileLabel(title) {
|
|
87
|
+
return typeof title === "string" || typeof title === "number" ? String(title) : "an untitled tile";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The bento container: a responsive grid that clamps the spans of its tiles.
|
|
91
|
+
*
|
|
92
|
+
* It maps `React.Children` and clones every child whose type is the tile,
|
|
93
|
+
* narrowing that tile's `span` to its own `cols`; anything else passes through
|
|
94
|
+
* with its props untouched, so a `<section>` or a bare `<div>` may sit in a
|
|
95
|
+
* band beside the tiles.
|
|
96
|
+
*
|
|
97
|
+
* **The clamp reaches direct children only, and that is a contract rather than
|
|
98
|
+
* an oversight.** `React.Children` does not descend into a component element,
|
|
99
|
+
* so a tile rendered by a child — `<Bento.Root><MyTiles /></Bento.Root>` — is
|
|
100
|
+
* whatever `span` it declared, and an over-wide one grows an implicit column
|
|
101
|
+
* exactly as an unclamped tile would. Reading through a component would mean
|
|
102
|
+
* rendering it, which a container may not do. So: **keep a tile a child
|
|
103
|
+
* component renders at `span={1}`, or clamp it in that component.** The same
|
|
104
|
+
* hazard in fragment form is why an authored `node` fixture of tiles is an
|
|
105
|
+
* array and not a `<>…</>`.
|
|
106
|
+
*
|
|
107
|
+
* Static markup — no `"use client"`.
|
|
108
|
+
*/
|
|
109
|
+
const BentoRoot = React.forwardRef(function BentoRoot({ className, cols = 3, rows, dense = false, gap = 4, children, ...elementProps }, ref) {
|
|
110
|
+
return /* @__PURE__ */ jsx("div", {
|
|
111
|
+
ref,
|
|
112
|
+
"data-slot": "bento",
|
|
113
|
+
className: cn("grid", COLUMN_CLASSES[cols], rows === void 0 ? null : ROW_CLASSES[rows], dense ? "grid-flow-row-dense" : null, GAP_CLASSES[gap], className),
|
|
114
|
+
...elementProps,
|
|
115
|
+
children: React.Children.map(children, (child) => clampTile(child, cols, rows))
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
/**
|
|
119
|
+
* Clamp one child's spans to the container's tracks, and leave everything else
|
|
120
|
+
* exactly as it was written.
|
|
121
|
+
*
|
|
122
|
+
* CSS Grid does not clamp: auto-placement grows the implicit grid to fit the
|
|
123
|
+
* largest definite span, so one `span={4}` in a `cols={3}` bento silently adds
|
|
124
|
+
* a fourth column and shifts every row. The tile cannot do this for itself —
|
|
125
|
+
* reading its container would need a hook, and this component is static markup
|
|
126
|
+
* on purpose — so the container does it, on the way past.
|
|
127
|
+
*
|
|
128
|
+
* **Both axes, and the row axis only where there is something to clamp to.**
|
|
129
|
+
* The column clamp always applies because `cols` always has a value; `rows` is
|
|
130
|
+
* optional, and a container that declares none is one whose rows are all
|
|
131
|
+
* implicit — there is no track count for `rowSpan` to be too large for, and the
|
|
132
|
+
* tile's own docblock already says that spanning rows there sizes the span to
|
|
133
|
+
* the tile's own content. So an undeclared `rows` leaves `rowSpan` alone, and a
|
|
134
|
+
* declared one is a promise the tile is held to.
|
|
135
|
+
*/
|
|
136
|
+
function clampTile(child, cols, rows) {
|
|
137
|
+
if (!React.isValidElement(child) || child.type !== BentoTile) return child;
|
|
138
|
+
const tile = child;
|
|
139
|
+
const span = tile.props.span ?? 1;
|
|
140
|
+
const rowSpan = tile.props.rowSpan ?? 1;
|
|
141
|
+
return React.cloneElement(tile, {
|
|
142
|
+
span: Math.min(span, cols),
|
|
143
|
+
...rows === void 0 ? {} : { rowSpan: Math.min(rowSpan, rows) }
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* One cell of a bento: a link, or a surface with an `action`.
|
|
148
|
+
*
|
|
149
|
+
* The two are a discriminated union rather than one shape with a runtime
|
|
150
|
+
* branch, because half of the rule is something a compiler can hold: `href`
|
|
151
|
+
* and `action` are mutually exclusive in the type. The other half — that a
|
|
152
|
+
* link tile's content is static — is held by a dev-time check here and by a
|
|
153
|
+
* DOM assertion in each grid that draws one.
|
|
154
|
+
*
|
|
155
|
+
* Static markup — no `"use client"`.
|
|
156
|
+
*/
|
|
157
|
+
const BentoTile = React.forwardRef(function BentoTile(props, ref) {
|
|
158
|
+
const { className, span = 1, rowSpan = 1, minHeight = "none", eyebrow, title, meta, action, href, render, children, ...elementProps } = props;
|
|
159
|
+
if (process.env.NODE_ENV !== "production" && href !== void 0) {
|
|
160
|
+
if (render !== void 0 && render.props.href === void 0) console.error(`Bento.Tile (${tileLabel(title)}): \`render\` was given an element with no \`href\` of its own. The clone does not pass the tile's, so the link would go nowhere — put the href on the element, as \`next/link\` requires anyway.`);
|
|
161
|
+
const offender = interactiveChild(children) ?? interactiveChild(action);
|
|
162
|
+
if (offender !== void 0) console.error(`Bento.Tile (${tileLabel(title)}): a link tile contains an interactive <${offender}>. An <a> admits no interactive descendant, so use a panel tile and put the control in \`action\` instead of nesting it here.`);
|
|
163
|
+
}
|
|
164
|
+
const head = eyebrow !== void 0 || title !== void 0;
|
|
165
|
+
const tail = meta !== void 0 || action !== void 0;
|
|
166
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [head || tail ? /* @__PURE__ */ jsxs("div", {
|
|
167
|
+
className: "flex items-start justify-between gap-(--cue-space-3)",
|
|
168
|
+
children: [head ? /* @__PURE__ */ jsxs("div", {
|
|
169
|
+
className: "flex min-w-0 flex-col gap-(--cue-space-1)",
|
|
170
|
+
children: [eyebrow === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
171
|
+
"data-slot": "bento-tile-eyebrow",
|
|
172
|
+
className: "font-mono text-(length:--cue-text-meta) text-fg-muted",
|
|
173
|
+
children: eyebrow
|
|
174
|
+
}), title === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
175
|
+
"data-slot": "bento-tile-title",
|
|
176
|
+
className: "font-mono text-(length:--cue-text-emphasis) font-medium text-fg",
|
|
177
|
+
children: title
|
|
178
|
+
})]
|
|
179
|
+
}) : null, tail ? /* @__PURE__ */ jsxs("div", {
|
|
180
|
+
className: "flex shrink-0 items-center gap-(--cue-space-2)",
|
|
181
|
+
children: [meta === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
182
|
+
"data-slot": "bento-tile-meta",
|
|
183
|
+
children: meta
|
|
184
|
+
}), action === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
185
|
+
"data-slot": "bento-tile-action",
|
|
186
|
+
children: action
|
|
187
|
+
})]
|
|
188
|
+
}) : null]
|
|
189
|
+
}) : null, children] });
|
|
190
|
+
const surface = {
|
|
191
|
+
"data-slot": "bento-tile",
|
|
192
|
+
"data-span": String(span),
|
|
193
|
+
className: cn(TILE_CLASS, href === void 0 ? null : LINK_TILE_CLASS, SPAN_CLASSES[span], ROW_SPAN_CLASSES[rowSpan], MIN_HEIGHT_CLASSES[minHeight], className),
|
|
194
|
+
...elementProps
|
|
195
|
+
};
|
|
196
|
+
if (href === void 0) return /* @__PURE__ */ jsx("div", {
|
|
197
|
+
...surface,
|
|
198
|
+
ref,
|
|
199
|
+
children: content
|
|
200
|
+
});
|
|
201
|
+
const anchorSurface = surface;
|
|
202
|
+
if (render !== void 0) {
|
|
203
|
+
const routerLink = render;
|
|
204
|
+
return React.cloneElement(routerLink, {
|
|
205
|
+
...anchorSurface,
|
|
206
|
+
className: cn(routerLink.props.className, anchorSurface.className),
|
|
207
|
+
ref
|
|
208
|
+
}, content);
|
|
209
|
+
}
|
|
210
|
+
return /* @__PURE__ */ jsx("a", {
|
|
211
|
+
...anchorSurface,
|
|
212
|
+
href,
|
|
213
|
+
ref,
|
|
214
|
+
children: content
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
/**
|
|
218
|
+
* A grid of unequal tiles: per-item spans, clamped to the container's columns.
|
|
219
|
+
*
|
|
220
|
+
* Where `Grid` lays out cells it never touches, a bento's whole content is
|
|
221
|
+
* per-item — so the span is a prop on the tile, from a closed set, and the
|
|
222
|
+
* container clamps it on the way past. One column below `sm`, two from `sm`,
|
|
223
|
+
* the asked-for count from `lg`; the clamp is per breakpoint and not per
|
|
224
|
+
* `cols`, because every container is two tracks wide in between whatever it
|
|
225
|
+
* was asked for.
|
|
226
|
+
*
|
|
227
|
+
* **Static markup — no hooks, no `"use client"`, and it must stay that way.**
|
|
228
|
+
* A directive is per *module*, so a `Bento` built on `useRender` would open a
|
|
229
|
+
* client boundary in every server page that draws one. That is why the router
|
|
230
|
+
* escape hatch is `render`, an *element* that is cloned, rather than a render
|
|
231
|
+
* function; and why {@link Bento.Tile} is a discriminated union rather than a
|
|
232
|
+
* tile that decides at runtime what it is.
|
|
233
|
+
*
|
|
234
|
+
* `BentoTileProps` omits the native `title` from its `<div>` props, the same
|
|
235
|
+
* omission `PanelHeader` and `Item` make: `React.ComponentPropsWithoutRef<"div">`
|
|
236
|
+
* already declares `title?: string`, and narrowing it to a `ReactNode` without
|
|
237
|
+
* the `Omit` is TS2430.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* <Bento.Root cols={3} rows={2} gap={5}>
|
|
241
|
+
* <Bento.Tile span={2} rowSpan={2} minHeight="hero" title="Kitchen sink">
|
|
242
|
+
* Every component, on one page.
|
|
243
|
+
* </Bento.Tile>
|
|
244
|
+
* <Bento.Tile title="Themes" meta={<Chip variant="outline">10</Chip>} />
|
|
245
|
+
* <Bento.Tile title="Density" meta={<Chip variant="outline">5</Chip>} />
|
|
246
|
+
* </Bento.Root>
|
|
247
|
+
* @example
|
|
248
|
+
* <Bento.Tile
|
|
249
|
+
* href="/docs/components/grid"
|
|
250
|
+
* render={<NextLink href="/docs/components/grid" />}
|
|
251
|
+
* eyebrow="@cueplusplus/ui"
|
|
252
|
+
* title="Grid"
|
|
253
|
+
* >
|
|
254
|
+
* Equal columns, or as many as fit.
|
|
255
|
+
* </Bento.Tile>
|
|
256
|
+
* @example
|
|
257
|
+
* <Bento.Tile title="Signal" action={<Button onClick={apply}>Apply</Button>}>
|
|
258
|
+
* <ThemeSwatches theme="signal" />
|
|
259
|
+
* </Bento.Tile>
|
|
260
|
+
*/
|
|
261
|
+
const Bento = {
|
|
262
|
+
Root: BentoRoot,
|
|
263
|
+
Tile: BentoTile
|
|
264
|
+
};
|
|
265
|
+
//#endregion
|
|
266
|
+
export { Bento };
|
package/dist/layout/index.d.ts
CHANGED
|
@@ -2,14 +2,15 @@ import { Link, LinkProps, linkVariants } from "./link.js";
|
|
|
2
2
|
import { Sidebar, SidebarItemProps, SidebarRailProps, SidebarRootProps, SidebarSectionProps, useSidebar } from "./sidebar.js";
|
|
3
3
|
import { Container, ContainerProps, ContainerWidth } from "./container.js";
|
|
4
4
|
import { Accordion, AccordionHeaderProps, AccordionItemProps, AccordionPanelProps, AccordionRootProps, AccordionTriggerProps } from "./accordion.js";
|
|
5
|
+
import { SpaceStep, Stack, StackAlign, StackJustify, StackProps } from "./stack.js";
|
|
6
|
+
import { Bento, BentoColumns, BentoMinHeight, BentoRootProps, BentoRowSpan, BentoRows, BentoSpan, BentoTileProps } from "./bento.js";
|
|
5
7
|
import { Breadcrumb, BreadcrumbItem, BreadcrumbProps } from "./breadcrumb.js";
|
|
6
8
|
import { Card, CardContentProps, CardDescriptionProps, CardFooterProps, CardHeaderProps, CardRootProps, CardTitleProps } from "./card.js";
|
|
7
9
|
import { Collapsible, CollapsiblePanelProps, CollapsibleRootProps, CollapsibleTriggerProps, Disclosure, DisclosureProps } from "./collapsible.js";
|
|
8
10
|
import { DescriptionList, DescriptionListDetailProps, DescriptionListLayout, DescriptionListRootProps, DescriptionListTermProps } from "./description-list.js";
|
|
9
|
-
import { SpaceStep, Stack, StackAlign, StackJustify, StackProps } from "./stack.js";
|
|
10
11
|
import { Grid, GridColumns, GridProps } from "./grid.js";
|
|
11
12
|
import { Item, ItemProps, itemVariants } from "./item.js";
|
|
12
13
|
import { Pagination, PaginationEntry, PaginationProps, paginationRange } from "./pagination.js";
|
|
13
14
|
import { Stepper, StepperProps, StepperState, StepperStep } from "./stepper.js";
|
|
14
15
|
import { Timeline, TimelineContentProps, TimelineItemProps, TimelineMarkerProps, TimelineRootProps } from "./timeline.js";
|
|
15
|
-
export { Accordion, type AccordionHeaderProps, type AccordionItemProps, type AccordionPanelProps, type AccordionRootProps, type AccordionTriggerProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Card, type CardContentProps, type CardDescriptionProps, type CardFooterProps, type CardHeaderProps, type CardRootProps, type CardTitleProps, Collapsible, type CollapsiblePanelProps, type CollapsibleRootProps, type CollapsibleTriggerProps, Container, type ContainerProps, type ContainerWidth, DescriptionList, type DescriptionListDetailProps, type DescriptionListLayout, type DescriptionListRootProps, type DescriptionListTermProps, Disclosure, type DisclosureProps, Grid, type GridColumns, type GridProps, Item, type ItemProps, Link, type LinkProps, Pagination, type PaginationEntry, type PaginationProps, Sidebar, type SidebarItemProps, type SidebarRailProps, type SidebarRootProps, type SidebarSectionProps, type SpaceStep, Stack, type StackAlign, type StackJustify, type StackProps, Stepper, type StepperProps, type StepperState, type StepperStep, Timeline, type TimelineContentProps, type TimelineItemProps, type TimelineMarkerProps, type TimelineRootProps, itemVariants, linkVariants, paginationRange, useSidebar };
|
|
16
|
+
export { Accordion, type AccordionHeaderProps, type AccordionItemProps, type AccordionPanelProps, type AccordionRootProps, type AccordionTriggerProps, Bento, type BentoColumns, type BentoMinHeight, type BentoRootProps, type BentoRowSpan, type BentoRows, type BentoSpan, type BentoTileProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Card, type CardContentProps, type CardDescriptionProps, type CardFooterProps, type CardHeaderProps, type CardRootProps, type CardTitleProps, Collapsible, type CollapsiblePanelProps, type CollapsibleRootProps, type CollapsibleTriggerProps, Container, type ContainerProps, type ContainerWidth, DescriptionList, type DescriptionListDetailProps, type DescriptionListLayout, type DescriptionListRootProps, type DescriptionListTermProps, Disclosure, type DisclosureProps, Grid, type GridColumns, type GridProps, Item, type ItemProps, Link, type LinkProps, Pagination, type PaginationEntry, type PaginationProps, Sidebar, type SidebarItemProps, type SidebarRailProps, type SidebarRootProps, type SidebarSectionProps, type SpaceStep, Stack, type StackAlign, type StackJustify, type StackProps, Stepper, type StepperProps, type StepperState, type StepperStep, Timeline, type TimelineContentProps, type TimelineItemProps, type TimelineMarkerProps, type TimelineRootProps, itemVariants, linkVariants, paginationRange, useSidebar };
|
package/dist/layout/index.js
CHANGED
|
@@ -2,14 +2,15 @@ import { Link, linkVariants } from "./link.js";
|
|
|
2
2
|
import { Sidebar, useSidebar } from "./sidebar.js";
|
|
3
3
|
import { Container } from "./container.js";
|
|
4
4
|
import { Accordion } from "./accordion.js";
|
|
5
|
+
import { Stack } from "./stack.js";
|
|
6
|
+
import { Bento } from "./bento.js";
|
|
5
7
|
import { Breadcrumb } from "./breadcrumb.js";
|
|
6
8
|
import { Card } from "./card.js";
|
|
7
9
|
import { Collapsible, Disclosure } from "./collapsible.js";
|
|
8
10
|
import { DescriptionList } from "./description-list.js";
|
|
9
|
-
import { Stack } from "./stack.js";
|
|
10
11
|
import { Grid } from "./grid.js";
|
|
11
12
|
import { Item, itemVariants } from "./item.js";
|
|
12
13
|
import { Pagination, paginationRange } from "./pagination.js";
|
|
13
14
|
import { Stepper } from "./stepper.js";
|
|
14
15
|
import { Timeline } from "./timeline.js";
|
|
15
|
-
export { Accordion, Breadcrumb, Card, Collapsible, Container, DescriptionList, Disclosure, Grid, Item, Link, Pagination, Sidebar, Stack, Stepper, Timeline, itemVariants, linkVariants, paginationRange, useSidebar };
|
|
16
|
+
export { Accordion, Bento, Breadcrumb, Card, Collapsible, Container, DescriptionList, Disclosure, Grid, Item, Link, Pagination, Sidebar, Stack, Stepper, Timeline, itemVariants, linkVariants, paginationRange, useSidebar };
|
|
@@ -49,7 +49,11 @@ const PianoKeyboard = React.forwardRef(function PianoKeyboard({ className, range
|
|
|
49
49
|
const [drag, setDrag] = React.useState(null);
|
|
50
50
|
const settled = React.useMemo(() => keyboardWindow(range, octaves), [range, octaves]);
|
|
51
51
|
const view = drag?.window ?? settled;
|
|
52
|
-
const
|
|
52
|
+
const { start: viewStart, end: viewEnd } = view;
|
|
53
|
+
const layout = React.useMemo(() => keyboardLayout({
|
|
54
|
+
start: viewStart,
|
|
55
|
+
end: viewEnd
|
|
56
|
+
}), [viewStart, viewEnd]);
|
|
53
57
|
const lit = React.useMemo(() => new Set(highlight ?? []), [highlight]);
|
|
54
58
|
const setEdge = (edge, note) => {
|
|
55
59
|
const next = edge === "start" ? {
|
|
@@ -26,6 +26,18 @@ interface ButtonProps extends React.ComponentPropsWithoutRef<"button">, VariantP
|
|
|
26
26
|
* level without the caller passing a pixel size.
|
|
27
27
|
*/
|
|
28
28
|
icon?: React.ElementType;
|
|
29
|
+
/**
|
|
30
|
+
* The label. A button with no children and no other accessible name is a
|
|
31
|
+
* control a screen reader announces as nothing.
|
|
32
|
+
*
|
|
33
|
+
* Declared explicitly, although `React.ComponentPropsWithoutRef<"button">`
|
|
34
|
+
* already carries it, for the reason `Card.Header` and `Bento.Tile` declare
|
|
35
|
+
* theirs: docgen documents a prop only where the library *declares* it, so
|
|
36
|
+
* without this line the manifest files no `children` for the system's most
|
|
37
|
+
* used control — the props table omits it, and a propSet cannot name it,
|
|
38
|
+
* which is how `/play/button` came to preview an unlabelled `<button>`.
|
|
39
|
+
*/
|
|
40
|
+
children?: React.ReactNode;
|
|
29
41
|
}
|
|
30
42
|
/**
|
|
31
43
|
* The system's primary action control.
|
package/dist/styles.css
CHANGED
|
@@ -3,13 +3,35 @@
|
|
|
3
3
|
* Consumer app CSS:
|
|
4
4
|
* @import "tailwindcss";
|
|
5
5
|
* @import "@cueplusplus/ui/styles.css";
|
|
6
|
+
* @import "@cueplusplus/theme-cue/theme.css"; (or any theme package)
|
|
6
7
|
*
|
|
7
8
|
* Tailwind v4 does not scan node_modules, so the library registers its own
|
|
8
9
|
* sources: `@source "./"` resolves relative to THIS file, i.e. the shipped
|
|
9
10
|
* dist/, which is where the class strings live after the build.
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
/* Two lines, and the first one is the release's whole behaviour change.
|
|
14
|
+
*
|
|
15
|
+
* It used to be `@cueplusplus/tokens/theme.css`, which carried ten palettes and
|
|
16
|
+
* painted `cue` on a bare `:root`. A palette is a package now, so what this
|
|
17
|
+
* library ships is the *blank* base: `theme-base/base.css` declares every colour
|
|
18
|
+
* token at a neutral default and imports `@cueplusplus/tokens/axes.css` for the
|
|
19
|
+
* geometry and type axes. That is why there is no third line — `base.css`
|
|
20
|
+
* carries the axes with it, and `tailwind.css` maps utilities onto token names
|
|
21
|
+
* and pulls nothing.
|
|
22
|
+
*
|
|
23
|
+
* An app that imports this and registers no theme therefore paints greys and one
|
|
24
|
+
* desaturated accent, rather than somebody's brand. To get a palette back:
|
|
25
|
+
* install a theme package, import its stylesheet after this one, and pass its
|
|
26
|
+
* manifest to the provider —
|
|
27
|
+
*
|
|
28
|
+
* @import "@cueplusplus/ui/styles.css";
|
|
29
|
+
* @import "@cueplusplus/theme-cue/theme.css";
|
|
30
|
+
*
|
|
31
|
+
* with `<ThemeProvider themes={[cue]} theme="cue">`. Order matters and is not an
|
|
32
|
+
* accident: `[data-theme]` and `:root` tie at (0,1,0), so a theme's block wins
|
|
33
|
+
* by being declared later. */
|
|
34
|
+
@import "@cueplusplus/theme-base/base.css";
|
|
13
35
|
@import "@cueplusplus/tokens/tailwind.css";
|
|
14
36
|
|
|
15
37
|
@source "./";
|
package/dist/system/density.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { Density } from "@cueplusplus/
|
|
2
|
+
import { Density } from "@cueplusplus/theme-base";
|
|
3
3
|
//#region src/system/density.d.ts
|
|
4
4
|
interface DensityProps {
|
|
5
5
|
/**
|
|
@@ -17,14 +17,23 @@ interface DensityProps {
|
|
|
17
17
|
/**
|
|
18
18
|
* Re-scope any subtree to a different density level.
|
|
19
19
|
*
|
|
20
|
-
* Renders a plain `<div data-density="…">`: the geometry
|
|
21
|
-
* re-declared by the attribute selector and inherit
|
|
22
|
-
* needs no JS. The matching React context is
|
|
23
|
-
* JS reads (`useDensity()`,
|
|
24
|
-
*
|
|
20
|
+
* Renders a plain `<div data-density="…" data-cue-theme="…">`: the geometry
|
|
21
|
+
* custom properties are re-declared by the attribute selector and inherit
|
|
22
|
+
* down, so nesting is free and needs no JS. The matching React context is
|
|
23
|
+
* published alongside for the rare JS reads (`useDensity()`,
|
|
24
|
+
* `useControlHeight()`, portal stamping) — the DOM attributes, not the
|
|
25
|
+
* context, are what actually restyle the tree.
|
|
25
26
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* `data-cue-theme` carries the nearest `<ThemeProvider>`'s name, or is
|
|
28
|
+
* omitted where there is none. It is read by nothing this island does —
|
|
29
|
+
* theme and mode are deliberately *not* re-scoped here, density is the only
|
|
30
|
+
* axis an island may override (spec §6) — it exists so a theme's own
|
|
31
|
+
* generated CSS can address exactly this island regardless of how many
|
|
32
|
+
* *other* themed providers sit between it and the one it belongs to. A CSS
|
|
33
|
+
* ancestor selector can only ask "does some ancestor carry theme `x`", never
|
|
34
|
+
* "is `x` the *nearest* one"; this stamp answers that question the way
|
|
35
|
+
* `useContext` already does, at render time, and hands the answer to CSS as
|
|
36
|
+
* an attribute rather than leaving it unanswerable there.
|
|
28
37
|
*
|
|
29
38
|
* @example
|
|
30
39
|
* <Density density="ultra-compact">
|
package/dist/system/density.js
CHANGED
|
@@ -10,14 +10,6 @@ import { jsx } from "react/jsx-runtime";
|
|
|
10
10
|
* but the level a screen gets when nobody chose is the dense one.
|
|
11
11
|
*/
|
|
12
12
|
const DEFAULT_DENSITY = "compact";
|
|
13
|
-
/** The five levels, as a runtime array for validating persisted input. */
|
|
14
|
-
const DENSITY_LEVELS = [
|
|
15
|
-
"ultra-compact",
|
|
16
|
-
"compact",
|
|
17
|
-
"normal",
|
|
18
|
-
"large",
|
|
19
|
-
"ultra-large"
|
|
20
|
-
];
|
|
21
13
|
/**
|
|
22
14
|
* Nearest ambient density. `null` means "nothing has stamped a level yet", which
|
|
23
15
|
* `useDensity()` reports as {@link DEFAULT_DENSITY}.
|
|
@@ -26,16 +18,45 @@ const DENSITY_LEVELS = [
|
|
|
26
18
|
*/
|
|
27
19
|
const DensityContext = React.createContext(null);
|
|
28
20
|
/**
|
|
21
|
+
* Nearest ambient theme's name, published for exactly one reader: `Density`
|
|
22
|
+
* below, which stamps it onto its island as `data-cue-theme` so a theme's
|
|
23
|
+
* CSS can tell *nearest* theme from *any* theme in the ancestor chain (see
|
|
24
|
+
* `densityRules`/`themeSelector`'s comment). `use-density.ts`'s measuring
|
|
25
|
+
* probe stamps the same attribute from the identical value, read through
|
|
26
|
+
* `ThemeContext` there instead, because it already imports that module with
|
|
27
|
+
* no cycle.
|
|
28
|
+
*
|
|
29
|
+
* Defined here, not in `theme-provider.tsx`, and re-exported from nowhere
|
|
30
|
+
* else. `theme-provider.tsx` already imports `DensityContext` from this
|
|
31
|
+
* module; a context this small living over there and imported back here
|
|
32
|
+
* would cycle the two modules. `null` outside a provider, the same as
|
|
33
|
+
* `ThemeContext`'s own theme field would be if it existed with no provider
|
|
34
|
+
* to require — `Density` used bare, with nothing above it, stamps nothing.
|
|
35
|
+
*
|
|
36
|
+
* Internal: `Density` is the only reader. Not `useTheme()` — that throws
|
|
37
|
+
* outside a provider, and this island has no reason to.
|
|
38
|
+
*/
|
|
39
|
+
const AmbientThemeContext = React.createContext(null);
|
|
40
|
+
/**
|
|
29
41
|
* Re-scope any subtree to a different density level.
|
|
30
42
|
*
|
|
31
|
-
* Renders a plain `<div data-density="…">`: the geometry
|
|
32
|
-
* re-declared by the attribute selector and inherit
|
|
33
|
-
* needs no JS. The matching React context is
|
|
34
|
-
* JS reads (`useDensity()`,
|
|
35
|
-
*
|
|
43
|
+
* Renders a plain `<div data-density="…" data-cue-theme="…">`: the geometry
|
|
44
|
+
* custom properties are re-declared by the attribute selector and inherit
|
|
45
|
+
* down, so nesting is free and needs no JS. The matching React context is
|
|
46
|
+
* published alongside for the rare JS reads (`useDensity()`,
|
|
47
|
+
* `useControlHeight()`, portal stamping) — the DOM attributes, not the
|
|
48
|
+
* context, are what actually restyle the tree.
|
|
36
49
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
50
|
+
* `data-cue-theme` carries the nearest `<ThemeProvider>`'s name, or is
|
|
51
|
+
* omitted where there is none. It is read by nothing this island does —
|
|
52
|
+
* theme and mode are deliberately *not* re-scoped here, density is the only
|
|
53
|
+
* axis an island may override (spec §6) — it exists so a theme's own
|
|
54
|
+
* generated CSS can address exactly this island regardless of how many
|
|
55
|
+
* *other* themed providers sit between it and the one it belongs to. A CSS
|
|
56
|
+
* ancestor selector can only ask "does some ancestor carry theme `x`", never
|
|
57
|
+
* "is `x` the *nearest* one"; this stamp answers that question the way
|
|
58
|
+
* `useContext` already does, at render time, and hands the answer to CSS as
|
|
59
|
+
* an attribute rather than leaving it unanswerable there.
|
|
39
60
|
*
|
|
40
61
|
* @example
|
|
41
62
|
* <Density density="ultra-compact">
|
|
@@ -43,10 +64,12 @@ const DensityContext = React.createContext(null);
|
|
|
43
64
|
* </Density>
|
|
44
65
|
*/
|
|
45
66
|
function Density({ density, children, className, style }) {
|
|
67
|
+
const theme = React.useContext(AmbientThemeContext);
|
|
46
68
|
return /* @__PURE__ */ jsx(DensityContext.Provider, {
|
|
47
69
|
value: density,
|
|
48
70
|
children: /* @__PURE__ */ jsx("div", {
|
|
49
71
|
"data-density": density,
|
|
72
|
+
"data-cue-theme": theme ?? void 0,
|
|
50
73
|
className,
|
|
51
74
|
style,
|
|
52
75
|
children
|
|
@@ -54,4 +77,4 @@ function Density({ density, children, className, style }) {
|
|
|
54
77
|
});
|
|
55
78
|
}
|
|
56
79
|
//#endregion
|
|
57
|
-
export {
|
|
80
|
+
export { AmbientThemeContext, DEFAULT_DENSITY, Density, DensityContext };
|