@cueplusplus/ui 0.9.0 → 0.11.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 +337 -0
- package/README.md +197 -9
- package/dist/chrome/index.d.ts +2 -1
- package/dist/chrome/index.js +3 -2
- package/dist/chrome/inspector.d.ts +61 -0
- package/dist/chrome/inspector.js +121 -0
- package/dist/forms/input.d.ts +12 -0
- package/dist/forms/textarea.d.ts +12 -0
- package/dist/forms/toggle.d.ts +6 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +8 -3
- package/dist/instruments/code-block.d.ts +35 -0
- package/dist/instruments/code-block.js +173 -0
- package/dist/instruments/index.d.ts +2 -1
- package/dist/instruments/index.js +2 -1
- 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 +4 -2
- package/dist/layout/index.js +4 -2
- package/dist/layout/preview.d.ts +110 -0
- package/dist/layout/preview.js +459 -0
- package/dist/primitives/button.d.ts +12 -0
- package/dist/primitives/chip.d.ts +1 -1
- package/dist/system/index.d.ts +2 -2
- package/dist/system/index.js +2 -1
- package/dist/system/overrides.d.ts +38 -1
- package/dist/system/overrides.js +40 -1
- 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-block.json +106 -0
- 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 +8 -4
- 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 +13 -3
- 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 +24 -4
- 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 -8
- 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 +33 -3
- package/manifest/components/inspector.json +199 -0
- 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 +58 -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 +12 -5
- package/manifest/components/preview.json +202 -0
- 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 +69 -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 +8 -4
- 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 +28 -3
- package/manifest/components/theme-configurator.json +47 -11
- package/manifest/components/theme-provider.json +79 -15
- 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 +33 -4
- package/manifest/components/token-editor.json +26 -7
- 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 +111 -0
- package/manifest/manifest.json +354 -297
- package/manifest/tokens.json +2 -2
- package/package.json +8 -7
|
@@ -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: "min-w-0 truncate 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,16 @@ 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";
|
|
14
|
+
import { Preview, PreviewAxis, PreviewProps, PreviewResizeOptions } from "./preview.js";
|
|
13
15
|
import { Stepper, StepperProps, StepperState, StepperStep } from "./stepper.js";
|
|
14
16
|
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 };
|
|
17
|
+
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, Preview, type PreviewAxis, type PreviewProps, type PreviewResizeOptions, 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,16 @@ 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";
|
|
14
|
+
import { Preview } from "./preview.js";
|
|
13
15
|
import { Stepper } from "./stepper.js";
|
|
14
16
|
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 };
|
|
17
|
+
export { Accordion, Bento, Breadcrumb, Card, Collapsible, Container, DescriptionList, Disclosure, Grid, Item, Link, Pagination, Preview, Sidebar, Stack, Stepper, Timeline, itemVariants, linkVariants, paginationRange, useSidebar };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Density, FontName, Mode, ThemeName } from "@cueplusplus/theme-base";
|
|
3
|
+
//#region src/layout/preview.d.ts
|
|
4
|
+
/** Which edges of the stage a reader may drag. */
|
|
5
|
+
type PreviewAxis = "x" | "y" | "both";
|
|
6
|
+
/** How far a resizable stage may go, in CSS pixels, and along which axes. */
|
|
7
|
+
interface PreviewResizeOptions {
|
|
8
|
+
/** Which axes resize. Defaults to `"both"`; `"x"` or `"y"` narrows it to one grip. */
|
|
9
|
+
axis?: PreviewAxis;
|
|
10
|
+
/** The narrowest the stage may be made, in px. Defaults to `160`. */
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
/**
|
|
13
|
+
* The widest the stage may be made, in px. Defaults to `1280`. The bound in
|
|
14
|
+
* force is the smaller of this and the frame's own width, measured live, so a
|
|
15
|
+
* stage never outgrows the frame — or the grid track — it sits in.
|
|
16
|
+
*/
|
|
17
|
+
maxWidth?: number;
|
|
18
|
+
/** The shortest the stage may be made, in px. Defaults to `96`. */
|
|
19
|
+
minHeight?: number;
|
|
20
|
+
/** The tallest the stage may be made, in px. Defaults to `960`. */
|
|
21
|
+
maxHeight?: number;
|
|
22
|
+
}
|
|
23
|
+
interface PreviewProps extends Omit<React.ComponentPropsWithoutRef<"div">, "children"> {
|
|
24
|
+
/** The specimen. It renders on the stage, inside whatever scope the stage sets. */
|
|
25
|
+
children: React.ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* The frame's accessible name — "Button preview". Required: a frame that holds
|
|
28
|
+
* controls and has no name is a group nobody can find.
|
|
29
|
+
*/
|
|
30
|
+
label: string;
|
|
31
|
+
/**
|
|
32
|
+
* A theme for the stage only. Unset, the stage inherits — no attribute is
|
|
33
|
+
* emitted at all. **Naming a theme does not load it**: the stage is scoped to
|
|
34
|
+
* `[data-theme="<name>"]`, and that theme's stylesheet must already be on the
|
|
35
|
+
* page (`@cueplusplus/theme-<name>/theme.css`). The tools, the footer and
|
|
36
|
+
* anything they open stay in the page's theme. With no `mode`, the stage
|
|
37
|
+
* repeats the page's mode beside the theme — `"system"` included — so a light
|
|
38
|
+
* page's stage paints the theme's light block, not its dark one, and agrees
|
|
39
|
+
* with every overlay opened on it.
|
|
40
|
+
*/
|
|
41
|
+
theme?: ThemeName;
|
|
42
|
+
/**
|
|
43
|
+
* Dark, light or system, for the stage only. A theme's light block is the
|
|
44
|
+
* compound selector `[data-theme][data-mode]`, so with no `theme` the stage
|
|
45
|
+
* restates the page's theme beside the mode; outside any `ThemeProvider` there
|
|
46
|
+
* is no theme to restate and the mode alone changes nothing. A stage
|
|
47
|
+
* `"system"` is stamped as it is, so the stylesheet's `[data-mode="system"]`
|
|
48
|
+
* block follows the OS; `useTheme().resolvedMode` read on the stage reports
|
|
49
|
+
* the page's resolved mode.
|
|
50
|
+
*/
|
|
51
|
+
mode?: Mode;
|
|
52
|
+
/** A rung of the density ladder for the stage only, as a `<Density>` island would set it. */
|
|
53
|
+
density?: Density;
|
|
54
|
+
/** A font pairing for the stage only, as `data-font`. Portals still follow the root's pairing. */
|
|
55
|
+
font?: FontName;
|
|
56
|
+
/**
|
|
57
|
+
* Resize the stage by dragging or with the keyboard. `true` gives both axes
|
|
58
|
+
* inside the default bounds (160–1280 px wide, 96–960 px tall); an object
|
|
59
|
+
* narrows the axis or moves the bounds. The width never outgrows the frame:
|
|
60
|
+
* its bound in force is the smaller of `maxWidth` and the frame's own width,
|
|
61
|
+
* observed with a `ResizeObserver`, so a Preview in a grid track stays inside
|
|
62
|
+
* it as the viewport changes. The height is bounded by `maxHeight` alone, and
|
|
63
|
+
* a taller stage grows its frame. Unset, the stage is fixed: no grips, and
|
|
64
|
+
* nothing measured or observed.
|
|
65
|
+
*
|
|
66
|
+
* A resizable frame fills its container's width (`w-full`), because the room
|
|
67
|
+
* it measures has to be its container's. In a flex row or a centred column a
|
|
68
|
+
* frame sized by its content would measure its own stage, and a stage bounded
|
|
69
|
+
* by itself can only shrink, with each step lowering the ceiling. A fixed
|
|
70
|
+
* Preview keeps sizing to its content; `className` can still set a width.
|
|
71
|
+
*/
|
|
72
|
+
resizable?: boolean | PreviewResizeOptions;
|
|
73
|
+
/** The top-right slot — by convention a row of `IconButton`s. Drawn outside the stage. */
|
|
74
|
+
tools?: React.ReactNode;
|
|
75
|
+
/** The strip under the stage: the thin text and the way out. Drawn outside the stage. */
|
|
76
|
+
footer?: React.ReactNode;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A frame for one component: a stage that is its own theme island, a slot for
|
|
80
|
+
* tools at the top right, and a footer.
|
|
81
|
+
*
|
|
82
|
+
* **The stage is the island; the chrome is not.** `theme`, `mode`, `density`
|
|
83
|
+
* and `font` land on the stage element only, and the stage republishes the
|
|
84
|
+
* theme and density contexts so an overlay opened on it follows it. The tools,
|
|
85
|
+
* the footer, the grips and anything they open stay in the scope around the
|
|
86
|
+
* Preview — a `terminal` preview's own controls do not turn cyan. With none of
|
|
87
|
+
* the four set, the stage carries no attribute and costs what a `<div>` costs.
|
|
88
|
+
* A stage `theme` with no `mode` repeats the page's mode beside it.
|
|
89
|
+
*
|
|
90
|
+
* **`resizable` is handles of its own**, both axes by default: an edge grip per
|
|
91
|
+
* axis that is a keyboard-operable `separator` valued in pixels, and a corner
|
|
92
|
+
* grip for the pointer. Double-click resets an axis. The width never outgrows
|
|
93
|
+
* the frame: its bound in force is the frame's own width, observed live, when
|
|
94
|
+
* that is under `maxWidth`. Not `Resizable`, which is split panes on an
|
|
95
|
+
* optional peer.
|
|
96
|
+
*
|
|
97
|
+
* Props, not a compound: one stage and two slots, each saying what it is.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* <Preview label="Button preview" tools={<IconButton aria-label="Configure Button" icon={Wrench} />}>
|
|
101
|
+
* <Button variant="primary">Take cue</Button>
|
|
102
|
+
* </Preview>
|
|
103
|
+
* @example
|
|
104
|
+
* <Preview label="Chip preview" theme="terminal" density="compact" resizable>
|
|
105
|
+
* <Chip tone="accent">Standby</Chip>
|
|
106
|
+
* </Preview>
|
|
107
|
+
*/
|
|
108
|
+
declare const Preview: React.ForwardRefExoticComponent<PreviewProps & React.RefAttributes<HTMLDivElement>>;
|
|
109
|
+
//#endregion
|
|
110
|
+
export { Preview, PreviewAxis, PreviewProps, PreviewResizeOptions };
|