@ciridae/ui 1.0.5 → 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 +65 -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 +109 -51
- package/dist/components/chat.d.ts +27 -56
- package/dist/components/chat.js +151 -129
- 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 -12
- package/dist/components/editable-field.js +13 -26
- 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 +39 -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 +805 -1279
- package/dist/styled-system/tokens/index.mjs +74 -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 +38 -92
- package/package.json +1 -1
- package/dist/theme/palettes.js +0 -254
package/dist/components/shell.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useRender } from "@base-ui/react/use-render";
|
|
3
3
|
import { ListIcon } from "@phosphor-icons/react";
|
|
4
|
-
import { createContext, useContext, useMemo, useState } from "react";
|
|
4
|
+
import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { css, cx } from "#primitives/css";
|
|
6
6
|
import { IconButton, IconButtonSizeContext } from "./button.js";
|
|
7
7
|
import { PageHotkeys, useHotkey } from "./hotkeys.js";
|
|
@@ -11,9 +11,9 @@ import { singleLineTextClass } from "./single-line-text.js";
|
|
|
11
11
|
// The sidebar sits flush against the window; only the main panel is inset from the edges.
|
|
12
12
|
const shell = css({
|
|
13
13
|
display: "flex",
|
|
14
|
-
height: "100dvh",
|
|
14
|
+
height: "[100dvh]",
|
|
15
15
|
overflow: "hidden",
|
|
16
|
-
background: "token(gradients.canvas)",
|
|
16
|
+
background: "[token(gradients.canvas)]",
|
|
17
17
|
color: "fg.primary",
|
|
18
18
|
// Compact line height leaves clipped text room for its descenders throughout the app frame.
|
|
19
19
|
textStyle: "body",
|
|
@@ -53,18 +53,18 @@ const sidebar = css({
|
|
|
53
53
|
// button, with its full labelled content rather than the rail.
|
|
54
54
|
_phone: {
|
|
55
55
|
position: "fixed",
|
|
56
|
-
insetBlock: "
|
|
57
|
-
insetInlineStart: "
|
|
56
|
+
insetBlock: "none",
|
|
57
|
+
insetInlineStart: "none",
|
|
58
58
|
zIndex: "drawer",
|
|
59
59
|
width: "shell.sidebar",
|
|
60
60
|
alignItems: "stretch",
|
|
61
|
-
background: "token(gradients.canvas)",
|
|
61
|
+
background: "[token(gradients.canvas)]",
|
|
62
62
|
borderInlineEnd: "1px solid token(colors.border.panel)",
|
|
63
63
|
boxShadow: "card",
|
|
64
64
|
transform: "translateX(-100%)",
|
|
65
65
|
_rtl: { transform: "translateX(100%)" },
|
|
66
66
|
visibility: "hidden",
|
|
67
|
-
transitionProperty: "transform, visibility",
|
|
67
|
+
transitionProperty: "[transform, visibility]",
|
|
68
68
|
transitionDuration: "fast",
|
|
69
69
|
"&[data-menu-open]": { transform: "none", visibility: "visible" },
|
|
70
70
|
},
|
|
@@ -74,7 +74,7 @@ const menuBackdrop = css({
|
|
|
74
74
|
_phone: {
|
|
75
75
|
display: "block",
|
|
76
76
|
position: "fixed",
|
|
77
|
-
inset: "
|
|
77
|
+
inset: "none",
|
|
78
78
|
zIndex: "drawer",
|
|
79
79
|
background: "bg.backdrop",
|
|
80
80
|
},
|
|
@@ -89,13 +89,13 @@ const main = css({
|
|
|
89
89
|
marginInlineEnd: "panel.compact",
|
|
90
90
|
border: "1px solid token(colors.border.canvas)",
|
|
91
91
|
borderRadius: "action",
|
|
92
|
-
background: "token(gradients.panel)",
|
|
92
|
+
background: "[token(gradients.panel)]",
|
|
93
93
|
overflow: "hidden",
|
|
94
94
|
// Only once the panel spans the whole window does rounding read as a gap.
|
|
95
95
|
_phone: {
|
|
96
96
|
margin: "none",
|
|
97
|
-
borderRadius: "
|
|
98
|
-
height: "100dvh",
|
|
97
|
+
borderRadius: "none",
|
|
98
|
+
height: "[100dvh]",
|
|
99
99
|
border: "0",
|
|
100
100
|
},
|
|
101
101
|
});
|
|
@@ -109,7 +109,7 @@ const header = css({
|
|
|
109
109
|
paddingInlineEnd: "control.compactInline",
|
|
110
110
|
paddingInlineStart: "control.inline",
|
|
111
111
|
borderBottom: "1px solid token(colors.border.divider)",
|
|
112
|
-
"& > :last-child": { minWidth: "0", maxWidth: "
|
|
112
|
+
"& > :last-child": { minWidth: "0", maxWidth: "full" },
|
|
113
113
|
// Once the sidebar is gone the header stays one row: the title truncates, the actions keep
|
|
114
114
|
// their width.
|
|
115
115
|
_phone: {
|
|
@@ -127,7 +127,6 @@ const header = css({
|
|
|
127
127
|
"& [data-slicer-label]": { srOnly: true },
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
|
-
// The trail's parents; the page itself, last, is in the primary text.
|
|
131
130
|
const headerTitle = css({
|
|
132
131
|
flex: "1",
|
|
133
132
|
minWidth: "0",
|
|
@@ -146,11 +145,18 @@ const content = css({
|
|
|
146
145
|
padding: "var(--app-content-inset)",
|
|
147
146
|
_phone: { "--app-content-inset": "token(spacing.panel.default)" },
|
|
148
147
|
});
|
|
148
|
+
/** Focuses the Menu button now in the ref, which a page change may have replaced. */
|
|
149
|
+
function focusMenuButton(buttonRef, onlyIfFocusIsLost) {
|
|
150
|
+
if (!onlyIfFocusIsLost || document.activeElement === document.body)
|
|
151
|
+
buttonRef.current?.focus();
|
|
152
|
+
}
|
|
149
153
|
/** Whether the phone menu (the sidebar slid in over the page) is open. */
|
|
150
154
|
const ShellMenuContext = createContext({
|
|
151
155
|
open: false,
|
|
152
156
|
setOpen: () => undefined,
|
|
157
|
+
buttonRef: { current: null },
|
|
153
158
|
});
|
|
159
|
+
const menuFocusableSelector = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex='-1'])";
|
|
154
160
|
/** In the page's scope, so Escape in an overlay over the menu closes only the overlay. */
|
|
155
161
|
function CloseShellMenuOnEscape() {
|
|
156
162
|
const menu = useContext(ShellMenuContext);
|
|
@@ -163,13 +169,50 @@ function CloseShellMenuOnEscape() {
|
|
|
163
169
|
}
|
|
164
170
|
export function AppShell({ className, children, ...props }) {
|
|
165
171
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
166
|
-
const
|
|
172
|
+
const buttonRef = useRef(null);
|
|
173
|
+
const menu = useMemo(() => ({ open: menuOpen, setOpen: setMenuOpen, buttonRef }), [menuOpen]);
|
|
167
174
|
return (_jsx(ShellMenuContext, { value: menu, children: _jsxs("div", { ...props, className: cx(shell, className), "data-ciridae-ui": "", children: [menuOpen && _jsx("div", { className: menuBackdrop, onClick: () => setMenuOpen(false) }), _jsxs(PageHotkeys, { children: [_jsx(CloseShellMenuOnEscape, {}), children] })] }) }));
|
|
168
175
|
}
|
|
169
|
-
export function AppSidebar({ className, collapsed, onClickCapture, ...props }) {
|
|
176
|
+
export function AppSidebar({ className, collapsed, onClickCapture, onKeyDown, ...props }) {
|
|
170
177
|
const menu = useContext(ShellMenuContext);
|
|
178
|
+
const sidebarRef = useRef(null);
|
|
179
|
+
const { buttonRef, open: menuIsOpen } = menu;
|
|
180
|
+
// The open menu takes the focus and gives it back to the Menu button when it closes.
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
if (!menuIsOpen)
|
|
183
|
+
return;
|
|
184
|
+
// The sidebar cannot take focus until its visibility transition has started, a frame later.
|
|
185
|
+
let frame = requestAnimationFrame(() => {
|
|
186
|
+
frame = requestAnimationFrame(() => sidebarRef.current?.querySelector(menuFocusableSelector)?.focus());
|
|
187
|
+
});
|
|
188
|
+
return () => {
|
|
189
|
+
cancelAnimationFrame(frame);
|
|
190
|
+
focusMenuButton(buttonRef, false);
|
|
191
|
+
// A page change replaces the header and its Menu button, which drops the focus again.
|
|
192
|
+
requestAnimationFrame(() => focusMenuButton(buttonRef, true));
|
|
193
|
+
};
|
|
194
|
+
}, [menuIsOpen, buttonRef]);
|
|
195
|
+
const keepTabInsideMenu = (event) => {
|
|
196
|
+
onKeyDown?.(event);
|
|
197
|
+
if (!menu.open || event.key !== "Tab")
|
|
198
|
+
return;
|
|
199
|
+
const focusable = [
|
|
200
|
+
...event.currentTarget.querySelectorAll(menuFocusableSelector),
|
|
201
|
+
].filter((element) => element.checkVisibility());
|
|
202
|
+
const first = focusable[0];
|
|
203
|
+
const last = focusable[focusable.length - 1];
|
|
204
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
205
|
+
event.preventDefault();
|
|
206
|
+
last?.focus();
|
|
207
|
+
}
|
|
208
|
+
else if (!event.shiftKey && document.activeElement === last) {
|
|
209
|
+
event.preventDefault();
|
|
210
|
+
first?.focus();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
171
213
|
// Choosing a page from the phone menu closes it, as does an item of a menu opened from it, such
|
|
172
|
-
// as the account menu; a row's action, such as a pin, and a menu's own
|
|
214
|
+
// as the account menu; a row's action, such as a pin, the More and Less row, and a menu's own
|
|
215
|
+
// trigger do not.
|
|
173
216
|
const closeMenuOnNavigation = (event) => {
|
|
174
217
|
onClickCapture?.(event);
|
|
175
218
|
const target = event.target instanceof Element ? event.target : null;
|
|
@@ -179,13 +222,13 @@ export function AppSidebar({ className, collapsed, onClickCapture, ...props }) {
|
|
|
179
222
|
menu.setOpen(false);
|
|
180
223
|
}
|
|
181
224
|
};
|
|
182
|
-
return (_jsx("aside", { ...props, className: cx(sidebar, className), "data-collapsed": collapsed || undefined, "data-menu-open": menu.open || undefined, onClickCapture: closeMenuOnNavigation }));
|
|
225
|
+
return (_jsx("aside", { ...props, ref: sidebarRef, className: cx(sidebar, className), "data-collapsed": collapsed || undefined, "data-menu-open": menu.open || undefined, onClickCapture: closeMenuOnNavigation, onKeyDown: keepTabInsideMenu }));
|
|
183
226
|
}
|
|
184
227
|
/** Opens the sidebar as a menu on a phone; hidden at any width that shows the sidebar. */
|
|
185
228
|
function AppMenuButton() {
|
|
186
229
|
const menu = useContext(ShellMenuContext);
|
|
187
230
|
const { labels } = useCiridaeLocale();
|
|
188
|
-
return (_jsx("span", { className: menuButton, children: _jsx(IconButton, { "aria-label": labels.shell.menu, "aria-expanded": menu.open, variant: "ghost", onClick: () => menu.setOpen(!menu.open), children: _jsx(ListIcon, { className: icon({ size: "small" }) }) }) }));
|
|
231
|
+
return (_jsx("span", { className: menuButton, children: _jsx(IconButton, { ref: menu.buttonRef, "aria-label": labels.shell.menu, "aria-expanded": menu.open, variant: "ghost", onClick: () => menu.setOpen(!menu.open), children: _jsx(ListIcon, { className: icon({ size: "small" }) }) }) }));
|
|
189
232
|
}
|
|
190
233
|
export function AppMain({ className, ...props }) {
|
|
191
234
|
return _jsx("main", { ...props, className: cx(main, className), "data-ciridae-ui": "" });
|
|
@@ -206,13 +249,15 @@ const sidebarRail = css({
|
|
|
206
249
|
gap: "sidebar.groupGap",
|
|
207
250
|
});
|
|
208
251
|
/* One sidebar's content stacks at its container's own gap, so a footer's controls keep their room. */
|
|
209
|
-
const sidebarOnly = css({ display: "flex", flexDirection: "column", gap: "inherit" });
|
|
252
|
+
const sidebarOnly = css({ display: "flex", flexDirection: "column", gap: "[inherit]" });
|
|
210
253
|
const sidebarNav = css({
|
|
211
254
|
display: "flex",
|
|
212
255
|
flexDirection: "column",
|
|
213
256
|
gap: "sidebar.groupGap",
|
|
214
257
|
minHeight: "0",
|
|
215
258
|
overflowY: "auto",
|
|
259
|
+
// It scrolls when its items outgrow it, so none of them shrinks to fit, the search field included.
|
|
260
|
+
"& > *": { flexShrink: "0" },
|
|
216
261
|
// Scrolling would clip the ring of anything outer-ringed placed among the items.
|
|
217
262
|
ringRoom: true,
|
|
218
263
|
});
|
|
@@ -314,7 +359,7 @@ const crumbButton = css({
|
|
|
314
359
|
padding: "none",
|
|
315
360
|
border: "0",
|
|
316
361
|
background: "transparent",
|
|
317
|
-
color: "inherit",
|
|
362
|
+
color: "[inherit]",
|
|
318
363
|
font: "inherit",
|
|
319
364
|
cursor: "pointer",
|
|
320
365
|
_hover: { textDecoration: "underline" },
|
|
@@ -338,9 +383,9 @@ const crumbCurrent = css({
|
|
|
338
383
|
// The page's heading, but read as a crumb, so it stays on the body face.
|
|
339
384
|
fontFamily: "sans",
|
|
340
385
|
color: "fg.primary",
|
|
341
|
-
fontSize: "inherit",
|
|
386
|
+
fontSize: "[inherit]",
|
|
342
387
|
fontWeight: "medium",
|
|
343
|
-
lineHeight: "inherit",
|
|
388
|
+
lineHeight: "[inherit]",
|
|
344
389
|
});
|
|
345
390
|
/** The slash between two crumbs. */
|
|
346
391
|
export function AppBreadcrumbSeparator() {
|
|
@@ -372,12 +417,12 @@ const account = css({
|
|
|
372
417
|
display: "flex",
|
|
373
418
|
alignItems: "center",
|
|
374
419
|
gap: "sidebar.markGap",
|
|
375
|
-
width: "
|
|
420
|
+
width: "full",
|
|
376
421
|
padding: "control.compactBlock",
|
|
377
422
|
border: "0",
|
|
378
423
|
borderRadius: "keycap",
|
|
379
424
|
background: "transparent",
|
|
380
|
-
color: "inherit",
|
|
425
|
+
color: "[inherit]",
|
|
381
426
|
font: "inherit",
|
|
382
427
|
textAlign: "start",
|
|
383
428
|
cursor: "pointer",
|
|
@@ -17,7 +17,7 @@ const aside = css({
|
|
|
17
17
|
display: "flex",
|
|
18
18
|
flexDirection: "column",
|
|
19
19
|
flexShrink: "0",
|
|
20
|
-
width: "
|
|
20
|
+
width: "overlay.sheetNarrow",
|
|
21
21
|
minWidth: "0",
|
|
22
22
|
minHeight: "0",
|
|
23
23
|
overflow: "hidden",
|
|
@@ -31,7 +31,7 @@ const headerRow = css({
|
|
|
31
31
|
alignItems: "center",
|
|
32
32
|
gap: "layout.controlGap",
|
|
33
33
|
// A list head's height: its block padding round one line of its text.
|
|
34
|
-
minHeight: "calc(token(spacing.panel.default) * 2 + 16px + 1px)",
|
|
34
|
+
minHeight: "[calc(token(spacing.panel.default) * 2 + 16px + 1px)]",
|
|
35
35
|
paddingInlineStart: "panel.comfortable",
|
|
36
36
|
paddingInlineEnd: "panel.default",
|
|
37
37
|
borderBottom: "1px solid token(colors.border.panel)",
|
|
@@ -88,7 +88,7 @@ const body = css({
|
|
|
88
88
|
overflowY: "auto",
|
|
89
89
|
padding: "panel.comfortable",
|
|
90
90
|
// A flush body holds its content edge to edge, such as tabs whose panels pad themselves.
|
|
91
|
-
"&[data-flush]": { display: "flex", flexDirection: "column", gap: "
|
|
91
|
+
"&[data-flush]": { display: "flex", flexDirection: "column", gap: "none", padding: "none" },
|
|
92
92
|
});
|
|
93
93
|
const footerRow = css({
|
|
94
94
|
display: "flex",
|
|
@@ -2,7 +2,6 @@ import { useRender } from "@base-ui/react/use-render";
|
|
|
2
2
|
import type { ComponentProps, ReactNode } from "react";
|
|
3
3
|
export declare function SidebarNavigation({ className, ...props }: ComponentProps<"nav">): import("react").JSX.Element;
|
|
4
4
|
export declare function SidebarDivider({ className, ...props }: ComponentProps<"hr">): import("react").JSX.Element;
|
|
5
|
-
/** Opens a labelled section in the rail, as its label does in the expanded sidebar. */
|
|
6
5
|
export declare function SidebarRailRule({ className, ...props }: ComponentProps<"hr">): import("react").JSX.Element;
|
|
7
6
|
export declare function SidebarPanel({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
8
7
|
export declare function SidebarSection({ label, action, iconTone, className, children, ...props }: ComponentProps<"div"> & {
|
|
@@ -31,10 +30,6 @@ export type SidebarItemProps = useRender.ComponentProps<"button"> & {
|
|
|
31
30
|
active?: boolean;
|
|
32
31
|
/** Tint the leading icon bronze while inactive, as the Projects hub sidebar does. */
|
|
33
32
|
iconTone?: "bronze";
|
|
34
|
-
/**
|
|
35
|
-
* `compact` is a secondary list's row, such as recently opened records; `short` a shorter row
|
|
36
|
-
* in the body type, such as the settings sidebar's Back to app.
|
|
37
|
-
*/
|
|
38
33
|
size?: "regular" | "compact" | "short";
|
|
39
34
|
};
|
|
40
35
|
export declare function SidebarItem({ icon, trailing, action, active, iconTone, size, href, render, className, children, ...props }: SidebarItemProps): import("react").JSX.Element;
|
|
@@ -6,7 +6,7 @@ import { singleLineText } from "./single-line-text.js";
|
|
|
6
6
|
// Navigation sits in the shell's sidebar; it is not a panel of its own.
|
|
7
7
|
const navigation = css({
|
|
8
8
|
display: "flex",
|
|
9
|
-
width: "
|
|
9
|
+
width: "full",
|
|
10
10
|
minWidth: "0",
|
|
11
11
|
flexDirection: "column",
|
|
12
12
|
gap: "layout.clusterGap",
|
|
@@ -34,7 +34,6 @@ const sectionLabel = css({
|
|
|
34
34
|
"&[data-icon-tone=bronze] > svg": { color: "accent.bronze" },
|
|
35
35
|
});
|
|
36
36
|
const sectionAction = css({ display: "inline-flex", marginInlineStart: "auto" });
|
|
37
|
-
// A labelled section's mark in the rail, where there is no room for its label: a short rule.
|
|
38
37
|
const railRule = css({
|
|
39
38
|
flexShrink: "0",
|
|
40
39
|
width: "sidebar.railRule",
|
|
@@ -46,22 +45,18 @@ const railRule = css({
|
|
|
46
45
|
background: "border.divider",
|
|
47
46
|
});
|
|
48
47
|
const divider = css({
|
|
49
|
-
width: "
|
|
48
|
+
width: "full",
|
|
50
49
|
height: "border.hairline",
|
|
51
50
|
margin: "none",
|
|
52
51
|
border: "0",
|
|
53
52
|
background: "border.hairline",
|
|
54
53
|
});
|
|
55
|
-
|
|
56
|
-
* A row is square-cornered at rest; hovered, open or focused it rounds into a pill. The open page
|
|
57
|
-
* sits on the canvas's field face inside its edge; a hover is a faint wash in light and the
|
|
58
|
-
* selected glass in dark.
|
|
59
|
-
*/
|
|
54
|
+
// A hover is a faint wash in light and the selected glass in dark.
|
|
60
55
|
const item = css({
|
|
61
56
|
display: "flex",
|
|
62
57
|
alignItems: "center",
|
|
63
58
|
gap: "layout.controlGap",
|
|
64
|
-
width: "
|
|
59
|
+
width: "full",
|
|
65
60
|
height: "control.row",
|
|
66
61
|
paddingInline: "control.compactInline",
|
|
67
62
|
border: "0",
|
|
@@ -77,27 +72,27 @@ const item = css({
|
|
|
77
72
|
lineHeight: "tight",
|
|
78
73
|
textAlign: "start",
|
|
79
74
|
cursor: "pointer",
|
|
80
|
-
transitionProperty: "background, color, border-radius",
|
|
75
|
+
transitionProperty: "[background, color, border-radius]",
|
|
81
76
|
transitionDuration: "fast",
|
|
82
|
-
"& > svg:first-child": { opacity: ".7" },
|
|
77
|
+
"& > svg:first-child": { opacity: "[.7]" },
|
|
83
78
|
"&[data-icon-tone=bronze] > svg:first-child": { color: "accent.bronze" },
|
|
84
79
|
"&:hover, &[aria-pressed=true]": {
|
|
85
80
|
borderRadius: "shell",
|
|
86
|
-
background: "token(gradients.selected)",
|
|
81
|
+
background: "[token(gradients.selected)]",
|
|
87
82
|
_light: { background: "bg.rowHover" },
|
|
88
83
|
color: "fg.primary",
|
|
89
|
-
"& > svg:first-child": { color: "inherit" },
|
|
84
|
+
"& > svg:first-child": { color: "[inherit]" },
|
|
90
85
|
},
|
|
91
86
|
// The open page keeps the hover shape and size; the field face and the canvas's edge mark it.
|
|
92
87
|
// The design counts that edge inside the row, so its content sits a hairline further in.
|
|
93
88
|
"&[aria-current=page]": {
|
|
94
89
|
borderRadius: "shell",
|
|
95
90
|
background: "bg.field",
|
|
96
|
-
boxShadow: "inset 0 0 0 1px token(colors.border.canvas)",
|
|
91
|
+
boxShadow: "[inset 0 0 0 1px token(colors.border.canvas)]",
|
|
97
92
|
color: "fg.primary",
|
|
98
|
-
"& > svg:first-child": { color: "inherit", opacity: "1" },
|
|
93
|
+
"& > svg:first-child": { color: "[inherit]", opacity: "[1]" },
|
|
99
94
|
"&:not([data-icon-only])": {
|
|
100
|
-
paddingInline: "calc(token(spacing.control.compactInline) + token(sizes.border.hairline))",
|
|
95
|
+
paddingInline: "[calc(token(spacing.control.compactInline) + token(sizes.border.hairline))]",
|
|
101
96
|
},
|
|
102
97
|
},
|
|
103
98
|
_focusVisible: { borderRadius: "shell", focusRing: "outer" },
|
|
@@ -108,16 +103,14 @@ const item = css({
|
|
|
108
103
|
color: "fg.secondary",
|
|
109
104
|
fontSize: "caption",
|
|
110
105
|
},
|
|
111
|
-
// A shorter row in the body type, such as the settings sidebar's way back to the app.
|
|
112
106
|
"&[data-size=short]": { height: "sidebar.shortRow" },
|
|
113
|
-
// With no label it is the rail's round button: the same hover, open-page face and edge, icon only.
|
|
114
107
|
"&[data-icon-only]": {
|
|
115
108
|
justifyContent: "center",
|
|
116
109
|
width: "control.compact",
|
|
117
110
|
height: "control.compact",
|
|
118
111
|
paddingInline: "none",
|
|
119
112
|
borderRadius: "round",
|
|
120
|
-
"& > svg:first-child": { opacity: "1", fontSize: "icon.small" },
|
|
113
|
+
"& > svg:first-child": { opacity: "[1]", fontSize: "icon.small" },
|
|
121
114
|
},
|
|
122
115
|
});
|
|
123
116
|
const label = css(singleLineText, { flex: "1" });
|
|
@@ -127,53 +120,53 @@ const trailingStyle = css({ display: "inline-flex", flexShrink: "0", color: "fg.
|
|
|
127
120
|
const itemGroup = css({
|
|
128
121
|
display: "flex",
|
|
129
122
|
alignItems: "center",
|
|
130
|
-
width: "
|
|
123
|
+
width: "full",
|
|
131
124
|
minWidth: "0",
|
|
132
125
|
borderRadius: "nav",
|
|
133
|
-
transitionProperty: "background, border-radius",
|
|
126
|
+
transitionProperty: "[background, border-radius]",
|
|
134
127
|
transitionDuration: "fast",
|
|
135
128
|
"&:hover": {
|
|
136
129
|
borderRadius: "shell",
|
|
137
|
-
background: "token(gradients.selected)",
|
|
130
|
+
background: "[token(gradients.selected)]",
|
|
138
131
|
_light: { background: "bg.rowHover" },
|
|
139
132
|
},
|
|
140
133
|
"&:hover > [data-sidebar-row]": { color: "fg.primary" },
|
|
141
134
|
"&:has(> [data-sidebar-row][aria-current=page])": {
|
|
142
135
|
borderRadius: "shell",
|
|
143
136
|
background: "bg.field",
|
|
144
|
-
boxShadow: "inset 0 0 0 1px token(colors.border.canvas)",
|
|
137
|
+
boxShadow: "[inset 0 0 0 1px token(colors.border.canvas)]",
|
|
145
138
|
},
|
|
146
139
|
// The group draws the one wash; the row inside never adds its own on hover or when current.
|
|
147
140
|
"& > [data-sidebar-row]": { minWidth: "0" },
|
|
148
|
-
"& > [data-sidebar-row], & > [data-sidebar-row]:is(:hover, [aria-current=page], [aria-pressed=true])": { background: "transparent", boxShadow: "none" },
|
|
141
|
+
"& > [data-sidebar-row], & > [data-sidebar-row]:is(:hover, [aria-current=page], [aria-pressed=true])": { background: "transparent", boxShadow: "[none]" },
|
|
149
142
|
// Focus rings the whole row, action included, not just the link inside it.
|
|
150
|
-
"& > [data-sidebar-row]:focus-visible": { outline: "
|
|
143
|
+
"& > [data-sidebar-row]:focus-visible": { outline: "0" },
|
|
151
144
|
"&:has(> [data-sidebar-row]:focus-visible)": { borderRadius: "shell", focusRing: "outer" },
|
|
152
|
-
"&:hover > [data-sidebar-action], & > [data-sidebar-action]:focus-within": { opacity: "1" },
|
|
145
|
+
"&:hover > [data-sidebar-action], & > [data-sidebar-action]:focus-within": { opacity: "[1]" },
|
|
153
146
|
});
|
|
154
147
|
// Revealed on hover or focus; always shown where there is no hover to reveal it.
|
|
155
148
|
const itemAction = css({
|
|
156
149
|
display: "inline-flex",
|
|
157
150
|
flexShrink: "0",
|
|
158
151
|
paddingInlineEnd: "control.trackInset",
|
|
159
|
-
opacity: "0",
|
|
160
|
-
transitionProperty: "opacity",
|
|
152
|
+
opacity: "[0]",
|
|
153
|
+
transitionProperty: "[opacity]",
|
|
161
154
|
transitionDuration: "fast",
|
|
162
|
-
_phone: { opacity: "1" },
|
|
163
|
-
"@media (hover: none)": { opacity: "1" },
|
|
155
|
+
_phone: { opacity: "[1]" },
|
|
156
|
+
"@media (hover: none)": { opacity: "[1]" },
|
|
164
157
|
});
|
|
165
158
|
const heading = css({
|
|
166
159
|
display: "flex",
|
|
167
160
|
alignItems: "center",
|
|
168
161
|
gap: "sidebar.markGap",
|
|
169
|
-
width: "
|
|
162
|
+
width: "full",
|
|
170
163
|
minWidth: "0",
|
|
171
164
|
paddingBlock: "control.block",
|
|
172
165
|
paddingInline: "control.block",
|
|
173
166
|
border: "0",
|
|
174
167
|
borderRadius: "field",
|
|
175
168
|
background: "transparent",
|
|
176
|
-
color: "inherit",
|
|
169
|
+
color: "[inherit]",
|
|
177
170
|
font: "inherit",
|
|
178
171
|
textAlign: "start",
|
|
179
172
|
cursor: "pointer",
|
|
@@ -195,7 +188,6 @@ export function SidebarNavigation({ className, ...props }) {
|
|
|
195
188
|
export function SidebarDivider({ className, ...props }) {
|
|
196
189
|
return _jsx("hr", { ...props, className: cx(divider, className), "data-ciridae-ui": "" });
|
|
197
190
|
}
|
|
198
|
-
/** Opens a labelled section in the rail, as its label does in the expanded sidebar. */
|
|
199
191
|
export function SidebarRailRule({ className, ...props }) {
|
|
200
192
|
return _jsx("hr", { ...props, className: cx(railRule, className), "data-ciridae-ui": "" });
|
|
201
193
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { css } from "#primitives/css";
|
|
2
2
|
/*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* class `singleLineTextClass`: Panda does not extract it from under a nested selector.
|
|
3
|
+
* It clips sideways only, so the descenders that reach below a line box that tight stay whole.
|
|
4
|
+
* Compose it at the top level of a `css()` call, or as the class `singleLineTextClass`: Panda does
|
|
5
|
+
* not extract it from under a nested selector.
|
|
7
6
|
*/
|
|
8
7
|
export const singleLineText = css.raw({
|
|
9
8
|
minWidth: "0",
|
|
@@ -10,14 +10,14 @@ const banner = cva({
|
|
|
10
10
|
alignItems: "center",
|
|
11
11
|
gap: "layout.controlGap",
|
|
12
12
|
flexShrink: "0",
|
|
13
|
-
width: "
|
|
13
|
+
width: "full",
|
|
14
14
|
boxSizing: "border-box",
|
|
15
15
|
paddingBlock: "control.trackInset",
|
|
16
16
|
paddingInline: "control.inline",
|
|
17
17
|
textAlign: "start",
|
|
18
|
-
fontSize: "11px",
|
|
18
|
+
fontSize: "[11px]",
|
|
19
19
|
fontWeight: "medium",
|
|
20
|
-
lineHeight: "16px",
|
|
20
|
+
lineHeight: "[16px]",
|
|
21
21
|
color: "fg.muted",
|
|
22
22
|
},
|
|
23
23
|
variants: {
|
|
@@ -33,7 +33,7 @@ const banner = cva({
|
|
|
33
33
|
});
|
|
34
34
|
const message = css({ flex: "1", minWidth: "0" });
|
|
35
35
|
// The strip keeps its height: the button reaches past the line by as much as it is taller.
|
|
36
|
-
const dismissButton = css({ marginBlock: "calc((1lh - token(sizes.control.shortcut)) / 2)" });
|
|
36
|
+
const dismissButton = css({ marginBlock: "[calc((1lh - token(sizes.control.shortcut)) / 2)]" });
|
|
37
37
|
/** A quiet, full-width site notice, separate from page-level status banners. */
|
|
38
38
|
export function SiteBanner({ tone, onDismiss, className, children, ...props }) {
|
|
39
39
|
const { labels } = useCiridaeLocale();
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { css, cx } from "#primitives/css";
|
|
3
3
|
// The design draws placeholders flat, with no shimmer: the canvas's gradient in light, a white
|
|
4
|
-
// wash in dark.
|
|
4
|
+
// wash in dark.
|
|
5
5
|
const skeleton = css({
|
|
6
6
|
display: "block",
|
|
7
7
|
flexShrink: "0",
|
|
8
|
-
background: "token(gradients.skeletonFill)",
|
|
8
|
+
background: "[token(gradients.skeletonFill)]",
|
|
9
9
|
"&[data-shape=block]": { minHeight: "skeleton.line", borderRadius: "control" },
|
|
10
10
|
// One line of the surrounding text: the bar is shorter than the line box and centered in it.
|
|
11
11
|
"&[data-shape=text]": {
|
|
12
|
-
width: "
|
|
13
|
-
height: "0.75em",
|
|
14
|
-
marginBlock: "calc((1lh - 0.75em) / 2)",
|
|
12
|
+
width: "full",
|
|
13
|
+
height: "[0.75em]",
|
|
14
|
+
marginBlock: "[calc((1lh - 0.75em) / 2)]",
|
|
15
15
|
borderRadius: "round",
|
|
16
16
|
},
|
|
17
17
|
"&[data-shape=circle]": {
|
|
@@ -24,7 +24,6 @@ const skeleton = css({
|
|
|
24
24
|
aspectRatio: "1",
|
|
25
25
|
borderRadius: "control",
|
|
26
26
|
},
|
|
27
|
-
// A status chip's or a badge's placeholder.
|
|
28
27
|
"&[data-shape=pill]": {
|
|
29
28
|
width: "skeleton.pill",
|
|
30
29
|
height: "skeleton.bar",
|
|
@@ -33,31 +32,29 @@ const skeleton = css({
|
|
|
33
32
|
"&[data-shape][data-width=short]": { width: "skeleton.short" },
|
|
34
33
|
"&[data-shape][data-width=medium]": { width: "skeleton.medium" },
|
|
35
34
|
"&[data-shape][data-width=long]": { width: "skeleton.long" },
|
|
36
|
-
"&[data-shape][data-width=full]": { width: "
|
|
37
|
-
// A line of small print, such as a row's meta line, under a line of text.
|
|
35
|
+
"&[data-shape][data-width=full]": { width: "full" },
|
|
38
36
|
"&[data-shape][data-height=caption]": {
|
|
39
37
|
height: "skeleton.caption",
|
|
40
|
-
marginBlock: "calc((1lh - token(sizes.skeleton.caption)) / 2)",
|
|
38
|
+
marginBlock: "[calc((1lh - token(sizes.skeleton.caption)) / 2)]",
|
|
41
39
|
},
|
|
42
40
|
"&[data-shape][data-height=text]": {
|
|
43
|
-
height: "0.75em",
|
|
44
|
-
marginBlock: "calc((1lh - 0.75em) / 2)",
|
|
41
|
+
height: "[0.75em]",
|
|
42
|
+
marginBlock: "[calc((1lh - 0.75em) / 2)]",
|
|
45
43
|
},
|
|
46
44
|
// The design's fixed text bars, with no line box round them: a line, and a small one.
|
|
47
|
-
"&[data-shape][data-height=line]": { height: "skeleton.textLine", marginBlock: "
|
|
48
|
-
"&[data-shape][data-height=smallLine]": { height: "skeleton.caption", marginBlock: "
|
|
49
|
-
|
|
50
|
-
"&[data-shape][data-height=
|
|
51
|
-
"&[data-shape][data-height=
|
|
52
|
-
"&[data-shape][data-height=
|
|
53
|
-
"&[data-shape][data-height=
|
|
54
|
-
"&[data-shape][data-height=block]": { height: "100%", marginBlock: "0" },
|
|
45
|
+
"&[data-shape][data-height=line]": { height: "skeleton.textLine", marginBlock: "none" },
|
|
46
|
+
"&[data-shape][data-height=smallLine]": { height: "skeleton.caption", marginBlock: "none" },
|
|
47
|
+
"&[data-shape][data-height=bar]": { height: "skeleton.bar", marginBlock: "none" },
|
|
48
|
+
"&[data-shape][data-height=badge]": { height: "skeleton.badge", marginBlock: "none" },
|
|
49
|
+
"&[data-shape][data-height=control]": { height: "control.default", marginBlock: "none" },
|
|
50
|
+
"&[data-shape][data-height=row]": { height: "control.field", marginBlock: "none" },
|
|
51
|
+
"&[data-shape][data-height=block]": { height: "full", marginBlock: "none" },
|
|
55
52
|
"&[data-shape][data-height=chart], &[data-shape][data-height='chart.medium']": {
|
|
56
53
|
height: "chart.medium",
|
|
57
|
-
marginBlock: "
|
|
54
|
+
marginBlock: "none",
|
|
58
55
|
},
|
|
59
|
-
"&[data-shape][data-height='chart.small']": { height: "chart.small", marginBlock: "
|
|
60
|
-
"&[data-shape][data-height='chart.large']": { height: "chart.large", marginBlock: "
|
|
56
|
+
"&[data-shape][data-height='chart.small']": { height: "chart.small", marginBlock: "none" },
|
|
57
|
+
"&[data-shape][data-height='chart.large']": { height: "chart.large", marginBlock: "none" },
|
|
61
58
|
});
|
|
62
59
|
/**
|
|
63
60
|
* Loading placeholder. `block` fills its box, `text` takes one line of the surrounding text,
|
|
@@ -13,15 +13,12 @@ export declare function PageHeaderSkeleton({ avatar, actions, }: {
|
|
|
13
13
|
export declare function PanelSkeleton({ rows }: {
|
|
14
14
|
rows?: number;
|
|
15
15
|
}): import("react").JSX.Element;
|
|
16
|
-
/** Stands in for list rows: a line of text over a line of small print, then a status chip. */
|
|
17
16
|
export declare function ListRowsSkeleton({ rows }: {
|
|
18
17
|
rows?: number;
|
|
19
18
|
}): import("react").JSX.Element;
|
|
20
|
-
/** Stands in for a stat tile: its label, a small badge for the figure, and a line of small print. */
|
|
21
19
|
export declare function StatTileSkeleton({ className }: {
|
|
22
20
|
className?: string;
|
|
23
21
|
}): import("react").JSX.Element;
|
|
24
|
-
/** Stands in for a card: a title and its meta line, labelled bars, and a takeaway under a rule. */
|
|
25
22
|
export declare function CardSkeleton({ bars }: {
|
|
26
23
|
bars?: number;
|
|
27
24
|
}): import("react").JSX.Element;
|