@godxjp/ui 18.15.3 → 19.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/date-format-labels.d.ts +1 -1
- package/dist/app/time-format-labels.d.ts +1 -1
- package/dist/components/data-display/badge.d.ts +1 -1
- package/dist/components/data-display/card.d.ts +4 -13
- package/dist/components/data-display/card.js +2 -15
- package/dist/components/data-display/data-table.d.ts +3 -8
- package/dist/components/data-display/data-table.js +106 -68
- package/dist/components/data-display/descriptions.js +34 -5
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/permission-matrix.js +7 -7
- package/dist/components/data-display/popover.js +2 -9
- package/dist/components/data-display/qr-code.d.ts +1 -1
- package/dist/components/data-display/scroll-area.d.ts +3 -1
- package/dist/components/data-display/scroll-area.js +150 -16
- package/dist/components/data-display/table.js +12 -3
- package/dist/components/data-entry/branch-scope-picker.js +4 -4
- package/dist/components/data-entry/calendar.js +15 -24
- package/dist/components/data-entry/cascader.js +67 -71
- package/dist/components/data-entry/checkbox.js +9 -1
- package/dist/components/data-entry/command.d.ts +6 -6
- package/dist/components/data-entry/date-picker.js +28 -15
- package/dist/components/data-entry/date-range-picker.js +10 -10
- package/dist/components/data-entry/form-field.js +7 -3
- package/dist/components/data-entry/index.d.ts +2 -1
- package/dist/components/data-entry/input.js +8 -19
- package/dist/components/data-entry/label.js +4 -2
- package/dist/components/data-entry/month-picker.js +16 -15
- package/dist/components/data-entry/month-range-picker.js +17 -16
- package/dist/components/data-entry/radio.js +6 -1
- package/dist/components/data-entry/search-select.js +29 -29
- package/dist/components/data-entry/select.js +15 -18
- package/dist/components/data-entry/switch.js +7 -1
- package/dist/components/data-entry/textarea.d.ts +56 -0
- package/dist/components/data-entry/textarea.js +103 -40
- package/dist/components/data-entry/time-picker.js +52 -52
- package/dist/components/data-entry/toggle-group.d.ts +1 -0
- package/dist/components/data-entry/toggle.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +14 -15
- package/dist/components/data-entry/tree-select.js +16 -22
- package/dist/components/data-entry/upload-crop-dialog.js +4 -4
- package/dist/components/data-entry/upload.d.ts +1 -1
- package/dist/components/data-entry/upload.js +46 -46
- package/dist/components/feedback/alert.js +7 -14
- package/dist/components/feedback/dialog.d.ts +23 -32
- package/dist/components/feedback/dialog.js +16 -13
- package/dist/components/feedback/sheet.d.ts +1 -1
- package/dist/components/feedback/sheet.js +14 -14
- package/dist/components/feedback/skeleton.js +13 -10
- package/dist/components/feedback/sonner.d.ts +1 -1
- package/dist/components/feedback/sonner.js +17 -8
- package/dist/components/feedback/tooltip.js +1 -1
- package/dist/components/general/activity.d.ts +44 -0
- package/dist/components/general/activity.js +65 -0
- package/dist/components/general/button.d.ts +2 -2
- package/dist/components/general/button.js +11 -24
- package/dist/components/general/index.d.ts +2 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/layout/app-shell.js +5 -3
- package/dist/components/layout/auth-divider.d.ts +9 -2
- package/dist/components/layout/auth-divider.js +7 -11
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +32 -20
- package/dist/components/layout/resizable.d.ts +12 -12
- package/dist/components/layout/separator.d.ts +1 -0
- package/dist/components/layout/service-role-panel.js +47 -42
- package/dist/components/layout/sidebar.js +13 -1
- package/dist/components/layout/split-pane.d.ts +12 -1
- package/dist/components/layout/split-pane.js +13 -4
- package/dist/components/navigation/app-setting-picker.js +5 -14
- package/dist/components/navigation/dropdown-menu.js +10 -16
- package/dist/components/navigation/menubar.d.ts +3 -6
- package/dist/components/navigation/pagination-utils.d.ts +15 -2
- package/dist/components/navigation/pagination-utils.js +27 -21
- package/dist/components/navigation/pagination.d.ts +4 -4
- package/dist/components/navigation/pagination.js +2 -2
- package/dist/components/navigation/steps.js +31 -67
- package/dist/components/navigation/tabs.js +17 -5
- package/dist/components/query/infinite-query-state.js +2 -2
- package/dist/components/ui/accordion.d.ts +1 -1
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +29 -10
- package/dist/components/ui/input-otp.d.ts +8 -6
- package/dist/components/ui/rating.js +1 -1
- package/dist/components/ui/separator.d.ts +27 -2
- package/dist/components/ui/separator.js +42 -11
- package/dist/components/ui/toggle-group.d.ts +15 -5
- package/dist/components/ui/toggle-group.js +43 -18
- package/dist/components/ui/toggle.d.ts +66 -5
- package/dist/components/ui/toggle.js +64 -9
- package/dist/i18n/messages/en.json +8 -0
- package/dist/i18n/messages/ja.json +8 -0
- package/dist/i18n/messages/vi.json +8 -0
- package/dist/lib/control-styles.d.ts +14 -0
- package/dist/lib/control-styles.js +2 -0
- package/dist/props/components/data-display.prop.d.ts +85 -3
- package/dist/props/components/data-entry.prop.d.ts +17 -0
- package/dist/props/components/general.prop.d.ts +52 -1
- package/dist/props/components/layout.prop.d.ts +137 -2
- package/dist/props/registry.d.ts +116 -5
- package/dist/props/registry.js +165 -4
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/interaction.prop.d.ts +15 -0
- package/dist/props/vocabulary/layout.prop.d.ts +8 -0
- package/dist/styles/alert-layout.css +69 -3
- package/dist/styles/badge-layout.css +2 -2
- package/dist/styles/base.css +6 -0
- package/dist/styles/card-layout.css +27 -7
- package/dist/styles/control.css +1150 -29
- package/dist/styles/data-display-layout.css +185 -11
- package/dist/styles/data-entry-layout.css +352 -1
- package/dist/styles/density.css +2 -2
- package/dist/styles/dialog-layout.css +203 -4
- package/dist/styles/focus-ring.css +155 -0
- package/dist/styles/form-layout.css +50 -5
- package/dist/styles/index.css +1 -0
- package/dist/styles/layout.css +412 -23
- package/dist/styles/motion.css +178 -0
- package/dist/styles/navigation-layout.css +398 -22
- package/dist/styles/shell-layout.css +137 -39
- package/dist/styles/table-layout.css +153 -22
- package/dist/styles/toggle.css +59 -0
- package/dist/tokens/base.css +5 -0
- package/dist/tokens/components/activity.css +64 -0
- package/dist/tokens/components/badge.css +7 -0
- package/dist/tokens/components/card.css +14 -10
- package/dist/tokens/components/chart.css +1 -1
- package/dist/tokens/components/control.css +358 -8
- package/dist/tokens/components/data-display.css +75 -0
- package/dist/tokens/components/data-entry.css +25 -0
- package/dist/tokens/components/descriptions.css +22 -0
- package/dist/tokens/components/feedback.css +143 -4
- package/dist/tokens/components/form.css +16 -0
- package/dist/tokens/components/legal-document.css +5 -1
- package/dist/tokens/components/navigation.css +109 -0
- package/dist/tokens/components/scroll-area.css +21 -0
- package/dist/tokens/components/separator.css +52 -0
- package/dist/tokens/components/shell.css +132 -20
- package/dist/tokens/components/table.css +52 -3
- package/dist/tokens/components/toggle.css +82 -0
- package/dist/tokens/components/upload.css +107 -0
- package/dist/tokens/foundation.css +171 -10
- package/dist/tokens/semantic/layout.css +120 -1
- package/package.json +84 -68
- package/scripts/ui-audit.mjs +51 -2
|
@@ -56,7 +56,7 @@ const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
56
56
|
className: cn(
|
|
57
57
|
// Scrim colour comes from the shared --overlay-background token (see dialog-layout.css),
|
|
58
58
|
// so a service tints every overlay's backdrop from one knob instead of a baked bg-black/50.
|
|
59
|
-
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 fixed
|
|
59
|
+
"ui-sheet-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 fixed",
|
|
60
60
|
className
|
|
61
61
|
),
|
|
62
62
|
...props
|
|
@@ -64,7 +64,7 @@ const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
64
64
|
));
|
|
65
65
|
SheetOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
66
66
|
const sheetVariants = cva(
|
|
67
|
-
"fixed
|
|
67
|
+
"ui-sheet-panel fixed flex flex-col gap-[var(--space-chrome-gap)] bg-background px-[var(--sheet-pad-x)] py-[var(--sheet-pad-y)] transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
|
|
68
68
|
{
|
|
69
69
|
variants: {
|
|
70
70
|
// `side` is a deliberately PHYSICAL API (left/right/top/bottom) — a sheet
|
|
@@ -75,8 +75,8 @@ const sheetVariants = cva(
|
|
|
75
75
|
right: "inset-y-0 right-0 h-full w-[min(var(--sheet-width-default),100%)] max-w-none border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
|
|
76
76
|
/* rtl-ignore: named physical side */
|
|
77
77
|
left: "inset-y-0 left-0 h-full w-[min(var(--sheet-width-default),100%)] max-w-none border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
|
|
78
|
-
top: "inset-x-0
|
|
79
|
-
bottom: "inset-x-0
|
|
78
|
+
top: "inset-x-0 h-auto data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
|
79
|
+
bottom: "inset-x-0 h-auto data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom"
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
defaultVariants: { side: "right" }
|
|
@@ -127,9 +127,9 @@ const SheetContent = React.forwardRef(
|
|
|
127
127
|
DialogPrimitive.Close,
|
|
128
128
|
{
|
|
129
129
|
"data-slot": "sheet-close",
|
|
130
|
-
className: "ring-offset-background focus:ring-ring
|
|
130
|
+
className: "ui-sheet-close ring-offset-background focus:ring-ring focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
|
|
131
131
|
children: [
|
|
132
|
-
/* @__PURE__ */ jsx(X, { className: "
|
|
132
|
+
/* @__PURE__ */ jsx(X, { className: "ui-sheet-close-icon", "aria-hidden": "true" }),
|
|
133
133
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("feedback.alert.dismiss") })
|
|
134
134
|
]
|
|
135
135
|
}
|
|
@@ -156,18 +156,18 @@ const SheetHeader = ({
|
|
|
156
156
|
"data-slot": "sheet-header",
|
|
157
157
|
"data-tone": tone,
|
|
158
158
|
className: cn(
|
|
159
|
-
"-mx-[var(--sheet-pad-x)] -mt-[var(--sheet-pad-y)]
|
|
159
|
+
"ui-sheet-header -mx-[var(--sheet-pad-x)] -mt-[var(--sheet-pad-y)] px-[var(--sheet-pad-x)] py-[var(--sheet-pad-y)]",
|
|
160
160
|
overlayHeaderToneClass[tone],
|
|
161
161
|
className
|
|
162
162
|
),
|
|
163
163
|
...props,
|
|
164
164
|
children: children ?? // `pe-8` reserves room for the absolute close button (end-4) so title/extra never sit under it.
|
|
165
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
166
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-sheet-title-row", children: [
|
|
166
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-sheet-title-block", children: [
|
|
167
167
|
title != null && /* @__PURE__ */ jsx(SheetTitle, { children: title }),
|
|
168
168
|
subtitle != null && /* @__PURE__ */ jsx(SheetDescription, { children: subtitle })
|
|
169
169
|
] }),
|
|
170
|
-
extra != null && /* @__PURE__ */ jsx("div", { className: "
|
|
170
|
+
extra != null && /* @__PURE__ */ jsx("div", { className: "ui-sheet-extra", children: extra })
|
|
171
171
|
] })
|
|
172
172
|
}
|
|
173
173
|
);
|
|
@@ -183,7 +183,7 @@ const SheetBody = ({ className, ...props }) => (
|
|
|
183
183
|
{
|
|
184
184
|
"data-slot": "sheet-body",
|
|
185
185
|
className: cn(
|
|
186
|
-
"-mx-[var(--sheet-pad-x)]
|
|
186
|
+
"ui-sheet-body-space -mx-[var(--sheet-pad-x)] flex-1 overflow-y-auto px-[var(--sheet-pad-x)]",
|
|
187
187
|
className
|
|
188
188
|
),
|
|
189
189
|
...props
|
|
@@ -201,7 +201,7 @@ const SheetFooter = ({ className, ...props }) => (
|
|
|
201
201
|
{
|
|
202
202
|
"data-slot": "sheet-footer",
|
|
203
203
|
className: cn(
|
|
204
|
-
"-mx-[var(--sheet-pad-x)] mt-auto -mb-[var(--sheet-pad-y)]
|
|
204
|
+
"ui-sheet-footer-row -mx-[var(--sheet-pad-x)] mt-auto -mb-[var(--sheet-pad-y)] px-[var(--sheet-pad-x)] py-[var(--sheet-pad-y)]",
|
|
205
205
|
className
|
|
206
206
|
),
|
|
207
207
|
...props
|
|
@@ -213,7 +213,7 @@ const SheetTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
213
213
|
{
|
|
214
214
|
ref,
|
|
215
215
|
"data-slot": "sheet-title",
|
|
216
|
-
className: cn("
|
|
216
|
+
className: cn("ui-sheet-title", className),
|
|
217
217
|
...props
|
|
218
218
|
}
|
|
219
219
|
));
|
|
@@ -223,7 +223,7 @@ const SheetDescription = React.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
223
223
|
{
|
|
224
224
|
ref,
|
|
225
225
|
"data-slot": "sheet-description",
|
|
226
|
-
className: cn("
|
|
226
|
+
className: cn("ui-sheet-description", className),
|
|
227
227
|
...props
|
|
228
228
|
}
|
|
229
229
|
));
|
|
@@ -16,19 +16,22 @@ function SkeletonRows({ rows = 6, columns = 4, className }) {
|
|
|
16
16
|
return /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-rows", className), "aria-busy": "true", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "ui-skeleton-row", children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(
|
|
17
17
|
Skeleton,
|
|
18
18
|
{
|
|
19
|
-
className: cn(
|
|
19
|
+
className: cn(
|
|
20
|
+
"ui-skeleton-line",
|
|
21
|
+
j === 0 ? "w-1/4" : j === columns - 1 ? "w-1/6" : "flex-1"
|
|
22
|
+
)
|
|
20
23
|
},
|
|
21
24
|
j
|
|
22
25
|
)) }, i)) });
|
|
23
26
|
}
|
|
24
27
|
function SkeletonTable({ rows = 8, columns = 5 }) {
|
|
25
28
|
return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-table", "aria-busy": "true", children: [
|
|
26
|
-
/* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-table-head", tableCellPaddingClass, tableRowHeightClass), children: Array.from({ length: columns }).map((_, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("
|
|
29
|
+
/* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-table-head", tableCellPaddingClass, tableRowHeightClass), children: Array.from({ length: columns }).map((_, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("ui-skeleton-caption", j === 0 ? "w-1/5" : "flex-1") }, j)) }),
|
|
27
30
|
/* @__PURE__ */ jsx("div", { className: "ui-skeleton-table-body", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsx(
|
|
28
31
|
"div",
|
|
29
32
|
{
|
|
30
33
|
className: cn("ui-skeleton-table-row", tableCellPaddingClass, tableRowHeightClass),
|
|
31
|
-
children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("
|
|
34
|
+
children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("ui-skeleton-line", j === 0 ? "w-1/5" : "flex-1") }, j))
|
|
32
35
|
},
|
|
33
36
|
i
|
|
34
37
|
)) })
|
|
@@ -36,19 +39,19 @@ function SkeletonTable({ rows = 8, columns = 5 }) {
|
|
|
36
39
|
}
|
|
37
40
|
function SkeletonDetail() {
|
|
38
41
|
return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-detail ui-skeleton-detail-stack", "aria-busy": "true", children: [
|
|
39
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
40
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
42
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-title w-1/3" }),
|
|
43
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-line w-1/2" }),
|
|
41
44
|
/* @__PURE__ */ jsx("div", { className: "ui-skeleton-detail-box ui-skeleton-detail-stack", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-detail-stack", children: [
|
|
42
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
43
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
45
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-detail-label" }),
|
|
46
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-detail-value" })
|
|
44
47
|
] }, i)) })
|
|
45
48
|
] });
|
|
46
49
|
}
|
|
47
50
|
function SkeletonStat() {
|
|
48
51
|
return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-stat", "aria-busy": "true", children: [
|
|
49
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
50
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
51
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "
|
|
52
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-detail-label" }),
|
|
53
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-stat-value" }),
|
|
54
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ui-skeleton-stat-caption" })
|
|
52
55
|
] });
|
|
53
56
|
}
|
|
54
57
|
export {
|
|
@@ -20,7 +20,7 @@ function useDocumentTheme() {
|
|
|
20
20
|
() => "light"
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
-
function Toaster({ ...props }) {
|
|
23
|
+
function Toaster({ style, ...props }) {
|
|
24
24
|
const theme = useDocumentTheme();
|
|
25
25
|
return /* @__PURE__ */ jsx(
|
|
26
26
|
Sonner,
|
|
@@ -28,11 +28,11 @@ function Toaster({ ...props }) {
|
|
|
28
28
|
theme,
|
|
29
29
|
className: "toaster group",
|
|
30
30
|
icons: {
|
|
31
|
-
success: /* @__PURE__ */ jsx(CheckCircle2, { className: "
|
|
32
|
-
info: /* @__PURE__ */ jsx(Info, { className: "
|
|
33
|
-
warning: /* @__PURE__ */ jsx(TriangleAlert, { className: "
|
|
34
|
-
error: /* @__PURE__ */ jsx(OctagonX, { className: "
|
|
35
|
-
loading: /* @__PURE__ */ jsx(Loader2, { className: "
|
|
31
|
+
success: /* @__PURE__ */ jsx(CheckCircle2, { className: "ui-toast-icon", "aria-hidden": "true" }),
|
|
32
|
+
info: /* @__PURE__ */ jsx(Info, { className: "ui-toast-icon", "aria-hidden": "true" }),
|
|
33
|
+
warning: /* @__PURE__ */ jsx(TriangleAlert, { className: "ui-toast-icon", "aria-hidden": "true" }),
|
|
34
|
+
error: /* @__PURE__ */ jsx(OctagonX, { className: "ui-toast-icon", "aria-hidden": "true" }),
|
|
35
|
+
loading: /* @__PURE__ */ jsx(Loader2, { className: "ui-toast-icon animate-spin", "aria-hidden": "true" })
|
|
36
36
|
},
|
|
37
37
|
style: {
|
|
38
38
|
// Color tokens are raw HSL triplets (consumed as hsl(var(--token)));
|
|
@@ -42,10 +42,19 @@ function Toaster({ ...props }) {
|
|
|
42
42
|
"--normal-bg": "hsl(var(--popover))",
|
|
43
43
|
"--normal-text": "hsl(var(--popover-foreground))",
|
|
44
44
|
"--normal-border": "hsl(var(--border))",
|
|
45
|
-
"--border-radius": "var(--radius)"
|
|
45
|
+
"--border-radius": "var(--radius)",
|
|
46
|
+
// MERGED, never spread over. `style` used to arrive with the rest of `{...props}` AFTER
|
|
47
|
+
// this object, so a consumer passing ANY style (a z-index, a width) replaced the whole
|
|
48
|
+
// object and wiped all four vars — and an unset `--normal-bg` renders the toast
|
|
49
|
+
// transparent. Merging keeps the surface intact and still lets a consumer override one
|
|
50
|
+
// var by name.
|
|
51
|
+
...style
|
|
46
52
|
},
|
|
47
53
|
position: "bottom-right",
|
|
48
|
-
mobileOffset: {
|
|
54
|
+
mobileOffset: {
|
|
55
|
+
bottom: "var(--toast-mobile-offset)",
|
|
56
|
+
right: "var(--toast-mobile-offset)"
|
|
57
|
+
},
|
|
49
58
|
...props
|
|
50
59
|
}
|
|
51
60
|
);
|
|
@@ -23,7 +23,7 @@ const TooltipContent = React.forwardRef(({ className, sideOffset = 6, children,
|
|
|
23
23
|
"data-slot": "tooltip-content",
|
|
24
24
|
sideOffset,
|
|
25
25
|
className: cn(
|
|
26
|
-
"
|
|
26
|
+
"ui-tooltip-content",
|
|
27
27
|
"data-[state=delayed-open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=delayed-open]:fade-in-0",
|
|
28
28
|
"data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1",
|
|
29
29
|
"data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { SizeProp } from "../../props/vocabulary/index.js";
|
|
3
|
+
export type { ActivityProp, ActivityProp as ActivityProps, } from "../../props/components/general.prop.js";
|
|
4
|
+
/**
|
|
5
|
+
* Activity — the official AMBIENT-motion primitive: a continuous, unbounded "something is happening
|
|
6
|
+
* right now, elsewhere". The LOOP counterpart to `Reveal`'s one-shot entrance, so a consumer never
|
|
7
|
+
* hand-rolls a looping `@keyframes` + its own `prefers-reduced-motion` guard. Every interval,
|
|
8
|
+
* stagger, offset, size and colour reads a DS token (`--activity-interval`,
|
|
9
|
+
* `--activity-stagger-step`, `--activity-mark-offset`, `--activity-color`, …), so a service retunes
|
|
10
|
+
* the whole ambient feel from its theme.
|
|
11
|
+
*
|
|
12
|
+
* NOT `Skeleton` (content is LOADING — it hard-codes `aria-busy` + an unconditional live region, so
|
|
13
|
+
* reusing it for a typing indicator tells every screen reader the region is busy for as long as
|
|
14
|
+
* anyone is typing). NOT `Button loading` (THIS ACTION is in flight, on a control).
|
|
15
|
+
* `Activity` means: someone is typing, a sync is running, a response is streaming, a recording is
|
|
16
|
+
* live — indefinitely, and not here.
|
|
17
|
+
*
|
|
18
|
+
* ACCESSIBILITY — the half consumers get wrong, owned here:
|
|
19
|
+
* - The mark is decorative and always `aria-hidden`; the `label` (or `children`) carries the
|
|
20
|
+
* meaning, so the indicator is never animation-only.
|
|
21
|
+
* - `announce` defaults to `false` and then emits NO live region at all. An ambient indicator
|
|
22
|
+
* flickers on and off with every socket event; a live region there re-announces continuously.
|
|
23
|
+
* `announce="polite"` wraps ONLY the label in one `aria-live="polite" aria-atomic="true"` region.
|
|
24
|
+
* - No `aria-busy`: activity elsewhere does not make THIS region busy, and `aria-busy` would
|
|
25
|
+
* suppress the surrounding content's own updates.
|
|
26
|
+
* - Not focusable, not a tab stop, no pointer affordance — it is a status mark, not a control.
|
|
27
|
+
* - Under `prefers-reduced-motion: reduce` the loop is dropped and every mark falls back to a
|
|
28
|
+
* DESIGNED resting state (three solid dots / a solid pulse mark / a bar segment parked at the
|
|
29
|
+
* reading-start), never to nothing, with no layout shift (WCAG 2.2 SC 2.3.3 and SC 2.2.2).
|
|
30
|
+
*
|
|
31
|
+
* Copy is consumer-owned and localized — pass a `t()`-translated `label`, and derive
|
|
32
|
+
* "N people are typing" from `Intl.PluralRules`. The library never invents the string.
|
|
33
|
+
*
|
|
34
|
+
* Pure/server-safe: no hooks, no effects, no timers — the loop is CSS.
|
|
35
|
+
*/
|
|
36
|
+
export declare const Activity: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLSpanElement>, "color"> & {
|
|
37
|
+
variant?: import("../../props/index.js").ActivityVariantProp;
|
|
38
|
+
size?: SizeProp;
|
|
39
|
+
tone?: import("../../props/index.js").TextToneProp;
|
|
40
|
+
label?: import("../../props/index.js").LabelProp;
|
|
41
|
+
children?: import("../../props/index.js").ChildrenProp;
|
|
42
|
+
announce?: import("../../props/index.js").ActivityAnnounceProp;
|
|
43
|
+
className?: import("../../props/index.js").ClassNameProp;
|
|
44
|
+
} & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../lib/utils.js";
|
|
4
|
+
import { Text } from "./typography.js";
|
|
5
|
+
const LABEL_SIZE = {
|
|
6
|
+
xs: "2xs",
|
|
7
|
+
sm: "xs",
|
|
8
|
+
md: "sm",
|
|
9
|
+
lg: "lg"
|
|
10
|
+
};
|
|
11
|
+
function ActivityMark({ variant }) {
|
|
12
|
+
if (variant === "pulse") return /* @__PURE__ */ jsx("span", { className: "ui-activity-pulse" });
|
|
13
|
+
if (variant === "bar") {
|
|
14
|
+
return /* @__PURE__ */ jsx("span", { className: "ui-activity-bar", children: /* @__PURE__ */ jsx("span", { className: "ui-activity-bar-segment" }) });
|
|
15
|
+
}
|
|
16
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17
|
+
/* @__PURE__ */ jsx("span", { className: "ui-activity-dot" }),
|
|
18
|
+
/* @__PURE__ */ jsx("span", { className: "ui-activity-dot" }),
|
|
19
|
+
/* @__PURE__ */ jsx("span", { className: "ui-activity-dot" })
|
|
20
|
+
] });
|
|
21
|
+
}
|
|
22
|
+
const Activity = React.forwardRef(function Activity2({
|
|
23
|
+
variant = "dots",
|
|
24
|
+
size = "sm",
|
|
25
|
+
tone = "muted",
|
|
26
|
+
label,
|
|
27
|
+
announce = false,
|
|
28
|
+
children,
|
|
29
|
+
className,
|
|
30
|
+
...props
|
|
31
|
+
}, ref) {
|
|
32
|
+
const hasChildren = children !== void 0 && children !== null && children !== false;
|
|
33
|
+
const visible = hasChildren ? children : label;
|
|
34
|
+
const describedOnly = hasChildren && label !== void 0 && label !== null ? label : void 0;
|
|
35
|
+
const text = visible === void 0 || visible === null ? null : /* @__PURE__ */ jsx(Text, { as: "span", size: LABEL_SIZE[size], tone, className: "ui-activity-label", children: visible });
|
|
36
|
+
const description = describedOnly === void 0 ? null : /* @__PURE__ */ jsx("span", { "data-slot": "activity-description", className: "sr-only", children: describedOnly });
|
|
37
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38
|
+
text,
|
|
39
|
+
description
|
|
40
|
+
] });
|
|
41
|
+
return /* @__PURE__ */ jsxs(
|
|
42
|
+
"span",
|
|
43
|
+
{
|
|
44
|
+
ref,
|
|
45
|
+
"data-slot": "activity",
|
|
46
|
+
"data-variant": variant,
|
|
47
|
+
"data-size": size,
|
|
48
|
+
"data-tone": tone,
|
|
49
|
+
className: cn("ui-activity", className),
|
|
50
|
+
...props,
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ jsx("span", { className: "ui-activity-mark", "data-slot": "activity-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx(ActivityMark, { variant }) }),
|
|
53
|
+
announce === "polite" ? (
|
|
54
|
+
// The region wraps ONLY the label and is atomic, so a change is announced once as a whole.
|
|
55
|
+
// It is rendered even while empty so a label that arrives later is heard — an inserted
|
|
56
|
+
// region is not reliably announced. The mark stays outside it.
|
|
57
|
+
/* @__PURE__ */ jsx("span", { "aria-live": "polite", "aria-atomic": "true", "data-slot": "activity-live", children: body })
|
|
58
|
+
) : body
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
export {
|
|
64
|
+
Activity
|
|
65
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
declare const buttonVariants: (props?: ({
|
|
3
|
-
variant?: "
|
|
4
|
-
size?: "default" | "
|
|
3
|
+
variant?: "dashed" | "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
4
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "md" | "sm" | "xs" | null | undefined;
|
|
5
5
|
shape?: "default" | "pill" | "sharp" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export type { ButtonProp, ButtonProp as ButtonProps } from "../../props/components/general.prop.js";
|
|
@@ -6,20 +6,11 @@ import { cva } from "class-variance-authority";
|
|
|
6
6
|
import { Loader2 } from "lucide-react";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
8
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
9
|
-
const buttonCountClass = {
|
|
10
|
-
default: "bg-primary-foreground/15",
|
|
11
|
-
destructive: "bg-destructive-foreground/15",
|
|
12
|
-
secondary: "bg-secondary-foreground/15",
|
|
13
|
-
outline: "bg-foreground/8 text-muted-foreground",
|
|
14
|
-
dashed: "bg-foreground/8 text-muted-foreground",
|
|
15
|
-
ghost: "bg-foreground/8 text-muted-foreground",
|
|
16
|
-
link: "bg-foreground/8 text-muted-foreground"
|
|
17
|
-
};
|
|
18
9
|
const buttonVariants = cva("ui-button", {
|
|
19
10
|
variants: {
|
|
20
11
|
variant: {
|
|
21
12
|
default: "ui-button--default bg-primary text-primary-foreground hover:bg-primary/90",
|
|
22
|
-
destructive: "ui-button--destructive bg-destructive text-destructive-foreground
|
|
13
|
+
destructive: "ui-button--destructive bg-destructive text-destructive-foreground",
|
|
23
14
|
outline: "ui-button--outline border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
24
15
|
dashed: "ui-button--dashed border border-dashed bg-background hover:bg-accent hover:text-accent-foreground",
|
|
25
16
|
secondary: "ui-button--secondary bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
@@ -27,13 +18,16 @@ const buttonVariants = cva("ui-button", {
|
|
|
27
18
|
link: "ui-button--link text-primary underline-offset-4 hover:underline"
|
|
28
19
|
},
|
|
29
20
|
size: {
|
|
30
|
-
default: "ui-button--default-size
|
|
31
|
-
md: "ui-button--default-size
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
default: "ui-button--default-size",
|
|
22
|
+
md: "ui-button--default-size",
|
|
23
|
+
// The glyph rules stay UTILITIES, not a components-layer rule: Tailwind v4 orders
|
|
24
|
+
// utilities after components, so only a utility can out-rank a child's own `size-*`.
|
|
25
|
+
// They read the token, so the value is still themeable.
|
|
26
|
+
xs: "ui-button--xs [&_svg:not([class*='size-'])]:size-[var(--button-xs-icon-size)]",
|
|
27
|
+
sm: "ui-button--sm",
|
|
28
|
+
lg: "ui-button--lg",
|
|
35
29
|
icon: "ui-button--icon",
|
|
36
|
-
"icon-xs": "ui-button--icon-xs [&_svg]:size-
|
|
30
|
+
"icon-xs": "ui-button--icon-xs [&_svg]:size-[var(--button-xs-icon-size)] [&_svg]:shrink-0",
|
|
37
31
|
"icon-sm": "ui-button--icon-sm",
|
|
38
32
|
"icon-lg": "ui-button--icon-lg"
|
|
39
33
|
},
|
|
@@ -79,10 +73,7 @@ const Button = React.forwardRef(
|
|
|
79
73
|
"span",
|
|
80
74
|
{
|
|
81
75
|
"data-slot": "button-count",
|
|
82
|
-
className:
|
|
83
|
-
"inline-flex min-w-4 items-center justify-center rounded-[var(--radius-pill)] px-1 text-xs leading-none tabular-nums",
|
|
84
|
-
buttonCountClass[variant ?? "default"]
|
|
85
|
-
),
|
|
76
|
+
className: "ui-button-count",
|
|
86
77
|
children: countLabel
|
|
87
78
|
}
|
|
88
79
|
) : null;
|
|
@@ -99,11 +90,7 @@ const Button = React.forwardRef(
|
|
|
99
90
|
disabled: isLoading || disabled,
|
|
100
91
|
type: asChild ? void 0 : type ?? "button",
|
|
101
92
|
className: cn(
|
|
102
|
-
"inline-flex shrink-0 items-center justify-center gap-2 text-sm font-medium whitespace-nowrap transition-all outline-none",
|
|
103
93
|
fullWidth && "w-full",
|
|
104
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
105
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
106
|
-
"data-[loading]:pointer-events-none",
|
|
107
94
|
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
108
95
|
"[&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
109
96
|
buttonVariants({ variant, size, shape, className })
|
|
@@ -6,3 +6,5 @@ export { Logo } from "./logo.js";
|
|
|
6
6
|
export type { LogoMark, LogoProps, LogoSize, LogoTone } from "./logo.js";
|
|
7
7
|
export { Reveal } from "./reveal.js";
|
|
8
8
|
export type { RevealProp, RevealProps } from "./reveal.js";
|
|
9
|
+
export { Activity } from "./activity.js";
|
|
10
|
+
export type { ActivityProp, ActivityProps } from "./activity.js";
|
|
@@ -2,7 +2,9 @@ import { Button, buttonVariants } from "./button.js";
|
|
|
2
2
|
import { Text, Heading } from "./typography.js";
|
|
3
3
|
import { Logo } from "./logo.js";
|
|
4
4
|
import { Reveal } from "./reveal.js";
|
|
5
|
+
import { Activity } from "./activity.js";
|
|
5
6
|
export {
|
|
7
|
+
Activity,
|
|
6
8
|
Button,
|
|
7
9
|
Heading,
|
|
8
10
|
Logo,
|
|
@@ -35,6 +35,7 @@ function AppShell({
|
|
|
35
35
|
setDrawerOpen(false);
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
+
const hasTopbarContent = topbar !== void 0 || topbarLeft !== void 0 || topbarRight !== void 0 || logo !== void 0;
|
|
38
39
|
const resolvedTopbar = topbar !== void 0 ? topbar : /* @__PURE__ */ jsxs("div", { className: "app-topbar-rail", children: [
|
|
39
40
|
logo !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-logo", children: logo }),
|
|
40
41
|
topbarLeft !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-left", children: topbarLeft }),
|
|
@@ -42,7 +43,7 @@ function AppShell({
|
|
|
42
43
|
topbarRight !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-right", children: topbarRight })
|
|
43
44
|
] });
|
|
44
45
|
const rail = /* @__PURE__ */ jsx("aside", { className: "app-sidebar", "aria-label": t("layout.appShell.sidebarLabel"), children: sidebar });
|
|
45
|
-
const bar = /* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
|
|
46
|
+
const bar = !hasTopbarContent && !hasDrawer ? null : /* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
|
|
46
47
|
hasDrawer && /* @__PURE__ */ jsxs(Sheet, { open: drawerOpen, onOpenChange: setDrawerOpen, children: [
|
|
47
48
|
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
48
49
|
Button,
|
|
@@ -53,7 +54,7 @@ function AppShell({
|
|
|
53
54
|
className: "app-mobile-nav-trigger hidden max-[900px]:inline-flex",
|
|
54
55
|
"aria-label": t("layout.appShell.openNav"),
|
|
55
56
|
"aria-haspopup": "dialog",
|
|
56
|
-
children: /* @__PURE__ */ jsx(Menu, { className: "size-
|
|
57
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "size-[var(--app-shell-mobile-nav-icon-size)]", "aria-hidden": "true" })
|
|
57
58
|
}
|
|
58
59
|
) }),
|
|
59
60
|
/* @__PURE__ */ jsxs(
|
|
@@ -77,7 +78,7 @@ function AppShell({
|
|
|
77
78
|
}
|
|
78
79
|
)
|
|
79
80
|
] }),
|
|
80
|
-
resolvedTopbar
|
|
81
|
+
hasTopbarContent && resolvedTopbar
|
|
81
82
|
] });
|
|
82
83
|
return /* @__PURE__ */ jsxs(
|
|
83
84
|
"div",
|
|
@@ -85,6 +86,7 @@ function AppShell({
|
|
|
85
86
|
className: "app-root",
|
|
86
87
|
"data-collapsed": sidebarCollapsed ? "true" : void 0,
|
|
87
88
|
"data-responsive-navigation": responsiveNavigation,
|
|
89
|
+
"data-topbar": hasTopbarContent ? void 0 : "none",
|
|
88
90
|
"data-topbar-span": topbarSpan === "full" ? "full" : void 0,
|
|
89
91
|
children: [
|
|
90
92
|
topbarSpan === "full" ? bar : rail,
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { AuthDividerProp } from "../../props/components/layout.prop.js";
|
|
2
2
|
export type { AuthDividerProp, AuthDividerProp as AuthDividerProps, } from "../../props/components/layout.prop.js";
|
|
3
3
|
/**
|
|
4
|
-
* AuthDivider — a centred, localized conjunction between two equal separator rules.
|
|
5
|
-
*
|
|
4
|
+
* AuthDivider — a centred, localized conjunction between two equal separator rules.
|
|
5
|
+
*
|
|
6
|
+
* Since gh#308 this is a thin PRESET over `Separator label`, not a parallel implementation: the
|
|
7
|
+
* grid, the accessible-name contract and the rule geometry all live on the primitive, and
|
|
8
|
+
* `.ui-auth-divider` only re-points Separator's `--separator-*` knobs at the `--auth-shell-divider-*`
|
|
9
|
+
* layer. That keeps #263's canonical login geometry byte-for-byte identical while breaking the
|
|
10
|
+
* coupling the issue reported — a service retuning its login divider no longer retunes every day
|
|
11
|
+
* divider in its message streams, and vice versa. New code that wants a labelled rule outside an
|
|
12
|
+
* auth form should use `<Separator label>` directly.
|
|
6
13
|
*/
|
|
7
14
|
export declare function AuthDivider({ label, className }: AuthDividerProp): import("react").JSX.Element;
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
3
|
import { cn } from "../../lib/utils.js";
|
|
4
|
+
import { Separator } from "../ui/separator.js";
|
|
3
5
|
function AuthDivider({ label, className }) {
|
|
4
|
-
return /* @__PURE__ */
|
|
5
|
-
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
Separator,
|
|
6
8
|
{
|
|
7
9
|
"data-slot": "auth-divider",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"aria-label": label,
|
|
11
|
-
children: [
|
|
12
|
-
/* @__PURE__ */ jsx("span", { className: "ui-auth-divider-rule", "aria-hidden": "true" }),
|
|
13
|
-
/* @__PURE__ */ jsx("span", { className: "ui-auth-divider-label", "aria-hidden": "true", children: label }),
|
|
14
|
-
/* @__PURE__ */ jsx("span", { className: "ui-auth-divider-rule", "aria-hidden": "true" })
|
|
15
|
-
]
|
|
10
|
+
label,
|
|
11
|
+
className: cn("ui-auth-divider", className)
|
|
16
12
|
}
|
|
17
13
|
);
|
|
18
14
|
}
|
|
@@ -39,6 +39,7 @@ export type { MasterDetailProps } from "./master-detail.js";
|
|
|
39
39
|
export { SplitPane } from "./split-pane.js";
|
|
40
40
|
export type { SplitPaneProps } from "./split-pane.js";
|
|
41
41
|
export { Separator } from "./separator.js";
|
|
42
|
+
export type { SeparatorProp, SeparatorProps } from "./separator.js";
|
|
42
43
|
export { AspectRatio } from "./aspect-ratio.js";
|
|
43
44
|
export { LegalDocumentShell } from "./legal-document-shell.js";
|
|
44
45
|
export type { LegalDocumentSectionProp, LegalDocumentShellProp, LegalDocumentShellProps, } from "./legal-document-shell.js";
|
|
@@ -2,7 +2,7 @@ import type { PageContainerProp, PageInsetProp } from "../../props/components/la
|
|
|
2
2
|
export type { PageContainerProp, PageContainerProp as PageContainerProps, } from "../../props/components/layout.prop.js";
|
|
3
3
|
export type { BreadcrumbItemProp, BreadcrumbItemProp as BreadcrumbItem, } from "../../props/vocabulary/navigation.prop.js";
|
|
4
4
|
export declare function PageContainerInset({ className, children, ...props }: PageInsetProp): import("react").JSX.Element;
|
|
5
|
-
declare function PageContainerRoot({ title, subtitle, status, extra, footer, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, headerLoading, density, variant, preset, headerLayout, measure, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react").JSX.Element;
|
|
5
|
+
declare function PageContainerRoot({ title, subtitle, status, extra, toolbar, footer, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, headerLoading, density, variant, preset, headerLayout, headerScale, measure, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react").JSX.Element;
|
|
6
6
|
export declare const PageContainer: typeof PageContainerRoot & {
|
|
7
7
|
Inset: typeof PageContainerInset;
|
|
8
8
|
};
|
|
@@ -38,6 +38,7 @@ function PageContainerRoot({
|
|
|
38
38
|
subtitle,
|
|
39
39
|
status,
|
|
40
40
|
extra,
|
|
41
|
+
toolbar,
|
|
41
42
|
footer,
|
|
42
43
|
breadcrumb,
|
|
43
44
|
breadcrumbLabel,
|
|
@@ -48,6 +49,7 @@ function PageContainerRoot({
|
|
|
48
49
|
variant = "default",
|
|
49
50
|
preset = "default",
|
|
50
51
|
headerLayout = "stack",
|
|
52
|
+
headerScale = "document",
|
|
51
53
|
measure = "default",
|
|
52
54
|
stickyFooter = false,
|
|
53
55
|
footerReveal = "always",
|
|
@@ -63,6 +65,7 @@ function PageContainerRoot({
|
|
|
63
65
|
{
|
|
64
66
|
"data-preset": preset,
|
|
65
67
|
"data-measure": measure,
|
|
68
|
+
"data-header-scale": headerScale === "chrome" ? "chrome" : void 0,
|
|
66
69
|
"data-revealed": revealed ? "true" : void 0,
|
|
67
70
|
className: cn(
|
|
68
71
|
"ui-page-container",
|
|
@@ -91,30 +94,38 @@ function PageContainerRoot({
|
|
|
91
94
|
className: "ui-breadcrumb",
|
|
92
95
|
children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: breadcrumb.map((item, i) => {
|
|
93
96
|
const isLast = i === breadcrumb.length - 1;
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
return (
|
|
98
|
+
// The package's own breadcrumb item hook (gh#319): same
|
|
99
|
+
// `--space-inline-xs` gap the previous `.ui-inline-xs` gave, and it brings
|
|
100
|
+
// `.ui-breadcrumb-item svg { 0.75rem }` with it, so the separator glyph no
|
|
101
|
+
// longer carries a `size-3` literal. It also drops `.ui-inline-xs`'s
|
|
102
|
+
// `flex-wrap: wrap` — a crumb must not break between its label and its
|
|
103
|
+
// chevron; the LIST wraps instead, exactly as <Breadcrumb> already behaves.
|
|
104
|
+
/* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
|
|
105
|
+
item.to && !isLast ? /* @__PURE__ */ jsx(
|
|
106
|
+
LinkComponent,
|
|
107
|
+
{
|
|
108
|
+
href: item.to,
|
|
109
|
+
to: item.to,
|
|
110
|
+
className: "hover:text-foreground hover:underline",
|
|
111
|
+
children: item.label
|
|
112
|
+
}
|
|
113
|
+
) : /* @__PURE__ */ jsx(
|
|
114
|
+
"span",
|
|
115
|
+
{
|
|
116
|
+
className: isLast ? "text-foreground" : "",
|
|
117
|
+
"aria-current": isLast ? "page" : void 0,
|
|
118
|
+
children: item.label
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
!isLast && /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
|
|
122
|
+
] }, i)
|
|
123
|
+
);
|
|
113
124
|
}) })
|
|
114
125
|
}
|
|
115
126
|
),
|
|
116
127
|
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-row", children: [
|
|
117
|
-
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-heading
|
|
128
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-heading", children: [
|
|
118
129
|
headerLoading ? /* @__PURE__ */ jsx("h1", { className: "ui-page-title ui-skeleton-block ui-page-title-placeholder", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("layout.pageHeader.loading") }) }) : status != null ? /* @__PURE__ */ jsxs("div", { className: "ui-page-header-title-row", children: [
|
|
119
130
|
/* @__PURE__ */ jsx("h1", { className: "ui-page-title", children: title }),
|
|
120
131
|
/* @__PURE__ */ jsx("div", { className: "ui-page-header-status", children: status })
|
|
@@ -136,6 +147,7 @@ function PageContainerRoot({
|
|
|
136
147
|
]
|
|
137
148
|
}
|
|
138
149
|
),
|
|
150
|
+
toolbar != null && /* @__PURE__ */ jsx("div", { className: "ui-page-toolbar", children: toolbar }),
|
|
139
151
|
children != null && /* @__PURE__ */ jsx("div", { className: "ui-page-body", children }),
|
|
140
152
|
footer && /* @__PURE__ */ jsx("footer", { className: "ui-page-footer", children: footer })
|
|
141
153
|
]
|