@cueplusplus/ui 0.20.1 → 0.22.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 +133 -0
- package/dist/chat/agent-pile.js +2 -2
- package/dist/chrome/_status-bar.js +1 -1
- package/dist/chrome/app-shell.js +1 -1
- package/dist/chrome/navigation-menu.js +3 -3
- package/dist/chrome/row.js +1 -1
- package/dist/chrome/scroll-area.js +1 -1
- package/dist/chrome/section-header.js +1 -1
- package/dist/chrome/segmented-control.js +1 -1
- package/dist/chrome/tabs.js +1 -1
- package/dist/chrome/toolbar.js +1 -1
- package/dist/chrome/tree.js +3 -3
- package/dist/date/calendar.js +3 -3
- package/dist/dmx/channel-matrix.js +1 -1
- package/dist/dmx/universe-grid.js +1 -1
- package/dist/elements/agent-handoff.js +3 -3
- package/dist/elements/agent-plan.js +1 -1
- package/dist/elements/agent-status.js +1 -1
- package/dist/elements/agent-surface.d.ts +9 -6
- package/dist/elements/agent-surface.js +3 -2
- package/dist/elements/approval-card.d.ts +29 -3
- package/dist/elements/approval-card.js +18 -8
- package/dist/elements/artifact-card.js +2 -2
- package/dist/elements/canvas-split.js +3 -3
- package/dist/elements/chart.js +1 -1
- package/dist/elements/chat-panel.js +2 -2
- package/dist/elements/checkpoint-history.js +1 -1
- package/dist/elements/code-diff.js +1 -1
- package/dist/elements/code-runner.js +1 -1
- package/dist/elements/composer.d.ts +8 -2
- package/dist/elements/composer.js +20 -12
- package/dist/elements/computer-use.js +2 -2
- package/dist/elements/confidence-marker.js +1 -1
- package/dist/elements/connection-state.js +2 -2
- package/dist/elements/context-breakdown.js +1 -1
- package/dist/elements/context-usage.js +1 -1
- package/dist/elements/conversation-search.js +2 -2
- package/dist/elements/cost-meter.js +1 -1
- package/dist/elements/data-table.js +1 -1
- package/dist/elements/diagram.js +1 -1
- package/dist/elements/draft-restore.js +2 -2
- package/dist/elements/edit-message.js +1 -1
- package/dist/elements/elements.css +134 -0
- package/dist/elements/elicitation-form.d.ts +8 -1
- package/dist/elements/elicitation-form.js +24 -16
- package/dist/elements/empty-state.js +3 -3
- package/dist/elements/error-state.js +2 -2
- package/dist/elements/event-feed.d.ts +88 -0
- package/dist/elements/event-feed.js +190 -0
- package/dist/elements/feedback-dialog.js +2 -2
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/flow-graph.js +2 -2
- package/dist/elements/generative.css +13 -0
- package/dist/elements/generative.d.ts +8 -6
- package/dist/elements/generative.js +4 -3
- package/dist/elements/image-generation.js +2 -2
- package/dist/elements/index.d.ts +7 -3
- package/dist/elements/index.js +5 -2
- package/dist/elements/inline-citation.js +1 -1
- package/dist/elements/job-progress.js +1 -1
- package/dist/elements/launcher-bubble.js +3 -3
- package/dist/elements/loading-state.js +1 -1
- package/dist/elements/map-answer.js +1 -1
- package/dist/elements/math-block.js +1 -1
- package/dist/elements/mcp-server-panel.js +3 -3
- package/dist/elements/memory-chips.js +1 -1
- package/dist/elements/message-attachment.js +3 -3
- package/dist/elements/message-branches.js +1 -1
- package/dist/elements/message-pair.js +2 -2
- package/dist/elements/message-queue.js +1 -1
- package/dist/elements/message-timing.js +1 -1
- package/dist/elements/mobile-composer.js +1 -1
- package/dist/elements/model-picker.js +1 -1
- package/dist/elements/number-ticker.js +1 -1
- package/dist/elements/onboarding.js +3 -3
- package/dist/elements/permission-grant.js +3 -3
- package/dist/elements/prompt-library.js +1 -1
- package/dist/elements/question-card.d.ts +50 -0
- package/dist/elements/question-card.js +117 -0
- package/dist/elements/queue-dock.js +1 -1
- package/dist/elements/quota-banner.js +1 -1
- package/dist/elements/quote-reply.js +3 -3
- package/dist/elements/read-aloud.js +2 -2
- package/dist/elements/reasoning-effort.js +2 -2
- package/dist/elements/reasoning-panel.js +3 -3
- package/dist/elements/recommendation-card.js +2 -2
- package/dist/elements/regenerate-menu.js +1 -1
- package/dist/elements/request-delivery.js +31 -0
- package/dist/elements/research-report.js +1 -1
- package/dist/elements/retrieval-chunks.js +3 -3
- package/dist/elements/revert-dock.js +1 -1
- package/dist/elements/reviewable-diff.js +4 -4
- package/dist/elements/schedule-card.js +2 -2
- package/dist/elements/score-breakdown.js +2 -2
- package/dist/elements/scroll-anchor.js +2 -2
- package/dist/elements/settings-panel.js +3 -3
- package/dist/elements/sources.js +1 -1
- package/dist/elements/spec-sheet.js +1 -1
- package/dist/elements/stopped-run.js +2 -2
- package/dist/elements/streaming-text.js +2 -2
- package/dist/elements/subagent-list.js +4 -4
- package/dist/elements/suggestions.js +1 -1
- package/dist/elements/surfaces.d.ts +6 -6
- package/dist/elements/surfaces.js +7 -7
- package/dist/elements/tail-status.js +1 -1
- package/dist/elements/terminal-block.js +1 -1
- package/dist/elements/thinking-indicator.js +1 -1
- package/dist/elements/timeline.js +1 -1
- package/dist/elements/todo-list.js +1 -1
- package/dist/elements/tool-call.d.ts +18 -2
- package/dist/elements/tool-call.js +20 -11
- package/dist/elements/tool-error.js +2 -2
- package/dist/elements/tool-group.d.ts +11 -3
- package/dist/elements/tool-group.js +62 -38
- package/dist/elements/tool-state.d.ts +13 -0
- package/dist/elements/tool-state.js +44 -0
- package/dist/elements/tool-timeline.js +2 -2
- package/dist/elements/trace-waterfall.js +2 -2
- package/dist/elements/unsupported-request-card.d.ts +31 -0
- package/dist/elements/unsupported-request-card.js +80 -0
- package/dist/elements/vocabulary.d.ts +50 -1
- package/dist/elements/vocabulary.js +50 -1
- package/dist/elements/voice-conversation.js +5 -5
- package/dist/elements/web-preview.js +1 -1
- package/dist/elements/web-search.js +2 -2
- package/dist/elements/work-collapse.js +1 -1
- package/dist/forms/_chassis.d.ts +6 -1
- package/dist/forms/_chassis.js +8 -3
- package/dist/forms/file-upload.js +1 -1
- package/dist/forms/rating.js +1 -1
- package/dist/forms/select.js +1 -1
- package/dist/forms/switch.js +2 -2
- package/dist/forms/toggle.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/instruments/_ledger-disclosure.js +1 -1
- package/dist/instruments/data-tree.js +1 -1
- package/dist/instruments/meter.js +1 -1
- package/dist/instruments/seam-grid.js +1 -1
- package/dist/layout/_collapse.js +3 -3
- package/dist/layout/bento.js +1 -1
- package/dist/layout/breadcrumb.js +1 -1
- package/dist/layout/carousel.js +1 -1
- package/dist/layout/collapsible.js +1 -1
- package/dist/layout/index.d.ts +3 -1
- package/dist/layout/index.js +3 -1
- package/dist/layout/item.js +1 -1
- package/dist/layout/link.js +1 -1
- package/dist/layout/pagination.js +1 -1
- package/dist/layout/pane-seam.d.ts +75 -0
- package/dist/layout/pane-seam.js +127 -0
- package/dist/layout/resizable.d.ts +2 -1
- package/dist/layout/resizable.js +3 -2
- package/dist/layout/sidebar.js +3 -3
- package/dist/layout/split-pane.d.ts +74 -0
- package/dist/layout/split-pane.js +135 -0
- package/dist/layout/stepper.js +1 -1
- package/dist/lib/auto-grow.js +42 -0
- package/dist/overlays/_surface.d.ts +5 -5
- package/dist/overlays/_surface.js +4 -4
- package/dist/overlays/drawer.js +1 -1
- package/dist/overlays/menubar.js +1 -1
- package/dist/overlays/sheet.js +1 -1
- package/dist/overlays/toast.js +1 -1
- package/dist/primitives/button.js +1 -1
- package/dist/primitives/chip.d.ts +1 -1
- package/dist/styles.css +52 -0
- package/dist/system/_paint-stroke-sunken.js +22 -2
- package/dist/system/_paint-stroke-surface-1.js +5 -1
- package/dist/system/_paint-stroke-surface-2.js +5 -1
- package/dist/system/_style-disabled.js +1 -7
- package/dist/system/agent-skin.d.ts +11 -5
- package/manifest/components/agent-surface.json +5 -4
- package/manifest/components/alert-dialog.json +1 -0
- package/manifest/components/approval-card.json +45 -7
- package/manifest/components/autocomplete.json +2 -0
- package/manifest/components/button.json +0 -3
- package/manifest/components/card.json +1 -0
- package/manifest/components/channel-matrix.json +1 -0
- package/manifest/components/chart-tooltip-content.json +1 -0
- package/manifest/components/checkbox-group.json +0 -3
- package/manifest/components/checkbox.json +0 -3
- package/manifest/components/color-field.json +1 -0
- package/manifest/components/color-picker.json +1 -0
- package/manifest/components/combobox.json +2 -0
- package/manifest/components/command-palette.json +1 -0
- package/manifest/components/composer-input.json +16 -2
- package/manifest/components/composer.json +1 -0
- package/manifest/components/context-menu.json +1 -0
- package/manifest/components/date-field.json +1 -0
- package/manifest/components/date-picker.json +1 -0
- package/manifest/components/date-range-picker.json +1 -0
- package/manifest/components/dialog.json +1 -0
- package/manifest/components/dmx-bar.json +1 -0
- package/manifest/components/dmx-strip.json +1 -0
- package/manifest/components/drawer.json +1 -0
- package/manifest/components/dropdown-menu.json +1 -0
- package/manifest/components/elicitation-form.json +16 -1
- package/manifest/components/env-var-input.json +1 -0
- package/manifest/components/event-feed.json +171 -0
- package/manifest/components/event-row.json +116 -0
- package/manifest/components/generative-ui.json +4 -3
- package/manifest/components/hover-card.json +1 -0
- package/manifest/components/input-group.json +1 -0
- package/manifest/components/input.json +1 -0
- package/manifest/components/menubar.json +1 -0
- package/manifest/components/multi-select.json +2 -0
- package/manifest/components/musical-time-input.json +1 -0
- package/manifest/components/navigation-menu.json +1 -0
- package/manifest/components/number-field.json +1 -0
- package/manifest/components/otp-field.json +1 -0
- package/manifest/components/pane-seam.json +171 -0
- package/manifest/components/password-input.json +1 -0
- package/manifest/components/popover.json +1 -0
- package/manifest/components/question-card.json +157 -0
- package/manifest/components/resizable.json +1 -1
- package/manifest/components/scrub-input.json +1 -0
- package/manifest/components/search-input.json +1 -0
- package/manifest/components/select.json +2 -0
- package/manifest/components/sheet.json +1 -0
- package/manifest/components/split-pane.json +224 -0
- package/manifest/components/switch.json +0 -3
- package/manifest/components/tags-input.json +2 -0
- package/manifest/components/textarea.json +1 -0
- package/manifest/components/theme-configurator.json +1 -0
- package/manifest/components/time-field.json +1 -0
- package/manifest/components/toast.json +1 -0
- package/manifest/components/toggle.json +0 -3
- package/manifest/components/tool-call.json +46 -2
- package/manifest/components/tool-group.json +15 -3
- package/manifest/components/tooltip.json +1 -0
- package/manifest/components/unsupported-request-card.json +117 -0
- package/manifest/fixtures.json +16 -0
- package/manifest/manifest.json +134 -56
- package/manifest/tokens.json +12 -2
- package/package.json +3 -3
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { FOCUS_RING_INSET_2 } from "../system/_focus-ring.js";
|
|
4
|
+
import { ChevronLeftGlyph, ChevronRightGlyph } from "./_glyphs.js";
|
|
5
|
+
import { PaneSeam } from "./pane-seam.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/layout/split-pane.tsx
|
|
9
|
+
/**
|
|
10
|
+
* A list beside its detail, which stacks into a drill-in when narrow (#102).
|
|
11
|
+
*
|
|
12
|
+
* The master-detail opinion on top of {@link PaneSeam}. Side by side while
|
|
13
|
+
* the detail would be at least twice the list, measured on the frame rather
|
|
14
|
+
* than the window, so it works in any column. Below that it stacks the way a
|
|
15
|
+
* phone does: the list, or the detail with a Back button, and Escape inside the
|
|
16
|
+
* detail goes back too. `detailOpen` says which shows; selection and the list's
|
|
17
|
+
* own keyboard stay with the list.
|
|
18
|
+
*
|
|
19
|
+
* The frame measures itself with a `ResizeObserver` and draws side by side
|
|
20
|
+
* until it has, so a server render and a browser without one get the split.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const [selected, setSelected] = React.useState<string | null>(null);
|
|
24
|
+
*
|
|
25
|
+
* <SplitPane
|
|
26
|
+
* listLabel="events"
|
|
27
|
+
* list={<EventFeed events={events} selectedId={selected} onSelect={setSelected} />}
|
|
28
|
+
* detail={selected ? <EventDetail id={selected} /> : <EmptyState title="Pick an event" />}
|
|
29
|
+
* detailOpen={selected !== null}
|
|
30
|
+
* onBack={() => setSelected(null)}
|
|
31
|
+
* collapsible
|
|
32
|
+
* />
|
|
33
|
+
*/
|
|
34
|
+
const SplitPane = React.forwardRef(function SplitPane({ list, detail, listLabel, listSize, defaultListSize = 320, onListSizeChange, minListSize = 200, maxListSize = 480, stackBelow, detailOpen = false, onBack, collapsible = false, collapsed, defaultCollapsed = false, onCollapsedChange, className, ...elementProps }, ref) {
|
|
35
|
+
const node = React.useRef(null);
|
|
36
|
+
const setNode = React.useCallback((element) => {
|
|
37
|
+
node.current = element;
|
|
38
|
+
if (typeof ref === "function") ref(element);
|
|
39
|
+
else if (ref) ref.current = element;
|
|
40
|
+
}, [ref]);
|
|
41
|
+
const [ownSize, setOwnSize] = React.useState(defaultListSize);
|
|
42
|
+
const size = listSize ?? ownSize;
|
|
43
|
+
const [ownCollapsed, setOwnCollapsed] = React.useState(defaultCollapsed);
|
|
44
|
+
const folded = collapsible && (collapsed ?? ownCollapsed);
|
|
45
|
+
const [width, setWidth] = React.useState(null);
|
|
46
|
+
React.useLayoutEffect(() => {
|
|
47
|
+
const element = node.current;
|
|
48
|
+
if (element === null || typeof ResizeObserver === "undefined") return;
|
|
49
|
+
const measure = () => setWidth(element.getBoundingClientRect().width);
|
|
50
|
+
const observer = new ResizeObserver(measure);
|
|
51
|
+
observer.observe(element);
|
|
52
|
+
measure();
|
|
53
|
+
return () => observer.disconnect();
|
|
54
|
+
}, []);
|
|
55
|
+
const threshold = stackBelow ?? size * 3;
|
|
56
|
+
const layout = width !== null && width < threshold ? "stacked" : "split";
|
|
57
|
+
const resize = (next) => {
|
|
58
|
+
if (listSize === void 0) setOwnSize(next);
|
|
59
|
+
onListSizeChange?.(next);
|
|
60
|
+
};
|
|
61
|
+
const fold = (next) => {
|
|
62
|
+
if (collapsed === void 0) setOwnCollapsed(next);
|
|
63
|
+
onCollapsedChange?.(next);
|
|
64
|
+
};
|
|
65
|
+
const quiet = `flex items-center justify-center rounded-control text-fg-muted transition-colors duration-fast outline-none hover:bg-surface-2 hover:text-fg ${FOCUS_RING_INSET_2} motion-reduce:transition-none`;
|
|
66
|
+
return /* @__PURE__ */ jsx("div", {
|
|
67
|
+
ref: setNode,
|
|
68
|
+
"data-slot": "split-pane",
|
|
69
|
+
"data-layout": layout,
|
|
70
|
+
"data-detail-open": detailOpen || void 0,
|
|
71
|
+
"data-collapsed": folded || void 0,
|
|
72
|
+
className: cn("flex min-h-0 min-w-0", className),
|
|
73
|
+
...elementProps,
|
|
74
|
+
children: layout === "stacked" ? detailOpen ? /* @__PURE__ */ jsxs("div", {
|
|
75
|
+
"data-slot": "split-pane-detail",
|
|
76
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col",
|
|
77
|
+
onKeyDown: (event) => {
|
|
78
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
onBack?.();
|
|
81
|
+
},
|
|
82
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
83
|
+
className: "flex shrink-0 items-center border-b border-border px-(--cue-space-2) py-(--cue-space-1)",
|
|
84
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
85
|
+
type: "button",
|
|
86
|
+
onClick: onBack,
|
|
87
|
+
className: cn(quiet, "gap-(--cue-space-1) px-(--cue-space-2) py-(--cue-space-1) text-(length:--cue-text-ui)"),
|
|
88
|
+
children: [/* @__PURE__ */ jsx(ChevronLeftGlyph, { className: "size-3" }), `Back to ${listLabel}`]
|
|
89
|
+
})
|
|
90
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
91
|
+
className: "min-h-0 min-w-0 flex-1",
|
|
92
|
+
children: detail
|
|
93
|
+
})]
|
|
94
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
95
|
+
"data-slot": "split-pane-list",
|
|
96
|
+
className: "min-h-0 min-w-0 flex-1",
|
|
97
|
+
children: list
|
|
98
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [folded ? /* @__PURE__ */ jsxs("button", {
|
|
99
|
+
type: "button",
|
|
100
|
+
"aria-expanded": false,
|
|
101
|
+
onClick: () => fold(false),
|
|
102
|
+
className: cn(quiet, "w-(--cue-space-6) shrink-0 self-stretch rounded-none border-e border-border"),
|
|
103
|
+
children: [/* @__PURE__ */ jsx(ChevronRightGlyph, { className: "size-3" }), /* @__PURE__ */ jsx("span", {
|
|
104
|
+
className: "sr-only",
|
|
105
|
+
children: `Show ${listLabel}`
|
|
106
|
+
})]
|
|
107
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
108
|
+
"data-slot": "split-pane-list",
|
|
109
|
+
className: "relative min-h-0 shrink-0",
|
|
110
|
+
style: { width: size },
|
|
111
|
+
children: [list, collapsible ? /* @__PURE__ */ jsxs("button", {
|
|
112
|
+
type: "button",
|
|
113
|
+
"aria-expanded": true,
|
|
114
|
+
onClick: () => fold(true),
|
|
115
|
+
className: cn(quiet, "absolute end-(--cue-space-1) top-(--cue-space-1) size-(--cue-space-6)"),
|
|
116
|
+
children: [/* @__PURE__ */ jsx(ChevronLeftGlyph, { className: "size-3" }), /* @__PURE__ */ jsx("span", {
|
|
117
|
+
className: "sr-only",
|
|
118
|
+
children: `Hide ${listLabel}`
|
|
119
|
+
})]
|
|
120
|
+
}) : null]
|
|
121
|
+
}), /* @__PURE__ */ jsx(PaneSeam, {
|
|
122
|
+
label: `Resize the ${listLabel}`,
|
|
123
|
+
min: minListSize,
|
|
124
|
+
max: maxListSize,
|
|
125
|
+
value: Math.min(maxListSize, Math.max(minListSize, size)),
|
|
126
|
+
onValueChange: resize
|
|
127
|
+
})] }), /* @__PURE__ */ jsx("div", {
|
|
128
|
+
"data-slot": "split-pane-detail",
|
|
129
|
+
className: "min-h-0 min-w-0 flex-1",
|
|
130
|
+
children: detail
|
|
131
|
+
})] })
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//#endregion
|
|
135
|
+
export { SplitPane };
|
package/dist/layout/stepper.js
CHANGED
|
@@ -19,7 +19,7 @@ const INDEX_TONES = {
|
|
|
19
19
|
current: "text-accent",
|
|
20
20
|
upcoming: "text-fg-subtle"
|
|
21
21
|
};
|
|
22
|
-
const STEP_BUTTON_CLASSES = `inline-flex cursor-pointer items-center gap-(--cue-space-2) rounded-control border-0 bg-transparent p-0 ${LABEL_FACE} text-[length:inherit] tracking-[inherit] text-inherit ${LABEL_CASE} transition-colors duration-
|
|
22
|
+
const STEP_BUTTON_CLASSES = `inline-flex cursor-pointer items-center gap-(--cue-space-2) rounded-control border-0 bg-transparent p-0 ${LABEL_FACE} text-[length:inherit] tracking-[inherit] text-inherit ${LABEL_CASE} transition-colors duration-fast outline-none hover:text-fg ${FOCUS_RING_OFFSET_2}`;
|
|
23
23
|
/**
|
|
24
24
|
* The step trail: `1 target · 2 preview · 3 apply`.
|
|
25
25
|
*
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useIsomorphicLayoutEffect } from "../system/use-isomorphic-layout-effect.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
//#region src/lib/auto-grow.ts
|
|
5
|
+
/** Whether this browser sizes a textarea to its content itself (`field-sizing: content`). */
|
|
6
|
+
function sizesItself() {
|
|
7
|
+
return typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("field-sizing", "content");
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Grow a textarea with what it holds, where CSS cannot.
|
|
11
|
+
*
|
|
12
|
+
* `field-sizing: content` sizes a textarea to its text in the browsers that
|
|
13
|
+
* have it, and a `max-height` caps it, so in those this does nothing. Where the
|
|
14
|
+
* property is missing, the textarea is measured instead: its height is reset
|
|
15
|
+
* and set to its `scrollHeight` on every input, and again whenever `value`
|
|
16
|
+
* changes from outside, so a composer the parent clears after sending shrinks
|
|
17
|
+
* back to one line. The cap stays the stylesheet's.
|
|
18
|
+
*
|
|
19
|
+
* Returns a ref for the textarea. A caller that passes its own `ref` after this
|
|
20
|
+
* one replaces it, and the field then sizes with CSS alone.
|
|
21
|
+
*
|
|
22
|
+
* @param value The textarea's value, so a change made from outside re-measures it.
|
|
23
|
+
*/
|
|
24
|
+
function useAutoGrow(value) {
|
|
25
|
+
const node = React.useRef(null);
|
|
26
|
+
const fit = React.useCallback(() => {
|
|
27
|
+
const element = node.current;
|
|
28
|
+
if (element === null || sizesItself()) return;
|
|
29
|
+
element.style.height = "auto";
|
|
30
|
+
element.style.height = `${element.scrollHeight}px`;
|
|
31
|
+
}, []);
|
|
32
|
+
const ref = React.useCallback((element) => {
|
|
33
|
+
node.current?.removeEventListener("input", fit);
|
|
34
|
+
node.current = element;
|
|
35
|
+
element?.addEventListener("input", fit);
|
|
36
|
+
fit();
|
|
37
|
+
}, [fit]);
|
|
38
|
+
useIsomorphicLayoutEffect(fit, [value, fit]);
|
|
39
|
+
return { ref };
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { useAutoGrow };
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @example
|
|
19
19
|
* <Popover.Popup className={cn(overlaySurfaceClasses, className)} />
|
|
20
20
|
*/
|
|
21
|
-
declare const overlaySurfaceClasses = "rounded-overlay border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-style-overlay-ground,var(--cue-surface-2)),var(--cue-style-overlay-ground,var(--cue-surface-2))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-overlay-from,var(--cue-border-overlay)),var(--cue-paint-stroke-overlay-to,var(--cue-border-overlay)))] bg-origin-border [background-clip:padding-box,border-box] shadow-[0_0_0_var(--cue-paint-rim-width)_var(--cue-paint-shade-hairline,transparent),0_calc(2px*var(--cue-paint-shadow-scale))_calc(6px*var(--cue-paint-shadow-scale))_var(--cue-paint-shadow-spread)_var(--cue-paint-shade-near,transparent),0_calc(8px*var(--cue-paint-shadow-scale))_calc(24px*var(--cue-paint-shadow-scale))_var(--cue-paint-shadow-spread)_var(--cue-paint-shade-far,rgba(0,0,0,0.4)),inset_0_1px_0_0_var(--cue-paint-sheen-ink,transparent)]";
|
|
21
|
+
declare const overlaySurfaceClasses = "rounded-overlay border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-style-overlay-ground,var(--cue-surface-2)),var(--cue-style-overlay-ground,var(--cue-surface-2))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-overlay-from,var(--cue-border-overlay)),var(--cue-paint-stroke-overlay-to,var(--cue-border-overlay)))] bg-origin-border [background-clip:padding-box,border-box] [--cue-ground:var(--cue-style-overlay-ground,var(--cue-surface-2))] shadow-[0_0_0_var(--cue-paint-rim-width)_var(--cue-paint-shade-hairline,transparent),0_calc(2px*var(--cue-paint-shadow-scale))_calc(6px*var(--cue-paint-shadow-scale))_var(--cue-paint-shadow-spread)_var(--cue-paint-shade-near,transparent),0_calc(8px*var(--cue-paint-shadow-scale))_calc(24px*var(--cue-paint-shadow-scale))_var(--cue-paint-shadow-spread)_var(--cue-paint-shade-far,rgba(0,0,0,0.4)),inset_0_1px_0_0_var(--cue-paint-sheen-ink,transparent)]";
|
|
22
22
|
/**
|
|
23
23
|
* The full-viewport dim behind a modal surface. `--cue-scrim` is theme-owned —
|
|
24
24
|
* dusk and hivehub tune their own — so the value is never hard-coded here.
|
|
@@ -73,9 +73,9 @@ declare const overlaySurfaceClasses = "rounded-overlay border-transparent border
|
|
|
73
73
|
* composed declaration without entering it; at rest the property is theirs.
|
|
74
74
|
* The pseudo's `transition` and timing are its own classes: Tailwind
|
|
75
75
|
* registers `--tw-duration` and `--tw-ease` with `inherits: false`, so the
|
|
76
|
-
* scrim's `duration-
|
|
76
|
+
* scrim's `duration-fast ease-out` never reach it.
|
|
77
77
|
*/
|
|
78
|
-
declare const scrimClasses = "fixed inset-0 z-50 bg-(--cue-scrim) before:absolute before:inset-0 before:content-[''] before:pointer-events-none before:[backdrop-filter:var(--cue-paint-scrim-filter,none)] transition-[background-color,backdrop-filter] duration-
|
|
78
|
+
declare const scrimClasses = "fixed inset-0 z-50 bg-(--cue-scrim) before:absolute before:inset-0 before:content-[''] before:pointer-events-none before:[backdrop-filter:var(--cue-paint-scrim-filter,none)] transition-[background-color,backdrop-filter] duration-fast ease-out before:transition-opacity before:duration-fast before:ease-out motion-reduce:transition-none motion-reduce:before:transition-none data-[starting-style]:bg-transparent data-[ending-style]:bg-transparent data-[starting-style]:[backdrop-filter:none] data-[ending-style]:[backdrop-filter:none] data-[starting-style]:before:opacity-0 data-[ending-style]:before:opacity-0";
|
|
79
79
|
/**
|
|
80
80
|
* What a Base UI `Positioner` needs and nothing more: it is a layout box, not a
|
|
81
81
|
* painted one. The stacking context lives here so the popup itself can stay
|
|
@@ -88,14 +88,14 @@ declare const overlayPositionerClasses = "z-50 outline-none";
|
|
|
88
88
|
* transitions — no animation library, and nothing to run on the main thread
|
|
89
89
|
* when the user has asked for reduced motion.
|
|
90
90
|
*/
|
|
91
|
-
declare const overlayPopupTransitionClasses = "origin-(--transform-origin) transition-[opacity,scale] duration-
|
|
91
|
+
declare const overlayPopupTransitionClasses = "origin-(--transform-origin) transition-[opacity,scale] duration-instant ease-out motion-reduce:transition-none data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0";
|
|
92
92
|
/**
|
|
93
93
|
* Enter/exit for a centred modal surface. Split from
|
|
94
94
|
* {@link overlayPopupTransitionClasses} because a dialog is centred with a
|
|
95
95
|
* translate, and animating `scale` alongside a static `translate` needs the
|
|
96
96
|
* transition property list to name both.
|
|
97
97
|
*/
|
|
98
|
-
declare const overlayModalTransitionClasses = "transition-[opacity,scale] duration-
|
|
98
|
+
declare const overlayModalTransitionClasses = "transition-[opacity,scale] duration-fast ease-out motion-reduce:transition-none data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0";
|
|
99
99
|
/**
|
|
100
100
|
* Body copy inside an overlay: the body voice (mono unless a style set names
|
|
101
101
|
* another face — `_style-body.ts`), one rung under the panel's own text.
|
|
@@ -88,9 +88,9 @@ const overlaySurfaceClasses = `rounded-overlay ${STROKE_SURFACE_2} ${ELEVATION_2
|
|
|
88
88
|
* composed declaration without entering it; at rest the property is theirs.
|
|
89
89
|
* The pseudo's `transition` and timing are its own classes: Tailwind
|
|
90
90
|
* registers `--tw-duration` and `--tw-ease` with `inherits: false`, so the
|
|
91
|
-
* scrim's `duration-
|
|
91
|
+
* scrim's `duration-fast ease-out` never reach it.
|
|
92
92
|
*/
|
|
93
|
-
const scrimClasses = "fixed inset-0 z-50 bg-(--cue-scrim) before:absolute before:inset-0 before:content-[''] before:pointer-events-none before:[backdrop-filter:var(--cue-paint-scrim-filter,none)] transition-[background-color,backdrop-filter] duration-
|
|
93
|
+
const scrimClasses = "fixed inset-0 z-50 bg-(--cue-scrim) before:absolute before:inset-0 before:content-[''] before:pointer-events-none before:[backdrop-filter:var(--cue-paint-scrim-filter,none)] transition-[background-color,backdrop-filter] duration-fast ease-out before:transition-opacity before:duration-fast before:ease-out motion-reduce:transition-none motion-reduce:before:transition-none data-[starting-style]:bg-transparent data-[ending-style]:bg-transparent data-[starting-style]:[backdrop-filter:none] data-[ending-style]:[backdrop-filter:none] data-[starting-style]:before:opacity-0 data-[ending-style]:before:opacity-0";
|
|
94
94
|
/**
|
|
95
95
|
* What a Base UI `Positioner` needs and nothing more: it is a layout box, not a
|
|
96
96
|
* painted one. The stacking context lives here so the popup itself can stay
|
|
@@ -103,14 +103,14 @@ const overlayPositionerClasses = "z-50 outline-none";
|
|
|
103
103
|
* transitions — no animation library, and nothing to run on the main thread
|
|
104
104
|
* when the user has asked for reduced motion.
|
|
105
105
|
*/
|
|
106
|
-
const overlayPopupTransitionClasses = "origin-(--transform-origin) transition-[opacity,scale] duration-
|
|
106
|
+
const overlayPopupTransitionClasses = "origin-(--transform-origin) transition-[opacity,scale] duration-instant ease-out motion-reduce:transition-none data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0";
|
|
107
107
|
/**
|
|
108
108
|
* Enter/exit for a centred modal surface. Split from
|
|
109
109
|
* {@link overlayPopupTransitionClasses} because a dialog is centred with a
|
|
110
110
|
* translate, and animating `scale` alongside a static `translate` needs the
|
|
111
111
|
* transition property list to name both.
|
|
112
112
|
*/
|
|
113
|
-
const overlayModalTransitionClasses = "transition-[opacity,scale] duration-
|
|
113
|
+
const overlayModalTransitionClasses = "transition-[opacity,scale] duration-fast ease-out motion-reduce:transition-none data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0";
|
|
114
114
|
/**
|
|
115
115
|
* Body copy inside an overlay: the body voice (mono unless a style set names
|
|
116
116
|
* another face — `_style-body.ts`), one rung under the panel's own text.
|
package/dist/overlays/drawer.js
CHANGED
|
@@ -106,7 +106,7 @@ const Drawer$1 = {
|
|
|
106
106
|
children: /* @__PURE__ */ jsxs(Drawer.Popup, {
|
|
107
107
|
ref,
|
|
108
108
|
"data-slot": "drawer-popup",
|
|
109
|
-
className: cn(overlaySurfaceClasses, DRAWER_RADIUS, "flex flex-col overflow-y-auto overscroll-contain outline-none transition-transform duration-
|
|
109
|
+
className: cn(overlaySurfaceClasses, DRAWER_RADIUS, "flex flex-col overflow-y-auto overscroll-contain outline-none transition-transform duration-brisk ease-out data-[swiping]:duration-0 motion-reduce:transition-none", POPUP_GEOMETRY[direction], className),
|
|
110
110
|
...popupProps,
|
|
111
111
|
children: [grabHandle ? /* @__PURE__ */ jsx("div", {
|
|
112
112
|
"data-slot": "drawer-grab-handle",
|
package/dist/overlays/menubar.js
CHANGED
|
@@ -68,7 +68,7 @@ const Menubar$1 = {
|
|
|
68
68
|
return /* @__PURE__ */ jsx(Menu.Trigger, {
|
|
69
69
|
ref,
|
|
70
70
|
"data-slot": "menubar-trigger",
|
|
71
|
-
className: cn(`inline-flex h-control-sm shrink-0 cursor-default items-center rounded-control px-(--cue-space-3) text-(length:--cue-text-ui) whitespace-nowrap text-fg-muted transition-colors duration-
|
|
71
|
+
className: cn(`inline-flex h-control-sm shrink-0 cursor-default items-center rounded-control px-(--cue-space-3) text-(length:--cue-text-ui) whitespace-nowrap text-fg-muted transition-colors duration-fast outline-none select-none hover:text-fg ${FOCUS_RING_INSET} data-[popup-open]:bg-accent-soft data-[popup-open]:text-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-40`, CONTROL_FACE, className),
|
|
72
72
|
...elementProps
|
|
73
73
|
});
|
|
74
74
|
}),
|
package/dist/overlays/sheet.js
CHANGED
|
@@ -23,7 +23,7 @@ import { Dialog } from "@base-ui/react/dialog";
|
|
|
23
23
|
* into a corner; killing the outer edge is what makes it read as part of the
|
|
24
24
|
* window.
|
|
25
25
|
*/
|
|
26
|
-
const sheetPopupVariants = cva(`${overlaySurfaceClasses} fixed z-50 flex flex-col gap-(--cue-space-4) overflow-y-auto p-(--cue-space-6) outline-none transition-transform duration-
|
|
26
|
+
const sheetPopupVariants = cva(`${overlaySurfaceClasses} fixed z-50 flex flex-col gap-(--cue-space-4) overflow-y-auto p-(--cue-space-6) outline-none transition-transform duration-brisk ease-out motion-reduce:transition-none`, {
|
|
27
27
|
variants: { side: {
|
|
28
28
|
right: "inset-y-0 right-0 w-[min(28rem,calc(100vw-2rem))] rounded-r-none border-y-0 border-r-0 data-[starting-style]:translate-x-full data-[ending-style]:translate-x-full",
|
|
29
29
|
left: "inset-y-0 left-0 w-[min(28rem,calc(100vw-2rem))] rounded-l-none border-y-0 border-l-0 data-[starting-style]:-translate-x-full data-[ending-style]:-translate-x-full",
|
package/dist/overlays/toast.js
CHANGED
|
@@ -83,7 +83,7 @@ function ToastItem({ toast, className, closeLabel }) {
|
|
|
83
83
|
return /* @__PURE__ */ jsxs(Toast.Root, {
|
|
84
84
|
toast,
|
|
85
85
|
"data-slot": "toast-root",
|
|
86
|
-
className: cn(overlaySurfaceClasses, `relative flex flex-col gap-(--cue-space-1) border-l-2 ${TOAST_PAD_Y} pr-(--cue-space-6) ${TOAST_PAD_X} outline-none`, "transition-[opacity,translate] duration-
|
|
86
|
+
className: cn(overlaySurfaceClasses, `relative flex flex-col gap-(--cue-space-1) border-l-2 ${TOAST_PAD_Y} pr-(--cue-space-6) ${TOAST_PAD_X} outline-none`, "transition-[opacity,translate] duration-fast ease-out motion-reduce:transition-none", "data-[starting-style]:translate-x-2 data-[starting-style]:opacity-0", "data-[ending-style]:translate-x-2 data-[ending-style]:opacity-0", "data-[limited]:hidden", TOAST_TONE_RAIL[toToastTone(toast.type)], className),
|
|
87
87
|
children: [
|
|
88
88
|
/* @__PURE__ */ jsx(Toast.Title, {
|
|
89
89
|
"data-slot": "toast-title",
|
|
@@ -38,7 +38,7 @@ import { useRender } from "@base-ui/react/use-render";
|
|
|
38
38
|
*
|
|
39
39
|
* @internal Not part of the public API; imported by `icon-button.tsx`.
|
|
40
40
|
*/
|
|
41
|
-
const buttonChassis = `inline-flex select-none items-center justify-center ${CONTROL_GAP} whitespace-nowrap rounded-control ${CONTROL_FACE} ${CONTROL_WEIGHT} ${CONTROL_TRACKING} ${CONTROL_TRIM} ${CONTROL_CASE} transition-colors duration-
|
|
41
|
+
const buttonChassis = `inline-flex select-none items-center justify-center ${CONTROL_GAP} whitespace-nowrap rounded-control ${CONTROL_FACE} ${CONTROL_WEIGHT} ${CONTROL_TRACKING} ${CONTROL_TRIM} ${CONTROL_CASE} transition-colors duration-fast outline-none ${FOCUS_RING_PAINT} focus-visible:outline-offset-[var(--cue-style-focus-offset,1px)] disabled:pointer-events-none ${DISABLED_OPACITY}`;
|
|
42
42
|
/**
|
|
43
43
|
* A style set's chevron cut (structural Looks, spec 2026-10-02 §3.3), for the tones
|
|
44
44
|
* that are a filled shape: primary and danger always, secondary only where the set
|
|
@@ -2,7 +2,7 @@ import { ClassProp, VariantProps } from "../lib/cva.js";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
//#region src/primitives/chip.d.ts
|
|
4
4
|
declare const chipVariants: (props?: ({
|
|
5
|
-
tone?: "danger" | "info" | "warn" | "
|
|
5
|
+
tone?: "danger" | "info" | "warn" | "busy" | "accent" | "ok" | "neutral" | null | undefined;
|
|
6
6
|
variant?: "outline" | "tinted" | "tag" | null | undefined;
|
|
7
7
|
interactive?: boolean | null | undefined;
|
|
8
8
|
} & ClassProp) | undefined) => string;
|
package/dist/styles.css
CHANGED
|
@@ -133,3 +133,55 @@
|
|
|
133
133
|
clip-path: none;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
/* A container's ground, for the relative field fill (spec 2026-10-08-field-ground R3).
|
|
138
|
+
*
|
|
139
|
+
* Every fill utility a container can paint with says what it painted, as
|
|
140
|
+
* `--cue-ground`, and a control inside `[data-field-ground="relative"]` mixes
|
|
141
|
+
* its fill from the nearest one (`system/_field-ground.ts`). Declaring it is
|
|
142
|
+
* free: nothing outside the opt-in reads it. In `base` so a consumer's own
|
|
143
|
+
* utility or inline `--cue-ground` wins; a container painted any other way — a
|
|
144
|
+
* gradient, an image, a translucent fill — sets `--cue-ground` itself. */
|
|
145
|
+
@layer base {
|
|
146
|
+
.bg-bg {
|
|
147
|
+
--cue-ground: var(--cue-bg);
|
|
148
|
+
}
|
|
149
|
+
.bg-sunken {
|
|
150
|
+
--cue-ground: var(--cue-sunken);
|
|
151
|
+
}
|
|
152
|
+
.bg-surface-1 {
|
|
153
|
+
--cue-ground: var(--cue-surface-1);
|
|
154
|
+
}
|
|
155
|
+
.bg-surface-2 {
|
|
156
|
+
--cue-ground: var(--cue-surface-2);
|
|
157
|
+
}
|
|
158
|
+
.bg-surface-3 {
|
|
159
|
+
--cue-ground: var(--cue-surface-3);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* The relative field fill (spec 2026-10-08-field-ground R3), and opt-in.
|
|
164
|
+
*
|
|
165
|
+
* Nothing happens until an ancestor carries `data-field-ground="relative"`.
|
|
166
|
+
* Inside one, a field that wears `field-ground` — every control the recessed
|
|
167
|
+
* chassis draws does — re-declares its OWN `--cue-sunken` one step off the
|
|
168
|
+
* nearest container's `--cue-ground` (declared above, and by the raised and
|
|
169
|
+
* overlay strokes), toward its text colour: lighter on a dark ground, deeper on
|
|
170
|
+
* a light one, 6% unless `--cue-style-field-step` says otherwise.
|
|
171
|
+
* `--cue-style-field-toward` changes the direction.
|
|
172
|
+
*
|
|
173
|
+
* On the field, never on the ancestor: a custom property resolves its `var()`s
|
|
174
|
+
* where it is declared, so declared on the opt-in element it would freeze at
|
|
175
|
+
* that element's ground and every field below — in a card, in a popover —
|
|
176
|
+
* would fill as if it stood on the page.
|
|
177
|
+
*
|
|
178
|
+
* Re-declaring `sunken` rather than adding a term to the field's fill keeps
|
|
179
|
+
* the chain the stroke already reads, `var(--cue-style-field-fill,
|
|
180
|
+
* var(--cue-sunken))`: a named fill still wins, a disabled field follows, and
|
|
181
|
+
* no field's class grows by more than this utility's name. A consumer's own
|
|
182
|
+
* field can wear `field-ground` too. */
|
|
183
|
+
@utility field-ground {
|
|
184
|
+
:where([data-field-ground="relative"]) & {
|
|
185
|
+
--cue-sunken: color-mix(in oklab, var(--cue-ground, var(--cue-bg)), var(--cue-style-field-toward, var(--cue-fg)) var(--cue-style-field-step, 6%));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -12,8 +12,28 @@
|
|
|
12
12
|
* The recipe itself, and why its off state is a flat gradient rather than
|
|
13
13
|
* `none`, is documented once in `./_paint`.
|
|
14
14
|
*
|
|
15
|
+
* **The fill is a name first** (spec 2026-10-08-field-ground R2):
|
|
16
|
+
* `--cue-style-field-fill`, declared on no `:root` for the reason
|
|
17
|
+
* `_style-input-face.ts` gives, so with nothing set this resolves to exactly
|
|
18
|
+
* the `--cue-sunken` it always painted. A style set, or any subtree, names it.
|
|
19
|
+
*
|
|
15
20
|
* @internal Not part of the public API.
|
|
16
21
|
*/
|
|
17
|
-
const STROKE_SUNKEN = "border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-sunken),var(--cue-sunken)),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-from,var(--cue-border)),var(--cue-paint-stroke-to,var(--cue-border)))] bg-origin-border [background-clip:padding-box,border-box]";
|
|
22
|
+
const STROKE_SUNKEN = "border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-style-field-fill,var(--cue-sunken)),var(--cue-style-field-fill,var(--cue-sunken))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-from,var(--cue-border)),var(--cue-paint-stroke-to,var(--cue-border)))] bg-origin-border [background-clip:padding-box,border-box]";
|
|
23
|
+
/**
|
|
24
|
+
* The same two layers when the field is disabled: the fill read through
|
|
25
|
+
* `style-disabled-fill`, then the field's own fill, then `sunken`, on
|
|
26
|
+
* `:disabled` and on `[data-disabled]`.
|
|
27
|
+
*
|
|
28
|
+
* **Here, beside the resting recipe, and not in `_style-disabled.ts`** with the
|
|
29
|
+
* other disabled recipes (spec 2026-10-08-field-ground R2). Docgen credits every
|
|
30
|
+
* `--cue-*` in a module to each component that imports it, and the button, the
|
|
31
|
+
* checkbox and the switch import that module for their own disabled recipes:
|
|
32
|
+
* left there, all of them would claim a field's fill they never paint. This
|
|
33
|
+
* module is imported by the field chassis alone, so the credit is exact, and
|
|
34
|
+
* the library ships one file per module, so a module of its own would have
|
|
35
|
+
* cost every page that draws a field one more request.
|
|
36
|
+
*/
|
|
37
|
+
const FIELD_DISABLED_FILL = "disabled:bg-[linear-gradient(var(--cue-style-disabled-fill,var(--cue-style-field-fill,var(--cue-sunken))),var(--cue-style-disabled-fill,var(--cue-style-field-fill,var(--cue-sunken)))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-from,var(--cue-border)),var(--cue-paint-stroke-to,var(--cue-border)))] data-[disabled]:bg-[linear-gradient(var(--cue-style-disabled-fill,var(--cue-style-field-fill,var(--cue-sunken))),var(--cue-style-disabled-fill,var(--cue-style-field-fill,var(--cue-sunken)))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-from,var(--cue-border)),var(--cue-paint-stroke-to,var(--cue-border)))]";
|
|
18
38
|
//#endregion
|
|
19
|
-
export { STROKE_SUNKEN };
|
|
39
|
+
export { FIELD_DISABLED_FILL, STROKE_SUNKEN };
|
|
@@ -12,8 +12,12 @@
|
|
|
12
12
|
* The recipe itself, and why its off state is a flat gradient rather than
|
|
13
13
|
* `none`, is documented once in `./_paint`.
|
|
14
14
|
*
|
|
15
|
+
* It also says what it painted, as `--cue-ground`, for the relative field fill
|
|
16
|
+
* (spec 2026-10-08-field-ground R3): a field inside `[data-field-ground="relative"]`
|
|
17
|
+
* takes its fill one step off the nearest container's ground.
|
|
18
|
+
*
|
|
15
19
|
* @internal Not part of the public API.
|
|
16
20
|
*/
|
|
17
|
-
const STROKE_SURFACE_1 = "border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-surface-1),var(--cue-surface-1)),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-raised-from,var(--cue-paint-stroke-from,var(--cue-border))),var(--cue-paint-stroke-raised-to,var(--cue-paint-stroke-to,var(--cue-border))))] bg-origin-border [background-clip:padding-box,border-box]";
|
|
21
|
+
const STROKE_SURFACE_1 = "border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-surface-1),var(--cue-surface-1)),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-raised-from,var(--cue-paint-stroke-from,var(--cue-border))),var(--cue-paint-stroke-raised-to,var(--cue-paint-stroke-to,var(--cue-border))))] bg-origin-border [background-clip:padding-box,border-box] [--cue-ground:var(--cue-surface-1)]";
|
|
18
22
|
//#endregion
|
|
19
23
|
export { STROKE_SURFACE_1 };
|
|
@@ -33,8 +33,12 @@
|
|
|
33
33
|
* The recipe itself, and why its off state is a flat gradient rather than
|
|
34
34
|
* `none`, is documented once in `./_paint`.
|
|
35
35
|
*
|
|
36
|
+
* It also says what it painted, as `--cue-ground`, for the relative field fill
|
|
37
|
+
* (spec 2026-10-08-field-ground R3): a field inside `[data-field-ground="relative"]`
|
|
38
|
+
* takes its fill one step off the nearest container's ground.
|
|
39
|
+
*
|
|
36
40
|
* @internal Not part of the public API.
|
|
37
41
|
*/
|
|
38
|
-
const STROKE_SURFACE_2 = "border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-style-overlay-ground,var(--cue-surface-2)),var(--cue-style-overlay-ground,var(--cue-surface-2))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-overlay-from,var(--cue-border-overlay)),var(--cue-paint-stroke-overlay-to,var(--cue-border-overlay)))] bg-origin-border [background-clip:padding-box,border-box]";
|
|
42
|
+
const STROKE_SURFACE_2 = "border-transparent border-(length:--cue-paint-stroke-width) bg-[linear-gradient(var(--cue-style-overlay-ground,var(--cue-surface-2)),var(--cue-style-overlay-ground,var(--cue-surface-2))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-overlay-from,var(--cue-border-overlay)),var(--cue-paint-stroke-overlay-to,var(--cue-border-overlay)))] bg-origin-border [background-clip:padding-box,border-box] [--cue-ground:var(--cue-style-overlay-ground,var(--cue-surface-2))]";
|
|
39
43
|
//#endregion
|
|
40
44
|
export { STROKE_SURFACE_2 };
|
|
@@ -33,12 +33,6 @@ const LABEL_DISABLED_OPACITY = "has-[[data-disabled]]:opacity-[var(--cue-style-d
|
|
|
33
33
|
/** A disabled control label's ink, falling back to the label ink it drew (`LABEL_INK`). */
|
|
34
34
|
const LABEL_DISABLED_INK = "has-[[data-disabled]]:text-[color:var(--cue-style-disabled-ink,var(--cue-style-label-ink,var(--cue-fg-muted)))]";
|
|
35
35
|
/**
|
|
36
|
-
* The field chassis's fill when disabled: its own two layers (`STROKE_SUNKEN`),
|
|
37
|
-
* with the fill layer's `sunken` read through `style-disabled-fill`, on
|
|
38
|
-
* `:disabled` and on `[data-disabled]`.
|
|
39
|
-
*/
|
|
40
|
-
const FIELD_DISABLED_FILL = "disabled:bg-[linear-gradient(var(--cue-style-disabled-fill,var(--cue-sunken)),var(--cue-style-disabled-fill,var(--cue-sunken))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-from,var(--cue-border)),var(--cue-paint-stroke-to,var(--cue-border)))] data-[disabled]:bg-[linear-gradient(var(--cue-style-disabled-fill,var(--cue-sunken)),var(--cue-style-disabled-fill,var(--cue-sunken))),linear-gradient(var(--cue-paint-stroke-angle),var(--cue-paint-stroke-from,var(--cue-border)),var(--cue-paint-stroke-to,var(--cue-border)))]";
|
|
41
|
-
/**
|
|
42
36
|
* The button tones' fill and ink when disabled, each falling back to the tone's own resting fill and ink.
|
|
43
37
|
* The two transparent tones keep their ground and take an edge instead (`style-disabled-edge`, falling
|
|
44
38
|
* back to the edge each drew): stripe.com's disabled icon button stays on its ground and draws a 1px rim
|
|
@@ -67,4 +61,4 @@ const CHECK_DISABLED = "data-[disabled]:bg-[color:var(--cue-style-disabled-fill,
|
|
|
67
61
|
/** The switch's track when disabled, unchecked and checked, each state keeping its own fallback. */
|
|
68
62
|
const SWITCH_DISABLED_TRACK = "data-[disabled]:bg-[color:var(--cue-style-disabled-fill,var(--cue-surface-3))] data-[disabled]:data-[checked]:bg-[color:var(--cue-style-disabled-fill,var(--cue-accent))]";
|
|
69
63
|
//#endregion
|
|
70
|
-
export { CHECK_DISABLED, DATA_DISABLED_OPACITY, DISABLED_OPACITY, DISABLED_TONES,
|
|
64
|
+
export { CHECK_DISABLED, DATA_DISABLED_OPACITY, DISABLED_OPACITY, DISABLED_TONES, LABEL_DISABLED_INK, LABEL_DISABLED_OPACITY, SWITCH_DISABLED_TRACK };
|
|
@@ -9,18 +9,24 @@ import "react";
|
|
|
9
9
|
* - `aui` — supersede mode. `@cueplusplus/ui/elements.css` re-points those same
|
|
10
10
|
* tokens to assistant-ui's own values under `[data-cue-skin="aui"]`, so one
|
|
11
11
|
* DOM paints two ways with no branching in any component.
|
|
12
|
+
* - `cursor` — the same mechanism with Cursor's agent-pane values, under
|
|
13
|
+
* `[data-cue-skin="cursor"]`: the gallery study's palette, published so a
|
|
14
|
+
* consumer wears it rather than copying it. Its light and dark halves follow
|
|
15
|
+
* `data-mode`, as assistant-ui's do.
|
|
12
16
|
*/
|
|
13
|
-
type AgentSkin = "cue" | "aui";
|
|
17
|
+
type AgentSkin = "cue" | "aui" | "cursor";
|
|
14
18
|
/**
|
|
15
19
|
* How far the supersede island goes: colour only, or colour and geometry.
|
|
16
20
|
*
|
|
17
21
|
* - `cue-metrics` — the default. Colour is re-pointed; cue's type scale, radius
|
|
18
22
|
* ladder and density ladder still apply, so an island tracks the density of
|
|
19
23
|
* the console around it.
|
|
20
|
-
* - `upstream` —
|
|
21
|
-
* 12 / 11 px type
|
|
22
|
-
*
|
|
23
|
-
* element exactly as its authors
|
|
24
|
+
* - `upstream` — the skin's own geometry too. Under `aui` that is
|
|
25
|
+
* assistant-ui's radii, their literal 13.5 / 12 / 11 px type and `--spacing`
|
|
26
|
+
* pinned at Tailwind's default, so density stops at the island edge, which is
|
|
27
|
+
* the point: this is the mode for showing an element exactly as its authors
|
|
28
|
+
* drew it. Under `cursor` it is Cursor's corners and its two faces. Cursor's
|
|
29
|
+
* type sizes and spacing were never recorded, so those stay cue's.
|
|
24
30
|
*/
|
|
25
31
|
type AgentFidelity = "upstream" | "cue-metrics";
|
|
26
32
|
//#endregion
|
|
@@ -5,17 +5,18 @@
|
|
|
5
5
|
"importPath": "@cueplusplus/ui/elements",
|
|
6
6
|
"peerDependencies": [],
|
|
7
7
|
"clientOnly": true,
|
|
8
|
-
"description": "The supersede island: one subtree, painted by a different set of values.\n\nRenders a plain `<div data-slot=\"agent-surface\" data-cue-skin=\"…\"\ndata-cue-fidelity=\"…\">` and publishes the same pair on React context. The attributes do the work —\n`@cueplusplus/ui/elements.css` re-declares, under them, the `--cue-*` tokens\nthe whole elements family reads, and custom properties inherit, so every\nelement inside repaints with no prop threading and no branch in any\ncomponent. The context exists for the one place that cannot see the DOM: an\noverlay portaled to `<body>` from inside the island, which\n{@link useCuePortalProps } stamps from the same values.\n\nTwo things this is not. It is not a theme — `data-theme`, `data-mode` and\n`data-density` are untouched, and a light app keeps a light island. And it is\nnot needed for cue mode: the elements were rewritten onto cue's tokens by the\nvendoring codemod, so `skin=\"cue\"` is what they already do. Reach for this to\nshow an element the way assistant-ui drew it,
|
|
8
|
+
"description": "The supersede island: one subtree, painted by a different set of values.\n\nRenders a plain `<div data-slot=\"agent-surface\" data-cue-skin=\"…\"\ndata-cue-fidelity=\"…\">` and publishes the same pair on React context. The attributes do the work —\n`@cueplusplus/ui/elements.css` re-declares, under them, the `--cue-*` tokens\nthe whole elements family reads, and custom properties inherit, so every\nelement inside repaints with no prop threading and no branch in any\ncomponent. The context exists for the one place that cannot see the DOM: an\noverlay portaled to `<body>` from inside the island, which\n{@link useCuePortalProps } stamps from the same values.\n\nTwo things this is not. It is not a theme — `data-theme`, `data-mode` and\n`data-density` are untouched, and a light app keeps a light island. And it is\nnot needed for cue mode: the elements were rewritten onto cue's tokens by the\nvendoring codemod, so `skin=\"cue\"` is what they already do. Reach for this to\nshow an element the way assistant-ui drew it, to hand a chat panel back to\nupstream's design language inside a console that is otherwise cue's, or to\nwear Cursor's agent pane with `skin=\"cursor\"` rather than copying its palette.\n\nWhat an `aui` island re-points is this family's own vocabulary rather than the\nwhole token contract: `--cue-busy`, `--cue-info`, `--cue-selection`,\n`--cue-focus`, `--cue-scrim` and every derived `*-soft` / `*-border` stay on\nthe console's theme. Nothing in the elements group reads them, so the island\nis complete for what it is for — but a *cue* component placed inside one (a\n`Chip tone=\"busy\"`, a `Toast`) paints half in each palette, and the\nderivations cannot be made to follow at all: they are `color-mix()` values\nresolved on the theme block and inherited as answers. `elements.css` carries\nthe full accounting beside the values themselves.\n\n`elements.css` is a consumer import: `@import \"@cueplusplus/ui/elements.css\";`\nafter the main stylesheet. Without it a `skin=\"aui\"` island simply stays in\ncue's palette.",
|
|
9
9
|
"props": [
|
|
10
10
|
{
|
|
11
11
|
"name": "skin",
|
|
12
|
-
"type": "\"cue\" | \"aui\"",
|
|
12
|
+
"type": "\"cursor\" | \"cue\" | \"aui\"",
|
|
13
13
|
"required": false,
|
|
14
14
|
"defaultValue": "cue",
|
|
15
|
-
"description": "Which value-set paints the subtree: `cue` (the default)
|
|
15
|
+
"description": "Which value-set paints the subtree: `cue` (the default); `aui`, which\ninstalls assistant-ui's own inks, grounds and hues; or `cursor`, Cursor's\nagent-pane values. Both halves of each follow `data-mode`.",
|
|
16
16
|
"control": {
|
|
17
17
|
"kind": "enum",
|
|
18
18
|
"members": [
|
|
19
|
+
"cursor",
|
|
19
20
|
"cue",
|
|
20
21
|
"aui"
|
|
21
22
|
]
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
"type": "\"upstream\" | \"cue-metrics\"",
|
|
27
28
|
"required": false,
|
|
28
29
|
"defaultValue": "cue-metrics",
|
|
29
|
-
"description": "How much a supersede island re-points: `cue-metrics` (the default, colour\nonly) or `upstream`, which also pins
|
|
30
|
+
"description": "How much a supersede island re-points: `cue-metrics` (the default, colour\nonly) or `upstream`, which also pins the skin's own geometry. For `aui`\nthat is its radii, literal type sizes and spacing, so the density ladder\nstops at the island edge; for `cursor`, its corners and faces.",
|
|
30
31
|
"control": {
|
|
31
32
|
"kind": "enum",
|
|
32
33
|
"members": [
|