@cueplusplus/ui 0.9.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 +195 -0
- package/README.md +91 -9
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -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/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-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 +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 +12 -5
- 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 +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 +8 -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 +23 -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 +106 -0
- package/manifest/manifest.json +315 -297
- package/manifest/tokens.json +2 -2
- package/package.json +7 -6
|
@@ -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 };
|
|
@@ -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.
|
|
@@ -30,7 +30,7 @@ import * as React from "react";
|
|
|
30
30
|
* <span className={chipVariants({ variant: "tag" })}>mcp</span>
|
|
31
31
|
*/
|
|
32
32
|
declare const chipVariants: (props?: ({
|
|
33
|
-
tone?: "
|
|
33
|
+
tone?: "danger" | "info" | "warn" | "accent" | "ok" | "busy" | "neutral" | null | undefined;
|
|
34
34
|
variant?: "outline" | "tinted" | "tag" | null | undefined;
|
|
35
35
|
interactive?: boolean | null | undefined;
|
|
36
36
|
} & ClassProp) | undefined) => string;
|
package/dist/system/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TokenOverrides } from "./overrides.js";
|
|
1
|
+
import { TokenOverrides, isSafeTokenValue } from "./overrides.js";
|
|
2
2
|
import { FontFamilies, ResolvedMode, ThemeContextValue, ThemeProvider, ThemeProviderProps } from "./theme-provider.js";
|
|
3
3
|
import { Density, DensityProps } from "./density.js";
|
|
4
4
|
import { CuePortalFrame, CuePortalFrameProps, useCuePortalProps } from "./portal.js";
|
|
@@ -8,4 +8,4 @@ import { useDensities, useFonts, useThemes } from "./theme-registry.js";
|
|
|
8
8
|
import { ControlSize, useControlHeight, useDensity } from "./use-density.js";
|
|
9
9
|
import { useTheme } from "./use-theme.js";
|
|
10
10
|
import { Density as DensityLevel, DensityEntry, FontEntry, FontName, Mode, ThemeManifest, ThemeName } from "@cueplusplus/theme-base";
|
|
11
|
-
export { type ControlSize, CuePortalFrame, type CuePortalFrameProps, DEFAULT_STORAGE_KEY, Density, type DensityEntry, type DensityLevel, type DensityProps, type FontEntry, type FontFamilies, type FontName, type Mode, type PersistedPreferences, type PrepaintDefaults, type PrepaintOptions, type ResolvedMode, type ThemeContextValue, type ThemeManifest, type ThemeName, ThemeProvider, type ThemeProviderProps, type ThemeRegistry, type TokenOverrides, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
|
|
11
|
+
export { type ControlSize, CuePortalFrame, type CuePortalFrameProps, DEFAULT_STORAGE_KEY, Density, type DensityEntry, type DensityLevel, type DensityProps, type FontEntry, type FontFamilies, type FontName, type Mode, type PersistedPreferences, type PrepaintDefaults, type PrepaintOptions, type ResolvedMode, type ThemeContextValue, type ThemeManifest, type ThemeName, ThemeProvider, type ThemeProviderProps, type ThemeRegistry, type TokenOverrides, isSafeTokenValue, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
|
package/dist/system/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Density } from "./density.js";
|
|
2
|
+
import { isSafeTokenValue } from "./overrides.js";
|
|
2
3
|
import { DEFAULT_STORAGE_KEY, prepaintScript } from "./prepaint.js";
|
|
3
4
|
import { useDensities, useFonts, useThemes } from "./theme-registry.js";
|
|
4
5
|
import { ThemeProvider } from "./theme-provider.js";
|
|
5
6
|
import { CuePortalFrame, useCuePortalProps } from "./portal.js";
|
|
6
7
|
import { useControlHeight, useDensity } from "./use-density.js";
|
|
7
8
|
import { useTheme } from "./use-theme.js";
|
|
8
|
-
export { CuePortalFrame, DEFAULT_STORAGE_KEY, Density, ThemeProvider, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
|
|
9
|
+
export { CuePortalFrame, DEFAULT_STORAGE_KEY, Density, ThemeProvider, isSafeTokenValue, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
|
|
@@ -39,5 +39,42 @@ interface TokenOverrides {
|
|
|
39
39
|
display: string;
|
|
40
40
|
}>;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Whether a string may be written into the density stylesheet this module
|
|
44
|
+
* builds.
|
|
45
|
+
*
|
|
46
|
+
* The same rule {@link overridesCss} applies at `SAFE_VALUE`, exported because a
|
|
47
|
+
* caller that builds a {@link TokenOverrides} wants to refuse a value at the
|
|
48
|
+
* *input* rather than watch it be dropped, silently and one warning later, at
|
|
49
|
+
* the sheet. A panel that cannot ask the question has two bad answers open to
|
|
50
|
+
* it: keep a second copy of this regex, which stops being this regex the first
|
|
51
|
+
* time either moves, or write the value anyway and let a reader wonder why the
|
|
52
|
+
* picture did not change.
|
|
53
|
+
*
|
|
54
|
+
* `@cueplusplus/ui/configurator` exports `isSafeCssValue` (`configurator/_overrides.ts:239`)
|
|
55
|
+
* for the configurator's own snapshot, and this is deliberately **not** that
|
|
56
|
+
* function: same rule, asked from the module that owns it, without dragging in
|
|
57
|
+
* a subpath that also carries `ThemeConfigurator`, `ExportDialog` and an
|
|
58
|
+
* optional `react-aria-components` peer. Neither imports the other, and the
|
|
59
|
+
* test beside this file is what holds them to one answer.
|
|
60
|
+
*
|
|
61
|
+
* **The one thing the rule does not cover, said out loud: an unterminated
|
|
62
|
+
* `/*`.** It carries none of the five refused characters, so it is accepted and
|
|
63
|
+
* written, and everything after it in that stylesheet — the closing brace and
|
|
64
|
+
* any later declaration — is inside a comment. That is a value of the caller's
|
|
65
|
+
* own that stops their *other* overrides applying, not an injection: with `;`,
|
|
66
|
+
* `{`, `}`, `<` and `\` all refused, no second value can close the comment and
|
|
67
|
+
* open a rule. A caller that wants to refuse it as well can say so on top of
|
|
68
|
+
* this; tightening `SAFE_VALUE` itself would change what `overridesCss` writes,
|
|
69
|
+
* which is a different release note from this one.
|
|
70
|
+
*
|
|
71
|
+
* @param value - The proposed declaration value.
|
|
72
|
+
* @returns `true` when it cannot close its declaration, its block or the
|
|
73
|
+
* `<style>` element — see the comment case above for what that does not mean.
|
|
74
|
+
* @example
|
|
75
|
+
* isSafeTokenValue("Iosevka, monospace"); // → true
|
|
76
|
+
* isSafeTokenValue("red;}"); // → false
|
|
77
|
+
*/
|
|
78
|
+
declare function isSafeTokenValue(value: string): boolean;
|
|
42
79
|
//#endregion
|
|
43
|
-
export { TokenOverrides };
|
|
80
|
+
export { TokenOverrides, isSafeTokenValue };
|
package/dist/system/overrides.js
CHANGED
|
@@ -102,6 +102,45 @@ function inlineOverrides(overrides, mode) {
|
|
|
102
102
|
*/
|
|
103
103
|
const SAFE_VALUE = /^[^;{}<>\\]+$/;
|
|
104
104
|
/**
|
|
105
|
+
* Whether a string may be written into the density stylesheet this module
|
|
106
|
+
* builds.
|
|
107
|
+
*
|
|
108
|
+
* The same rule {@link overridesCss} applies at `SAFE_VALUE`, exported because a
|
|
109
|
+
* caller that builds a {@link TokenOverrides} wants to refuse a value at the
|
|
110
|
+
* *input* rather than watch it be dropped, silently and one warning later, at
|
|
111
|
+
* the sheet. A panel that cannot ask the question has two bad answers open to
|
|
112
|
+
* it: keep a second copy of this regex, which stops being this regex the first
|
|
113
|
+
* time either moves, or write the value anyway and let a reader wonder why the
|
|
114
|
+
* picture did not change.
|
|
115
|
+
*
|
|
116
|
+
* `@cueplusplus/ui/configurator` exports `isSafeCssValue` (`configurator/_overrides.ts:239`)
|
|
117
|
+
* for the configurator's own snapshot, and this is deliberately **not** that
|
|
118
|
+
* function: same rule, asked from the module that owns it, without dragging in
|
|
119
|
+
* a subpath that also carries `ThemeConfigurator`, `ExportDialog` and an
|
|
120
|
+
* optional `react-aria-components` peer. Neither imports the other, and the
|
|
121
|
+
* test beside this file is what holds them to one answer.
|
|
122
|
+
*
|
|
123
|
+
* **The one thing the rule does not cover, said out loud: an unterminated
|
|
124
|
+
* `/*`.** It carries none of the five refused characters, so it is accepted and
|
|
125
|
+
* written, and everything after it in that stylesheet — the closing brace and
|
|
126
|
+
* any later declaration — is inside a comment. That is a value of the caller's
|
|
127
|
+
* own that stops their *other* overrides applying, not an injection: with `;`,
|
|
128
|
+
* `{`, `}`, `<` and `\` all refused, no second value can close the comment and
|
|
129
|
+
* open a rule. A caller that wants to refuse it as well can say so on top of
|
|
130
|
+
* this; tightening `SAFE_VALUE` itself would change what `overridesCss` writes,
|
|
131
|
+
* which is a different release note from this one.
|
|
132
|
+
*
|
|
133
|
+
* @param value - The proposed declaration value.
|
|
134
|
+
* @returns `true` when it cannot close its declaration, its block or the
|
|
135
|
+
* `<style>` element — see the comment case above for what that does not mean.
|
|
136
|
+
* @example
|
|
137
|
+
* isSafeTokenValue("Iosevka, monospace"); // → true
|
|
138
|
+
* isSafeTokenValue("red;}"); // → false
|
|
139
|
+
*/
|
|
140
|
+
function isSafeTokenValue(value) {
|
|
141
|
+
return SAFE_VALUE.test(value);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
105
144
|
* The document-scoped stylesheet text for the density layer.
|
|
106
145
|
*
|
|
107
146
|
* **Why the selector says the attribute twice.** A rung a theme retunes ships
|
|
@@ -235,4 +274,4 @@ function reportOverrides(manifest, mode, overrides, theme) {
|
|
|
235
274
|
for (const check of after.advisories) if (caused(check)) noteOnce(`overrides: ${check.id} at ${check.ratio.toFixed(2)}:1 misses its ${check.minimum} advisory floor under theme "${theme}"`);
|
|
236
275
|
}
|
|
237
276
|
//#endregion
|
|
238
|
-
export { OverridesContext, inlineOverrides, overridesCss, reportOverrides };
|
|
277
|
+
export { OverridesContext, inlineOverrides, isSafeTokenValue, overridesCss, reportOverrides };
|
|
@@ -26,7 +26,10 @@
|
|
|
26
26
|
"type": "string",
|
|
27
27
|
"required": false,
|
|
28
28
|
"defaultValue": null,
|
|
29
|
-
"description": "Extra classes for the accordion frame."
|
|
29
|
+
"description": "Extra classes for the accordion frame.",
|
|
30
|
+
"control": {
|
|
31
|
+
"kind": "string"
|
|
32
|
+
}
|
|
30
33
|
}
|
|
31
34
|
],
|
|
32
35
|
"typeReferences": [
|
|
@@ -43,7 +46,10 @@
|
|
|
43
46
|
"type": "string",
|
|
44
47
|
"required": false,
|
|
45
48
|
"defaultValue": null,
|
|
46
|
-
"description": "Extra classes for the section."
|
|
49
|
+
"description": "Extra classes for the section.",
|
|
50
|
+
"control": {
|
|
51
|
+
"kind": "string"
|
|
52
|
+
}
|
|
47
53
|
}
|
|
48
54
|
],
|
|
49
55
|
"typeReferences": [
|
|
@@ -60,7 +66,10 @@
|
|
|
60
66
|
"type": "string",
|
|
61
67
|
"required": false,
|
|
62
68
|
"defaultValue": null,
|
|
63
|
-
"description": "Extra classes for the heading."
|
|
69
|
+
"description": "Extra classes for the heading.",
|
|
70
|
+
"control": {
|
|
71
|
+
"kind": "string"
|
|
72
|
+
}
|
|
64
73
|
}
|
|
65
74
|
],
|
|
66
75
|
"typeReferences": [
|
|
@@ -77,7 +86,10 @@
|
|
|
77
86
|
"type": "string",
|
|
78
87
|
"required": false,
|
|
79
88
|
"defaultValue": null,
|
|
80
|
-
"description": "Extra classes for the summary row."
|
|
89
|
+
"description": "Extra classes for the summary row.",
|
|
90
|
+
"control": {
|
|
91
|
+
"kind": "string"
|
|
92
|
+
}
|
|
81
93
|
}
|
|
82
94
|
],
|
|
83
95
|
"typeReferences": [
|
|
@@ -94,14 +106,20 @@
|
|
|
94
106
|
"type": "string",
|
|
95
107
|
"required": false,
|
|
96
108
|
"defaultValue": null,
|
|
97
|
-
"description": "Extra classes for the animating box. Padding belongs on `bodyClassName`."
|
|
109
|
+
"description": "Extra classes for the animating box. Padding belongs on `bodyClassName`.",
|
|
110
|
+
"control": {
|
|
111
|
+
"kind": "string"
|
|
112
|
+
}
|
|
98
113
|
},
|
|
99
114
|
{
|
|
100
115
|
"name": "bodyClassName",
|
|
101
116
|
"type": "string",
|
|
102
117
|
"required": false,
|
|
103
118
|
"defaultValue": null,
|
|
104
|
-
"description": "Extra classes for the padded body inside it."
|
|
119
|
+
"description": "Extra classes for the padded body inside it.",
|
|
120
|
+
"control": {
|
|
121
|
+
"kind": "string"
|
|
122
|
+
}
|
|
105
123
|
}
|
|
106
124
|
],
|
|
107
125
|
"typeReferences": [
|
|
@@ -14,35 +14,50 @@
|
|
|
14
14
|
"type": "readonly DataPoint[]",
|
|
15
15
|
"required": true,
|
|
16
16
|
"defaultValue": null,
|
|
17
|
-
"description": "Date and count pairs from the heat-graph package. Levels are classified for you;\ngaps are filled as empty cells."
|
|
17
|
+
"description": "Date and count pairs from the heat-graph package. Levels are classified for you;\ngaps are filled as empty cells.",
|
|
18
|
+
"control": {
|
|
19
|
+
"kind": "array"
|
|
20
|
+
}
|
|
18
21
|
},
|
|
19
22
|
{
|
|
20
23
|
"name": "start",
|
|
21
24
|
"type": "string | Date",
|
|
22
25
|
"required": true,
|
|
23
26
|
"defaultValue": null,
|
|
24
|
-
"description": "First day of the window. Pass it explicitly: left unset, heat-graph draws a full\nyear ending today, which will not match your data."
|
|
27
|
+
"description": "First day of the window. Pass it explicitly: left unset, heat-graph draws a full\nyear ending today, which will not match your data.",
|
|
28
|
+
"control": {
|
|
29
|
+
"kind": "opaque"
|
|
30
|
+
}
|
|
25
31
|
},
|
|
26
32
|
{
|
|
27
33
|
"name": "end",
|
|
28
34
|
"type": "string | Date",
|
|
29
35
|
"required": true,
|
|
30
36
|
"defaultValue": null,
|
|
31
|
-
"description": "Last day of the window. Cells are fixed-size, so a long window scrolls\nhorizontally rather than shrinking."
|
|
37
|
+
"description": "Last day of the window. Cells are fixed-size, so a long window scrolls\nhorizontally rather than shrinking.",
|
|
38
|
+
"control": {
|
|
39
|
+
"kind": "opaque"
|
|
40
|
+
}
|
|
32
41
|
},
|
|
33
42
|
{
|
|
34
43
|
"name": "title",
|
|
35
44
|
"type": "string",
|
|
36
45
|
"required": true,
|
|
37
46
|
"defaultValue": null,
|
|
38
|
-
"description": "What is being counted."
|
|
47
|
+
"description": "What is being counted.",
|
|
48
|
+
"control": {
|
|
49
|
+
"kind": "string"
|
|
50
|
+
}
|
|
39
51
|
},
|
|
40
52
|
{
|
|
41
53
|
"name": "total",
|
|
42
54
|
"type": "string",
|
|
43
55
|
"required": true,
|
|
44
56
|
"defaultValue": null,
|
|
45
|
-
"description": "Pre-formatted summary shown opposite the title."
|
|
57
|
+
"description": "Pre-formatted summary shown opposite the title.",
|
|
58
|
+
"control": {
|
|
59
|
+
"kind": "string"
|
|
60
|
+
}
|
|
46
61
|
}
|
|
47
62
|
],
|
|
48
63
|
"typeReferences": [
|