@ciridae/ui 1.0.4 → 1.0.9
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/README.md +3 -2
- package/dist/chat/conversation-source.d.ts +1 -3
- package/dist/chat/message-text.js +6 -6
- package/dist/chat/use-chat-conversation.d.ts +7 -2
- package/dist/chat/use-chat-conversation.js +2 -1
- package/dist/components/activity-feed.d.ts +0 -1
- package/dist/components/activity-feed.js +6 -7
- package/dist/components/agent-work.d.ts +5 -1
- package/dist/components/agent-work.js +27 -13
- package/dist/components/app-frame.d.ts +3 -17
- package/dist/components/app-frame.js +11 -30
- package/dist/components/app-navigation.d.ts +5 -6
- package/dist/components/app-navigation.js +70 -40
- package/dist/components/badge.d.ts +0 -4
- package/dist/components/badge.js +17 -27
- package/dist/components/bulk-action-bar.js +2 -2
- package/dist/components/button.js +41 -50
- package/dist/components/calendar.js +5 -8
- package/dist/components/centered-page.js +4 -4
- package/dist/components/chart.js +3 -4
- package/dist/components/chat-client-source.js +55 -34
- package/dist/components/chat-page.js +1 -1
- package/dist/components/chat-sheet.d.ts +30 -20
- package/dist/components/chat-sheet.js +112 -54
- package/dist/components/chat.d.ts +27 -56
- package/dist/components/chat.js +153 -132
- package/dist/components/checkbox-item.js +4 -4
- package/dist/components/checkbox-list.js +6 -6
- package/dist/components/chip.js +2 -2
- package/dist/components/collapsible.js +3 -3
- package/dist/components/color-theme.d.ts +3 -6
- package/dist/components/color-theme.js +10 -11
- package/dist/components/column-settings.js +3 -3
- package/dist/components/command-menu.d.ts +1 -2
- package/dist/components/command-menu.js +56 -77
- package/dist/components/command-palette.js +5 -2
- package/dist/components/copyable-id.js +5 -5
- package/dist/components/data-display.d.ts +1 -7
- package/dist/components/data-display.js +32 -55
- package/dist/components/data-grid.d.ts +4 -7
- package/dist/components/data-grid.js +106 -90
- package/dist/components/date-range-picker.js +4 -5
- package/dist/components/document-viewer.js +23 -23
- package/dist/components/drawer.d.ts +2 -1
- package/dist/components/drawer.js +45 -20
- package/dist/components/dropzone.js +13 -13
- package/dist/components/editable-field.d.ts +2 -7
- package/dist/components/editable-field.js +14 -27
- package/dist/components/email-input.js +2 -3
- package/dist/components/environment-frame.js +7 -7
- package/dist/components/expandable-text.js +2 -2
- package/dist/components/feedback-screenshot.js +7 -7
- package/dist/components/feedback-sheet.js +8 -8
- package/dist/components/filter-bar.js +41 -27
- package/dist/components/form-controls.d.ts +3 -6
- package/dist/components/form-controls.js +15 -22
- package/dist/components/form-layout.d.ts +6 -6
- package/dist/components/form-layout.js +10 -16
- package/dist/components/glass-menu.d.ts +2 -0
- package/dist/components/glass-menu.js +14 -18
- package/dist/components/gradient-edge.d.ts +0 -1
- package/dist/components/gradient-edge.js +8 -9
- package/dist/components/icon.js +1 -1
- package/dist/components/input.js +18 -17
- package/dist/components/keycap.d.ts +2 -6
- package/dist/components/keycap.js +4 -12
- package/dist/components/layout.js +11 -10
- package/dist/components/lightbox.js +8 -8
- package/dist/components/link.js +1 -1
- package/dist/components/locale.d.ts +23 -7
- package/dist/components/locale.js +19 -7
- package/dist/components/log-entry.d.ts +2 -14
- package/dist/components/log-entry.js +11 -22
- package/dist/components/log-list.js +1 -1
- package/dist/components/mention-input.js +13 -14
- package/dist/components/menu.d.ts +7 -4
- package/dist/components/menu.js +23 -10
- package/dist/components/meter.d.ts +2 -3
- package/dist/components/meter.js +12 -16
- package/dist/components/navigation.d.ts +0 -7
- package/dist/components/navigation.js +3 -12
- package/dist/components/notification-tray.js +7 -7
- package/dist/components/overlays.d.ts +5 -2
- package/dist/components/overlays.js +24 -24
- package/dist/components/panel.js +3 -3
- package/dist/components/progress.js +2 -2
- package/dist/components/radio-card.d.ts +1 -1
- package/dist/components/radio-card.js +9 -9
- package/dist/components/record.d.ts +2 -4
- package/dist/components/record.js +19 -32
- package/dist/components/scroll-area.js +10 -10
- package/dist/components/segmented-bar.js +9 -9
- package/dist/components/select.d.ts +3 -5
- package/dist/components/select.js +26 -44
- package/dist/components/settings.js +1 -1
- package/dist/components/shell-skeleton.js +1 -1
- package/dist/components/shell.d.ts +1 -1
- package/dist/components/shell.js +69 -24
- package/dist/components/side-panel.js +3 -3
- package/dist/components/sidebar.d.ts +0 -5
- package/dist/components/sidebar.js +25 -33
- package/dist/components/single-line-text.js +3 -4
- package/dist/components/site-banner.js +4 -4
- package/dist/components/skeleton.js +19 -22
- package/dist/components/skeletons.d.ts +0 -3
- package/dist/components/skeletons.js +5 -10
- package/dist/components/stages.d.ts +6 -3
- package/dist/components/stages.js +77 -105
- package/dist/components/stat-card.d.ts +2 -5
- package/dist/components/stat-card.js +23 -31
- package/dist/components/status-banner.js +6 -6
- package/dist/components/status.js +3 -3
- package/dist/components/steps.js +2 -2
- package/dist/components/switch.js +1 -1
- package/dist/components/tabs.js +15 -18
- package/dist/components/theme-customizer.d.ts +5 -8
- package/dist/components/theme-customizer.js +9 -41
- package/dist/components/theme-toggle.d.ts +0 -1
- package/dist/components/theme-toggle.js +6 -11
- package/dist/components/toast.d.ts +1 -7
- package/dist/components/toast.js +19 -22
- package/dist/components/user-chip.js +8 -8
- package/dist/components/wizard.js +6 -4
- package/dist/preset.d.ts +1 -2
- package/dist/preset.js +41 -89
- package/dist/styled-system/css/conditions.mjs +1 -1
- package/dist/styled-system/css/css.mjs +1 -1
- package/dist/styled-system/styles.css +820 -1297
- package/dist/styled-system/tokens/index.mjs +78 -1926
- package/dist/styled-system/tokens/tokens.d.ts +18 -33
- package/dist/styled-system/types/conditions.d.ts +0 -74
- package/dist/styled-system/types/prop-type.d.ts +15 -40
- package/dist/styled-system/types/style-props.d.ts +705 -705
- package/dist/theme/color.d.ts +0 -1
- package/dist/theme/color.js +0 -16
- package/dist/theme/derive.d.ts +3 -3
- package/dist/theme/derive.js +9 -32
- package/dist/theme/index.d.ts +1 -2
- package/dist/theme/index.js +3 -5
- package/dist/theme/options.d.ts +2 -4
- package/dist/theme/options.js +0 -1
- package/dist/theme/{palettes.d.ts → palette.d.ts} +12 -23
- package/dist/theme/palette.js +127 -0
- package/dist/theme/tokens.d.ts +8 -13
- package/dist/theme/tokens.js +39 -92
- package/package.json +1 -1
- package/dist/theme/palettes.js +0 -254
|
@@ -29,28 +29,28 @@ export function Trend({ direction, tone = "neutral", arrow = true, children }) {
|
|
|
29
29
|
const Arrow = TREND_ARROWS[direction];
|
|
30
30
|
return (_jsxs("span", { className: trend, "data-tone": tone, "data-ciridae-ui": "", children: [arrow && _jsx(Arrow, { className: icon({ size: "compact" }), weight: "bold", "aria-hidden": "true" }), _jsx("span", { className: trendText, "data-trend-text": "", children: children })] }));
|
|
31
31
|
}
|
|
32
|
-
/*
|
|
33
|
-
* Sparkline: drawn into a 100x100 box that stretches to its plot. The plot fills the box unless
|
|
34
|
-
* `--sparkline-plot-width` and `--sparkline-plot-height` size it, at the box's foot and start, so
|
|
35
|
-
* the end point's ring has room above and after the line.
|
|
36
|
-
*/
|
|
32
|
+
/* The plot fills the box unless `--sparkline-plot-width` and `--sparkline-plot-height` size it, at the box's foot and start, so the end point's ring has room above and after the line. */
|
|
37
33
|
const plot = css({ position: "relative", color: "chart.trend" });
|
|
38
34
|
const plotArea = css({
|
|
39
35
|
position: "absolute",
|
|
40
|
-
insetInlineStart: "
|
|
41
|
-
bottom: "
|
|
36
|
+
insetInlineStart: "none",
|
|
37
|
+
bottom: "none",
|
|
42
38
|
width: "var(--sparkline-plot-width, 100%)",
|
|
43
39
|
height: "var(--sparkline-plot-height, 100%)",
|
|
44
40
|
});
|
|
45
41
|
const svg = css({
|
|
46
42
|
position: "absolute",
|
|
47
|
-
inset: "
|
|
48
|
-
width: "
|
|
49
|
-
height: "
|
|
43
|
+
inset: "none",
|
|
44
|
+
width: "full",
|
|
45
|
+
height: "full",
|
|
50
46
|
overflow: "visible",
|
|
51
47
|
});
|
|
52
48
|
// The area under the line, clipped to it, so its gradient runs top to foot whatever the box.
|
|
53
|
-
const area = css({
|
|
49
|
+
const area = css({
|
|
50
|
+
position: "absolute",
|
|
51
|
+
inset: "none",
|
|
52
|
+
background: "[token(gradients.chart.area)]",
|
|
53
|
+
});
|
|
54
54
|
// The ring is the tile's face, so the point reads as cut out of the line.
|
|
55
55
|
const endPoint = css({
|
|
56
56
|
position: "absolute",
|
|
@@ -58,19 +58,15 @@ const endPoint = css({
|
|
|
58
58
|
background: "chart.trend",
|
|
59
59
|
borderStyle: "solid",
|
|
60
60
|
borderColor: "bg.surface",
|
|
61
|
-
translate: "-50% -50%",
|
|
61
|
+
translate: "[-50% -50%]",
|
|
62
62
|
});
|
|
63
|
-
// No run to draw: a dashed rule across the middle holds the line's place.
|
|
64
63
|
const noRun = css({
|
|
65
64
|
position: "absolute",
|
|
66
|
-
insetInline: "
|
|
67
|
-
top: "50%",
|
|
65
|
+
insetInline: "none",
|
|
66
|
+
top: "[50%]",
|
|
68
67
|
borderTop: "2px dashed token(colors.border.divider)",
|
|
69
68
|
});
|
|
70
|
-
/**
|
|
71
|
-
* A run of values as a line filling its box; decorative, as the figure beside it says what it
|
|
72
|
-
* shows. Under two values there is no line, and a dashed rule stands in for it.
|
|
73
|
-
*/
|
|
69
|
+
/** Decorative, as the figure beside it says what it shows. Under two values there is no line, and a dashed rule stands in for it. */
|
|
74
70
|
export function Sparkline({ values, low: ownLow, high: ownHigh, strokeWidth = 1.5, endPointSize = 6, className, ...props }) {
|
|
75
71
|
if (values.length < 2)
|
|
76
72
|
return (_jsx("div", { "aria-hidden": "true", ...props, className: cx(plot, className), "data-ciridae-ui": "", children: _jsx("span", { className: noRun }) }));
|
|
@@ -84,19 +80,14 @@ export function Sparkline({ values, low: ownLow, high: ownHigh, strokeWidth = 1.
|
|
|
84
80
|
const lastTop = tops[tops.length - 1] ?? 100;
|
|
85
81
|
const areaOutline = tops.map((top, index) => `${index * step}% ${top}%`).join(", ");
|
|
86
82
|
return (_jsx("div", { "aria-hidden": "true", ...props, className: cx(plot, className), "data-ciridae-ui": "", children: _jsxs("span", { className: plotArea, children: [_jsx("span", { className: area, style: { clipPath: `polygon(0% 100%, ${areaOutline}, 100% 100%)` } }), _jsx("svg", { className: svg, viewBox: "0 0 100 100", preserveAspectRatio: "none", children: _jsx("polyline", { points: points, fill: "none", stroke: "currentColor", strokeWidth: strokeWidth, strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) }), _jsx("span", { className: endPoint, style: {
|
|
87
|
-
|
|
83
|
+
left: "100%",
|
|
88
84
|
top: `${lastTop}%`,
|
|
89
85
|
width: endPointSize,
|
|
90
86
|
height: endPointSize,
|
|
91
87
|
borderWidth: strokeWidth,
|
|
92
88
|
} })] }) }));
|
|
93
89
|
}
|
|
94
|
-
/*
|
|
95
|
-
* Metric card: a figure with its change, and its run beside it. A tile in a row of them drops the
|
|
96
|
-
* card for a rule on its leading edge, or for nothing, and its label steps back to the label grey.
|
|
97
|
-
* The change's words are the label grey too, the kit's Stat tile: its arrow carries the tone.
|
|
98
|
-
* The run sits in the kit's 88x32 chart slot, its line in the slot's lower 84x25.
|
|
99
|
-
*/
|
|
90
|
+
/* The label keeps the primary ink, as Foundations' type rule has it where the kit's Stat tile draws it grey; the change's words are the label grey, its arrow in the tone. The run sits in the kit's 88x32 chart slot, its line in the slot's lower 84x25. */
|
|
100
91
|
const metricCard = cva({
|
|
101
92
|
base: {
|
|
102
93
|
display: "flex",
|
|
@@ -127,13 +118,11 @@ const metricCard = cva({
|
|
|
127
118
|
border: "0",
|
|
128
119
|
borderInlineStart: "1px solid token(colors.border.panel)",
|
|
129
120
|
background: "transparent",
|
|
130
|
-
"& [data-metric-label]": { color: "fg.label" },
|
|
131
121
|
},
|
|
132
122
|
none: {
|
|
133
123
|
minWidth: "0",
|
|
134
124
|
border: "0",
|
|
135
125
|
background: "transparent",
|
|
136
|
-
"& [data-metric-label]": { color: "fg.label" },
|
|
137
126
|
},
|
|
138
127
|
},
|
|
139
128
|
},
|
|
@@ -152,7 +141,7 @@ const metricValue = css({
|
|
|
152
141
|
lineHeight: "tight",
|
|
153
142
|
fontVariantNumeric: "tabular-nums",
|
|
154
143
|
});
|
|
155
|
-
export function MetricCard({ label, value, change, sparkline, onSelect, href, divider = "card", render, className, ...props }) {
|
|
144
|
+
export function MetricCard({ label, value, change, sparkline, onSelect, onClick, href, divider = "card", render, className, ...props }) {
|
|
156
145
|
return useRender({
|
|
157
146
|
defaultTagName: href !== undefined ? "a" : onSelect !== undefined ? "button" : "div",
|
|
158
147
|
render,
|
|
@@ -163,10 +152,13 @@ export function MetricCard({ label, value, change, sparkline, onSelect, href, di
|
|
|
163
152
|
? { type: "button" }
|
|
164
153
|
: {}),
|
|
165
154
|
...props,
|
|
166
|
-
onClick:
|
|
155
|
+
onClick: (event) => {
|
|
156
|
+
onClick?.(event);
|
|
157
|
+
onSelect?.();
|
|
158
|
+
},
|
|
167
159
|
className: cx(metricCard({ divider }), className),
|
|
168
160
|
"data-ciridae-ui": "",
|
|
169
|
-
children: (_jsxs(_Fragment, { children: [_jsxs("span", { className: metricCopy, children: [_jsx("span", { className: metricLabel,
|
|
161
|
+
children: (_jsxs(_Fragment, { children: [_jsxs("span", { className: metricCopy, children: [_jsx("span", { className: metricLabel, children: label }), _jsx("span", { className: metricValue, children: value }), change && _jsx(Trend, { ...change })] }), sparkline && _jsx(Sparkline, { values: sparkline, "data-sparkline": "" })] })),
|
|
170
162
|
},
|
|
171
163
|
});
|
|
172
164
|
}
|
|
@@ -15,7 +15,7 @@ const banner = cva({
|
|
|
15
15
|
display: "flex",
|
|
16
16
|
alignItems: "flex-start",
|
|
17
17
|
gap: "layout.controlGap",
|
|
18
|
-
width: "
|
|
18
|
+
width: "full",
|
|
19
19
|
color: "fg.primary",
|
|
20
20
|
fontSize: "body",
|
|
21
21
|
lineHeight: "compact",
|
|
@@ -62,7 +62,7 @@ const bannerIcon = cva({
|
|
|
62
62
|
display: "inline-flex",
|
|
63
63
|
flexShrink: "0",
|
|
64
64
|
// Centred on the first line of text.
|
|
65
|
-
height: "1lh",
|
|
65
|
+
height: "[1lh]",
|
|
66
66
|
alignItems: "center",
|
|
67
67
|
},
|
|
68
68
|
variants: {
|
|
@@ -80,20 +80,20 @@ const message = css({ flex: "1", minWidth: "0", overflowWrap: "anywhere" });
|
|
|
80
80
|
const titleStyle = css({ fontWeight: "medium" });
|
|
81
81
|
const detailStyle = css({
|
|
82
82
|
color: "fg.muted",
|
|
83
|
-
"[data-emphasis=filled] &": { color: "inherit", opacity: "0.85" },
|
|
83
|
+
"[data-emphasis=filled] &": { color: "[inherit]", opacity: "[0.85]" },
|
|
84
84
|
});
|
|
85
85
|
// An action reads as a link at the end of the message; a filled banner underlines it.
|
|
86
86
|
const actionStyle = css({
|
|
87
87
|
display: "inline-flex",
|
|
88
88
|
marginInlineStart: "control.iconGap",
|
|
89
89
|
color: "accent.brand",
|
|
90
|
-
"[data-emphasis=filled] &": { color: "inherit", textDecoration: "underline" },
|
|
90
|
+
"[data-emphasis=filled] &": { color: "[inherit]", textDecoration: "underline" },
|
|
91
91
|
"& :is(a, button)": {
|
|
92
92
|
padding: "none",
|
|
93
93
|
height: "auto",
|
|
94
94
|
border: "0",
|
|
95
95
|
background: "transparent",
|
|
96
|
-
color: "inherit",
|
|
96
|
+
color: "[inherit]",
|
|
97
97
|
font: "inherit",
|
|
98
98
|
textDecoration: "inherit",
|
|
99
99
|
cursor: "pointer",
|
|
@@ -108,7 +108,7 @@ const dismissButton = css({
|
|
|
108
108
|
flexShrink: "0",
|
|
109
109
|
width: "control.shortcut",
|
|
110
110
|
height: "control.shortcut",
|
|
111
|
-
marginBlock: "calc((1lh - token(sizes.control.shortcut)) / 2)",
|
|
111
|
+
marginBlock: "[calc((1lh - token(sizes.control.shortcut)) / 2)]",
|
|
112
112
|
padding: "none",
|
|
113
113
|
border: "0",
|
|
114
114
|
borderRadius: "round",
|
|
@@ -47,8 +47,8 @@ const dotBox = css({
|
|
|
47
47
|
fontSize: "icon.small",
|
|
48
48
|
alignItems: "center",
|
|
49
49
|
justifyContent: "center",
|
|
50
|
-
width: "1em",
|
|
51
|
-
height: "1em",
|
|
50
|
+
width: "[1em]",
|
|
51
|
+
height: "[1em]",
|
|
52
52
|
});
|
|
53
53
|
const liveIndicator = css({
|
|
54
54
|
boxShadow: "indicator.live",
|
|
@@ -83,7 +83,7 @@ const pendingText = css({
|
|
|
83
83
|
"&[data-placement=centered]": {
|
|
84
84
|
display: "flex",
|
|
85
85
|
justifyContent: "center",
|
|
86
|
-
width: "
|
|
86
|
+
width: "full",
|
|
87
87
|
minHeight: "emptyState.minimum",
|
|
88
88
|
},
|
|
89
89
|
});
|
package/dist/components/steps.js
CHANGED
|
@@ -27,14 +27,14 @@ const number = css({
|
|
|
27
27
|
color: "fg.primary",
|
|
28
28
|
fontSize: "caption",
|
|
29
29
|
fontVariantNumeric: "tabular-nums",
|
|
30
|
-
lineHeight: "
|
|
30
|
+
lineHeight: "tight",
|
|
31
31
|
});
|
|
32
32
|
const content = css({ display: "grid", gap: "layout.controlGap", minWidth: "0" });
|
|
33
33
|
const stepTitle = css({ fontWeight: "medium" });
|
|
34
34
|
const muted = css({ color: "fg.muted", fontSize: "caption" });
|
|
35
35
|
const screenshot = css({
|
|
36
36
|
display: "block",
|
|
37
|
-
maxWidth: "
|
|
37
|
+
maxWidth: "full",
|
|
38
38
|
maxHeight: "steps.image",
|
|
39
39
|
width: "auto",
|
|
40
40
|
height: "auto",
|
|
@@ -25,7 +25,7 @@ const thumb = css({
|
|
|
25
25
|
height: "control.knob",
|
|
26
26
|
borderRadius: "round",
|
|
27
27
|
background: "bg.knob",
|
|
28
|
-
transitionProperty: "transform",
|
|
28
|
+
transitionProperty: "[transform]",
|
|
29
29
|
transitionDuration: "fast",
|
|
30
30
|
"&[data-checked]": {
|
|
31
31
|
transform: "translateX(calc(token(sizes.control.compact) - 2 * token(spacing.control.trackInset) - token(sizes.control.knob)))",
|
package/dist/components/tabs.js
CHANGED
|
@@ -9,22 +9,21 @@ import { useCiridaeLocale } from "./locale.js";
|
|
|
9
9
|
import { Menu } from "./menu.js";
|
|
10
10
|
// Shrinkable by default, so a tab row in a flex or grid row scrolls inside itself rather than
|
|
11
11
|
// widening the page.
|
|
12
|
-
const root = css({ minWidth: "0", maxWidth: "
|
|
12
|
+
const root = css({ minWidth: "0", maxWidth: "full" });
|
|
13
13
|
export function TabsRoot({ className, ...props }) {
|
|
14
14
|
return _jsx(BaseTabs.Root, { ...props, className: cx(root, className) });
|
|
15
15
|
}
|
|
16
16
|
export const TabsPanel = BaseTabs.Panel;
|
|
17
17
|
const list = css({
|
|
18
18
|
display: "flex",
|
|
19
|
-
maxWidth: "
|
|
19
|
+
maxWidth: "full",
|
|
20
20
|
alignItems: "center",
|
|
21
21
|
gap: "none",
|
|
22
22
|
overflowX: "auto",
|
|
23
|
-
scrollbarWidth: "none",
|
|
23
|
+
scrollbarWidth: "[none]",
|
|
24
24
|
});
|
|
25
|
-
/** Finalization "View tabs": tabs sit inside a grey pill well with a hairline inset. */
|
|
26
25
|
const containedList = css({
|
|
27
|
-
width: "max-content",
|
|
26
|
+
width: "[max-content]",
|
|
28
27
|
padding: "control.trackInset",
|
|
29
28
|
border: "1px solid token(colors.border.control)",
|
|
30
29
|
borderRadius: "pill",
|
|
@@ -64,18 +63,17 @@ const tab = css({
|
|
|
64
63
|
cursor: "pointer",
|
|
65
64
|
flexShrink: "0",
|
|
66
65
|
"&[data-icon-tone=bronze] svg": { color: "accent.bronze" },
|
|
67
|
-
|
|
68
|
-
_before: { display: "none", background: "token(gradients.border.raised)" },
|
|
66
|
+
_before: { display: "none", background: "[token(gradients.border.raised)]" },
|
|
69
67
|
_hover: {
|
|
70
68
|
background: "bg.controlHover",
|
|
71
69
|
color: "fg.primary",
|
|
72
|
-
"& svg": { color: "inherit" },
|
|
70
|
+
"& svg": { color: "[inherit]" },
|
|
73
71
|
},
|
|
74
72
|
"&[data-active]": {
|
|
75
|
-
background: "token(gradients.raised)",
|
|
73
|
+
background: "[token(gradients.raised)]",
|
|
76
74
|
boxShadow: "soft",
|
|
77
75
|
color: "fg.primary",
|
|
78
|
-
"& svg": { color: "inherit" },
|
|
76
|
+
"& svg": { color: "[inherit]" },
|
|
79
77
|
_before: { display: "block" },
|
|
80
78
|
},
|
|
81
79
|
// On a face, the words read in the primary ink in light, where only the open tab is raised, and
|
|
@@ -92,12 +90,11 @@ const tab = css({
|
|
|
92
90
|
border: "0",
|
|
93
91
|
background: "transparent",
|
|
94
92
|
_hover: { background: "transparent" },
|
|
95
|
-
"&[data-active]": { background: "transparent", boxShadow: "none" },
|
|
96
|
-
// No edge either: the open word is the only mark.
|
|
93
|
+
"&[data-active]": { background: "transparent", boxShadow: "[none]" },
|
|
97
94
|
"&::before, &:hover::before, &[data-active]::before": { display: "none" },
|
|
98
95
|
_focusVisible: {
|
|
99
|
-
boxShadow: "none",
|
|
100
|
-
outline: "
|
|
96
|
+
boxShadow: "[none]",
|
|
97
|
+
outline: "0",
|
|
101
98
|
color: "fg.primary",
|
|
102
99
|
textDecoration: "underline",
|
|
103
100
|
textUnderlineOffset: "3px",
|
|
@@ -108,13 +105,13 @@ const tab = css({
|
|
|
108
105
|
paddingInline: "none",
|
|
109
106
|
border: "0",
|
|
110
107
|
borderBottom: "2px solid transparent",
|
|
111
|
-
borderRadius: "
|
|
112
|
-
marginBottom: "-1px",
|
|
108
|
+
borderRadius: "none",
|
|
109
|
+
marginBottom: "[-1px]",
|
|
113
110
|
background: "transparent",
|
|
114
111
|
_hover: { background: "transparent" },
|
|
115
112
|
"&[data-active]": {
|
|
116
113
|
background: "transparent",
|
|
117
|
-
boxShadow: "none",
|
|
114
|
+
boxShadow: "[none]",
|
|
118
115
|
borderBottomColor: "fg.primary",
|
|
119
116
|
},
|
|
120
117
|
"&::before, &:hover::before, &[data-active]::before": { display: "none" },
|
|
@@ -225,7 +222,7 @@ const bar = css({
|
|
|
225
222
|
flexWrap: "nowrap",
|
|
226
223
|
gap: "layout.contentGap",
|
|
227
224
|
minWidth: "0",
|
|
228
|
-
"& > :first-child": { flex: "1 1 auto", minWidth: "0", maxWidth: "
|
|
225
|
+
"& > :first-child": { flex: "[1 1 auto]", minWidth: "0", maxWidth: "full" },
|
|
229
226
|
_phone: { flexWrap: "wrap" },
|
|
230
227
|
});
|
|
231
228
|
const barActions = css({
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type ComponentProps } from "react";
|
|
2
|
-
import { type PaletteName } from "../theme/palettes.js";
|
|
3
2
|
import { type CiridaeLabels } from "./locale.js";
|
|
4
3
|
import type { CiridaeTheme } from "../theme/options.js";
|
|
5
4
|
/** A face the app offers: its id, its name in the menu and its CSS family. */
|
|
@@ -14,15 +13,13 @@ export type ThemeFontOptions = {
|
|
|
14
13
|
sans: readonly ThemeFontOption[];
|
|
15
14
|
mono: readonly ThemeFontOption[];
|
|
16
15
|
};
|
|
17
|
-
/** The palette and the faces, by font id. */
|
|
18
16
|
export type ThemeCustomization = {
|
|
19
|
-
palette: PaletteName;
|
|
20
17
|
displayFont: string;
|
|
21
18
|
sansFont: string;
|
|
22
19
|
monoFont: string;
|
|
23
20
|
};
|
|
24
|
-
/** The
|
|
25
|
-
export declare function themeCustomizationTheme(value: ThemeCustomization, fonts: ThemeFontOptions): Pick<CiridaeTheme, "
|
|
21
|
+
/** The font families `ThemeProvider` (and `createCiridaePreset`) take for `value`. */
|
|
22
|
+
export declare function themeCustomizationTheme(value: ThemeCustomization, fonts: ThemeFontOptions): Pick<CiridaeTheme, "fonts">;
|
|
26
23
|
/** A stored customization read back field by field, taking `fallback`'s for any it lacks. */
|
|
27
24
|
export declare function parseThemeCustomization(stored: unknown, fallback: ThemeCustomization, fonts: ThemeFontOptions): ThemeCustomization;
|
|
28
25
|
export type UseThemeCustomizationOptions<Value extends ThemeCustomization> = {
|
|
@@ -34,15 +31,15 @@ export type UseThemeCustomizationOptions<Value extends ThemeCustomization> = {
|
|
|
34
31
|
parse: (stored: unknown) => Value;
|
|
35
32
|
};
|
|
36
33
|
/**
|
|
37
|
-
* A customization the app holds at its root: the value, a setter, and the `
|
|
38
|
-
*
|
|
34
|
+
* A customization the app holds at its root: the value, a setter, and the `fonts` to pass
|
|
35
|
+
* `ThemeProvider`. With `persistKey` it survives reloads; anything the app keeps beside
|
|
39
36
|
* the theme in `Value`, such as a brand name, is stored with it.
|
|
40
37
|
*/
|
|
41
38
|
export declare function useThemeCustomization<Value extends ThemeCustomization>({ defaultValue, fonts, persistKey, parse, }: UseThemeCustomizationOptions<Value>): {
|
|
42
39
|
value: Value;
|
|
43
40
|
setValue: import("react").Dispatch<import("react").SetStateAction<Value>>;
|
|
44
41
|
reset: () => void;
|
|
45
|
-
theme: Pick<CiridaeTheme, "fonts"
|
|
42
|
+
theme: Pick<CiridaeTheme, "fonts">;
|
|
46
43
|
};
|
|
47
44
|
export type ThemeCustomizerProps<Value extends ThemeCustomization> = Omit<ComponentProps<"div">, "children" | "onChange"> & {
|
|
48
45
|
value: Value;
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/*
|
|
3
|
-
* The Appearance controls: the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `ThemeProvider`
|
|
7
|
-
* the color theme is `ThemeProvider`'s own, so it is read and set through `useColorTheme`.
|
|
3
|
+
* The Appearance controls: the color theme (System, Light, Dark) and the display, body and mono
|
|
4
|
+
* faces from fonts the app offers. The faces are the caller's `value`, which it hands to
|
|
5
|
+
* `ThemeProvider` (`useThemeCustomization` keeps one in `localStorage` and builds that prop); the
|
|
6
|
+
* color theme is `ThemeProvider`'s own, so it is read and set through `useColorTheme`.
|
|
8
7
|
*/
|
|
9
8
|
import { useCallback, useEffect, useState } from "react";
|
|
10
9
|
import { css, cx } from "#primitives/css";
|
|
11
|
-
import { derivePaletteTokens } from "../theme/derive.js";
|
|
12
|
-
import { PALETTE_NAMES, palettes } from "../theme/palettes.js";
|
|
13
10
|
import { useColorTheme } from "./color-theme.js";
|
|
14
11
|
import { DrawerField, DrawerFieldRow } from "./drawer.js";
|
|
15
12
|
import { SegmentedControl, SegmentedOption } from "./form-layout.js";
|
|
16
13
|
import { useCiridaeLocale } from "./locale.js";
|
|
17
|
-
import { RadioCard, RadioCardGroup } from "./radio-card.js";
|
|
18
14
|
import { Select } from "./select.js";
|
|
19
15
|
function fontFamily(options, id) {
|
|
20
16
|
return options.find((option) => option.id === id)?.family;
|
|
21
17
|
}
|
|
22
|
-
/** The
|
|
18
|
+
/** The font families `ThemeProvider` (and `createCiridaePreset`) take for `value`. */
|
|
23
19
|
export function themeCustomizationTheme(value, fonts) {
|
|
24
20
|
return {
|
|
25
|
-
palette: value.palette,
|
|
26
21
|
fonts: {
|
|
27
22
|
display: fontFamily(fonts.display ?? fonts.sans, value.displayFont),
|
|
28
23
|
sans: fontFamily(fonts.sans, value.sansFont),
|
|
@@ -35,17 +30,15 @@ export function parseThemeCustomization(stored, fallback, fonts) {
|
|
|
35
30
|
if (typeof stored !== "object" || stored === null)
|
|
36
31
|
return fallback;
|
|
37
32
|
const fontId = (options, value, otherwise) => options.find((option) => option.id === value)?.id ?? otherwise;
|
|
38
|
-
const palette = "palette" in stored ? stored.palette : undefined;
|
|
39
33
|
return {
|
|
40
|
-
palette: PALETTE_NAMES.find((name) => name === palette) ?? fallback.palette,
|
|
41
34
|
displayFont: fontId(fonts.display ?? fonts.sans, "displayFont" in stored ? stored.displayFont : undefined, fallback.displayFont),
|
|
42
35
|
sansFont: fontId(fonts.sans, "sansFont" in stored ? stored.sansFont : undefined, fallback.sansFont),
|
|
43
36
|
monoFont: fontId(fonts.mono, "monoFont" in stored ? stored.monoFont : undefined, fallback.monoFont),
|
|
44
37
|
};
|
|
45
38
|
}
|
|
46
39
|
/**
|
|
47
|
-
* A customization the app holds at its root: the value, a setter, and the `
|
|
48
|
-
*
|
|
40
|
+
* A customization the app holds at its root: the value, a setter, and the `fonts` to pass
|
|
41
|
+
* `ThemeProvider`. With `persistKey` it survives reloads; anything the app keeps beside
|
|
49
42
|
* the theme in `Value`, such as a brand name, is stored with it.
|
|
50
43
|
*/
|
|
51
44
|
export function useThemeCustomization({ defaultValue, fonts, persistKey, parse, }) {
|
|
@@ -74,31 +67,10 @@ export function useThemeCustomization({ defaultValue, fonts, persistKey, parse,
|
|
|
74
67
|
return { value, setValue, reset, theme: themeCustomizationTheme(value, fonts) };
|
|
75
68
|
}
|
|
76
69
|
const root = css({ display: "flex", flexDirection: "column", gap: "layout.clusterGap" });
|
|
77
|
-
const swatches = css({ display: "flex", gap: "layout.tightGap" });
|
|
78
|
-
const swatch = css({
|
|
79
|
-
width: "indicator.badge",
|
|
80
|
-
height: "indicator.badge",
|
|
81
|
-
borderRadius: "round",
|
|
82
|
-
boxShadow: "inset 0 0 0 1px token(colors.border.glass)",
|
|
83
|
-
});
|
|
84
|
-
/** The palette's accent, primary face and four status hues, under the color theme on screen. */
|
|
85
|
-
function PaletteSwatches({ name, colorTheme }) {
|
|
86
|
-
const tokens = derivePaletteTokens(palettes[name]);
|
|
87
|
-
const themed = (value) => colorTheme === "light" ? value._light : value.base;
|
|
88
|
-
const fills = [
|
|
89
|
-
themed(tokens.colors["accent.brand"]),
|
|
90
|
-
themed(tokens.colors["bg.primary"]),
|
|
91
|
-
themed(tokens.colors["accent.green"]),
|
|
92
|
-
themed(tokens.colors["accent.red"]),
|
|
93
|
-
themed(tokens.colors["accent.yellow"]),
|
|
94
|
-
themed(tokens.colors["accent.blue"]),
|
|
95
|
-
];
|
|
96
|
-
return (_jsx("span", { className: swatches, "aria-hidden": "true", children: fills.map((fill, index) => (_jsx("span", { className: swatch, style: { background: fill } }, index))) }));
|
|
97
|
-
}
|
|
98
70
|
export function ThemeCustomizer({ value, onValueChange, fonts, labels: ownLabels, className, ...props }) {
|
|
99
71
|
const { labels: localeLabels } = useCiridaeLocale();
|
|
100
72
|
const labels = { ...localeLabels.themeCustomizer, ...ownLabels };
|
|
101
|
-
const {
|
|
73
|
+
const { preference, setPreference } = useColorTheme();
|
|
102
74
|
const colorThemes = [
|
|
103
75
|
{ value: "system", label: labels.system },
|
|
104
76
|
{ value: "light", label: labels.light },
|
|
@@ -108,9 +80,5 @@ export function ThemeCustomizer({ value, onValueChange, fonts, labels: ownLabels
|
|
|
108
80
|
if (id !== null && options.some((option) => option.id === id))
|
|
109
81
|
pick(id);
|
|
110
82
|
} }) }));
|
|
111
|
-
return (_jsxs("div", { ...props, className: cx(root, className), "data-ciridae-ui": "", children: [_jsx(DrawerField, { label: labels.
|
|
112
|
-
const palette = PALETTE_NAMES.find((name) => name === next);
|
|
113
|
-
if (palette)
|
|
114
|
-
onValueChange({ ...value, palette });
|
|
115
|
-
}, children: PALETTE_NAMES.map((name) => (_jsx(RadioCard, { value: name, title: labels.paletteName(name), source: _jsx(PaletteSwatches, { name: name, colorTheme: theme }) }, name))) }) }), _jsx(DrawerField, { label: labels.colorTheme, children: _jsx(SegmentedControl, { "aria-label": labels.colorTheme, children: colorThemes.map((option) => (_jsx(SegmentedOption, { selected: option.value === preference, onClick: () => setPreference(option.value), children: option.label }, option.value))) }) }), _jsxs(DrawerFieldRow, { children: [fontSelect(labels.displayFont, fonts.display ?? fonts.sans, value.displayFont, (id) => onValueChange({ ...value, displayFont: id })), fontSelect(labels.sansFont, fonts.sans, value.sansFont, (id) => onValueChange({ ...value, sansFont: id }))] }), _jsx(DrawerFieldRow, { children: fontSelect(labels.monoFont, fonts.mono, value.monoFont, (id) => onValueChange({ ...value, monoFont: id })) })] }));
|
|
83
|
+
return (_jsxs("div", { ...props, className: cx(root, className), "data-ciridae-ui": "", children: [_jsx(DrawerField, { label: labels.colorTheme, children: _jsx(SegmentedControl, { "aria-label": labels.colorTheme, children: colorThemes.map((option) => (_jsx(SegmentedOption, { selected: option.value === preference, onClick: () => setPreference(option.value), children: option.label }, option.value))) }) }), _jsxs(DrawerFieldRow, { children: [fontSelect(labels.displayFont, fonts.display ?? fonts.sans, value.displayFont, (id) => onValueChange({ ...value, displayFont: id })), fontSelect(labels.sansFont, fonts.sans, value.sansFont, (id) => onValueChange({ ...value, sansFont: id }))] }), _jsx(DrawerFieldRow, { children: fontSelect(labels.monoFont, fonts.mono, value.monoFont, (id) => onValueChange({ ...value, monoFont: id })) })] }));
|
|
116
84
|
}
|
|
@@ -5,10 +5,6 @@ import { useColorTheme } from "./color-theme.js";
|
|
|
5
5
|
import { faceEdge } from "./gradient-edge.js";
|
|
6
6
|
import { icon } from "./icon.js";
|
|
7
7
|
import { useCiridaeLocale } from "./locale.js";
|
|
8
|
-
/*
|
|
9
|
-
* Light, dark or the system's theme, as three icon segments in a pale track: the chosen one is
|
|
10
|
-
* raised on the secondary button's face, its icon in the primary ink, the others a step quieter.
|
|
11
|
-
*/
|
|
12
8
|
const track = css({
|
|
13
9
|
display: "inline-flex",
|
|
14
10
|
alignItems: "center",
|
|
@@ -16,32 +12,31 @@ const track = css({
|
|
|
16
12
|
padding: "control.trackInset",
|
|
17
13
|
// The design lays the track's edge over its inset, and rounds it to its options' corners.
|
|
18
14
|
border: "0",
|
|
19
|
-
borderRadius: "calc(token(radii.inset) + token(spacing.control.trackInset))",
|
|
20
|
-
background: "token(gradients.panel)",
|
|
15
|
+
borderRadius: "[calc(token(radii.inset) + token(spacing.control.trackInset))]",
|
|
16
|
+
background: "[token(gradients.panel)]",
|
|
21
17
|
});
|
|
22
18
|
const option = css({
|
|
23
19
|
display: "inline-grid",
|
|
24
20
|
placeItems: "center",
|
|
25
21
|
width: "control.small",
|
|
26
|
-
height: "calc(token(sizes.control.small) - 2 * token(spacing.control.trackInset))",
|
|
22
|
+
height: "[calc(token(sizes.control.small) - 2 * token(spacing.control.trackInset))]",
|
|
27
23
|
padding: "none",
|
|
28
24
|
border: "0",
|
|
29
25
|
borderRadius: "inset",
|
|
30
26
|
background: "transparent",
|
|
31
27
|
color: "fg.secondary",
|
|
32
28
|
cursor: "pointer",
|
|
33
|
-
transitionProperty: "background, color",
|
|
29
|
+
transitionProperty: "[background, color]",
|
|
34
30
|
transitionDuration: "fast",
|
|
35
31
|
_hover: { color: "fg.primary" },
|
|
36
32
|
_focusVisible: { focusRing: "outer" },
|
|
37
|
-
_before: { display: "none", background: "token(gradients.border.raised)" },
|
|
33
|
+
_before: { display: "none", background: "[token(gradients.border.raised)]" },
|
|
38
34
|
"&[aria-pressed=true]": {
|
|
39
|
-
background: "token(gradients.raised)",
|
|
35
|
+
background: "[token(gradients.raised)]",
|
|
40
36
|
color: "fg.primary",
|
|
41
37
|
_before: { display: "block" },
|
|
42
38
|
},
|
|
43
39
|
});
|
|
44
|
-
/** Sets the color theme the `ThemeProvider` keeps: light, dark, or the operating system's. */
|
|
45
40
|
export function ThemeToggle({ className }) {
|
|
46
41
|
const { preference, setPreference } = useColorTheme();
|
|
47
42
|
const { labels } = useCiridaeLocale();
|
|
@@ -11,19 +11,13 @@ export type ToastOptions = {
|
|
|
11
11
|
variant?: ToastVariant;
|
|
12
12
|
/** Milliseconds it stays; `0` keeps it until dismissed. An error stays by default. */
|
|
13
13
|
timeout?: number;
|
|
14
|
-
/**
|
|
15
|
-
* One small secondary button, such as Undo; its children are the label. It closes the toast, and
|
|
16
|
-
* takes the close button's place.
|
|
17
|
-
*/
|
|
14
|
+
/** One small secondary button, such as Undo. It closes the toast, and takes the close button's place. */
|
|
18
15
|
actionProps?: Pick<ComponentProps<"button">, "children" | "onClick">;
|
|
19
|
-
/** Replaces the toast already shown with this id, such as a progress toast moving along. */
|
|
20
16
|
id?: string | number;
|
|
21
|
-
/** How far a `progress` toast is, 0 to 100, shown as a track and a percentage after its message. */
|
|
22
17
|
percent?: number;
|
|
23
18
|
};
|
|
24
19
|
/** Raises a toast with the kit's options, returning its id. */
|
|
25
20
|
declare function addToast({ title: ownMessage, description: detail, variant, timeout, actionProps, id, percent, }: ToastOptions): string | number;
|
|
26
|
-
/** The kit's toast calls: `add` raises one and returns its id, `close` dismisses it. */
|
|
27
21
|
export declare function useToast(): {
|
|
28
22
|
add: typeof addToast;
|
|
29
23
|
close: (id?: string | number) => string | number;
|