@ciridae/ui 1.0.2 → 1.0.4
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/dist/app/auth.d.ts +10 -0
- package/dist/app/auth.js +60 -0
- package/dist/app/error-boundary.d.ts +18 -0
- package/dist/app/error-boundary.js +45 -0
- package/dist/app/feedback.d.ts +12 -0
- package/dist/app/feedback.js +128 -0
- package/dist/app/index.d.ts +8 -0
- package/dist/app/index.js +8 -0
- package/dist/app/request-errors.d.ts +63 -0
- package/dist/app/request-errors.js +172 -0
- package/dist/app/sentry.d.ts +18 -0
- package/dist/app/sentry.js +52 -0
- package/dist/app/telemetry.d.ts +7 -0
- package/dist/app/telemetry.js +28 -0
- package/dist/app/trail.d.ts +9 -0
- package/dist/app/trail.js +18 -0
- package/dist/chat/chat-query-keys.d.ts +3 -3
- package/dist/chat/contract.d.ts +15 -15
- package/dist/chat/conversation-items-query-options.d.ts +114 -114
- package/dist/chat/conversation-source.d.ts +89 -0
- package/dist/chat/conversation-source.js +1 -0
- package/dist/chat/describe-tool-call.d.ts +3 -3
- package/dist/chat/describe-tool-call.js +3 -3
- package/dist/chat/message-text.d.ts +1 -1
- package/dist/chat/message-text.js +116 -48
- package/dist/chat/use-conversation-list.d.ts +6 -6
- package/dist/ciridae.css +16 -4
- package/dist/components/activity-feed.d.ts +3 -2
- package/dist/components/activity-feed.js +1 -0
- package/dist/components/agent-work.d.ts +3 -3
- package/dist/components/app-frame.d.ts +91 -0
- package/dist/components/app-frame.js +134 -0
- package/dist/components/app-navigation.d.ts +30 -3
- package/dist/components/app-navigation.js +105 -14
- package/dist/components/badge.d.ts +30 -5
- package/dist/components/badge.js +134 -15
- package/dist/components/brand-icons.d.ts +3 -3
- package/dist/components/bulk-action-bar.d.ts +1 -1
- package/dist/components/bulk-action-bar.js +3 -3
- package/dist/components/button.d.ts +12 -5
- package/dist/components/button.js +77 -44
- package/dist/components/calendar.d.ts +1 -1
- package/dist/components/calendar.js +44 -17
- package/dist/components/centered-page.d.ts +1 -1
- package/dist/components/centered-page.js +2 -2
- package/dist/components/chart.d.ts +22 -2
- package/dist/components/chart.js +251 -51
- package/dist/components/chat-client-source.d.ts +16 -0
- package/dist/components/chat-client-source.js +297 -0
- package/dist/components/chat-page.d.ts +9 -8
- package/dist/components/chat-page.js +7 -11
- package/dist/components/chat-sheet-controller.d.ts +11 -14
- package/dist/components/chat-sheet-controller.js +3 -3
- package/dist/components/chat-sheet.d.ts +18 -11
- package/dist/components/chat-sheet.js +188 -289
- package/dist/components/chat.d.ts +109 -19
- package/dist/components/chat.js +520 -124
- package/dist/components/checkbox-item.d.ts +6 -3
- package/dist/components/checkbox-item.js +9 -5
- package/dist/components/checkbox-list.d.ts +1 -1
- package/dist/components/chip.d.ts +6 -1
- package/dist/components/chip.js +27 -1
- package/dist/components/collapsible.d.ts +1 -1
- package/dist/components/color-theme.d.ts +1 -1
- package/dist/components/column-settings.d.ts +1 -1
- package/dist/components/column-settings.js +1 -1
- package/dist/components/command-menu.d.ts +5 -1
- package/dist/components/command-menu.js +98 -32
- package/dist/components/command-palette.d.ts +7 -3
- package/dist/components/command-palette.js +20 -11
- package/dist/components/copyable-id.d.ts +22 -5
- package/dist/components/copyable-id.js +46 -6
- package/dist/components/data-display.d.ts +39 -8
- package/dist/components/data-display.js +138 -19
- package/dist/components/data-grid.d.ts +23 -11
- package/dist/components/data-grid.js +61 -26
- package/dist/components/date-range-picker.d.ts +1 -1
- package/dist/components/date-range-picker.js +9 -20
- package/dist/components/date-time.d.ts +1 -1
- package/dist/components/dialog-height-context.d.ts +1 -1
- package/dist/components/document-viewer.d.ts +2 -2
- package/dist/components/drawer.d.ts +11 -6
- package/dist/components/drawer.js +91 -54
- package/dist/components/dropzone.d.ts +4 -4
- package/dist/components/editable-field.d.ts +12 -3
- package/dist/components/editable-field.js +57 -27
- package/dist/components/email-input.d.ts +1 -1
- package/dist/components/email-input.js +6 -5
- package/dist/components/environment-frame.d.ts +2 -2
- package/dist/components/environment-frame.js +37 -6
- package/dist/components/expandable-text.d.ts +1 -1
- package/dist/components/feedback-screenshot.d.ts +1 -1
- package/dist/components/feedback-sheet.d.ts +18 -3
- package/dist/components/feedback-sheet.js +216 -55
- package/dist/components/field-context.d.ts +1 -1
- package/dist/components/filter-bar.d.ts +3 -3
- package/dist/components/filter-bar.js +43 -29
- package/dist/components/form-controls.d.ts +12 -3
- package/dist/components/form-controls.js +46 -22
- package/dist/components/form-layout.d.ts +14 -10
- package/dist/components/form-layout.js +68 -23
- package/dist/components/glass-menu.d.ts +3 -0
- package/dist/components/glass-menu.js +63 -0
- package/dist/components/gradient-edge.d.ts +9 -0
- package/dist/components/gradient-edge.js +31 -0
- package/dist/components/hotkeys.d.ts +2 -2
- package/dist/components/icon.d.ts +1 -1
- package/dist/components/input.d.ts +7 -5
- package/dist/components/input.js +29 -17
- package/dist/components/keyboard-shortcuts.d.ts +2 -2
- package/dist/components/keycap.d.ts +10 -6
- package/dist/components/keycap.js +57 -19
- package/dist/components/layout.d.ts +13 -13
- package/dist/components/lightbox.d.ts +9 -3
- package/dist/components/lightbox.js +13 -9
- package/dist/components/link.d.ts +1 -1
- package/dist/components/locale.d.ts +42 -2
- package/dist/components/locale.js +43 -3
- package/dist/components/log-entry.d.ts +40 -0
- package/dist/components/log-entry.js +146 -0
- package/dist/components/log-list.d.ts +3 -3
- package/dist/components/mention-input.d.ts +2 -2
- package/dist/components/mention-input.js +4 -3
- package/dist/components/menu.d.ts +7 -3
- package/dist/components/menu.js +34 -37
- package/dist/components/meter.d.ts +10 -2
- package/dist/components/meter.js +64 -6
- package/dist/components/navigation.d.ts +21 -4
- package/dist/components/navigation.js +84 -19
- package/dist/components/notification-tray.d.ts +1 -1
- package/dist/components/notification-tray.js +5 -4
- package/dist/components/overlays.d.ts +6 -4
- package/dist/components/overlays.js +69 -40
- package/dist/components/page-frame.d.ts +4 -4
- package/dist/components/page-frame.js +1 -1
- package/dist/components/panel.d.ts +4 -4
- package/dist/components/panel.js +18 -12
- package/dist/components/profile-header.d.ts +1 -1
- package/dist/components/progress.d.ts +1 -1
- package/dist/components/project-avatar.d.ts +1 -1
- package/dist/components/radio-card.d.ts +2 -2
- package/dist/components/radio-card.js +10 -9
- package/dist/components/record.d.ts +29 -5
- package/dist/components/record.js +147 -18
- package/dist/components/resolved-file-url.d.ts +19 -0
- package/dist/components/resolved-file-url.js +49 -0
- package/dist/components/scroll-area.d.ts +1 -1
- package/dist/components/secret-dialog.d.ts +1 -1
- package/dist/components/segmented-bar.d.ts +4 -2
- package/dist/components/segmented-bar.js +16 -6
- package/dist/components/select.d.ts +9 -6
- package/dist/components/select.js +103 -127
- package/dist/components/settings.d.ts +4 -4
- package/dist/components/shell-skeleton.d.ts +1 -1
- package/dist/components/shell-skeleton.js +1 -1
- package/dist/components/shell.d.ts +21 -21
- package/dist/components/shell.js +43 -43
- package/dist/components/side-panel.d.ts +3 -3
- package/dist/components/sidebar.d.ts +13 -8
- package/dist/components/sidebar.js +55 -27
- package/dist/components/single-line-text.d.ts +2 -0
- package/dist/components/single-line-text.js +16 -0
- package/dist/components/site-banner.d.ts +5 -2
- package/dist/components/site-banner.js +17 -6
- package/dist/components/skeleton.d.ts +8 -7
- package/dist/components/skeleton.js +28 -16
- package/dist/components/skeletons.d.ts +17 -5
- package/dist/components/skeletons.js +71 -8
- package/dist/components/stages.d.ts +83 -11
- package/dist/components/stages.js +512 -156
- package/dist/components/stat-card.d.ts +12 -4
- package/dist/components/stat-card.js +92 -37
- package/dist/components/status-banner.d.ts +1 -1
- package/dist/components/status-banner.js +1 -1
- package/dist/components/status.d.ts +2 -2
- package/dist/components/steps.d.ts +1 -1
- package/dist/components/switch.d.ts +1 -1
- package/dist/components/tabs.d.ts +8 -8
- package/dist/components/tabs.js +26 -13
- package/dist/components/theme-customizer.d.ts +2 -2
- package/dist/components/theme-toggle.d.ts +4 -0
- package/dist/components/theme-toggle.js +67 -0
- package/dist/components/toast.d.ts +10 -3
- package/dist/components/toast.js +78 -29
- package/dist/components/use-new-version-available.d.ts +6 -0
- package/dist/components/use-new-version-available.js +29 -0
- package/dist/components/user-chip.d.ts +3 -3
- package/dist/components/wizard.d.ts +2 -2
- package/dist/feedback/contract.d.ts +136 -136
- package/dist/feedback/feedback-controller.d.ts +6 -6
- package/dist/feedback/generated/zod.gen.d.ts +28 -28
- package/dist/feedback/operator-contract.d.ts +11 -11
- package/dist/feedback/operator-controller.d.ts +32 -13
- package/dist/feedback/operator-controller.js +44 -11
- package/dist/preset.js +289 -33
- package/dist/styled-system/styles.css +3294 -1079
- package/dist/styled-system/tokens/index.mjs +598 -22
- package/dist/styled-system/tokens/tokens.d.ts +11 -11
- package/dist/styled-system/types/prop-type.d.ts +2 -2
- package/dist/styles.css +16 -4
- package/dist/theme/color.d.ts +3 -0
- package/dist/theme/color.js +5 -0
- package/dist/theme/derive.d.ts +9 -2
- package/dist/theme/derive.js +72 -12
- package/dist/theme/palettes.d.ts +49 -6
- package/dist/theme/palettes.js +84 -15
- package/dist/theme/tokens.d.ts +3 -3
- package/dist/theme/tokens.js +107 -32
- package/package.json +40 -3
package/dist/components/shell.js
CHANGED
|
@@ -7,14 +7,13 @@ import { IconButton, IconButtonSizeContext } from "./button.js";
|
|
|
7
7
|
import { PageHotkeys, useHotkey } from "./hotkeys.js";
|
|
8
8
|
import { icon } from "./icon.js";
|
|
9
9
|
import { useCiridaeLocale } from "./locale.js";
|
|
10
|
+
import { singleLineTextClass } from "./single-line-text.js";
|
|
10
11
|
// The sidebar sits flush against the window; only the main panel is inset from the edges.
|
|
11
12
|
const shell = css({
|
|
12
13
|
display: "flex",
|
|
13
14
|
height: "100dvh",
|
|
14
|
-
paddingBlock: "panel.compact",
|
|
15
|
-
paddingInlineEnd: "panel.compact",
|
|
16
15
|
overflow: "hidden",
|
|
17
|
-
background: "
|
|
16
|
+
background: "token(gradients.canvas)",
|
|
18
17
|
color: "fg.primary",
|
|
19
18
|
// Compact line height leaves clipped text room for its descenders throughout the app frame.
|
|
20
19
|
textStyle: "body",
|
|
@@ -23,24 +22,23 @@ const shell = css({
|
|
|
23
22
|
const sidebar = css({
|
|
24
23
|
display: "flex",
|
|
25
24
|
flexDirection: "column",
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// line beside it: half the difference, plus the main panel's 1px edge.
|
|
30
|
-
_notPhone: {
|
|
31
|
-
paddingTop: "calc((token(sizes.shell.header) - token(sizes.control.default)) / 2 + 1px)",
|
|
32
|
-
},
|
|
25
|
+
// Between the navigation and the footer; the navigation's own groups stand `sidebar.groupGap` apart.
|
|
26
|
+
gap: "sidebar.footerGap",
|
|
27
|
+
paddingBlock: "sidebar.block",
|
|
33
28
|
paddingInline: "sidebar.inline",
|
|
34
29
|
width: "shell.sidebar",
|
|
35
30
|
flexShrink: "0",
|
|
36
31
|
overflowY: "auto",
|
|
37
32
|
// The rail swaps every expanded control for its `data-compact-sidebar` icon twin.
|
|
38
33
|
"& [data-compact-sidebar]": { display: "none" },
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
// A phone's menu always shows the labelled navigation, whatever the desktop sidebar's state.
|
|
35
|
+
_notPhone: {
|
|
36
|
+
"&[data-collapsed]": {
|
|
37
|
+
width: "shell.collapsed",
|
|
38
|
+
alignItems: "center",
|
|
39
|
+
"& [data-expanded-sidebar]": { display: "none" },
|
|
40
|
+
"& [data-compact-sidebar]": { display: "flex" },
|
|
41
|
+
},
|
|
44
42
|
},
|
|
45
43
|
_rail: {
|
|
46
44
|
width: "shell.collapsed",
|
|
@@ -60,7 +58,7 @@ const sidebar = css({
|
|
|
60
58
|
zIndex: "drawer",
|
|
61
59
|
width: "shell.sidebar",
|
|
62
60
|
alignItems: "stretch",
|
|
63
|
-
background: "
|
|
61
|
+
background: "token(gradients.canvas)",
|
|
64
62
|
borderInlineEnd: "1px solid token(colors.border.panel)",
|
|
65
63
|
boxShadow: "card",
|
|
66
64
|
transform: "translateX(-100%)",
|
|
@@ -87,12 +85,15 @@ const main = css({
|
|
|
87
85
|
flexDirection: "column",
|
|
88
86
|
flex: "1",
|
|
89
87
|
minWidth: "0",
|
|
90
|
-
|
|
88
|
+
marginBlock: "panel.compact",
|
|
89
|
+
marginInlineEnd: "panel.compact",
|
|
90
|
+
border: "1px solid token(colors.border.canvas)",
|
|
91
91
|
borderRadius: "action",
|
|
92
|
-
background: "
|
|
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
|
+
margin: "none",
|
|
96
97
|
borderRadius: "0",
|
|
97
98
|
height: "100dvh",
|
|
98
99
|
border: "0",
|
|
@@ -107,7 +108,7 @@ const header = css({
|
|
|
107
108
|
flexShrink: "0",
|
|
108
109
|
paddingInlineEnd: "control.compactInline",
|
|
109
110
|
paddingInlineStart: "control.inline",
|
|
110
|
-
borderBottom: "1px solid token(colors.border.
|
|
111
|
+
borderBottom: "1px solid token(colors.border.divider)",
|
|
111
112
|
"& > :last-child": { minWidth: "0", maxWidth: "100%" },
|
|
112
113
|
// Once the sidebar is gone the header stays one row: the title truncates, the actions keep
|
|
113
114
|
// their width.
|
|
@@ -116,22 +117,25 @@ const header = css({
|
|
|
116
117
|
padding: "panel.default",
|
|
117
118
|
"& > [data-header-title]": {
|
|
118
119
|
minWidth: "0",
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
overflowX: "clip",
|
|
121
|
+
overflowY: "visible",
|
|
121
122
|
textOverflow: "ellipsis",
|
|
122
|
-
|
|
123
|
+
whiteSpace: "nowrap",
|
|
123
124
|
},
|
|
124
125
|
// The actions hold one line: a slicer keeps its value and drops the dimension it names.
|
|
125
126
|
"& > :last-child": { flexShrink: "0", flexWrap: "nowrap" },
|
|
126
127
|
"& [data-slicer-label]": { srOnly: true },
|
|
127
128
|
},
|
|
128
129
|
});
|
|
130
|
+
// The trail's parents; the page itself, last, is in the primary text.
|
|
129
131
|
const headerTitle = css({
|
|
130
132
|
flex: "1",
|
|
131
133
|
minWidth: "0",
|
|
132
134
|
color: "fg.muted",
|
|
135
|
+
_light: { color: "fg.secondary" },
|
|
133
136
|
fontSize: "caption",
|
|
134
137
|
fontWeight: "medium",
|
|
138
|
+
lineHeight: "tight",
|
|
135
139
|
});
|
|
136
140
|
const content = css({
|
|
137
141
|
flex: "1",
|
|
@@ -199,14 +203,14 @@ const sidebarRail = css({
|
|
|
199
203
|
display: "flex",
|
|
200
204
|
flexDirection: "column",
|
|
201
205
|
alignItems: "center",
|
|
202
|
-
gap: "
|
|
206
|
+
gap: "sidebar.groupGap",
|
|
203
207
|
});
|
|
204
208
|
/* One sidebar's content stacks at its container's own gap, so a footer's controls keep their room. */
|
|
205
209
|
const sidebarOnly = css({ display: "flex", flexDirection: "column", gap: "inherit" });
|
|
206
210
|
const sidebarNav = css({
|
|
207
211
|
display: "flex",
|
|
208
212
|
flexDirection: "column",
|
|
209
|
-
gap: "
|
|
213
|
+
gap: "sidebar.groupGap",
|
|
210
214
|
minHeight: "0",
|
|
211
215
|
overflowY: "auto",
|
|
212
216
|
// Scrolling would clip the ring of anything outer-ringed placed among the items.
|
|
@@ -214,11 +218,9 @@ const sidebarNav = css({
|
|
|
214
218
|
});
|
|
215
219
|
const sidebarFooter = css({
|
|
216
220
|
marginTop: "auto",
|
|
217
|
-
// Room above the footer's first control, so it never sits tight under the last nav row.
|
|
218
|
-
paddingTop: "layout.contentGap",
|
|
219
221
|
display: "flex",
|
|
220
222
|
flexDirection: "column",
|
|
221
|
-
gap: "layout.
|
|
223
|
+
gap: "layout.controlGap",
|
|
222
224
|
// A phone shows the footer in its menu at full width, as the expanded sidebar does.
|
|
223
225
|
_rail: { _notPhone: { alignItems: "center" } },
|
|
224
226
|
});
|
|
@@ -268,7 +270,7 @@ const headerActions = css({
|
|
|
268
270
|
display: "flex",
|
|
269
271
|
alignItems: "center",
|
|
270
272
|
justifyContent: "flex-end",
|
|
271
|
-
gap: "layout.
|
|
273
|
+
gap: "layout.tightGap",
|
|
272
274
|
minWidth: "0",
|
|
273
275
|
});
|
|
274
276
|
/** The header's copy of the rail, for widths where the sidebar is gone altogether. */
|
|
@@ -288,9 +290,9 @@ const crumbs = css({
|
|
|
288
290
|
whiteSpace: "nowrap",
|
|
289
291
|
"& > :last-child": {
|
|
290
292
|
minWidth: "0",
|
|
291
|
-
|
|
293
|
+
overflowX: "clip",
|
|
294
|
+
overflowY: "visible",
|
|
292
295
|
textOverflow: "ellipsis",
|
|
293
|
-
lineHeight: "compact",
|
|
294
296
|
},
|
|
295
297
|
_phone: { gap: "layout.tightGap" },
|
|
296
298
|
"& a:hover": { textDecoration: "underline" },
|
|
@@ -329,7 +331,7 @@ export function AppBreadcrumbs({ className, ...props }) {
|
|
|
329
331
|
const { labels } = useCiridaeLocale();
|
|
330
332
|
return _jsx("nav", { "aria-label": labels.shell.breadcrumb, ...props, className: cx(crumbs, className) });
|
|
331
333
|
}
|
|
332
|
-
const crumbSeparator = css({ color: "fg.
|
|
334
|
+
const crumbSeparator = css({ color: "fg.subtle" });
|
|
333
335
|
// The page's title, as its one h1, set in the trail's own type.
|
|
334
336
|
const crumbCurrent = css({
|
|
335
337
|
margin: "none",
|
|
@@ -371,9 +373,9 @@ const account = css({
|
|
|
371
373
|
alignItems: "center",
|
|
372
374
|
gap: "sidebar.markGap",
|
|
373
375
|
width: "100%",
|
|
374
|
-
padding: "
|
|
376
|
+
padding: "control.compactBlock",
|
|
375
377
|
border: "0",
|
|
376
|
-
borderRadius: "
|
|
378
|
+
borderRadius: "keycap",
|
|
377
379
|
background: "transparent",
|
|
378
380
|
color: "inherit",
|
|
379
381
|
font: "inherit",
|
|
@@ -391,25 +393,23 @@ const accountAvatarOnly = css({
|
|
|
391
393
|
cursor: "pointer",
|
|
392
394
|
_focusVisible: { focusRing: "outer" },
|
|
393
395
|
});
|
|
396
|
+
// The name and the detail under it, 4px apart as the design's account row stacks them: each line
|
|
397
|
+
// sits at its type's own height, so without the gap the two would touch.
|
|
394
398
|
const accountCopy = css({
|
|
395
399
|
display: "grid",
|
|
400
|
+
gap: "layout.tightGap",
|
|
396
401
|
flex: "1",
|
|
397
402
|
minWidth: "0",
|
|
398
|
-
"& >
|
|
399
|
-
|
|
400
|
-
textOverflow: "ellipsis",
|
|
401
|
-
whiteSpace: "nowrap",
|
|
402
|
-
lineHeight: "compact",
|
|
403
|
-
},
|
|
404
|
-
"& > :last-child": { color: "fg.muted", fontSize: "caption" },
|
|
403
|
+
"& > strong": { fontWeight: "medium" },
|
|
404
|
+
"& > :nth-child(2)": { color: "fg.muted", fontSize: "caption" },
|
|
405
405
|
});
|
|
406
406
|
/**
|
|
407
|
-
* The signed-in account as a menu trigger: avatar, name, and a detail line, or with
|
|
408
|
-
* avatar alone.
|
|
407
|
+
* The signed-in account as a menu trigger: avatar, name, and a detail line if given, or with
|
|
408
|
+
* `compact` the avatar alone.
|
|
409
409
|
*/
|
|
410
410
|
export function AppAccountButton({ avatar, name, detail, trailing, compact = false, className, ...props }) {
|
|
411
411
|
if (compact) {
|
|
412
412
|
return (_jsx("button", { type: "button", ...props, className: cx(accountAvatarOnly, className), children: avatar }));
|
|
413
413
|
}
|
|
414
|
-
return (_jsxs("button", { type: "button", ...props, className: cx(account, className), children: [avatar, _jsxs("span", { className: accountCopy, children: [_jsx("strong", { children: name }), _jsx("span", { children: detail })] }), trailing] }));
|
|
414
|
+
return (_jsxs("button", { type: "button", ...props, className: cx(account, className), children: [avatar, _jsxs("span", { className: accountCopy, children: [_jsx("strong", { className: singleLineTextClass, children: name }), detail && _jsx("span", { className: singleLineTextClass, children: detail })] }), trailing] }));
|
|
415
415
|
}
|
|
@@ -27,10 +27,10 @@ export type SidePanelProps = Omit<ComponentProps<"aside">, "title"> & {
|
|
|
27
27
|
* optional previous / next stepper, actions and close, a scrolling body and a footer. Put it beside
|
|
28
28
|
* the list in a `SidePanelLayout`.
|
|
29
29
|
*/
|
|
30
|
-
export declare function SidePanel({ title, eyebrow, subtitle, titleAccessory, actions, headerContent, footer, onClose, stepper, onPrevious, onNext, flushBody, bodyClassName, className, children, ...props }: SidePanelProps): import("
|
|
30
|
+
export declare function SidePanel({ title, eyebrow, subtitle, titleAccessory, actions, headerContent, footer, onClose, stepper, onPrevious, onNext, flushBody, bodyClassName, className, children, ...props }: SidePanelProps): import("react").JSX.Element;
|
|
31
31
|
/** A list and its `SidePanel` side by side; the list takes the room the panel leaves. */
|
|
32
|
-
export declare function SidePanelLayout({ className, ...props }: ComponentProps<"div">): import("
|
|
32
|
+
export declare function SidePanelLayout({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
33
33
|
/** A labelled block of a side panel's body. */
|
|
34
34
|
export declare function SidePanelSection({ label, className, children, ...props }: Omit<ComponentProps<"section">, "title"> & {
|
|
35
35
|
label: ReactNode;
|
|
36
|
-
}): import("
|
|
36
|
+
}): import("react").JSX.Element;
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { useRender } from "@base-ui/react/use-render";
|
|
2
2
|
import type { ComponentProps, ReactNode } from "react";
|
|
3
|
-
export declare function SidebarNavigation({ className, ...props }: ComponentProps<"nav">): import("
|
|
4
|
-
export declare function SidebarDivider({ className, ...props }: ComponentProps<"hr">): import("
|
|
5
|
-
|
|
3
|
+
export declare function SidebarNavigation({ className, ...props }: ComponentProps<"nav">): import("react").JSX.Element;
|
|
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
|
+
export declare function SidebarRailRule({ className, ...props }: ComponentProps<"hr">): import("react").JSX.Element;
|
|
7
|
+
export declare function SidebarPanel({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
6
8
|
export declare function SidebarSection({ label, action, iconTone, className, children, ...props }: ComponentProps<"div"> & {
|
|
7
9
|
label?: ReactNode;
|
|
8
10
|
action?: ReactNode;
|
|
9
11
|
iconTone?: "bronze";
|
|
10
|
-
}): import("
|
|
12
|
+
}): import("react").JSX.Element;
|
|
11
13
|
/** The subject a sidebar is scoped to, such as the open project. */
|
|
12
14
|
export declare function SidebarHeading({ icon, className, children, ...props }: ComponentProps<"button"> & {
|
|
13
15
|
icon?: ReactNode;
|
|
14
|
-
}): import("
|
|
16
|
+
}): import("react").JSX.Element;
|
|
15
17
|
/**
|
|
16
18
|
* A sidebar row. Without children it renders icon-only, for the rail; give it an `aria-label`
|
|
17
19
|
* then, since the label is what names it.
|
|
@@ -29,7 +31,10 @@ export type SidebarItemProps = useRender.ComponentProps<"button"> & {
|
|
|
29
31
|
active?: boolean;
|
|
30
32
|
/** Tint the leading icon bronze while inactive, as the Projects hub sidebar does. */
|
|
31
33
|
iconTone?: "bronze";
|
|
32
|
-
/**
|
|
33
|
-
|
|
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
|
+
size?: "regular" | "compact" | "short";
|
|
34
39
|
};
|
|
35
|
-
export declare function SidebarItem({ icon, trailing, action, active, iconTone, size, href, render, className, children, ...props }: SidebarItemProps): import("
|
|
40
|
+
export declare function SidebarItem({ icon, trailing, action, active, iconTone, size, href, render, className, children, ...props }: SidebarItemProps): import("react").JSX.Element;
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useRender } from "@base-ui/react/use-render";
|
|
3
3
|
import { css, cx } from "#primitives/css";
|
|
4
4
|
import { IconButtonSizeContext } from "./button.js";
|
|
5
|
+
import { singleLineText } from "./single-line-text.js";
|
|
5
6
|
// Navigation sits in the shell's sidebar; it is not a panel of its own.
|
|
6
7
|
const navigation = css({
|
|
7
8
|
display: "flex",
|
|
@@ -33,6 +34,17 @@ const sectionLabel = css({
|
|
|
33
34
|
"&[data-icon-tone=bronze] > svg": { color: "accent.bronze" },
|
|
34
35
|
});
|
|
35
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
|
+
const railRule = css({
|
|
39
|
+
flexShrink: "0",
|
|
40
|
+
width: "sidebar.railRule",
|
|
41
|
+
height: "border.hairline",
|
|
42
|
+
marginTop: "none",
|
|
43
|
+
marginInline: "auto",
|
|
44
|
+
marginBottom: "panel.default",
|
|
45
|
+
border: "0",
|
|
46
|
+
background: "border.divider",
|
|
47
|
+
});
|
|
36
48
|
const divider = css({
|
|
37
49
|
width: "100%",
|
|
38
50
|
height: "border.hairline",
|
|
@@ -40,15 +52,20 @@ const divider = css({
|
|
|
40
52
|
border: "0",
|
|
41
53
|
background: "border.hairline",
|
|
42
54
|
});
|
|
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
|
+
*/
|
|
43
60
|
const item = css({
|
|
44
61
|
display: "flex",
|
|
45
62
|
alignItems: "center",
|
|
46
63
|
gap: "layout.controlGap",
|
|
47
64
|
width: "100%",
|
|
48
|
-
height: "control.
|
|
65
|
+
height: "control.row",
|
|
49
66
|
paddingInline: "control.compactInline",
|
|
50
67
|
border: "0",
|
|
51
|
-
borderRadius: "
|
|
68
|
+
borderRadius: "nav",
|
|
52
69
|
background: "transparent",
|
|
53
70
|
// Muted against the dark canvas; light keeps every item at full contrast, as Round 2 does.
|
|
54
71
|
color: "fg.muted",
|
|
@@ -60,24 +77,30 @@ const item = css({
|
|
|
60
77
|
lineHeight: "tight",
|
|
61
78
|
textAlign: "start",
|
|
62
79
|
cursor: "pointer",
|
|
63
|
-
transitionProperty: "background, color",
|
|
80
|
+
transitionProperty: "background, color, border-radius",
|
|
64
81
|
transitionDuration: "fast",
|
|
65
82
|
"& > svg:first-child": { opacity: ".7" },
|
|
66
83
|
"&[data-icon-tone=bronze] > svg:first-child": { color: "accent.bronze" },
|
|
67
84
|
"&:hover, &[aria-pressed=true]": {
|
|
68
|
-
|
|
85
|
+
borderRadius: "shell",
|
|
86
|
+
background: "token(gradients.selected)",
|
|
87
|
+
_light: { background: "bg.rowHover" },
|
|
69
88
|
color: "fg.primary",
|
|
70
89
|
"& > svg:first-child": { color: "inherit" },
|
|
71
90
|
},
|
|
72
|
-
// The open page keeps the hover shape and size
|
|
73
|
-
//
|
|
91
|
+
// The open page keeps the hover shape and size; the field face and the canvas's edge mark it.
|
|
92
|
+
// The design counts that edge inside the row, so its content sits a hairline further in.
|
|
74
93
|
"&[aria-current=page]": {
|
|
75
|
-
|
|
76
|
-
|
|
94
|
+
borderRadius: "shell",
|
|
95
|
+
background: "bg.field",
|
|
96
|
+
boxShadow: "inset 0 0 0 1px token(colors.border.canvas)",
|
|
77
97
|
color: "fg.primary",
|
|
78
98
|
"& > svg:first-child": { color: "inherit", opacity: "1" },
|
|
99
|
+
"&:not([data-icon-only])": {
|
|
100
|
+
paddingInline: "calc(token(spacing.control.compactInline) + token(sizes.border.hairline))",
|
|
101
|
+
},
|
|
79
102
|
},
|
|
80
|
-
_focusVisible: { focusRing: "
|
|
103
|
+
_focusVisible: { borderRadius: "shell", focusRing: "outer" },
|
|
81
104
|
// A secondary list under the navigation, such as recently opened records: a shorter row in
|
|
82
105
|
// smaller, quieter text, so it reads apart from the pages above it.
|
|
83
106
|
"&[data-size=compact]": {
|
|
@@ -85,23 +108,19 @@ const item = css({
|
|
|
85
108
|
color: "fg.secondary",
|
|
86
109
|
fontSize: "caption",
|
|
87
110
|
},
|
|
88
|
-
//
|
|
111
|
+
// A shorter row in the body type, such as the settings sidebar's way back to the app.
|
|
112
|
+
"&[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.
|
|
89
114
|
"&[data-icon-only]": {
|
|
90
115
|
justifyContent: "center",
|
|
91
|
-
width: "control.
|
|
92
|
-
height: "control.
|
|
116
|
+
width: "control.compact",
|
|
117
|
+
height: "control.compact",
|
|
93
118
|
paddingInline: "none",
|
|
94
|
-
|
|
119
|
+
borderRadius: "round",
|
|
120
|
+
"& > svg:first-child": { opacity: "1", fontSize: "icon.small" },
|
|
95
121
|
},
|
|
96
122
|
});
|
|
97
|
-
const label = css({
|
|
98
|
-
minWidth: "0",
|
|
99
|
-
flex: "1",
|
|
100
|
-
overflow: "hidden",
|
|
101
|
-
textOverflow: "ellipsis",
|
|
102
|
-
whiteSpace: "nowrap",
|
|
103
|
-
lineHeight: "compact",
|
|
104
|
-
});
|
|
123
|
+
const label = css(singleLineText, { flex: "1" });
|
|
105
124
|
const trailingStyle = css({ display: "inline-flex", flexShrink: "0", color: "fg.subtle" });
|
|
106
125
|
// A row with an action: the group draws the row's hover, open-page fill and edge, so they span the
|
|
107
126
|
// action too, and the row inside it stays transparent.
|
|
@@ -110,21 +129,26 @@ const itemGroup = css({
|
|
|
110
129
|
alignItems: "center",
|
|
111
130
|
width: "100%",
|
|
112
131
|
minWidth: "0",
|
|
113
|
-
borderRadius: "
|
|
114
|
-
transitionProperty: "background",
|
|
132
|
+
borderRadius: "nav",
|
|
133
|
+
transitionProperty: "background, border-radius",
|
|
115
134
|
transitionDuration: "fast",
|
|
116
|
-
"&:hover": {
|
|
135
|
+
"&:hover": {
|
|
136
|
+
borderRadius: "shell",
|
|
137
|
+
background: "token(gradients.selected)",
|
|
138
|
+
_light: { background: "bg.rowHover" },
|
|
139
|
+
},
|
|
117
140
|
"&:hover > [data-sidebar-row]": { color: "fg.primary" },
|
|
118
141
|
"&:has(> [data-sidebar-row][aria-current=page])": {
|
|
119
|
-
|
|
120
|
-
|
|
142
|
+
borderRadius: "shell",
|
|
143
|
+
background: "bg.field",
|
|
144
|
+
boxShadow: "inset 0 0 0 1px token(colors.border.canvas)",
|
|
121
145
|
},
|
|
122
146
|
// The group draws the one wash; the row inside never adds its own on hover or when current.
|
|
123
147
|
"& > [data-sidebar-row]": { minWidth: "0" },
|
|
124
148
|
"& > [data-sidebar-row], & > [data-sidebar-row]:is(:hover, [aria-current=page], [aria-pressed=true])": { background: "transparent", boxShadow: "none" },
|
|
125
149
|
// Focus rings the whole row, action included, not just the link inside it.
|
|
126
150
|
"& > [data-sidebar-row]:focus-visible": { outline: "none" },
|
|
127
|
-
"&:has(> [data-sidebar-row]:focus-visible)": { focusRing: "
|
|
151
|
+
"&:has(> [data-sidebar-row]:focus-visible)": { borderRadius: "shell", focusRing: "outer" },
|
|
128
152
|
"&:hover > [data-sidebar-action], & > [data-sidebar-action]:focus-within": { opacity: "1" },
|
|
129
153
|
});
|
|
130
154
|
// Revealed on hover or focus; always shown where there is no hover to reveal it.
|
|
@@ -171,6 +195,10 @@ export function SidebarNavigation({ className, ...props }) {
|
|
|
171
195
|
export function SidebarDivider({ className, ...props }) {
|
|
172
196
|
return _jsx("hr", { ...props, className: cx(divider, className), "data-ciridae-ui": "" });
|
|
173
197
|
}
|
|
198
|
+
/** Opens a labelled section in the rail, as its label does in the expanded sidebar. */
|
|
199
|
+
export function SidebarRailRule({ className, ...props }) {
|
|
200
|
+
return _jsx("hr", { ...props, className: cx(railRule, className), "data-ciridae-ui": "" });
|
|
201
|
+
}
|
|
174
202
|
export function SidebarPanel({ className, ...props }) {
|
|
175
203
|
return _jsx("div", { ...props, className: cx(panel, className), "data-ciridae-ui": "" });
|
|
176
204
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { css } from "#primitives/css";
|
|
2
|
+
/*
|
|
3
|
+
* One line of text at the type's own height, as the design sets every single-line label, cut
|
|
4
|
+
* with an ellipsis when it runs out of room. It clips sideways only, so the descenders that reach
|
|
5
|
+
* below a line box that tight stay whole. Compose it at the top level of a `css()` call, or as the
|
|
6
|
+
* class `singleLineTextClass`: Panda does not extract it from under a nested selector.
|
|
7
|
+
*/
|
|
8
|
+
export const singleLineText = css.raw({
|
|
9
|
+
minWidth: "0",
|
|
10
|
+
overflowX: "clip",
|
|
11
|
+
overflowY: "visible",
|
|
12
|
+
textOverflow: "ellipsis",
|
|
13
|
+
whiteSpace: "nowrap",
|
|
14
|
+
lineHeight: "tight",
|
|
15
|
+
});
|
|
16
|
+
export const singleLineTextClass = css(singleLineText);
|
|
@@ -19,7 +19,10 @@ declare const banner: import("../styled-system/types/index.js").RecipeRuntimeFn<
|
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
}>;
|
|
22
|
-
export type SiteBannerProps = ComponentProps<"div"> & RecipeVariantProps<typeof banner
|
|
22
|
+
export type SiteBannerProps = ComponentProps<"div"> & RecipeVariantProps<typeof banner> & {
|
|
23
|
+
/** Adds a close button at the strip's end. */
|
|
24
|
+
onDismiss?: () => void;
|
|
25
|
+
};
|
|
23
26
|
/** A quiet, full-width site notice, separate from page-level status banners. */
|
|
24
|
-
export declare function SiteBanner({ tone, className, ...props }: SiteBannerProps): import("
|
|
27
|
+
export declare function SiteBanner({ tone, onDismiss, className, children, ...props }: SiteBannerProps): import("react").JSX.Element;
|
|
25
28
|
export {};
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { XIcon } from "@phosphor-icons/react";
|
|
3
|
+
import { css, cva, cx } from "#primitives/css";
|
|
4
|
+
import { IconButton } from "./button.js";
|
|
5
|
+
import { icon } from "./icon.js";
|
|
6
|
+
import { useCiridaeLocale } from "./locale.js";
|
|
3
7
|
const banner = cva({
|
|
4
8
|
base: {
|
|
9
|
+
display: "flex",
|
|
10
|
+
alignItems: "center",
|
|
11
|
+
gap: "layout.controlGap",
|
|
5
12
|
flexShrink: "0",
|
|
6
13
|
width: "100%",
|
|
7
14
|
boxSizing: "border-box",
|
|
8
|
-
paddingBlock: "
|
|
9
|
-
paddingInline: "
|
|
15
|
+
paddingBlock: "control.trackInset",
|
|
16
|
+
paddingInline: "control.inline",
|
|
10
17
|
textAlign: "start",
|
|
11
18
|
fontSize: "11px",
|
|
12
19
|
fontWeight: "medium",
|
|
@@ -24,7 +31,11 @@ const banner = cva({
|
|
|
24
31
|
},
|
|
25
32
|
defaultVariants: { tone: "info" },
|
|
26
33
|
});
|
|
34
|
+
const message = css({ flex: "1", minWidth: "0" });
|
|
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)" });
|
|
27
37
|
/** A quiet, full-width site notice, separate from page-level status banners. */
|
|
28
|
-
export function SiteBanner({ tone, className, ...props }) {
|
|
29
|
-
|
|
38
|
+
export function SiteBanner({ tone, onDismiss, className, children, ...props }) {
|
|
39
|
+
const { labels } = useCiridaeLocale();
|
|
40
|
+
return (_jsxs("div", { ...props, className: cx(banner({ tone }), className), children: [_jsx("span", { className: message, children: children }), onDismiss && (_jsx(IconButton, { "aria-label": labels.common.dismiss, variant: "ghost", size: "compact", className: dismissButton, onClick: onDismiss, children: _jsx(XIcon, { className: icon({ size: "compact" }) }) }))] }));
|
|
30
41
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { ComponentProps } from "react";
|
|
2
2
|
export type SkeletonWidth = "short" | "medium" | "long" | "full" | `${number}%`;
|
|
3
|
-
export type SkeletonHeight = "text" | "caption" | "control" | "row" | "block" | "chart" | "chart.small" | "chart.medium" | "chart.large";
|
|
3
|
+
export type SkeletonHeight = "text" | "caption" | "line" | "smallLine" | "bar" | "badge" | "control" | "row" | "block" | "chart" | "chart.small" | "chart.medium" | "chart.large";
|
|
4
4
|
/**
|
|
5
|
-
* Loading placeholder
|
|
6
|
-
*
|
|
7
|
-
* length, `full`, or a percentage of its box) and `height` (a line of text
|
|
8
|
-
*
|
|
5
|
+
* Loading placeholder. `block` fills its box, `text` takes one line of the surrounding text,
|
|
6
|
+
* `circle` stands in for an avatar, `square` for a checkbox, and `pill` for a status chip. Size it
|
|
7
|
+
* with `width` (a token length, `full`, or a percentage of its box) and `height` (a line of text
|
|
8
|
+
* or small print, the design's fixed line or small line, a bar, a small badge, a control, a list
|
|
9
|
+
* row, the whole box, or a chart's height).
|
|
9
10
|
*/
|
|
10
11
|
export declare function Skeleton({ shape, width, height, className, style, ...props }: ComponentProps<"span"> & {
|
|
11
|
-
shape?: "block" | "text" | "circle" | "square";
|
|
12
|
+
shape?: "block" | "text" | "circle" | "square" | "pill";
|
|
12
13
|
/** A token width, for a value of roughly known length, or a share of the box such as `"60%"`. */
|
|
13
14
|
width?: SkeletonWidth;
|
|
14
15
|
height?: SkeletonHeight;
|
|
15
|
-
}): import("
|
|
16
|
+
}): import("react").JSX.Element;
|
|
@@ -1,43 +1,54 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { css, cx } from "#primitives/css";
|
|
3
|
+
// The design draws placeholders flat, with no shimmer: the canvas's gradient in light, a white
|
|
4
|
+
// wash in dark. Every bar is fully rounded except the block, the box and the bar.
|
|
3
5
|
const skeleton = css({
|
|
4
6
|
display: "block",
|
|
5
7
|
flexShrink: "0",
|
|
6
|
-
background: "token(gradients.
|
|
7
|
-
|
|
8
|
-
animation: "skeletonShimmer 1.6s ease-in-out infinite",
|
|
9
|
-
_motionReduce: { animation: "none" },
|
|
10
|
-
"&[data-shape=block]": { minHeight: "skeleton.line", borderRadius: "action" },
|
|
8
|
+
background: "token(gradients.skeletonFill)",
|
|
9
|
+
"&[data-shape=block]": { minHeight: "skeleton.line", borderRadius: "control" },
|
|
11
10
|
// One line of the surrounding text: the bar is shorter than the line box and centered in it.
|
|
12
11
|
"&[data-shape=text]": {
|
|
13
12
|
width: "100%",
|
|
14
13
|
height: "0.75em",
|
|
15
14
|
marginBlock: "calc((1lh - 0.75em) / 2)",
|
|
16
|
-
borderRadius: "
|
|
15
|
+
borderRadius: "round",
|
|
17
16
|
},
|
|
18
17
|
"&[data-shape=circle]": {
|
|
19
|
-
width: "
|
|
18
|
+
width: "avatar.menu",
|
|
20
19
|
aspectRatio: "1",
|
|
21
20
|
borderRadius: "round",
|
|
22
21
|
},
|
|
23
22
|
"&[data-shape=square]": {
|
|
24
|
-
width: "control.
|
|
23
|
+
width: "control.checkbox",
|
|
25
24
|
aspectRatio: "1",
|
|
26
|
-
borderRadius: "
|
|
25
|
+
borderRadius: "control",
|
|
26
|
+
},
|
|
27
|
+
// A status chip's or a badge's placeholder.
|
|
28
|
+
"&[data-shape=pill]": {
|
|
29
|
+
width: "skeleton.pill",
|
|
30
|
+
height: "skeleton.bar",
|
|
31
|
+
borderRadius: "round",
|
|
27
32
|
},
|
|
28
33
|
"&[data-shape][data-width=short]": { width: "skeleton.short" },
|
|
29
34
|
"&[data-shape][data-width=medium]": { width: "skeleton.medium" },
|
|
30
35
|
"&[data-shape][data-width=long]": { width: "skeleton.long" },
|
|
31
36
|
"&[data-shape][data-width=full]": { width: "100%" },
|
|
32
|
-
// A line of
|
|
37
|
+
// A line of small print, such as a row's meta line, under a line of text.
|
|
33
38
|
"&[data-shape][data-height=caption]": {
|
|
34
|
-
height: "
|
|
35
|
-
marginBlock: "calc((1lh - token(
|
|
39
|
+
height: "skeleton.caption",
|
|
40
|
+
marginBlock: "calc((1lh - token(sizes.skeleton.caption)) / 2)",
|
|
36
41
|
},
|
|
37
42
|
"&[data-shape][data-height=text]": {
|
|
38
43
|
height: "0.75em",
|
|
39
44
|
marginBlock: "calc((1lh - 0.75em) / 2)",
|
|
40
45
|
},
|
|
46
|
+
// 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: "0" },
|
|
48
|
+
"&[data-shape][data-height=smallLine]": { height: "skeleton.caption", marginBlock: "0" },
|
|
49
|
+
// A bar in a chart's or a breakdown's placeholder, and a small badge's.
|
|
50
|
+
"&[data-shape][data-height=bar]": { height: "skeleton.bar", marginBlock: "0" },
|
|
51
|
+
"&[data-shape][data-height=badge]": { height: "skeleton.badge", marginBlock: "0" },
|
|
41
52
|
"&[data-shape][data-height=control]": { height: "control.default", marginBlock: "0" },
|
|
42
53
|
"&[data-shape][data-height=row]": { height: "control.field", marginBlock: "0" },
|
|
43
54
|
"&[data-shape][data-height=block]": { height: "100%", marginBlock: "0" },
|
|
@@ -49,10 +60,11 @@ const skeleton = css({
|
|
|
49
60
|
"&[data-shape][data-height='chart.large']": { height: "chart.large", marginBlock: "0" },
|
|
50
61
|
});
|
|
51
62
|
/**
|
|
52
|
-
* Loading placeholder
|
|
53
|
-
*
|
|
54
|
-
* length, `full`, or a percentage of its box) and `height` (a line of text
|
|
55
|
-
*
|
|
63
|
+
* Loading placeholder. `block` fills its box, `text` takes one line of the surrounding text,
|
|
64
|
+
* `circle` stands in for an avatar, `square` for a checkbox, and `pill` for a status chip. Size it
|
|
65
|
+
* with `width` (a token length, `full`, or a percentage of its box) and `height` (a line of text
|
|
66
|
+
* or small print, the design's fixed line or small line, a bar, a small badge, a control, a list
|
|
67
|
+
* row, the whole box, or a chart's height).
|
|
56
68
|
*/
|
|
57
69
|
export function Skeleton({ shape = "block", width, height, className, style, ...props }) {
|
|
58
70
|
const percent = width?.endsWith("%") ? width : undefined;
|