gridsmith-ui 0.23.0 → 0.24.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/Breadcrumbs-CGS8GKl-.d.ts +33 -0
- package/dist/chat.js +1 -1
- package/dist/{chunk-CKWITUSH.js → chunk-2PWGJ4PK.js} +10 -5
- package/dist/chunk-2PWGJ4PK.js.map +1 -0
- package/dist/chunk-2YSEME33.js +118 -0
- package/dist/chunk-2YSEME33.js.map +1 -0
- package/dist/{chunk-ICNWPNMM.js → chunk-6XAU44U4.js} +4 -3
- package/dist/chunk-6XAU44U4.js.map +1 -0
- package/dist/{chunk-RT7RYGC3.js → chunk-JXANCXK6.js} +4 -39
- package/dist/chunk-JXANCXK6.js.map +1 -0
- package/dist/{chunk-6PL7FXYH.js → chunk-MV7JXWXK.js} +318 -9
- package/dist/chunk-MV7JXWXK.js.map +1 -0
- package/dist/{chunk-EYMGLK4M.js → chunk-SVP2IG4S.js} +2 -2
- package/dist/{chunk-EYMGLK4M.js.map → chunk-SVP2IG4S.js.map} +1 -1
- package/dist/chunk-WOVYHFUD.js +50 -0
- package/dist/chunk-WOVYHFUD.js.map +1 -0
- package/dist/chunk-XVB55M3N.js +42 -0
- package/dist/chunk-XVB55M3N.js.map +1 -0
- package/dist/data-grid.js +4 -3
- package/dist/data-grid.js.map +1 -1
- package/dist/editor.js +2 -1
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +199 -38
- package/dist/index.js +598 -369
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +22 -5
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.d.ts +16 -1
- package/dist/resizable.js +87 -20
- package/dist/resizable.js.map +1 -1
- package/dist/roots.css +5 -0
- package/dist/virtualized.js +4 -3
- package/dist/virtualized.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6PL7FXYH.js.map +0 -1
- package/dist/chunk-CKWITUSH.js.map +0 -1
- package/dist/chunk-ICNWPNMM.js.map +0 -1
- package/dist/chunk-RT7RYGC3.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import { useAppShell, REACT_VERSION_PROBLEM, useOverlayMark, useDirtyGuard, useScrollbarInset, DrawerFooterCtx, OverlayMarkScope, OverlayCloseCtx, insetLessScrollbar, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, useCompact, useElementWidth, DrawerPanel, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-
|
|
2
|
-
export { AppShell, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-
|
|
1
|
+
import { useAppShell, REACT_VERSION_PROBLEM, Breadcrumbs, useCrumbFollow, crumbGoes, useOverlayMark, useDirtyGuard, useScrollbarInset, DrawerFooterCtx, OverlayMarkScope, OverlayCloseCtx, insetLessScrollbar, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, useCompact, useElementWidth, DrawerPanel, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-MV7JXWXK.js';
|
|
2
|
+
export { AppShell, Breadcrumbs, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-MV7JXWXK.js';
|
|
3
3
|
import { Skeleton, TITLE_TEXT } from './chunk-NCIZQYXQ.js';
|
|
4
4
|
export { Skeleton } from './chunk-NCIZQYXQ.js';
|
|
5
5
|
import { useScrollEdges, EDGE_FADE } from './chunk-3BRQRKDO.js';
|
|
6
|
-
import { Link } from './chunk-
|
|
7
|
-
export { CodeBlock, Divider, Link } from './chunk-
|
|
6
|
+
import { Link } from './chunk-SVP2IG4S.js';
|
|
7
|
+
export { CodeBlock, Divider, Link } from './chunk-SVP2IG4S.js';
|
|
8
|
+
import { useFillHeight, FillContext } from './chunk-2YSEME33.js';
|
|
8
9
|
import { Badge } from './chunk-SBTBMAIU.js';
|
|
9
10
|
export { Badge } from './chunk-SBTBMAIU.js';
|
|
10
11
|
import { inferColumnKinds, useCardsSwitch, CARDS_BELOW, kindOfRenderedText, CardValue } from './chunk-IVCVNAXG.js';
|
|
11
|
-
import { useWholeListCheck, pagerPart, Pagination, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, warnOnce, Label, InlineFieldError, AddAnotherRowCtx,
|
|
12
|
-
export { Dropdown, Field, InlineFieldError, Input, Label, NumberInput, Pagination, Popover, Textarea, Toggle, usePagination } from './chunk-
|
|
12
|
+
import { useWholeListCheck, pagerPart, Pagination, Input, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, warnOnce, Label, InlineFieldError, AddAnotherRowCtx, Field } from './chunk-6XAU44U4.js';
|
|
13
|
+
export { Dropdown, Field, InlineFieldError, Input, Label, NumberInput, Pagination, Popover, Textarea, Toggle, usePagination } from './chunk-6XAU44U4.js';
|
|
13
14
|
import { Button, ControlSizeContext, triggerType, Spinner, useShellPreferences, preferenceActionKey } from './chunk-7TOJ4G7S.js';
|
|
14
15
|
export { Button, ButtonSizeContext, ControlSizeContext, PreferencesContext, Spinner, preferenceActionKey, usePreferences } from './chunk-7TOJ4G7S.js';
|
|
15
16
|
import { useBreakpoint, readBreakpointPx } from './chunk-CRQ6KCRD.js';
|
|
16
17
|
export { BreakpointWidthProvider, useBreakpoint } from './chunk-CRQ6KCRD.js';
|
|
17
|
-
import {
|
|
18
|
-
export { useFormContext
|
|
19
|
-
import { CardSurfaceCtx, useScrollsInside, SplitPaneCtx, SurfaceBoundary, useFramesItself, TableCardCtx } from './chunk-
|
|
18
|
+
import { FormChangeCtx, useReportedChange, useOptionalFormContext, FormCtx } from './chunk-XVB55M3N.js';
|
|
19
|
+
export { useFormContext } from './chunk-XVB55M3N.js';
|
|
20
|
+
import { CardSurfaceCtx, useScrollsInside, SplitPaneCtx, PageActionsCtx, SurfaceBoundary, useFramesItself, TableCardCtx } from './chunk-2PWGJ4PK.js';
|
|
21
|
+
import { FOCUSABLE, usePopupFocus, FIELD, ZOOM_KEYS, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberFocus, focusInitial, OVERLAY_CLOSE_ATTR, rovingTabStop, useGridKeyboard, focusAfterRemoval, useNonModalDialog, useReturnFocus, useCloseOnFocusOut } from './chunk-JXANCXK6.js';
|
|
22
|
+
export { useGridKeyboard } from './chunk-JXANCXK6.js';
|
|
20
23
|
import { useTextOverflow, Tooltip, usePosition } from './chunk-CXMV7SXJ.js';
|
|
21
24
|
export { Tooltip, useTextOverflow } from './chunk-CXMV7SXJ.js';
|
|
22
25
|
import { mergeRefs, Slot } from './chunk-7Q46JXSK.js';
|
|
@@ -1882,9 +1885,9 @@ function FileUpload({ onFiles, files, upload, onCancel, onRetry, onRemove, accep
|
|
|
1882
1885
|
useEffect(() => {
|
|
1883
1886
|
const owner = inputRef.current?.form;
|
|
1884
1887
|
if (!owner) return;
|
|
1885
|
-
const
|
|
1886
|
-
owner.addEventListener("submit",
|
|
1887
|
-
return () => owner.removeEventListener("submit",
|
|
1888
|
+
const clear2 = () => setRejected(null);
|
|
1889
|
+
owner.addEventListener("submit", clear2);
|
|
1890
|
+
return () => owner.removeEventListener("submit", clear2);
|
|
1888
1891
|
}, []);
|
|
1889
1892
|
const invalid = error || rejected != null || !!waiting;
|
|
1890
1893
|
const describedBy = [constraints ? constraintsId : null, field?.describedBy, rejected ? rejectedId : null, waiting ? waitingId : null].filter(Boolean).join(" ") || void 0;
|
|
@@ -3587,7 +3590,7 @@ function focusTarget(el) {
|
|
|
3587
3590
|
if (el.tabIndex >= 0 || /^(?:INPUT|SELECT|TEXTAREA|BUTTON)$/.test(el.tagName)) return el;
|
|
3588
3591
|
return el.querySelector("[aria-checked='true'], [aria-selected='true']:not([tabindex='-1'])") ?? el.querySelector("input, select, textarea, button, [tabindex]:not([tabindex='-1'])") ?? el;
|
|
3589
3592
|
}
|
|
3590
|
-
function FormWrapper({ onSubmit, validationMode: validationModeProp, children, actions: actionsProp, actionsAlign: actionsAlignProp, onCancel, cancelLabel = "Cancel", focusFirstError = true, errorSummary = true, className, ref }) {
|
|
3593
|
+
function FormWrapper({ onSubmit, validationMode: validationModeProp, children, actions: actionsProp, actionsAlign: actionsAlignProp, onCancel, cancelLabel = "Cancel", focusFirstError = true, errorSummary = true, fullWidth = false, className, ref }) {
|
|
3591
3594
|
const preferences = useShellPreferences();
|
|
3592
3595
|
const validationMode = validationModeProp ?? preferences.validationTiming ?? "onSubmit";
|
|
3593
3596
|
const actionsAlign = actionsAlignProp ?? preferences.formActions?.align ?? "end";
|
|
@@ -3754,7 +3757,7 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
3754
3757
|
f.message
|
|
3755
3758
|
] }, f.id || f.label)) }) }) : null;
|
|
3756
3759
|
const actionsNode = actions && !drawerFooter ? /* @__PURE__ */ jsx("div", { "data-form-actions": "", className: cn("flex flex-wrap items-center gap-ds-2 pt-ds-2", actionsAlign === "end" ? "justify-end" : "justify-start"), children: actions }) : null;
|
|
3757
|
-
return /* @__PURE__ */ jsx(FormCtx.Provider, { value: { errors, setError, clearErrors, validationMode, submitted, register }, children: /* @__PURE__ */ jsx(FormChangeCtx.Provider, { value: reportChange, children: /* @__PURE__ */ jsxs("form", { ref: setRefs, id: drawerFooter ? formId : void 0, onSubmit: handleSubmit, onFocusCapture: userActed, onInputCapture: userActed, className: cn("flex flex-col gap-ds-5 max-w-[var(--ds-form-max,
|
|
3760
|
+
return /* @__PURE__ */ jsx(FormCtx.Provider, { value: { errors, setError, clearErrors, validationMode, submitted, register }, children: /* @__PURE__ */ jsx(FormChangeCtx.Provider, { value: reportChange, children: /* @__PURE__ */ jsxs("form", { ref: setRefs, id: drawerFooter ? formId : void 0, onSubmit: handleSubmit, onFocusCapture: userActed, onInputCapture: userActed, className: cn("flex flex-col gap-ds-5 max-w-[var(--ds-form-max,calc(var(--ds-bp-md)_-_2*var(--ds-space-6)))]", className), style: fullWidth ? { "--ds-form-max": "none" } : void 0, noValidate: true, children: [
|
|
3758
3761
|
summaryNode && /* @__PURE__ */ jsx("div", { ref: summaryRef, "data-form-error-summary": "", tabIndex: -1, className: "rounded-[var(--ds-radius-md)] outline-none focus-visible:shadow-[var(--ds-shadow-focus)]", children: summaryNode }),
|
|
3759
3762
|
children,
|
|
3760
3763
|
actionsNode
|
|
@@ -5353,6 +5356,9 @@ var PINNED_LAYERS = cn(
|
|
|
5353
5356
|
);
|
|
5354
5357
|
var PIN_SHADOW = "oklch(0 0 0 / 0.18)";
|
|
5355
5358
|
var ROW_CONTROL = `${FOCUSABLE}, label, [role="button"], [role="checkbox"], [role="switch"], [role="menuitem"], [role="link"]`;
|
|
5359
|
+
function clickIsCard(e) {
|
|
5360
|
+
return clickIsRows(e) && !(e.target instanceof Element && e.target.closest("[data-card-detail]"));
|
|
5361
|
+
}
|
|
5356
5362
|
function clickIsRows(e) {
|
|
5357
5363
|
const target = e.target;
|
|
5358
5364
|
if (!(target instanceof Element) || !e.currentTarget.contains(target)) return false;
|
|
@@ -5693,9 +5699,16 @@ function Table({
|
|
|
5693
5699
|
const expandedKey = expanded.map(String).join("");
|
|
5694
5700
|
const shownBefore = useRef(/* @__PURE__ */ new Set());
|
|
5695
5701
|
const pendingScroll = useRef(null);
|
|
5702
|
+
const scrollFrame = useRef(0);
|
|
5696
5703
|
const scrollToRow = useCallback((key) => {
|
|
5697
|
-
|
|
5698
|
-
|
|
5704
|
+
cancelAnimationFrame(scrollFrame.current);
|
|
5705
|
+
scrollFrame.current = requestAnimationFrame(() => {
|
|
5706
|
+
const row = rootRef.current?.querySelector(`[data-row-key="${CSS.escape(key)}"], [data-row-index="${CSS.escape(key)}"]`);
|
|
5707
|
+
if (!row || typeof row.scrollIntoView !== "function") return;
|
|
5708
|
+
const panel = row.nextElementSibling?.querySelector("[data-row-panel]") ? row.nextElementSibling : null;
|
|
5709
|
+
panel?.scrollIntoView({ block: "nearest" });
|
|
5710
|
+
row.scrollIntoView({ block: "nearest" });
|
|
5711
|
+
});
|
|
5699
5712
|
}, [rootRef]);
|
|
5700
5713
|
useEffect(() => {
|
|
5701
5714
|
const now = new Set(expanded.map(String));
|
|
@@ -5774,6 +5787,14 @@ function Table({
|
|
|
5774
5787
|
drawn.map(({ row, originalIdx }) => {
|
|
5775
5788
|
const isSelected = selectedSet.has(originalIdx);
|
|
5776
5789
|
const id = idOf(row, originalIdx);
|
|
5790
|
+
const opens = !!expandable && !!renderExpanded;
|
|
5791
|
+
const isExpanded = opens && expandedSet.has(String(id));
|
|
5792
|
+
const toggleCard = (card) => {
|
|
5793
|
+
const closing = isExpanded;
|
|
5794
|
+
const inDetail = closing && card.querySelector("[data-card-detail]")?.contains(document.activeElement);
|
|
5795
|
+
toggleExpand(id);
|
|
5796
|
+
if (inDetail) card.querySelector("[data-card-toggle]")?.focus();
|
|
5797
|
+
};
|
|
5777
5798
|
return /* @__PURE__ */ jsxs(
|
|
5778
5799
|
"div",
|
|
5779
5800
|
{
|
|
@@ -5784,10 +5805,15 @@ function Table({
|
|
|
5784
5805
|
"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]",
|
|
5785
5806
|
"p-ds-4 space-y-ds-3",
|
|
5786
5807
|
isSelected && ACTIVE_RING,
|
|
5787
|
-
onRowClick && "cursor-pointer hover:bg-[var(--ds-bg-muted)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]"
|
|
5808
|
+
onRowClick && "cursor-pointer hover:bg-[var(--ds-bg-muted)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
5809
|
+
// with no onRowClick a tap on the card opens and closes it, as a click on the row does; the toggle is the
|
|
5810
|
+
// keyboard's way
|
|
5811
|
+
!onRowClick && canOpenByClick && "cursor-pointer"
|
|
5788
5812
|
),
|
|
5789
5813
|
onClick: onRowClick ? (e) => {
|
|
5790
|
-
if (
|
|
5814
|
+
if (clickIsCard(e)) onRowClick(row, originalIdx);
|
|
5815
|
+
} : canOpenByClick ? (e) => {
|
|
5816
|
+
if (clickIsCard(e)) toggleCard(e.currentTarget);
|
|
5791
5817
|
} : void 0,
|
|
5792
5818
|
tabIndex: onRowClick ? 0 : void 0,
|
|
5793
5819
|
onKeyDown: onRowClick ? (e) => {
|
|
@@ -5804,7 +5830,36 @@ function Table({
|
|
|
5804
5830
|
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider", children: col.header }),
|
|
5805
5831
|
/* @__PURE__ */ jsx(CardValue, { value: row[col.key], id: lead + c === nameIndex ? `${headingId}-card-name-${idPart(id)}` : void 0 })
|
|
5806
5832
|
] }, col.key)),
|
|
5807
|
-
|
|
5833
|
+
opens && // Alert's disclosure: a button that says whether it is open, at the card's foot, the detail below it, so
|
|
5834
|
+
// the control the user pressed stays where it was. Its name carries the row's (T15).
|
|
5835
|
+
/* @__PURE__ */ jsxs("div", { className: "pt-ds-1", children: [
|
|
5836
|
+
/* @__PURE__ */ jsxs(
|
|
5837
|
+
"button",
|
|
5838
|
+
{
|
|
5839
|
+
type: "button",
|
|
5840
|
+
"data-card-toggle": "",
|
|
5841
|
+
"aria-expanded": isExpanded,
|
|
5842
|
+
...nameIndex >= 0 ? { "aria-labelledby": `${headingId}-card-toggle-${idPart(id)} ${headingId}-card-name-${idPart(id)}` } : {},
|
|
5843
|
+
onClick: (e) => {
|
|
5844
|
+
e.stopPropagation();
|
|
5845
|
+
toggleCard(e.currentTarget.closest("[data-row]"));
|
|
5846
|
+
},
|
|
5847
|
+
className: cn(
|
|
5848
|
+
// at least 24 px tall: the card around it is a target too, so its own box must meet the size (WCAG 2.5.8)
|
|
5849
|
+
"inline-flex min-h-[24px] items-center gap-ds-1 text-xs font-medium cursor-pointer",
|
|
5850
|
+
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
5851
|
+
"text-[var(--ds-accent-primary)] hover:bg-[var(--ds-accent-muted)]",
|
|
5852
|
+
"rounded-[var(--ds-radius-sm)] px-ds-1.5 py-ds-0.5 -mx-ds-1.5",
|
|
5853
|
+
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]"
|
|
5854
|
+
),
|
|
5855
|
+
children: [
|
|
5856
|
+
/* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 12, className: cn("transition-transform duration-[var(--ds-transition-speed)]", isExpanded && "rotate-90") }),
|
|
5857
|
+
/* @__PURE__ */ jsx("span", { id: `${headingId}-card-toggle-${idPart(id)}`, children: isExpanded ? "Hide details" : "Show details" })
|
|
5858
|
+
]
|
|
5859
|
+
}
|
|
5860
|
+
),
|
|
5861
|
+
isExpanded && /* @__PURE__ */ jsx("div", { "data-card-detail": "", className: "mt-ds-3 pt-ds-3 border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] text-sm text-[var(--ds-text-secondary)]", children: /* @__PURE__ */ jsx(PanelContent, { children: renderExpanded(row, originalIdx) }) })
|
|
5862
|
+
] })
|
|
5808
5863
|
]
|
|
5809
5864
|
},
|
|
5810
5865
|
String(id)
|
|
@@ -6070,6 +6125,9 @@ var indicatorInset = {
|
|
|
6070
6125
|
md: "4px",
|
|
6071
6126
|
lg: "4px"
|
|
6072
6127
|
};
|
|
6128
|
+
function segmentRadius(inset, bordered) {
|
|
6129
|
+
return `max(var(--ds-radius-sm), calc(var(--ds-radius-md) - ${inset}${bordered ? " - var(--ds-border-width)" : ""}))`;
|
|
6130
|
+
}
|
|
6073
6131
|
function SegmentedControl({
|
|
6074
6132
|
value,
|
|
6075
6133
|
onChange: onChangeProp,
|
|
@@ -6211,19 +6269,26 @@ function SegmentedControl({
|
|
|
6211
6269
|
containerPadding[size],
|
|
6212
6270
|
containerHeight[size],
|
|
6213
6271
|
"bg-[var(--ds-bg-muted)]",
|
|
6214
|
-
|
|
6215
|
-
//
|
|
6216
|
-
|
|
6272
|
+
// The owner's review of 1 October 2026: the frame's corner is a field's, so the two change together with the
|
|
6273
|
+
// theme's radius; the segments inside sit concentric with it (SEGMENT_RADIUS)
|
|
6274
|
+
"rounded-[var(--ds-radius-md)]",
|
|
6275
|
+
// The frame's edge is a button's: each segment is a labelled button, so the frame isn't what identifies the
|
|
6276
|
+
// control, and WCAG 1.4.11 asks no 3:1 of it. The selected segment carries the 3:1 edge instead (below)
|
|
6277
|
+
variant === "default" && "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
6217
6278
|
control.invalid && "border-[length:var(--ds-border-width)] border-[var(--ds-status-error)]",
|
|
6218
6279
|
className
|
|
6219
6280
|
),
|
|
6281
|
+
style: { "--ds-segment-radius": segmentRadius(indicatorInset[size], variant === "default" || !!control.invalid) },
|
|
6220
6282
|
children: [
|
|
6221
6283
|
/* @__PURE__ */ jsx(
|
|
6222
6284
|
"div",
|
|
6223
6285
|
{
|
|
6224
6286
|
className: cn(
|
|
6225
|
-
"absolute rounded-[var(--ds-radius
|
|
6287
|
+
"absolute rounded-[var(--ds-segment-radius)]",
|
|
6226
6288
|
"bg-[var(--ds-bg-surface)]",
|
|
6289
|
+
// The selected state is what the control shows, so its edge is the one at 3:1 (WCAG 1.4.11), against the
|
|
6290
|
+
// frame's fill and its own: the surface on the muted fill alone measures 1.05–1.46:1 across the presets
|
|
6291
|
+
"border-[length:var(--ds-border-width)] border-[var(--ds-input-border)]",
|
|
6227
6292
|
variant === "default" && "shadow-[var(--ds-shadow-sm)]",
|
|
6228
6293
|
"transition-all motion-reduce:transition-none"
|
|
6229
6294
|
),
|
|
@@ -6254,7 +6319,7 @@ function SegmentedControl({
|
|
|
6254
6319
|
className: cn(
|
|
6255
6320
|
"relative z-10 inline-flex items-center justify-center self-stretch font-medium whitespace-nowrap",
|
|
6256
6321
|
fullWidth && "flex-1",
|
|
6257
|
-
"rounded-[var(--ds-radius
|
|
6322
|
+
"rounded-[var(--ds-segment-radius)]",
|
|
6258
6323
|
"transition-colors cursor-pointer",
|
|
6259
6324
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
6260
6325
|
sizes2[size],
|
|
@@ -7369,16 +7434,16 @@ function MonthDropdown({
|
|
|
7369
7434
|
)
|
|
7370
7435
|
] }),
|
|
7371
7436
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-ds-1", children: MONTH_NAMES_SHORT.map((name, i) => {
|
|
7372
|
-
const
|
|
7437
|
+
const isActive2 = i === currentMonth && browseYear === currentYear;
|
|
7373
7438
|
return /* @__PURE__ */ jsx(
|
|
7374
7439
|
"button",
|
|
7375
7440
|
{
|
|
7376
7441
|
className: cn(
|
|
7377
7442
|
"px-ds-2 py-ds-1.5 text-xs font-medium rounded-[var(--ds-radius-sm)] cursor-pointer transition-colors",
|
|
7378
7443
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
7379
|
-
|
|
7444
|
+
isActive2 ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-emphasis)] hover:text-[var(--ds-text-primary)]"
|
|
7380
7445
|
),
|
|
7381
|
-
"data-current":
|
|
7446
|
+
"data-current": isActive2 || void 0,
|
|
7382
7447
|
onClick: () => {
|
|
7383
7448
|
returnFocus();
|
|
7384
7449
|
onSelect(new Date(browseYear, i, 1));
|
|
@@ -7966,7 +8031,7 @@ function TableToolbar({
|
|
|
7966
8031
|
const iconSize = size === "sm" ? 14 : 16;
|
|
7967
8032
|
const count = activeFilterCount ?? activeFilters?.length ?? 0;
|
|
7968
8033
|
const hasChips = !!activeFilters?.length;
|
|
7969
|
-
const inPane = useContext(SplitPaneCtx);
|
|
8034
|
+
const inPane = !!useContext(SplitPaneCtx);
|
|
7970
8035
|
const searchFills = inPane || !primaryFilter && !filters && !actions;
|
|
7971
8036
|
const hasControls = !!(search || primaryFilter || filters || actions);
|
|
7972
8037
|
const noun = (n) => n === 1 ? resultNoun[0] : resultNoun[1];
|
|
@@ -8285,12 +8350,26 @@ function Kbd({ children, className }) {
|
|
|
8285
8350
|
}
|
|
8286
8351
|
);
|
|
8287
8352
|
}
|
|
8353
|
+
|
|
8354
|
+
// ../../showcase/src/lib/nested-items.ts
|
|
8355
|
+
function holdsCurrent(items, isCurrent) {
|
|
8356
|
+
return !!items?.some((item) => isCurrent(item) || holdsCurrent(item.children, isCurrent));
|
|
8357
|
+
}
|
|
8288
8358
|
function TruncLabel2({ children }) {
|
|
8289
8359
|
const { ref, isTruncated } = useTextOverflow({ lines: 1 });
|
|
8290
8360
|
const label = /* @__PURE__ */ jsx("span", { ref, className: "truncate", children });
|
|
8291
8361
|
if (!isTruncated) return label;
|
|
8292
8362
|
return /* @__PURE__ */ jsx(Tooltip, { content: children, children: label });
|
|
8293
8363
|
}
|
|
8364
|
+
function foldersHolding(nodes, selected) {
|
|
8365
|
+
const ids = [];
|
|
8366
|
+
for (const node of nodes) {
|
|
8367
|
+
if (!holdsCurrent(node.children, (n) => selected.has(n.id))) continue;
|
|
8368
|
+
ids.push(node.id, ...foldersHolding(node.children, selected));
|
|
8369
|
+
}
|
|
8370
|
+
return ids;
|
|
8371
|
+
}
|
|
8372
|
+
var inTree = (nodes, id) => holdsCurrent(nodes, (n) => n.id === id);
|
|
8294
8373
|
function allDescendantIds(node) {
|
|
8295
8374
|
const ids = [node.id];
|
|
8296
8375
|
if (node.children) {
|
|
@@ -8305,13 +8384,26 @@ function TreeView({
|
|
|
8305
8384
|
checkable,
|
|
8306
8385
|
defaultExpanded = [],
|
|
8307
8386
|
defaultSelected = [],
|
|
8387
|
+
selected: selectedProp,
|
|
8308
8388
|
defaultChecked = [],
|
|
8309
8389
|
onSelect,
|
|
8310
8390
|
onCheck,
|
|
8311
8391
|
className
|
|
8312
8392
|
}) {
|
|
8313
|
-
const [
|
|
8314
|
-
const
|
|
8393
|
+
const [ownSelected, setOwnSelected] = useState(() => new Set(defaultSelected));
|
|
8394
|
+
const selected = useMemo(() => selectedProp ? new Set(selectedProp) : ownSelected, [selectedProp, ownSelected]);
|
|
8395
|
+
const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set([...defaultExpanded, ...foldersHolding(nodes, selected)]));
|
|
8396
|
+
const revealed = useRef(null);
|
|
8397
|
+
if (revealed.current === null) revealed.current = new Set([...selected].filter((id) => inTree(nodes, id)));
|
|
8398
|
+
useEffect(() => {
|
|
8399
|
+
const seen = revealed.current;
|
|
8400
|
+
const fresh = [...selected].filter((id) => !seen.has(id) && inTree(nodes, id));
|
|
8401
|
+
if (!fresh.length) return;
|
|
8402
|
+
for (const id of fresh) seen.add(id);
|
|
8403
|
+
const folders = foldersHolding(nodes, new Set(fresh));
|
|
8404
|
+
if (folders.length) setExpanded((prev) => folders.every((id) => prev.has(id)) ? prev : /* @__PURE__ */ new Set([...prev, ...folders]));
|
|
8405
|
+
}, [nodes, selected]);
|
|
8406
|
+
const holding = useMemo(() => new Set(foldersHolding(nodes, selected)), [nodes, selected]);
|
|
8315
8407
|
const [checked, setChecked] = useState(new Set(defaultChecked));
|
|
8316
8408
|
const baseId = useId();
|
|
8317
8409
|
const toggleExpand = useCallback((id) => {
|
|
@@ -8325,20 +8417,18 @@ function TreeView({
|
|
|
8325
8417
|
const handleSelect = useCallback(
|
|
8326
8418
|
(id) => {
|
|
8327
8419
|
if (!selectable) return;
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
return next;
|
|
8339
|
-
});
|
|
8420
|
+
let next;
|
|
8421
|
+
if (multiSelect) {
|
|
8422
|
+
next = new Set(selected);
|
|
8423
|
+
if (next.has(id)) next.delete(id);
|
|
8424
|
+
else next.add(id);
|
|
8425
|
+
} else {
|
|
8426
|
+
next = selected.has(id) ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([id]);
|
|
8427
|
+
}
|
|
8428
|
+
if (!selectedProp) setOwnSelected(next);
|
|
8429
|
+
onSelect?.(Array.from(next));
|
|
8340
8430
|
},
|
|
8341
|
-
[selectable, multiSelect, onSelect]
|
|
8431
|
+
[selectable, multiSelect, selected, selectedProp, onSelect]
|
|
8342
8432
|
);
|
|
8343
8433
|
const handleCheck = useCallback(
|
|
8344
8434
|
(node) => {
|
|
@@ -8423,6 +8513,7 @@ function TreeView({
|
|
|
8423
8513
|
baseId,
|
|
8424
8514
|
expanded,
|
|
8425
8515
|
selected,
|
|
8516
|
+
holding,
|
|
8426
8517
|
checked,
|
|
8427
8518
|
checkable,
|
|
8428
8519
|
selectable,
|
|
@@ -8441,6 +8532,7 @@ function TreeNodeRow({
|
|
|
8441
8532
|
baseId,
|
|
8442
8533
|
expanded,
|
|
8443
8534
|
selected,
|
|
8535
|
+
holding,
|
|
8444
8536
|
checkable,
|
|
8445
8537
|
selectable,
|
|
8446
8538
|
toggleExpand,
|
|
@@ -8452,6 +8544,7 @@ function TreeNodeRow({
|
|
|
8452
8544
|
const hasChildren = !!node.children?.length;
|
|
8453
8545
|
const isExpanded = expanded.has(node.id);
|
|
8454
8546
|
const isSelected = selected.has(node.id);
|
|
8547
|
+
const holdsSelection = !isSelected && holding.has(node.id);
|
|
8455
8548
|
const checkState = checkable ? getCheckState(node) : "unchecked";
|
|
8456
8549
|
return /* @__PURE__ */ jsxs("div", { role: "treeitem", "aria-expanded": hasChildren ? isExpanded : void 0, "aria-selected": selectable ? isSelected : void 0, children: [
|
|
8457
8550
|
/* @__PURE__ */ jsxs(
|
|
@@ -8467,6 +8560,9 @@ function TreeNodeRow({
|
|
|
8467
8560
|
// transparent placeholder so content never shifts on selection.
|
|
8468
8561
|
"border-l-[length:var(--ds-tree-active-rail)]",
|
|
8469
8562
|
isSelected ? "bg-[var(--ds-tree-active-bg)] text-[var(--ds-tree-active-text)] font-medium border-[var(--ds-accent-primary)]" : "border-transparent text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)] hover:text-[var(--ds-text-primary)]",
|
|
8563
|
+
// A folder holding the selection, as SidebarNav draws a parent of the current page (Sprint 25.16 A18): no
|
|
8564
|
+
// fill, so it reads the plain tokens, never the active set (pill's on-primary text would vanish here).
|
|
8565
|
+
holdsSelection && "font-medium",
|
|
8470
8566
|
node.disabled && "opacity-disabled pointer-events-none"
|
|
8471
8567
|
),
|
|
8472
8568
|
style: { paddingLeft: `calc(var(--ds-space-3) * ${depth} + var(--ds-space-2))` },
|
|
@@ -8493,7 +8589,7 @@ function TreeNodeRow({
|
|
|
8493
8589
|
{
|
|
8494
8590
|
name: "chevron-right",
|
|
8495
8591
|
size: 14,
|
|
8496
|
-
className: cn(isSelected ? "text-[var(--ds-tree-active-muted)]" : "text-[var(--ds-text-muted)]", "transition-transform", isExpanded && "rotate-90")
|
|
8592
|
+
className: cn(isSelected ? "text-[var(--ds-tree-active-muted)]" : holdsSelection ? "text-[var(--ds-accent-primary)]" : "text-[var(--ds-text-muted)]", "transition-transform", isExpanded && "rotate-90")
|
|
8497
8593
|
}
|
|
8498
8594
|
)
|
|
8499
8595
|
}
|
|
@@ -8508,7 +8604,7 @@ function TreeNodeRow({
|
|
|
8508
8604
|
}
|
|
8509
8605
|
}
|
|
8510
8606
|
),
|
|
8511
|
-
node.icon && /* @__PURE__ */ jsx(Icon, { name: node.icon, size: 16, className: cn("shrink-0", isSelected ? "text-[var(--ds-tree-active-text)]" : "text-[var(--ds-text-muted)]") }),
|
|
8607
|
+
node.icon && /* @__PURE__ */ jsx(Icon, { name: node.icon, size: 16, className: cn("shrink-0", isSelected ? "text-[var(--ds-tree-active-text)]" : holdsSelection ? "text-[var(--ds-accent-primary)]" : "text-[var(--ds-text-muted)]") }),
|
|
8512
8608
|
/* @__PURE__ */ jsx(TruncLabel2, { children: node.label })
|
|
8513
8609
|
]
|
|
8514
8610
|
}
|
|
@@ -8521,6 +8617,7 @@ function TreeNodeRow({
|
|
|
8521
8617
|
baseId,
|
|
8522
8618
|
expanded,
|
|
8523
8619
|
selected,
|
|
8620
|
+
holding,
|
|
8524
8621
|
checked: /* @__PURE__ */ new Set(),
|
|
8525
8622
|
checkable,
|
|
8526
8623
|
selectable,
|
|
@@ -9481,7 +9578,7 @@ var StackedList = forwardRef(function StackedList2({
|
|
|
9481
9578
|
useScrollsInside();
|
|
9482
9579
|
const isPhone = useBreakpoint("sm");
|
|
9483
9580
|
const inCard = useContext(CardSurfaceCtx);
|
|
9484
|
-
const inPane = useContext(SplitPaneCtx);
|
|
9581
|
+
const inPane = !!useContext(SplitPaneCtx);
|
|
9485
9582
|
const variant = variantProp ?? (flush || hover === "title" ? "articles" : "list");
|
|
9486
9583
|
const legacy = flush !== void 0 || hover !== void 0;
|
|
9487
9584
|
useEffect(() => {
|
|
@@ -10148,6 +10245,8 @@ var TimeViewport = forwardRef(function TimeViewport2({
|
|
|
10148
10245
|
className
|
|
10149
10246
|
}, ref) {
|
|
10150
10247
|
const scrollerRef = useRef(null);
|
|
10248
|
+
const rootRef = useRef(null);
|
|
10249
|
+
const fill2 = useFillHeight(rootRef);
|
|
10151
10250
|
const headerRef = useRef(null);
|
|
10152
10251
|
const rowsRef = useRef(null);
|
|
10153
10252
|
const [frame, setFrame] = useState({ width: 0, header: 0 });
|
|
@@ -10370,23 +10469,26 @@ var TimeViewport = forwardRef(function TimeViewport2({
|
|
|
10370
10469
|
};
|
|
10371
10470
|
const headerNode = header === void 0 ? /* @__PURE__ */ jsx(TimeScaleHeader, {}) : header;
|
|
10372
10471
|
const hasHeader = headerNode != null || labelHeader != null;
|
|
10373
|
-
const bar = toolbar === false ? null :
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
/* @__PURE__ */
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10472
|
+
const bar = toolbar === false ? null : (
|
|
10473
|
+
// a wrapped line (a chart's key, or controls on a phone) stands a row gap apart (Sprint 25.16 A43)
|
|
10474
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 flex-wrap items-center gap-x-ds-1 gap-y-ds-2 px-ds-2 py-ds-1.5 border-b-[length:var(--ds-border-width)]", border), children: [
|
|
10475
|
+
onZoomChange && levels.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10476
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Zoom out", "aria-disabled": !canZoomOut || void 0, className: "aria-disabled:opacity-disabled aria-disabled:cursor-not-allowed", onClick: () => zoom(1), children: /* @__PURE__ */ jsx(Icon, { name: "minus", size: 14 }) }),
|
|
10477
|
+
/* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "min-w-[4.5rem] text-center text-xs text-[var(--ds-text-secondary)]", children: ZOOM_NAMES[scale.zoom] }),
|
|
10478
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Zoom in", "aria-disabled": !canZoomIn || void 0, className: "aria-disabled:opacity-disabled aria-disabled:cursor-not-allowed", onClick: () => zoom(-1), children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 14 }) })
|
|
10479
|
+
] }),
|
|
10480
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Previous period", onClick: () => api.page(-1), children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", size: 14 }) }),
|
|
10481
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", disabled: todayAtX === null, onClick: () => {
|
|
10482
|
+
if (todayAtX !== null) setLeft(todayAtX - visibleWidth / 2);
|
|
10483
|
+
}, children: "Today" }),
|
|
10484
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Next period", onClick: () => api.page(1), children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) }),
|
|
10485
|
+
toolbar
|
|
10486
|
+
] })
|
|
10487
|
+
);
|
|
10386
10488
|
return (
|
|
10387
10489
|
// Inline-size containment: the rows' width never widens the frame (in a grid or flex parent it would, and the
|
|
10388
10490
|
// wider frame would extend the scale again). The viewport takes the width it is given and scrolls inside it.
|
|
10389
|
-
/* @__PURE__ */ jsx("div", { "data-time-viewport": "", "data-compact": phone || void 0, className: cn("flex h-full min-h-0 w-full min-w-0 flex-col [contain:inline-size] bg-[var(--ds-bg-surface)]", className), onKeyDown, children: /* @__PURE__ */ jsx(TimeViewportCtx, { value: layout, children: /* @__PURE__ */ jsxs(TimeViewportScrollCtx, { value: store, children: [
|
|
10491
|
+
/* @__PURE__ */ jsx("div", { ref: rootRef, "data-time-viewport": "", "data-compact": phone || void 0, "data-fill": fill2 != null ? "" : void 0, className: cn("flex h-full min-h-0 w-full min-w-0 flex-col [contain:inline-size] bg-[var(--ds-bg-surface)]", className), style: fill2 != null ? { height: fill2 } : void 0, onKeyDown, children: /* @__PURE__ */ jsx(TimeViewportCtx, { value: layout, children: /* @__PURE__ */ jsxs(TimeViewportScrollCtx, { value: store, children: [
|
|
10390
10492
|
bar,
|
|
10391
10493
|
/* @__PURE__ */ jsxs("div", { className: "relative min-h-0 flex-1", children: [
|
|
10392
10494
|
/* @__PURE__ */ jsx(
|
|
@@ -10662,7 +10764,7 @@ function Cue({ name, size }) {
|
|
|
10662
10764
|
function Legend({ statuses }) {
|
|
10663
10765
|
const entries = Object.entries(statuses);
|
|
10664
10766
|
if (!entries.length) return null;
|
|
10665
|
-
return /* @__PURE__ */ jsx("ul", { "aria-label": "Status key", className: "
|
|
10767
|
+
return /* @__PURE__ */ jsx("ul", { "aria-label": "Status key", className: "flex flex-wrap items-center gap-x-ds-3 gap-y-ds-1 text-xs text-[var(--ds-text-secondary)]", children: entries.map(([key, s]) => {
|
|
10666
10768
|
const tone = TONES[s.tone] ?? TONES.neutral;
|
|
10667
10769
|
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-ds-1.5", children: [
|
|
10668
10770
|
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("grid size-4 shrink-0 place-items-center rounded-[var(--ds-radius-sm)]", EDGE, tone.fill, tone.on), children: /* @__PURE__ */ jsx(Cue, { name: s.icon ?? tone.icon, size: 10 }) }),
|
|
@@ -11004,6 +11106,8 @@ function Gantt({
|
|
|
11004
11106
|
};
|
|
11005
11107
|
const legend = /* @__PURE__ */ jsx(Legend, { statuses });
|
|
11006
11108
|
const legendApart = toolbar === false && hasStatuses;
|
|
11109
|
+
const apartRef = useRef(null);
|
|
11110
|
+
const apartFill = useFillHeight(apartRef, legendApart);
|
|
11007
11111
|
const chart = /* @__PURE__ */ jsx(
|
|
11008
11112
|
TimeViewport,
|
|
11009
11113
|
{
|
|
@@ -11013,6 +11117,7 @@ function Gantt({
|
|
|
11013
11117
|
labelHeader,
|
|
11014
11118
|
toolbar: toolbar === false ? false : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11015
11119
|
toolbar,
|
|
11120
|
+
hasStatuses && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "min-w-0 flex-1" }),
|
|
11016
11121
|
legend
|
|
11017
11122
|
] }),
|
|
11018
11123
|
tabStop: false,
|
|
@@ -11041,9 +11146,9 @@ function Gantt({
|
|
|
11041
11146
|
}
|
|
11042
11147
|
);
|
|
11043
11148
|
if (!legendApart) return chart;
|
|
11044
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 w-full min-w-0 flex-col", className), children: [
|
|
11045
|
-
/* @__PURE__ */ jsx("div", { className: "flex shrink-0 px-ds-2 py-ds-1.5", children: legend }),
|
|
11046
|
-
chart
|
|
11149
|
+
return /* @__PURE__ */ jsxs("div", { ref: apartRef, "data-fill": apartFill != null ? "" : void 0, className: cn("flex h-full min-h-0 w-full min-w-0 flex-col", className), style: apartFill != null ? { height: apartFill } : void 0, children: [
|
|
11150
|
+
/* @__PURE__ */ jsx("div", { className: "flex shrink-0 justify-end px-ds-2 py-ds-1.5", children: legend }),
|
|
11151
|
+
/* @__PURE__ */ jsx(FillContext, { value: true, children: chart })
|
|
11047
11152
|
] });
|
|
11048
11153
|
}
|
|
11049
11154
|
var DEFAULT_OFFSET2 = "var(--ds-space-4)";
|
|
@@ -11469,14 +11574,14 @@ function TabButton({
|
|
|
11469
11574
|
hasPanel
|
|
11470
11575
|
}) {
|
|
11471
11576
|
const { ref: truncRef, isTruncated } = useTextOverflow({ lines: 1, disabled: !truncate && orientation !== "horizontal" });
|
|
11472
|
-
const
|
|
11577
|
+
const isActive2 = activeTab === id;
|
|
11473
11578
|
const tabId = `ds-tab-${id}`;
|
|
11474
11579
|
const panelId = hasPanel === false ? void 0 : `ds-tabpanel-${id}`;
|
|
11475
11580
|
const badgeBg = orientation === "vertical" ? "bg-[var(--ds-nav-v-badge-bg)]" : "bg-[var(--ds-nav-h-badge-bg)]";
|
|
11476
11581
|
const countBadge = count !== void 0 ? /* @__PURE__ */ jsx("span", { className: cn(
|
|
11477
11582
|
orientation === "vertical" ? "ml-ds-2" : "",
|
|
11478
11583
|
"px-ds-1.5 py-ds-0.5 text-xs rounded-[var(--ds-radius-sm)]",
|
|
11479
|
-
|
|
11584
|
+
isActive2 ? cn(badgeBg, "text-[var(--ds-text-on-primary)]") : "bg-[var(--ds-bg-emphasis)] text-[var(--ds-text-muted)]"
|
|
11480
11585
|
), children: count }) : null;
|
|
11481
11586
|
if (orientation === "vertical") {
|
|
11482
11587
|
const btn2 = /* @__PURE__ */ jsxs(
|
|
@@ -11485,10 +11590,10 @@ function TabButton({
|
|
|
11485
11590
|
type: "button",
|
|
11486
11591
|
id: tabId,
|
|
11487
11592
|
role: "tab",
|
|
11488
|
-
"aria-selected":
|
|
11593
|
+
"aria-selected": isActive2,
|
|
11489
11594
|
"aria-controls": panelId,
|
|
11490
11595
|
"aria-disabled": disabled || void 0,
|
|
11491
|
-
tabIndex:
|
|
11596
|
+
tabIndex: isActive2 ? 0 : -1,
|
|
11492
11597
|
onClick: disabled ? void 0 : () => onTabChange(id),
|
|
11493
11598
|
onKeyDown,
|
|
11494
11599
|
className: cn(
|
|
@@ -11500,7 +11605,7 @@ function TabButton({
|
|
|
11500
11605
|
// Every item carries the rail width as a transparent placeholder so the
|
|
11501
11606
|
// label does not shift when the rail appears on the active item.
|
|
11502
11607
|
"border-l-[length:var(--ds-nav-v-active-rail)]",
|
|
11503
|
-
|
|
11608
|
+
isActive2 ? "bg-[var(--ds-nav-v-active-bg)] text-[var(--ds-nav-v-active-text)] border-[var(--ds-accent-primary)]" : "border-transparent text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)]",
|
|
11504
11609
|
className
|
|
11505
11610
|
),
|
|
11506
11611
|
children: [
|
|
@@ -11521,10 +11626,10 @@ function TabButton({
|
|
|
11521
11626
|
type: "button",
|
|
11522
11627
|
id: tabId,
|
|
11523
11628
|
role: "tab",
|
|
11524
|
-
"aria-selected":
|
|
11629
|
+
"aria-selected": isActive2,
|
|
11525
11630
|
"aria-controls": panelId,
|
|
11526
11631
|
"aria-disabled": disabled || void 0,
|
|
11527
|
-
tabIndex:
|
|
11632
|
+
tabIndex: isActive2 ? 0 : -1,
|
|
11528
11633
|
onClick: disabled ? void 0 : () => onTabChange(id),
|
|
11529
11634
|
onKeyDown,
|
|
11530
11635
|
className: cn(
|
|
@@ -11540,10 +11645,10 @@ function TabButton({
|
|
|
11540
11645
|
fullWidth && "flex-1",
|
|
11541
11646
|
truncate && "flex-1 min-w-0 justify-start",
|
|
11542
11647
|
"rounded-[var(--ds-nav-h-item-radius)]",
|
|
11543
|
-
|
|
11648
|
+
isActive2 ? "bg-[var(--ds-nav-h-active-bg)] text-[var(--ds-nav-h-active-text)] border-[var(--ds-accent-primary)]" : "text-[var(--ds-nav-h-inactive-text)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-nav-h-hover-bg)]",
|
|
11544
11649
|
className
|
|
11545
11650
|
),
|
|
11546
|
-
style:
|
|
11651
|
+
style: isActive2 ? { borderBottomWidth: "var(--ds-nav-h-indicator)", marginBottom: "calc(var(--ds-nav-h-track-border) * -1)" } : void 0,
|
|
11547
11652
|
children: truncate ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11548
11653
|
icon && /* @__PURE__ */ jsx(Icon, { name: icon, size: 16, className: "shrink-0" }),
|
|
11549
11654
|
/* @__PURE__ */ jsx("span", { ref: truncRef, className: "truncate min-w-0 flex-1", children: label }),
|
|
@@ -11772,241 +11877,6 @@ function SettingsLayout({
|
|
|
11772
11877
|
/* @__PURE__ */ jsx("div", { "data-settings-panel": "", className: cn("flex-1", PANEL_CLASSES), style: PANEL_STYLE, children })
|
|
11773
11878
|
] });
|
|
11774
11879
|
}
|
|
11775
|
-
function SeparatorIcon({ type, size }) {
|
|
11776
|
-
const iconSize = size === "sm" ? 10 : 12;
|
|
11777
|
-
if (type === "chevron") return /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: iconSize });
|
|
11778
|
-
if (type === "arrow") return /* @__PURE__ */ jsx(Icon, { name: "arrow-right", size: iconSize });
|
|
11779
|
-
if (type === "dot") return /* @__PURE__ */ jsx("span", { children: "\xB7" });
|
|
11780
|
-
return /* @__PURE__ */ jsx("span", { children: "/" });
|
|
11781
|
-
}
|
|
11782
|
-
var Breadcrumbs = forwardRef(function Breadcrumbs2({
|
|
11783
|
-
items,
|
|
11784
|
-
separator = "chevron",
|
|
11785
|
-
variant = "inline",
|
|
11786
|
-
itemVariant,
|
|
11787
|
-
size = "md",
|
|
11788
|
-
showIcons = false,
|
|
11789
|
-
maxItems,
|
|
11790
|
-
bleed = false,
|
|
11791
|
-
contentMaxWidth,
|
|
11792
|
-
className,
|
|
11793
|
-
container
|
|
11794
|
-
}, ref) {
|
|
11795
|
-
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
11796
|
-
const [activeIdx, setActiveIdx] = useState(0);
|
|
11797
|
-
const ellipsisBtnRef = useRef(null);
|
|
11798
|
-
const dropdownRef = useRef(null);
|
|
11799
|
-
const closeDropdown = useCallback(() => setDropdownOpen(false), []);
|
|
11800
|
-
const { isTop, returnFocus } = usePopupFocus(dropdownOpen, { trigger: ellipsisBtnRef, panel: dropdownRef, close: closeDropdown, tabExits: "any" });
|
|
11801
|
-
const pos = usePosition(ellipsisBtnRef, dropdownRef, dropdownOpen, { side: "bottom", align: "start", offset: 4, flip: true });
|
|
11802
|
-
const effectiveMaxItems = maxItems ? Math.max(maxItems, 2) : void 0;
|
|
11803
|
-
const shouldCollapse = effectiveMaxItems && items.length > effectiveMaxItems;
|
|
11804
|
-
const collapsedItems = shouldCollapse ? items.slice(1, -(effectiveMaxItems - 1)) : [];
|
|
11805
|
-
const visibleItems = shouldCollapse ? [...items.slice(0, 1), null, ...items.slice(-(effectiveMaxItems - 1))] : items;
|
|
11806
|
-
useEffect(() => {
|
|
11807
|
-
if (!dropdownOpen) return;
|
|
11808
|
-
const handler = (e) => {
|
|
11809
|
-
const target = e.target;
|
|
11810
|
-
if (ellipsisBtnRef.current?.contains(target) || dropdownRef.current?.contains(target)) return;
|
|
11811
|
-
setDropdownOpen(false);
|
|
11812
|
-
};
|
|
11813
|
-
const onKeyDown = (e) => {
|
|
11814
|
-
if (e.key !== "Escape" || e.defaultPrevented || !isTop()) return;
|
|
11815
|
-
e.preventDefault();
|
|
11816
|
-
returnFocus();
|
|
11817
|
-
setDropdownOpen(false);
|
|
11818
|
-
};
|
|
11819
|
-
document.addEventListener("mousedown", handler);
|
|
11820
|
-
document.addEventListener("keydown", onKeyDown);
|
|
11821
|
-
return () => {
|
|
11822
|
-
document.removeEventListener("mousedown", handler);
|
|
11823
|
-
document.removeEventListener("keydown", onKeyDown);
|
|
11824
|
-
};
|
|
11825
|
-
}, [dropdownOpen, isTop, returnFocus]);
|
|
11826
|
-
useEffect(() => {
|
|
11827
|
-
if (!dropdownOpen) return;
|
|
11828
|
-
const id = requestAnimationFrame(() => dropdownRef.current?.querySelector(`[data-index="${activeIdx}"]`)?.focus());
|
|
11829
|
-
return () => cancelAnimationFrame(id);
|
|
11830
|
-
}, [dropdownOpen, activeIdx]);
|
|
11831
|
-
function onMenuKeyDown(e) {
|
|
11832
|
-
const last = collapsedItems.length - 1;
|
|
11833
|
-
const next = e.key === "ArrowDown" ? activeIdx >= last ? 0 : activeIdx + 1 : e.key === "ArrowUp" ? activeIdx <= 0 ? last : activeIdx - 1 : e.key === "Home" ? 0 : e.key === "End" ? last : null;
|
|
11834
|
-
if (next === null) return;
|
|
11835
|
-
e.preventDefault();
|
|
11836
|
-
setActiveIdx(next);
|
|
11837
|
-
}
|
|
11838
|
-
const textClass = size === "sm" ? "text-xs" : "text-sm";
|
|
11839
|
-
const gapClass = size === "sm" ? "gap-ds-1" : "gap-ds-1.5";
|
|
11840
|
-
const iconSize = size === "sm" ? 12 : 14;
|
|
11841
|
-
const isContainedBleed = variant === "contained" && bleed;
|
|
11842
|
-
const wrapperClasses = cn(
|
|
11843
|
-
variant === "contained" && !bleed && cn(
|
|
11844
|
-
"bg-[var(--ds-bg-muted)] rounded-[var(--ds-radius-md)]",
|
|
11845
|
-
size === "sm" ? "py-ds-1 px-ds-2" : "py-ds-1.5 px-ds-3"
|
|
11846
|
-
),
|
|
11847
|
-
!isContainedBleed && className
|
|
11848
|
-
);
|
|
11849
|
-
function renderItem(item, _index, isLast) {
|
|
11850
|
-
const isPill = itemVariant === "pill" || variant === "pill" && !itemVariant;
|
|
11851
|
-
const insideContained = variant === "contained";
|
|
11852
|
-
const pillClasses = isPill ? cn(
|
|
11853
|
-
"rounded-[var(--ds-radius-full)]",
|
|
11854
|
-
insideContained ? "bg-[var(--ds-bg-surface)]" : "bg-[var(--ds-bg-muted)]",
|
|
11855
|
-
size === "sm" ? "px-ds-2 py-[2px]" : "px-ds-2.5 py-ds-0.5"
|
|
11856
|
-
) : "";
|
|
11857
|
-
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11858
|
-
showIcons && item.icon && /* @__PURE__ */ jsx(Icon, { name: item.icon, size: iconSize, className: "shrink-0" }),
|
|
11859
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
|
|
11860
|
-
] });
|
|
11861
|
-
if (isLast) {
|
|
11862
|
-
return /* @__PURE__ */ jsx(
|
|
11863
|
-
"span",
|
|
11864
|
-
{
|
|
11865
|
-
"aria-current": "page",
|
|
11866
|
-
className: cn(
|
|
11867
|
-
"font-medium text-[var(--ds-text-primary)] flex items-center",
|
|
11868
|
-
gapClass,
|
|
11869
|
-
pillClasses
|
|
11870
|
-
),
|
|
11871
|
-
children: content
|
|
11872
|
-
}
|
|
11873
|
-
);
|
|
11874
|
-
}
|
|
11875
|
-
return /* @__PURE__ */ jsx(
|
|
11876
|
-
"a",
|
|
11877
|
-
{
|
|
11878
|
-
href: item.href ?? "#",
|
|
11879
|
-
onClick: (e) => {
|
|
11880
|
-
e.preventDefault();
|
|
11881
|
-
item.onClick?.();
|
|
11882
|
-
},
|
|
11883
|
-
className: cn(
|
|
11884
|
-
"text-[var(--ds-text-secondary)] flex items-center",
|
|
11885
|
-
"hover:text-[var(--ds-text-primary)]",
|
|
11886
|
-
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
11887
|
-
gapClass,
|
|
11888
|
-
pillClasses
|
|
11889
|
-
),
|
|
11890
|
-
children: content
|
|
11891
|
-
}
|
|
11892
|
-
);
|
|
11893
|
-
}
|
|
11894
|
-
const listContent = /* @__PURE__ */ jsx("ol", { className: cn("flex items-center flex-wrap", gapClass, textClass), children: visibleItems.map((item, i) => {
|
|
11895
|
-
if (item === null) {
|
|
11896
|
-
return /* @__PURE__ */ jsxs("li", { className: cn("flex items-center", gapClass), children: [
|
|
11897
|
-
i > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-[var(--ds-text-secondary)] select-none flex items-center", children: /* @__PURE__ */ jsx(SeparatorIcon, { type: separator, size }) }),
|
|
11898
|
-
/* @__PURE__ */ jsx(
|
|
11899
|
-
"button",
|
|
11900
|
-
{
|
|
11901
|
-
type: "button",
|
|
11902
|
-
ref: ellipsisBtnRef,
|
|
11903
|
-
onClick: () => {
|
|
11904
|
-
if (!dropdownOpen) setActiveIdx(0);
|
|
11905
|
-
setDropdownOpen(!dropdownOpen);
|
|
11906
|
-
},
|
|
11907
|
-
"aria-label": "Show hidden breadcrumbs",
|
|
11908
|
-
"aria-expanded": dropdownOpen,
|
|
11909
|
-
"aria-haspopup": "menu",
|
|
11910
|
-
className: cn(
|
|
11911
|
-
"text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)]",
|
|
11912
|
-
"transition-colors duration-[var(--ds-transition-speed)] cursor-pointer",
|
|
11913
|
-
"flex items-center",
|
|
11914
|
-
(itemVariant === "pill" || variant === "pill" && !itemVariant) && cn(
|
|
11915
|
-
"rounded-[var(--ds-radius-full)]",
|
|
11916
|
-
variant === "contained" ? "bg-[var(--ds-bg-surface)]" : "bg-[var(--ds-bg-muted)]",
|
|
11917
|
-
size === "sm" ? "px-ds-2 py-[2px]" : "px-ds-2.5 py-ds-0.5"
|
|
11918
|
-
)
|
|
11919
|
-
),
|
|
11920
|
-
children: "\xB7\xB7\xB7"
|
|
11921
|
-
}
|
|
11922
|
-
)
|
|
11923
|
-
] }, "__ellipsis");
|
|
11924
|
-
}
|
|
11925
|
-
const isLast = i === visibleItems.length - 1;
|
|
11926
|
-
return /* @__PURE__ */ jsxs("li", { className: cn("flex items-center", gapClass), children: [
|
|
11927
|
-
i > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-[var(--ds-text-secondary)] select-none flex items-center", children: /* @__PURE__ */ jsx(SeparatorIcon, { type: separator, size }) }),
|
|
11928
|
-
renderItem(item, i, isLast)
|
|
11929
|
-
] }, i);
|
|
11930
|
-
}) });
|
|
11931
|
-
const dropdown = dropdownOpen && collapsedItems.length > 0 && createPortal(
|
|
11932
|
-
/* @__PURE__ */ jsx(
|
|
11933
|
-
"div",
|
|
11934
|
-
{
|
|
11935
|
-
ref: dropdownRef,
|
|
11936
|
-
role: "menu",
|
|
11937
|
-
"aria-label": "Hidden breadcrumbs",
|
|
11938
|
-
onKeyDown: onMenuKeyDown,
|
|
11939
|
-
className: cn(
|
|
11940
|
-
"fixed z-[var(--ds-z-popover)] min-w-[160px] max-h-60 overflow-auto",
|
|
11941
|
-
"bg-[var(--ds-bg-surface-elevated)]",
|
|
11942
|
-
"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
|
|
11943
|
-
"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
11944
|
-
"rounded-[var(--ds-radius-md)]",
|
|
11945
|
-
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
|
|
11946
|
-
"py-ds-1"
|
|
11947
|
-
),
|
|
11948
|
-
style: { top: pos.top, left: pos.left },
|
|
11949
|
-
children: collapsedItems.map((ci, idx) => /* @__PURE__ */ jsxs(
|
|
11950
|
-
"button",
|
|
11951
|
-
{
|
|
11952
|
-
type: "button",
|
|
11953
|
-
"data-index": idx,
|
|
11954
|
-
role: "menuitem",
|
|
11955
|
-
tabIndex: idx === activeIdx ? 0 : -1,
|
|
11956
|
-
className: cn(
|
|
11957
|
-
"flex items-center w-full text-left text-sm cursor-pointer",
|
|
11958
|
-
"px-ds-3 py-ds-1.5 transition-colors",
|
|
11959
|
-
"text-[var(--ds-text-secondary)]",
|
|
11960
|
-
"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]",
|
|
11961
|
-
"focus-visible:outline-none focus-visible:bg-[var(--ds-bg-muted)] focus-visible:text-[var(--ds-text-primary)] focus-visible:shadow-[inset_var(--ds-shadow-focus)]",
|
|
11962
|
-
gapClass
|
|
11963
|
-
),
|
|
11964
|
-
onClick: () => {
|
|
11965
|
-
setDropdownOpen(false);
|
|
11966
|
-
ci.onClick?.();
|
|
11967
|
-
},
|
|
11968
|
-
children: [
|
|
11969
|
-
showIcons && ci.icon && /* @__PURE__ */ jsx(Icon, { name: ci.icon, size: iconSize, className: "shrink-0" }),
|
|
11970
|
-
ci.label
|
|
11971
|
-
]
|
|
11972
|
-
},
|
|
11973
|
-
idx
|
|
11974
|
-
))
|
|
11975
|
-
}
|
|
11976
|
-
),
|
|
11977
|
-
container ?? document.body
|
|
11978
|
-
);
|
|
11979
|
-
if (isContainedBleed) {
|
|
11980
|
-
return /* @__PURE__ */ jsxs(
|
|
11981
|
-
"nav",
|
|
11982
|
-
{
|
|
11983
|
-
ref,
|
|
11984
|
-
"aria-label": "Breadcrumb",
|
|
11985
|
-
className: cn(
|
|
11986
|
-
"w-full bg-[var(--ds-bg-muted)]",
|
|
11987
|
-
// Hairline under the band: it sits within ~1.2:1 of both canvas and a tinted header, so the edge needs a line.
|
|
11988
|
-
"border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
|
|
11989
|
-
className
|
|
11990
|
-
),
|
|
11991
|
-
children: [
|
|
11992
|
-
/* @__PURE__ */ jsx(
|
|
11993
|
-
"div",
|
|
11994
|
-
{
|
|
11995
|
-
className: cn("w-full mx-auto px-ds-6", size === "sm" ? "py-ds-1" : "py-ds-1.5"),
|
|
11996
|
-
style: { maxWidth: contentMaxWidth ?? "var(--ds-bp-xl)" },
|
|
11997
|
-
children: listContent
|
|
11998
|
-
}
|
|
11999
|
-
),
|
|
12000
|
-
dropdown
|
|
12001
|
-
]
|
|
12002
|
-
}
|
|
12003
|
-
);
|
|
12004
|
-
}
|
|
12005
|
-
return /* @__PURE__ */ jsxs("nav", { ref, "aria-label": "Breadcrumb", className: wrapperClasses, children: [
|
|
12006
|
-
listContent,
|
|
12007
|
-
dropdown
|
|
12008
|
-
] });
|
|
12009
|
-
});
|
|
12010
11880
|
var HeaderTabRowContext = createContext(null);
|
|
12011
11881
|
function useHeaderTabRow() {
|
|
12012
11882
|
return useContext(HeaderTabRowContext);
|
|
@@ -12059,13 +11929,13 @@ function Stepper({ steps, currentStep, onStepChange, orientation = "horizontal",
|
|
|
12059
11929
|
const isLast = i === steps.length - 1;
|
|
12060
11930
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-start min-w-0", isLast ? "flex-none" : "flex-1"), children: [
|
|
12061
11931
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center w-full", children: [
|
|
12062
|
-
/* @__PURE__ */ jsx(StepCircle, { status, index: i, onClick: onStepChange ? () => onStepChange(i) : void 0, clickable: !!onStepChange }),
|
|
11932
|
+
/* @__PURE__ */ jsx(StepCircle, { status, index: i, label: step.label, onClick: onStepChange && !step.disabled ? () => onStepChange(i) : void 0, clickable: !!onStepChange && !step.disabled }),
|
|
12063
11933
|
!isLast && /* @__PURE__ */ jsx(
|
|
12064
11934
|
"div",
|
|
12065
11935
|
{
|
|
12066
11936
|
className: cn(
|
|
12067
11937
|
"flex-1 h-0.5 mx-ds-2 transition-colors",
|
|
12068
|
-
i < currentStep ? "bg-[var(--ds-accent-primary)]" : "bg-[var(--ds-border-subtle)]"
|
|
11938
|
+
i < currentStep || steps[i + 1]?.status === "complete" ? "bg-[var(--ds-accent-primary)]" : "bg-[var(--ds-border-subtle)]"
|
|
12069
11939
|
)
|
|
12070
11940
|
}
|
|
12071
11941
|
)
|
|
@@ -12092,13 +11962,13 @@ function Stepper({ steps, currentStep, onStepChange, orientation = "horizontal",
|
|
|
12092
11962
|
const isLast = i === steps.length - 1;
|
|
12093
11963
|
return /* @__PURE__ */ jsxs("div", { className: "flex gap-ds-3", children: [
|
|
12094
11964
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
|
|
12095
|
-
/* @__PURE__ */ jsx(StepCircle, { status, index: i, onClick: onStepChange ? () => onStepChange(i) : void 0, clickable: !!onStepChange }),
|
|
11965
|
+
/* @__PURE__ */ jsx(StepCircle, { status, index: i, label: step.label, onClick: onStepChange && !step.disabled ? () => onStepChange(i) : void 0, clickable: !!onStepChange && !step.disabled }),
|
|
12096
11966
|
!isLast && /* @__PURE__ */ jsx(
|
|
12097
11967
|
"div",
|
|
12098
11968
|
{
|
|
12099
11969
|
className: cn(
|
|
12100
11970
|
"w-0.5 flex-1 min-h-6 transition-colors",
|
|
12101
|
-
i < currentStep ? "bg-[var(--ds-accent-primary)]" : "bg-[var(--ds-border-subtle)]"
|
|
11971
|
+
i < currentStep || steps[i + 1]?.status === "complete" ? "bg-[var(--ds-accent-primary)]" : "bg-[var(--ds-border-subtle)]"
|
|
12102
11972
|
)
|
|
12103
11973
|
}
|
|
12104
11974
|
)
|
|
@@ -12139,13 +12009,13 @@ function Stepper({ steps, currentStep, onStepChange, orientation = "horizontal",
|
|
|
12139
12009
|
)
|
|
12140
12010
|
}
|
|
12141
12011
|
),
|
|
12142
|
-
/* @__PURE__ */ jsx(StepCircle, { status, index: i, onClick: onStepChange ? () => onStepChange(i) : void 0, clickable: !!onStepChange }),
|
|
12012
|
+
/* @__PURE__ */ jsx(StepCircle, { status, index: i, label: step.label, onClick: onStepChange && !step.disabled ? () => onStepChange(i) : void 0, clickable: !!onStepChange && !step.disabled }),
|
|
12143
12013
|
/* @__PURE__ */ jsx(
|
|
12144
12014
|
"div",
|
|
12145
12015
|
{
|
|
12146
12016
|
className: cn(
|
|
12147
12017
|
"flex-1 h-0.5 transition-colors",
|
|
12148
|
-
isLast ? "bg-transparent" : i < currentStep ? "bg-[var(--ds-accent-primary)]" : "bg-[var(--ds-border-subtle)]"
|
|
12018
|
+
isLast ? "bg-transparent" : i < currentStep || steps[i + 1]?.status === "complete" ? "bg-[var(--ds-accent-primary)]" : "bg-[var(--ds-border-subtle)]"
|
|
12149
12019
|
)
|
|
12150
12020
|
}
|
|
12151
12021
|
)
|
|
@@ -12168,13 +12038,14 @@ function Stepper({ steps, currentStep, onStepChange, orientation = "horizontal",
|
|
|
12168
12038
|
}
|
|
12169
12039
|
);
|
|
12170
12040
|
}
|
|
12171
|
-
function StepCircle({ status, index, onClick, clickable }) {
|
|
12041
|
+
function StepCircle({ status, index, label, onClick, clickable }) {
|
|
12172
12042
|
return /* @__PURE__ */ jsx(
|
|
12173
12043
|
"button",
|
|
12174
12044
|
{
|
|
12175
12045
|
type: "button",
|
|
12176
12046
|
onClick,
|
|
12177
12047
|
disabled: !clickable,
|
|
12048
|
+
"aria-label": `Step ${index + 1}: ${label}${status === "complete" ? ", completed" : ""}`,
|
|
12178
12049
|
"aria-current": status === "current" ? "step" : void 0,
|
|
12179
12050
|
className: cn(
|
|
12180
12051
|
"flex items-center justify-center shrink-0 w-8 h-8 rounded-[var(--ds-radius-full)] text-xs font-bold transition-colors",
|
|
@@ -12185,7 +12056,9 @@ function StepCircle({ status, index, onClick, clickable }) {
|
|
|
12185
12056
|
status === "current" && `border-2 ${ACTIVE_RING} text-[var(--ds-accent-primary)] bg-[var(--ds-bg-surface)]`,
|
|
12186
12057
|
status === "error" && "bg-[var(--ds-status-error)] text-[var(--ds-text-on-error)]",
|
|
12187
12058
|
status === "loading" && `border-2 ${ACTIVE_RING} text-[var(--ds-accent-primary)] bg-[var(--ds-bg-surface)] animate-pulse`,
|
|
12188
|
-
status === "upcoming" && "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)] text-[var(--ds-text-muted)] bg-[var(--ds-bg-surface)]"
|
|
12059
|
+
status === "upcoming" && "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)] text-[var(--ds-text-muted)] bg-[var(--ds-bg-surface)]",
|
|
12060
|
+
// a step reached but not done (the user went back) can be gone to: it answers the pointer as the done ones do
|
|
12061
|
+
status === "upcoming" && clickable && "hover:border-[var(--ds-accent-primary)] hover:text-[var(--ds-accent-primary)]"
|
|
12189
12062
|
),
|
|
12190
12063
|
children: status === "complete" ? /* @__PURE__ */ jsx(Icon, { name: "check", size: 14 }) : status === "error" ? /* @__PURE__ */ jsx(Icon, { name: "warning", size: 14 }) : index + 1
|
|
12191
12064
|
}
|
|
@@ -12517,17 +12390,13 @@ function TruncLabel3({ children, className, side = "right", container, lines = 1
|
|
|
12517
12390
|
if (!isTruncated) return label;
|
|
12518
12391
|
return /* @__PURE__ */ jsx(Tooltip, { content: children, side, delay: 200, container, children: label });
|
|
12519
12392
|
}
|
|
12520
|
-
|
|
12521
|
-
return items.some(
|
|
12522
|
-
(it) => it.active || it.children && hasActiveDescendant(it.children)
|
|
12523
|
-
);
|
|
12524
|
-
}
|
|
12393
|
+
var isActive = (item) => !!item.active;
|
|
12525
12394
|
function collectInitialExpanded(items, prefix = "") {
|
|
12526
12395
|
const keys = [];
|
|
12527
12396
|
for (const item of items) {
|
|
12528
12397
|
if (!item.children?.length) continue;
|
|
12529
12398
|
const key = prefix ? `${prefix}/${item.label}` : item.label;
|
|
12530
|
-
if (item.defaultExpanded ||
|
|
12399
|
+
if (item.defaultExpanded || holdsCurrent(item.children, isActive)) {
|
|
12531
12400
|
keys.push(key);
|
|
12532
12401
|
}
|
|
12533
12402
|
keys.push(...collectInitialExpanded(item.children, key));
|
|
@@ -12749,7 +12618,7 @@ function SidebarNav({
|
|
|
12749
12618
|
function renderCompactItem(item, index, parentKey) {
|
|
12750
12619
|
const hasChildren = !!item.children?.length;
|
|
12751
12620
|
const key = makeKey(item.label, parentKey);
|
|
12752
|
-
const childActive = hasChildren &&
|
|
12621
|
+
const childActive = hasChildren && holdsCurrent(item.children, isActive);
|
|
12753
12622
|
const isOpen = openFlyout === key;
|
|
12754
12623
|
return /* @__PURE__ */ jsx(
|
|
12755
12624
|
CompactNavItem,
|
|
@@ -12783,7 +12652,7 @@ function SidebarNav({
|
|
|
12783
12652
|
return renderLeaf(item, depth, index);
|
|
12784
12653
|
}
|
|
12785
12654
|
const isExpanded = expandedItems.has(key);
|
|
12786
|
-
const childActive =
|
|
12655
|
+
const childActive = holdsCurrent(item.children, isActive);
|
|
12787
12656
|
const isRoot = depth === 0;
|
|
12788
12657
|
const rootPy = isSm ? "py-ds-1.5" : "py-ds-2";
|
|
12789
12658
|
const childPy = isSm ? "py-ds-1" : "py-ds-1.5";
|
|
@@ -13353,7 +13222,7 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
|
|
|
13353
13222
|
const noteShown = useCallback((id, variant, action, fresh) => {
|
|
13354
13223
|
if (runs.current.size) shownDuringRuns.current.push({ seq: ++showSeq.current, at: Date.now(), id, variant, action, fresh });
|
|
13355
13224
|
}, []);
|
|
13356
|
-
const
|
|
13225
|
+
const update2 = useCallback((id, message, options = {}) => {
|
|
13357
13226
|
const list2 = entries.current;
|
|
13358
13227
|
const at = list2.findIndex((t2) => t2.id === id);
|
|
13359
13228
|
if (at === -1) return;
|
|
@@ -13403,21 +13272,21 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
|
|
|
13403
13272
|
success: (m, o) => toast(m, { ...o, variant: "success" }),
|
|
13404
13273
|
warning: (m, o) => toast(m, { ...o, variant: "warning" }),
|
|
13405
13274
|
error: (m, o) => toast(m, { ...o, variant: "error" }),
|
|
13406
|
-
update,
|
|
13275
|
+
update: update2,
|
|
13407
13276
|
dismiss: remove,
|
|
13408
13277
|
dismissAll,
|
|
13409
13278
|
promise: async (promise, messages, options = {}) => {
|
|
13410
13279
|
const id = toast(messages.loading, { ...options, variant: "default", duration: Infinity });
|
|
13411
13280
|
try {
|
|
13412
13281
|
const value = await promise;
|
|
13413
|
-
|
|
13282
|
+
update2(id, typeof messages.success === "function" ? messages.success(value) : messages.success, { variant: "success", duration });
|
|
13414
13283
|
return value;
|
|
13415
13284
|
} catch (err) {
|
|
13416
|
-
|
|
13285
|
+
update2(id, typeof messages.error === "function" ? messages.error(err) : messages.error, { variant: "error", duration });
|
|
13417
13286
|
throw err;
|
|
13418
13287
|
}
|
|
13419
13288
|
}
|
|
13420
|
-
}), [toast,
|
|
13289
|
+
}), [toast, update2, remove, dismissAll, duration]);
|
|
13421
13290
|
const ledger = useMemo(() => ({
|
|
13422
13291
|
begin: () => {
|
|
13423
13292
|
const run = ++runSeq.current;
|
|
@@ -13749,15 +13618,16 @@ var paddingClasses = {
|
|
|
13749
13618
|
default: "px-[var(--ds-page-gutter)]",
|
|
13750
13619
|
wide: "px-ds-10"
|
|
13751
13620
|
};
|
|
13621
|
+
var FILLED_BOTTOM = "has-[[data-fill]]:pb-[var(--ds-page-gutter)]";
|
|
13752
13622
|
var verticalPaddingClasses = {
|
|
13753
13623
|
none: "",
|
|
13754
|
-
default:
|
|
13755
|
-
spacious:
|
|
13624
|
+
default: `pt-ds-8 pb-ds-12 ${FILLED_BOTTOM}`,
|
|
13625
|
+
spacious: `pt-ds-8 pb-ds-16 ${FILLED_BOTTOM}`
|
|
13756
13626
|
};
|
|
13757
13627
|
var bottomPaddingClasses = {
|
|
13758
13628
|
none: "",
|
|
13759
|
-
default:
|
|
13760
|
-
spacious:
|
|
13629
|
+
default: `pb-ds-12 ${FILLED_BOTTOM}`,
|
|
13630
|
+
spacious: `pb-ds-16 ${FILLED_BOTTOM}`
|
|
13761
13631
|
};
|
|
13762
13632
|
var bottomPaddingValues = {
|
|
13763
13633
|
none: "0px",
|
|
@@ -13780,6 +13650,38 @@ function useContentWidth(width) {
|
|
|
13780
13650
|
return () => request(null);
|
|
13781
13651
|
}, [request, width]);
|
|
13782
13652
|
}
|
|
13653
|
+
function PageActions({ children }) {
|
|
13654
|
+
const slot = useContext(PageActionsCtx);
|
|
13655
|
+
const add = slot?.add;
|
|
13656
|
+
useEffect(() => add?.(), [add]);
|
|
13657
|
+
const target = slot?.target;
|
|
13658
|
+
return target ? createPortal(/* @__PURE__ */ jsx(ControlSizeContext, { value: target.size, children }), target.el) : null;
|
|
13659
|
+
}
|
|
13660
|
+
var pageOrder = (a, b) => a.el.compareDocumentPosition(b.el) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
|
|
13661
|
+
function usePageActionsSlot() {
|
|
13662
|
+
const outer = useContext(PageActionsCtx);
|
|
13663
|
+
const [asking, setAsking] = useState(0);
|
|
13664
|
+
const [slots, setSlots] = useState([]);
|
|
13665
|
+
const register = useCallback((el, size) => {
|
|
13666
|
+
setSlots((list) => [...list.filter((s) => s.el !== el), { el, size }]);
|
|
13667
|
+
return () => setSlots((list) => list.filter((s) => s.el !== el));
|
|
13668
|
+
}, []);
|
|
13669
|
+
const outerAdd = outer?.add;
|
|
13670
|
+
const add = useCallback(() => {
|
|
13671
|
+
setAsking((n) => n + 1);
|
|
13672
|
+
const releaseOuter = outerAdd?.();
|
|
13673
|
+
let released = false;
|
|
13674
|
+
return () => {
|
|
13675
|
+
if (released) return;
|
|
13676
|
+
released = true;
|
|
13677
|
+
setAsking((n) => n - 1);
|
|
13678
|
+
releaseOuter?.();
|
|
13679
|
+
};
|
|
13680
|
+
}, [outerAdd]);
|
|
13681
|
+
const own = useMemo(() => [...slots].sort(pageOrder)[0] ?? null, [slots]);
|
|
13682
|
+
const target = own ?? outer?.target ?? null;
|
|
13683
|
+
return useMemo(() => ({ wanted: asking > 0, target, register, add }), [asking, target, register, add]);
|
|
13684
|
+
}
|
|
13783
13685
|
function usePageContainer() {
|
|
13784
13686
|
return useContext(PageContainerContext);
|
|
13785
13687
|
}
|
|
@@ -13856,6 +13758,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
13856
13758
|
headerCount.current = Math.max(0, headerCount.current + (present ? 1 : -1));
|
|
13857
13759
|
setWrappedHeader(headerCount.current > 0);
|
|
13858
13760
|
}, []);
|
|
13761
|
+
const pageActions = usePageActionsSlot();
|
|
13859
13762
|
const launcherCorner = shell?.launcherCorner ?? null;
|
|
13860
13763
|
const vPad = verticalPadding ?? "default";
|
|
13861
13764
|
const launcherPadding = launcherCorner ? { paddingBottom: `max(${bottomPaddingValues[vPad]}, var(--ds-toast-inset-${launcherCorner}, 0px))` } : {};
|
|
@@ -13901,7 +13804,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
13901
13804
|
observedRef.current = null;
|
|
13902
13805
|
}, []);
|
|
13903
13806
|
if (headerIdx === -1 || !headerEl || !r) {
|
|
13904
|
-
return /* @__PURE__ */ jsx(PageContainerContext, { value: { contentMaxWidth: maxWidthValue, placement: "inside", containedBreadcrumbs: false, breadcrumbsInsideHeader: false, noBottomMargin: false, overlap: false, setPinnedHeight, reportHeader, requestContentWidth, insidePaddedColumn: true }, children: /* @__PURE__ */ jsx(
|
|
13807
|
+
return /* @__PURE__ */ jsx(PageActionsCtx, { value: pageActions, children: /* @__PURE__ */ jsx(PageContainerContext, { value: { contentMaxWidth: maxWidthValue, placement: "inside", containedBreadcrumbs: false, breadcrumbsInsideHeader: false, noBottomMargin: false, overlap: false, setPinnedHeight, reportHeader, requestContentWidth, insidePaddedColumn: true }, children: /* @__PURE__ */ jsx(
|
|
13905
13808
|
"div",
|
|
13906
13809
|
{
|
|
13907
13810
|
ref: setRoot,
|
|
@@ -13917,7 +13820,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
13917
13820
|
style: { maxWidth: maxWidthValue, containerType: "inline-size", ...launcherPadding },
|
|
13918
13821
|
children: capped(children)
|
|
13919
13822
|
}
|
|
13920
|
-
) });
|
|
13823
|
+
) }) });
|
|
13921
13824
|
}
|
|
13922
13825
|
const rest = kids.filter((_, i) => i !== headerIdx);
|
|
13923
13826
|
const snapping = r.behavior === "snapping";
|
|
@@ -13938,7 +13841,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
13938
13841
|
...overlapActive ? { marginTop: "calc(-1 * var(--ds-overlap, 0px))", position: "relative", zIndex: 1 } : {}
|
|
13939
13842
|
} : void 0;
|
|
13940
13843
|
const column = /* @__PURE__ */ jsx(PageContainerContext, { value: { contentMaxWidth: maxWidthValue, placement: "inside", containedBreadcrumbs: false, breadcrumbsInsideHeader: false, noBottomMargin: false, overlap: false, setPinnedHeight, reportHeader, requestContentWidth, insidePaddedColumn: true }, children: /* @__PURE__ */ jsx("div", { ref: columnRef, className: cn(columnClass(contentPadding), bottomPaddingClasses[vPad], className), style: { ...columnStyle, ...launcherPadding }, children: capped(rest) }) });
|
|
13941
|
-
return /* @__PURE__ */ jsxs("div", { ref: setRoot, "data-page-container": "", "data-width": dataWidth, className: "w-full", children: [
|
|
13844
|
+
return /* @__PURE__ */ jsx(PageActionsCtx, { value: pageActions, children: /* @__PURE__ */ jsxs("div", { ref: setRoot, "data-page-container": "", "data-width": dataWidth, className: "w-full", children: [
|
|
13942
13845
|
placement === "block" ? /* @__PURE__ */ jsx("div", { style: floatingBlockPadding(r.navbarFloating, r.sidebarFloating, overlapActive), children: /* @__PURE__ */ jsxs("div", { className: FLOATING_BLOCK, children: [
|
|
13943
13846
|
strip,
|
|
13944
13847
|
colourful ? header : /* @__PURE__ */ jsx("div", { className: columnClass(padding), style: columnStyle, children: header })
|
|
@@ -13950,7 +13853,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
13950
13853
|
/* @__PURE__ */ jsx("div", { className: columnClass(padding), style: columnStyle, children: header })
|
|
13951
13854
|
] }),
|
|
13952
13855
|
wrapperStyle ? /* @__PURE__ */ jsx("div", { style: wrapperStyle, children: column }) : column
|
|
13953
|
-
] });
|
|
13856
|
+
] }) });
|
|
13954
13857
|
});
|
|
13955
13858
|
function TruncHeading({ as: Tag3 = "h1", className, children, lines: linesProp }) {
|
|
13956
13859
|
const lines = linesProp ?? (Tag3 === "h1" ? 2 : 1);
|
|
@@ -13978,7 +13881,8 @@ function outerHeight(el) {
|
|
|
13978
13881
|
const s = getComputedStyle(el);
|
|
13979
13882
|
return el.getBoundingClientRect().height + (parseFloat(s.marginTop) || 0) + (parseFloat(s.marginBottom) || 0);
|
|
13980
13883
|
}
|
|
13981
|
-
function
|
|
13884
|
+
function Breadcrumbs2({ items, onLight, onTint, pill, separator = "chevron" }) {
|
|
13885
|
+
const follow = useCrumbFollow();
|
|
13982
13886
|
if (!items.length) return null;
|
|
13983
13887
|
const mutedCls = onLight ? "text-[var(--ds-text-on-primary)]/40" : onTint ? "text-[var(--ds-text-muted-on-tint)]" : "text-[var(--ds-text-secondary)]";
|
|
13984
13888
|
const sepEl = (key) => {
|
|
@@ -13993,17 +13897,15 @@ function Breadcrumbs3({ items, onLight, onTint, pill, separator = "chevron" }) {
|
|
|
13993
13897
|
onLight ? "bg-[var(--ds-text-on-primary)]/10" : onTint ? "bg-[var(--ds-bg-surface)]/70" : "bg-[var(--ds-bg-muted)]"
|
|
13994
13898
|
) : "";
|
|
13995
13899
|
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "flex items-center gap-ds-1.5 text-sm", children: items.map((item, i) => {
|
|
13996
|
-
const isNavigable =
|
|
13900
|
+
const isNavigable = crumbGoes(item);
|
|
13901
|
+
const isCurrent = !isNavigable && i === items.length - 1;
|
|
13997
13902
|
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-ds-1.5", children: [
|
|
13998
13903
|
i > 0 && sepEl(i),
|
|
13999
13904
|
isNavigable ? /* @__PURE__ */ jsx(
|
|
14000
13905
|
"a",
|
|
14001
13906
|
{
|
|
14002
13907
|
href: item.href ?? "#",
|
|
14003
|
-
onClick: (e) =>
|
|
14004
|
-
e.preventDefault();
|
|
14005
|
-
item.onClick?.();
|
|
14006
|
-
},
|
|
13908
|
+
onClick: (e) => follow(e, item),
|
|
14007
13909
|
className: cn(
|
|
14008
13910
|
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
14009
13911
|
onLight ? "text-[var(--ds-text-on-primary)]/60 hover:text-[var(--ds-text-on-primary)]/90" : cn(mutedCls, "hover:text-[var(--ds-text-primary)]"),
|
|
@@ -14011,9 +13913,8 @@ function Breadcrumbs3({ items, onLight, onTint, pill, separator = "chevron" }) {
|
|
|
14011
13913
|
),
|
|
14012
13914
|
children: item.label
|
|
14013
13915
|
}
|
|
14014
|
-
) : /* @__PURE__ */ jsx("span", { className: cn(
|
|
14015
|
-
"font-medium",
|
|
14016
|
-
onLight ? "text-[var(--ds-text-on-primary)]/80" : "text-[var(--ds-text-primary)]",
|
|
13916
|
+
) : /* @__PURE__ */ jsx("span", { "aria-current": isCurrent ? "page" : void 0, className: cn(
|
|
13917
|
+
isCurrent ? cn("font-medium", onLight ? "text-[var(--ds-text-on-primary)]/80" : "text-[var(--ds-text-primary)]") : onLight ? "text-[var(--ds-text-on-primary)]/60" : mutedCls,
|
|
14017
13918
|
pillCls
|
|
14018
13919
|
), children: item.label })
|
|
14019
13920
|
] }, i);
|
|
@@ -14028,6 +13929,11 @@ function TintWash() {
|
|
|
14028
13929
|
}
|
|
14029
13930
|
);
|
|
14030
13931
|
}
|
|
13932
|
+
function PageActionsSlotMark({ register }) {
|
|
13933
|
+
const size = useContext(ControlSizeContext);
|
|
13934
|
+
const ref = useCallback((el) => el ? register(el, size) : void 0, [register, size]);
|
|
13935
|
+
return /* @__PURE__ */ jsx("span", { ref, "data-page-actions": "", className: "contents" });
|
|
13936
|
+
}
|
|
14031
13937
|
function BackButton({ onLight, onClick }) {
|
|
14032
13938
|
return /* @__PURE__ */ jsx(
|
|
14033
13939
|
"button",
|
|
@@ -14134,6 +14040,11 @@ var PageHeader = forwardRef(function PageHeader2({
|
|
|
14134
14040
|
}, ref) {
|
|
14135
14041
|
const shell = useAppShell();
|
|
14136
14042
|
const container = usePageContainer();
|
|
14043
|
+
const pageActions = useContext(PageActionsCtx);
|
|
14044
|
+
const shownActions = pageActions?.wanted ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14045
|
+
actions,
|
|
14046
|
+
/* @__PURE__ */ jsx(PageActionsSlotMark, { register: pageActions.register })
|
|
14047
|
+
] }) : actions;
|
|
14137
14048
|
const reportHeader = container?.reportHeader;
|
|
14138
14049
|
useLayoutEffect(() => {
|
|
14139
14050
|
if (!reportHeader) return;
|
|
@@ -14179,7 +14090,7 @@ var PageHeader = forwardRef(function PageHeader2({
|
|
|
14179
14090
|
badge,
|
|
14180
14091
|
breadcrumbs: inlineBreadcrumbs,
|
|
14181
14092
|
onBack,
|
|
14182
|
-
actions,
|
|
14093
|
+
actions: shownActions,
|
|
14183
14094
|
avatar,
|
|
14184
14095
|
filters,
|
|
14185
14096
|
expandedContent,
|
|
@@ -14207,7 +14118,7 @@ var PageHeader = forwardRef(function PageHeader2({
|
|
|
14207
14118
|
}
|
|
14208
14119
|
let header;
|
|
14209
14120
|
if (variant === "minimal") {
|
|
14210
|
-
header = /* @__PURE__ */ jsx(MinimalHeader, { title, description, caption, focusBack, badge, breadcrumbs: inlineBreadcrumbs, actions, tabs, breadcrumbPill: bcPill, breadcrumbSeparator: bcSep, as: Heading, className, headerRef: floating ? void 0 : ref, isFloating: floating, contentMaxWidth: gutterWidth });
|
|
14121
|
+
header = /* @__PURE__ */ jsx(MinimalHeader, { title, description, caption, focusBack, badge, breadcrumbs: inlineBreadcrumbs, actions: shownActions, tabs, breadcrumbPill: bcPill, breadcrumbSeparator: bcSep, as: Heading, className, headerRef: floating ? void 0 : ref, isFloating: floating, contentMaxWidth: gutterWidth });
|
|
14211
14122
|
} else if (variant === "tabs-integrated") {
|
|
14212
14123
|
header = /* @__PURE__ */ jsx(
|
|
14213
14124
|
TabsIntegratedHeader,
|
|
@@ -14219,7 +14130,7 @@ var PageHeader = forwardRef(function PageHeader2({
|
|
|
14219
14130
|
badge,
|
|
14220
14131
|
breadcrumbs: inlineBreadcrumbs,
|
|
14221
14132
|
onBack,
|
|
14222
|
-
actions,
|
|
14133
|
+
actions: shownActions,
|
|
14223
14134
|
avatar,
|
|
14224
14135
|
tabs,
|
|
14225
14136
|
breadcrumbPill: bcPill,
|
|
@@ -14244,7 +14155,7 @@ var PageHeader = forwardRef(function PageHeader2({
|
|
|
14244
14155
|
badge,
|
|
14245
14156
|
breadcrumbs: inlineBreadcrumbs,
|
|
14246
14157
|
onBack,
|
|
14247
|
-
actions,
|
|
14158
|
+
actions: shownActions,
|
|
14248
14159
|
avatar,
|
|
14249
14160
|
filters,
|
|
14250
14161
|
intensity,
|
|
@@ -14272,7 +14183,7 @@ var PageHeader = forwardRef(function PageHeader2({
|
|
|
14272
14183
|
badge,
|
|
14273
14184
|
breadcrumbs: inlineBreadcrumbs,
|
|
14274
14185
|
onBack,
|
|
14275
|
-
actions,
|
|
14186
|
+
actions: shownActions,
|
|
14276
14187
|
avatar,
|
|
14277
14188
|
filters,
|
|
14278
14189
|
bannerImage,
|
|
@@ -14354,7 +14265,7 @@ function DefaultHeader({
|
|
|
14354
14265
|
hasBanner && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[var(--ds-bg-canvas)]/85" }),
|
|
14355
14266
|
/* @__PURE__ */ jsxs("div", { className: inner.className, style: inner.style, children: [
|
|
14356
14267
|
focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
|
|
14357
|
-
hasBreadcrumbs && /* @__PURE__ */ jsx(
|
|
14268
|
+
hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
|
|
14358
14269
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
14359
14270
|
"flex flex-col @sm:flex-row @sm:items-center justify-between gap-ds-4",
|
|
14360
14271
|
hasBreadcrumbs && "mt-ds-1"
|
|
@@ -14401,7 +14312,7 @@ function MinimalHeader({
|
|
|
14401
14312
|
const inner = floatingContentProps(isFloating, contentMaxWidth);
|
|
14402
14313
|
return /* @__PURE__ */ jsx("header", { "data-gs": "page-header", ref: headerRef, className: cn("py-ds-2", hasBreadcrumbs && "pt-ds-1", tabs && "pb-ds-4", isFloating && FLOATING_HEADER, className), children: /* @__PURE__ */ jsxs("div", { className: inner.className, style: inner.style, children: [
|
|
14403
14314
|
focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
|
|
14404
|
-
hasBreadcrumbs && /* @__PURE__ */ jsx(
|
|
14315
|
+
hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
|
|
14405
14316
|
caption && /* @__PURE__ */ jsx(Caption, { children: caption }),
|
|
14406
14317
|
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-ds-4", hasBreadcrumbs && "mt-ds-0.5"), children: [
|
|
14407
14318
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2 min-w-0", children: [
|
|
@@ -14491,7 +14402,7 @@ function ColourfulHeader({
|
|
|
14491
14402
|
},
|
|
14492
14403
|
children: [
|
|
14493
14404
|
focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack, onLight: isBold }),
|
|
14494
|
-
hasBreadcrumbs && /* @__PURE__ */ jsx(
|
|
14405
|
+
hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, onLight: isBold, onTint: !isBold, pill: breadcrumbPill, separator: breadcrumbSeparator }),
|
|
14495
14406
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
14496
14407
|
"flex flex-col @sm:flex-row @sm:items-center justify-between gap-ds-4",
|
|
14497
14408
|
hasBreadcrumbs && "mt-ds-1"
|
|
@@ -14558,6 +14469,7 @@ function SnappingHeader({
|
|
|
14558
14469
|
stickyTop = "top-[var(--ds-navbar-height)]"
|
|
14559
14470
|
}) {
|
|
14560
14471
|
const [collapsed, setCollapsed] = useState(false);
|
|
14472
|
+
const followCrumb = useCrumbFollow();
|
|
14561
14473
|
const container = usePageContainer();
|
|
14562
14474
|
const stickyRef = useRef(null);
|
|
14563
14475
|
const setStickyRef = useCallback((node) => {
|
|
@@ -14692,7 +14604,7 @@ function SnappingHeader({
|
|
|
14692
14604
|
const hasBreadcrumbs = !!(breadcrumbs && breadcrumbs.length > 0);
|
|
14693
14605
|
const innerContent = isMinimal && !collapsed ? /* @__PURE__ */ jsxs("div", { className: cn("py-ds-2", hasBreadcrumbs && !hideExpandedBreadcrumbs && "pt-ds-1", tabs && "pb-ds-4"), children: [
|
|
14694
14606
|
focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
|
|
14695
|
-
hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(
|
|
14607
|
+
hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
|
|
14696
14608
|
caption && /* @__PURE__ */ jsx(Caption, { children: caption }),
|
|
14697
14609
|
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-ds-4", hasBreadcrumbs && !hideExpandedBreadcrumbs && "mt-ds-0.5"), children: [
|
|
14698
14610
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2 min-w-0", children: [
|
|
@@ -14719,7 +14631,7 @@ function SnappingHeader({
|
|
|
14719
14631
|
style: !collapsed && isColourful && overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px) - ${isBoldColourful && !(isFloating && !wrapperHasCard) ? "2px" : "var(--ds-border-width)"})` } : void 0,
|
|
14720
14632
|
children: [
|
|
14721
14633
|
!collapsed && focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack, onLight }),
|
|
14722
|
-
!collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(
|
|
14634
|
+
!collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, onLight, onTint, pill: breadcrumbPill, separator: breadcrumbSeparator }),
|
|
14723
14635
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
14724
14636
|
"flex justify-between gap-ds-4",
|
|
14725
14637
|
collapsed ? "items-center" : "flex-col @sm:flex-row @sm:items-center",
|
|
@@ -14734,17 +14646,14 @@ function SnappingHeader({
|
|
|
14734
14646
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
|
|
14735
14647
|
collapsed && hasBreadcrumbs && (() => {
|
|
14736
14648
|
const lastCrumb = breadcrumbs[breadcrumbs.length - 1];
|
|
14737
|
-
const isClickable = !!
|
|
14649
|
+
const isClickable = !!lastCrumb && crumbGoes(lastCrumb);
|
|
14738
14650
|
const Tag3 = isClickable ? "a" : "span";
|
|
14739
14651
|
return /* @__PURE__ */ jsxs(
|
|
14740
14652
|
Tag3,
|
|
14741
14653
|
{
|
|
14742
14654
|
...isClickable ? {
|
|
14743
14655
|
href: lastCrumb.href ?? "#",
|
|
14744
|
-
onClick: (e) =>
|
|
14745
|
-
e.preventDefault();
|
|
14746
|
-
lastCrumb.onClick?.();
|
|
14747
|
-
}
|
|
14656
|
+
onClick: (e) => followCrumb(e, lastCrumb)
|
|
14748
14657
|
} : {},
|
|
14749
14658
|
className: cn(
|
|
14750
14659
|
"text-sm hidden @sm:inline-flex items-center gap-ds-1",
|
|
@@ -14841,7 +14750,7 @@ function TabsIntegratedHeader({
|
|
|
14841
14750
|
const inner = floatingContentProps(isFloating, contentMaxWidth);
|
|
14842
14751
|
return /* @__PURE__ */ jsx("header", { "data-gs": "page-header", ref: headerRef, className: cn(hasBreadcrumbs ? "pt-ds-3" : "pt-ds-6", "pb-ds-4", isFloating && cn(FLOATING_HEADER, "overflow-hidden"), className), children: /* @__PURE__ */ jsxs("div", { className: inner.className, style: inner.style, children: [
|
|
14843
14752
|
focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
|
|
14844
|
-
hasBreadcrumbs && /* @__PURE__ */ jsx(
|
|
14753
|
+
hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
|
|
14845
14754
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
14846
14755
|
"flex flex-col @sm:flex-row @sm:items-center justify-between gap-ds-4",
|
|
14847
14756
|
hasBreadcrumbs && "mt-ds-1"
|
|
@@ -15390,7 +15299,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
|
|
|
15390
15299
|
"data-gs": "dialog",
|
|
15391
15300
|
"aria-labelledby": titleId,
|
|
15392
15301
|
"aria-describedby": description ? descriptionId : void 0,
|
|
15393
|
-
style: { containerType: "inline-size" },
|
|
15302
|
+
style: { containerType: "inline-size", "--ds-form-max": "none" },
|
|
15394
15303
|
className: cn(
|
|
15395
15304
|
// a column: the title row, a body that scrolls when it is taller than the room, and the footer (Sprint 25.14,
|
|
15396
15305
|
// with A36's full-screen phone dialog: its content ran past the screen with the footer cut off)
|
|
@@ -15601,7 +15510,7 @@ var Navbar = forwardRef(function Navbar2({
|
|
|
15601
15510
|
}
|
|
15602
15511
|
focus.onExit?.();
|
|
15603
15512
|
};
|
|
15604
|
-
const exitControl = focus ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: requestExit, children: focus.exitLabel ?? (focus.kind === "before-app" ? "Save and log out" : "Exit") }) : null;
|
|
15513
|
+
const exitControl = focus && !appShell?.flowLeft ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: requestExit, children: focus.exitLabel ?? (focus.kind === "before-app" ? "Save and log out" : "Exit") }) : null;
|
|
15605
15514
|
const shownUserMenu = focus?.kind === "before-app" ? null : userMenu;
|
|
15606
15515
|
const asking = confirmExit && focus?.kind === "in-app" && !!appShell?.hasUnsavedChanges;
|
|
15607
15516
|
if (confirmExit && !asking) setConfirmExit(false);
|
|
@@ -16735,6 +16644,310 @@ function getPopoverPosition(rect, placement, padding) {
|
|
|
16735
16644
|
top = Math.max(8, Math.min(top, window.innerHeight - popH - 8));
|
|
16736
16645
|
return { top, left };
|
|
16737
16646
|
}
|
|
16647
|
+
var FLOW_STORAGE_PREFIX = "gridsmith-flow:";
|
|
16648
|
+
var stores = /* @__PURE__ */ new Map();
|
|
16649
|
+
var storeFor = (key) => {
|
|
16650
|
+
let store = stores.get(key);
|
|
16651
|
+
if (!store) {
|
|
16652
|
+
store = { value: null, raw: void 0, stale: false, listeners: /* @__PURE__ */ new Set(), finished: false, focusStep: null, left: null };
|
|
16653
|
+
stores.set(key, store);
|
|
16654
|
+
}
|
|
16655
|
+
return store;
|
|
16656
|
+
};
|
|
16657
|
+
var notify = (store) => store.listeners.forEach((listener) => listener());
|
|
16658
|
+
function subscribeTo(key, listener) {
|
|
16659
|
+
const store = storeFor(key);
|
|
16660
|
+
store.listeners.add(listener);
|
|
16661
|
+
if (!store.onStorage && typeof window !== "undefined") {
|
|
16662
|
+
store.onStorage = (e) => {
|
|
16663
|
+
if (e.key !== null && e.key !== FLOW_STORAGE_PREFIX + key) return;
|
|
16664
|
+
store.stale = true;
|
|
16665
|
+
notify(store);
|
|
16666
|
+
};
|
|
16667
|
+
window.addEventListener("storage", store.onStorage);
|
|
16668
|
+
}
|
|
16669
|
+
return () => {
|
|
16670
|
+
store.listeners.delete(listener);
|
|
16671
|
+
if (store.listeners.size > 0) return;
|
|
16672
|
+
if (store.onStorage) window.removeEventListener("storage", store.onStorage);
|
|
16673
|
+
store.onStorage = void 0;
|
|
16674
|
+
store.finished = false;
|
|
16675
|
+
};
|
|
16676
|
+
}
|
|
16677
|
+
var readRaw = (key) => {
|
|
16678
|
+
try {
|
|
16679
|
+
return window.localStorage.getItem(FLOW_STORAGE_PREFIX + key);
|
|
16680
|
+
} catch {
|
|
16681
|
+
return null;
|
|
16682
|
+
}
|
|
16683
|
+
};
|
|
16684
|
+
function readRecord(key) {
|
|
16685
|
+
return parseRecord(readRaw(key));
|
|
16686
|
+
}
|
|
16687
|
+
function parseRecord(raw) {
|
|
16688
|
+
try {
|
|
16689
|
+
if (!raw) return null;
|
|
16690
|
+
const stored = JSON.parse(raw);
|
|
16691
|
+
const furthest = Math.max(1, Math.floor(Number(stored.furthest)) || 1);
|
|
16692
|
+
const current = Math.floor(Number(stored.current)) || void 0;
|
|
16693
|
+
return { furthest, current, answers: stored.answers ?? {} };
|
|
16694
|
+
} catch {
|
|
16695
|
+
return null;
|
|
16696
|
+
}
|
|
16697
|
+
}
|
|
16698
|
+
function writeRecord(key, value) {
|
|
16699
|
+
for (const text of [() => JSON.stringify(value), () => JSON.stringify({ furthest: value.furthest, current: value.current })]) {
|
|
16700
|
+
try {
|
|
16701
|
+
const raw = text();
|
|
16702
|
+
window.localStorage.setItem(FLOW_STORAGE_PREFIX + key, raw);
|
|
16703
|
+
return raw;
|
|
16704
|
+
} catch {
|
|
16705
|
+
}
|
|
16706
|
+
}
|
|
16707
|
+
return null;
|
|
16708
|
+
}
|
|
16709
|
+
function snapshot(key) {
|
|
16710
|
+
const store = storeFor(key);
|
|
16711
|
+
if (store.raw === void 0 || store.stale || store.listeners.size === 0) {
|
|
16712
|
+
store.stale = false;
|
|
16713
|
+
const raw = readRaw(key);
|
|
16714
|
+
if (raw !== store.raw || store.value === null) {
|
|
16715
|
+
store.raw = raw;
|
|
16716
|
+
store.value = parseRecord(raw) ?? { furthest: 1, answers: {} };
|
|
16717
|
+
}
|
|
16718
|
+
}
|
|
16719
|
+
return store.value;
|
|
16720
|
+
}
|
|
16721
|
+
function update(key, change) {
|
|
16722
|
+
const store = storeFor(key);
|
|
16723
|
+
const raw = readRaw(key);
|
|
16724
|
+
if (raw !== null && raw !== store.raw) {
|
|
16725
|
+
store.raw = raw;
|
|
16726
|
+
store.value = parseRecord(raw) ?? store.value;
|
|
16727
|
+
}
|
|
16728
|
+
store.value = change(store.value ?? { furthest: 1, answers: {} });
|
|
16729
|
+
store.raw = writeRecord(key, store.value) ?? store.raw;
|
|
16730
|
+
store.stale = false;
|
|
16731
|
+
notify(store);
|
|
16732
|
+
}
|
|
16733
|
+
function clear(key) {
|
|
16734
|
+
const store = storeFor(key);
|
|
16735
|
+
try {
|
|
16736
|
+
window.localStorage.removeItem(FLOW_STORAGE_PREFIX + key);
|
|
16737
|
+
} catch {
|
|
16738
|
+
}
|
|
16739
|
+
store.value = null;
|
|
16740
|
+
store.raw = void 0;
|
|
16741
|
+
notify(store);
|
|
16742
|
+
}
|
|
16743
|
+
function markFlowMove(storageKey, step) {
|
|
16744
|
+
storeFor(storageKey).focusStep = step;
|
|
16745
|
+
}
|
|
16746
|
+
function stepJustLeft(storageKey) {
|
|
16747
|
+
const left = storeFor(storageKey).left;
|
|
16748
|
+
return left && Date.now() - left.time < 3e3 ? left.step : null;
|
|
16749
|
+
}
|
|
16750
|
+
function readFlowProgress(storageKey, initialAnswers) {
|
|
16751
|
+
const record = typeof window === "undefined" ? null : readRecord(storageKey);
|
|
16752
|
+
return record ? { ...record, answers: { ...initialAnswers, ...record.answers } } : null;
|
|
16753
|
+
}
|
|
16754
|
+
function useFlowNavigate(navigate) {
|
|
16755
|
+
const shellNavigate = useAppShell()?.navigate;
|
|
16756
|
+
return useCallback((href, options) => {
|
|
16757
|
+
const go = navigate ?? shellNavigate;
|
|
16758
|
+
if (go) go(href, options);
|
|
16759
|
+
else if (options?.replace) window.location.replace(href);
|
|
16760
|
+
else window.location.assign(href);
|
|
16761
|
+
}, [navigate, shellNavigate]);
|
|
16762
|
+
}
|
|
16763
|
+
function focusHeading() {
|
|
16764
|
+
const heading = document.querySelector("main h1") ?? document.querySelector("main");
|
|
16765
|
+
if (!heading) return;
|
|
16766
|
+
if (!heading.hasAttribute("tabindex")) heading.setAttribute("tabindex", "-1");
|
|
16767
|
+
heading.focus({ preventScroll: false });
|
|
16768
|
+
}
|
|
16769
|
+
function focusAfterLeaving() {
|
|
16770
|
+
if (typeof window === "undefined" || typeof requestAnimationFrame === "undefined") return () => {
|
|
16771
|
+
};
|
|
16772
|
+
const from = window.location.href;
|
|
16773
|
+
const old = document.querySelector("main h1");
|
|
16774
|
+
const oldText = old?.textContent ?? null;
|
|
16775
|
+
return () => {
|
|
16776
|
+
let frames = 0;
|
|
16777
|
+
const tick = () => {
|
|
16778
|
+
const heading = document.querySelector("main h1");
|
|
16779
|
+
const drawn = window.location.href !== from && !!heading && (heading !== old || heading.textContent !== oldText);
|
|
16780
|
+
if (!drawn) {
|
|
16781
|
+
if (++frames < 60) requestAnimationFrame(tick);
|
|
16782
|
+
return;
|
|
16783
|
+
}
|
|
16784
|
+
const active = document.activeElement;
|
|
16785
|
+
if (!active || active === document.body || !active.isConnected) focusHeading();
|
|
16786
|
+
};
|
|
16787
|
+
requestAnimationFrame(tick);
|
|
16788
|
+
};
|
|
16789
|
+
}
|
|
16790
|
+
var titleBase = null;
|
|
16791
|
+
var titleUsers = 0;
|
|
16792
|
+
function usePageTitle(title) {
|
|
16793
|
+
useEffect(() => {
|
|
16794
|
+
if (!title || typeof document === "undefined") return;
|
|
16795
|
+
if (titleUsers++ === 0) titleBase = document.title;
|
|
16796
|
+
document.title = titleBase ? `${title} \u2013 ${titleBase}` : title;
|
|
16797
|
+
return () => {
|
|
16798
|
+
if (--titleUsers > 0) return;
|
|
16799
|
+
if (titleBase !== null) document.title = titleBase;
|
|
16800
|
+
titleBase = null;
|
|
16801
|
+
};
|
|
16802
|
+
}, [title]);
|
|
16803
|
+
}
|
|
16804
|
+
var shownSteps = (steps, answers) => steps.filter((s) => !s.when || s.when(answers));
|
|
16805
|
+
var STEP = /^[1-9]\d*$/;
|
|
16806
|
+
function useFlowSteps(options) {
|
|
16807
|
+
const { steps, at, href, initialAnswers, exitTo, finishTo } = options;
|
|
16808
|
+
const key = options.storageKey || null;
|
|
16809
|
+
const go = useFlowNavigate(options.navigate);
|
|
16810
|
+
const subscribe = useCallback((listener) => key ? subscribeTo(key, listener) : () => {
|
|
16811
|
+
}, [key]);
|
|
16812
|
+
const stored = useSyncExternalStore(subscribe, () => key ? snapshot(key) : null, () => null);
|
|
16813
|
+
const answers = useMemo(() => ({ ...initialAnswers, ...stored?.answers ?? {} }), [initialAnswers, stored]);
|
|
16814
|
+
const shown = useMemo(() => shownSteps(steps, answers), [steps, answers]);
|
|
16815
|
+
const total = Math.max(shown.length, 1);
|
|
16816
|
+
const furthest = Math.min(stored?.furthest ?? 1, total);
|
|
16817
|
+
const asked = at !== void 0 && STEP.test(at) ? Number(at) : NaN;
|
|
16818
|
+
const valid = asked >= 1 && asked <= furthest;
|
|
16819
|
+
const step = valid ? asked : furthest;
|
|
16820
|
+
const finished = !!key && storeFor(key).finished;
|
|
16821
|
+
const ready = !!key && stored != null && valid && !finished;
|
|
16822
|
+
const redirected = useRef(null);
|
|
16823
|
+
useEffect(() => {
|
|
16824
|
+
if (!key || storeFor(key).finished) return;
|
|
16825
|
+
if (!stored || valid) {
|
|
16826
|
+
redirected.current = null;
|
|
16827
|
+
return;
|
|
16828
|
+
}
|
|
16829
|
+
const target = href(furthest);
|
|
16830
|
+
if (redirected.current === `${at} ${target}`) return;
|
|
16831
|
+
redirected.current = `${at} ${target}`;
|
|
16832
|
+
go(target, { replace: true });
|
|
16833
|
+
}, [key, stored, valid, furthest, href, go, at]);
|
|
16834
|
+
useEffect(() => {
|
|
16835
|
+
if (key && ready && stored?.current !== step) update(key, (v) => ({ ...v, current: step }));
|
|
16836
|
+
}, [key, ready, stored?.current, step]);
|
|
16837
|
+
useEffect(() => {
|
|
16838
|
+
if (!key || !ready) return;
|
|
16839
|
+
const store = storeFor(key);
|
|
16840
|
+
if (store.focusStep !== step) return;
|
|
16841
|
+
store.focusStep = null;
|
|
16842
|
+
focusHeading();
|
|
16843
|
+
}, [key, ready, step]);
|
|
16844
|
+
useLayoutEffect(() => {
|
|
16845
|
+
if (!key || !ready) return;
|
|
16846
|
+
const store = storeFor(key);
|
|
16847
|
+
return () => {
|
|
16848
|
+
store.left = { step, time: Date.now() };
|
|
16849
|
+
};
|
|
16850
|
+
}, [key, ready, step]);
|
|
16851
|
+
const current = shown[step - 1] ?? steps[0];
|
|
16852
|
+
usePageTitle(ready ? current.title : null);
|
|
16853
|
+
const setAnswers = useCallback((patch) => {
|
|
16854
|
+
if (!key) return;
|
|
16855
|
+
update(key, (before) => {
|
|
16856
|
+
const prev = { ...initialAnswers, ...before.answers };
|
|
16857
|
+
const next2 = { ...prev, ...patch };
|
|
16858
|
+
const here = Math.max(step, before.current ?? step);
|
|
16859
|
+
const ahead = (list) => list.slice(here).map((s) => s.label).join("\0");
|
|
16860
|
+
const changes = ahead(shownSteps(steps, prev)) !== ahead(shownSteps(steps, next2));
|
|
16861
|
+
return { ...before, furthest: changes ? Math.min(before.furthest, here) : before.furthest, answers: next2 };
|
|
16862
|
+
});
|
|
16863
|
+
}, [key, initialAnswers, step, steps]);
|
|
16864
|
+
const moveTo = useCallback((target) => {
|
|
16865
|
+
if (key) storeFor(key).focusStep = target;
|
|
16866
|
+
go(href(target));
|
|
16867
|
+
}, [key, go, href]);
|
|
16868
|
+
const goTo = useCallback((target) => {
|
|
16869
|
+
if (!Number.isInteger(target) || target < 1 || target > furthest || target === step) return;
|
|
16870
|
+
moveTo(target);
|
|
16871
|
+
}, [furthest, step, moveTo]);
|
|
16872
|
+
const next = useCallback((patch) => {
|
|
16873
|
+
if (!key) return;
|
|
16874
|
+
if (patch) setAnswers(patch);
|
|
16875
|
+
const shownNow = patch ? shownSteps(steps, { ...answers, ...patch }) : shown;
|
|
16876
|
+
if (step >= shownNow.length) return;
|
|
16877
|
+
update(key, (v) => ({ ...v, furthest: Math.max(v.furthest, step + 1), current: step + 1 }));
|
|
16878
|
+
moveTo(step + 1);
|
|
16879
|
+
}, [key, setAnswers, steps, answers, shown, step, moveTo]);
|
|
16880
|
+
const back = step > 1 ? () => moveTo(step - 1) : void 0;
|
|
16881
|
+
const saveAndExit = useCallback(() => {
|
|
16882
|
+
if (key && stored) update(key, (v) => ({ ...v, current: step }));
|
|
16883
|
+
const left = focusAfterLeaving();
|
|
16884
|
+
go(exitTo);
|
|
16885
|
+
left();
|
|
16886
|
+
}, [key, stored, step, go, exitTo]);
|
|
16887
|
+
const finish = useCallback(() => {
|
|
16888
|
+
if (key) storeFor(key).finished = true;
|
|
16889
|
+
const left = focusAfterLeaving();
|
|
16890
|
+
go(finishTo);
|
|
16891
|
+
if (key) clear(key);
|
|
16892
|
+
left();
|
|
16893
|
+
}, [key, go, finishTo]);
|
|
16894
|
+
return {
|
|
16895
|
+
ready,
|
|
16896
|
+
step,
|
|
16897
|
+
total,
|
|
16898
|
+
current,
|
|
16899
|
+
caption: `Step ${step} of ${total}`,
|
|
16900
|
+
title: current.title,
|
|
16901
|
+
answers,
|
|
16902
|
+
setAnswers,
|
|
16903
|
+
furthest,
|
|
16904
|
+
isFirst: step === 1,
|
|
16905
|
+
isLast: step === total,
|
|
16906
|
+
next,
|
|
16907
|
+
back,
|
|
16908
|
+
goTo,
|
|
16909
|
+
stepper: {
|
|
16910
|
+
steps: shown.map((s, i) => ({
|
|
16911
|
+
label: s.label,
|
|
16912
|
+
status: i + 1 < furthest && i + 1 !== step ? "complete" : void 0,
|
|
16913
|
+
disabled: i + 1 > furthest || void 0
|
|
16914
|
+
})),
|
|
16915
|
+
currentStep: step - 1,
|
|
16916
|
+
onStepChange: (index) => goTo(index + 1)
|
|
16917
|
+
},
|
|
16918
|
+
saveAndExit,
|
|
16919
|
+
finish
|
|
16920
|
+
};
|
|
16921
|
+
}
|
|
16922
|
+
function FlowSaved({ storageKey, href, title = "Your progress has been saved", children, navigate }) {
|
|
16923
|
+
const go = useFlowNavigate(navigate);
|
|
16924
|
+
const titleId = useId();
|
|
16925
|
+
const markFlowLeft = useAppShell()?.markFlowLeft;
|
|
16926
|
+
useLayoutEffect(() => markFlowLeft?.(), [markFlowLeft]);
|
|
16927
|
+
const [saved, setSaved] = useState(void 0);
|
|
16928
|
+
useLayoutEffect(() => {
|
|
16929
|
+
const progress = readFlowProgress(storageKey, {});
|
|
16930
|
+
const step = progress ? progress.current ?? progress.furthest : null;
|
|
16931
|
+
setSaved(step === null ? null : { step, behind: stepJustLeft(storageKey) === step });
|
|
16932
|
+
}, [storageKey]);
|
|
16933
|
+
const resume = () => {
|
|
16934
|
+
const step = saved?.step ?? 1;
|
|
16935
|
+
markFlowMove(storageKey, step);
|
|
16936
|
+
if (saved?.behind) window.history.back();
|
|
16937
|
+
else go(href(step), { replace: true });
|
|
16938
|
+
};
|
|
16939
|
+
useLayoutEffect(() => {
|
|
16940
|
+
if (saved !== void 0) focusHeading();
|
|
16941
|
+
}, [saved]);
|
|
16942
|
+
const heading = saved === null ? "There's no saved progress" : title;
|
|
16943
|
+
usePageTitle(saved === void 0 ? null : heading);
|
|
16944
|
+
return /* @__PURE__ */ jsx(PageContainer, { width: "narrow", children: /* @__PURE__ */ jsxs("section", { "aria-labelledby": titleId, className: "flex min-h-[60vh] flex-col items-center justify-center py-ds-12 text-center", children: [
|
|
16945
|
+
saved !== null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "grid size-14 place-items-center rounded-[var(--ds-radius-full)] bg-[var(--ds-status-success-bg)] text-[var(--ds-status-success)]", children: /* @__PURE__ */ jsx(Icon, { name: "check", size: 28 }) }),
|
|
16946
|
+
/* @__PURE__ */ jsx("h1", { id: titleId, className: "mt-ds-6 font-[family-name:var(--ds-font-display)] text-3xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: heading }),
|
|
16947
|
+
/* @__PURE__ */ jsx("div", { className: "mt-ds-3 max-w-md text-[var(--ds-text-secondary)]", children: saved === null ? /* @__PURE__ */ jsx("p", { children: "Nothing has been saved in this browser yet." }) : children ?? /* @__PURE__ */ jsx("p", { children: "Your answers are kept in this browser. Come back to it to carry on where you left off." }) }),
|
|
16948
|
+
/* @__PURE__ */ jsx("div", { className: "mt-ds-8 flex flex-wrap justify-center gap-ds-3", children: /* @__PURE__ */ jsx(Button, { type: "button", onClick: resume, children: saved === null ? "Start" : "Continue" }) })
|
|
16949
|
+
] }) });
|
|
16950
|
+
}
|
|
16738
16951
|
function useDestructiveAction(options) {
|
|
16739
16952
|
const { action, title, description, confirmLabel, typeToConfirm, onConfirm, onUndo, doneMessage, undoMessage, restoredMessage, severity } = options;
|
|
16740
16953
|
const preferences = useShellPreferences();
|
|
@@ -16900,6 +17113,8 @@ function pastTenseOf(label) {
|
|
|
16900
17113
|
}
|
|
16901
17114
|
var SectionHeading = forwardRef(function SectionHeading2({
|
|
16902
17115
|
title,
|
|
17116
|
+
onTitleChange,
|
|
17117
|
+
titleLabel = "Title",
|
|
16903
17118
|
description,
|
|
16904
17119
|
actions,
|
|
16905
17120
|
badge,
|
|
@@ -16911,6 +17126,8 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
16911
17126
|
}, ref) {
|
|
16912
17127
|
const isPhone = useBreakpoint("sm");
|
|
16913
17128
|
const pane = variant === "pane";
|
|
17129
|
+
const inDetail = useContext(SplitPaneCtx) === "detail";
|
|
17130
|
+
const editable = !!onTitleChange;
|
|
16914
17131
|
return /* @__PURE__ */ jsxs(
|
|
16915
17132
|
"div",
|
|
16916
17133
|
{
|
|
@@ -16918,7 +17135,7 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
16918
17135
|
"data-gs": "section-heading",
|
|
16919
17136
|
"data-variant": variant,
|
|
16920
17137
|
className: cn(
|
|
16921
|
-
pane ? "shrink-0
|
|
17138
|
+
pane ? cn("shrink-0 pt-ds-4 pb-ds-3 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]", inDetail ? "px-[var(--ds-page-gutter)]" : "px-ds-4") : "mb-[var(--ds-heading-gap)]",
|
|
16922
17139
|
!pane && bordered && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] pb-ds-4",
|
|
16923
17140
|
className
|
|
16924
17141
|
),
|
|
@@ -16927,11 +17144,23 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
16927
17144
|
"flex gap-ds-4",
|
|
16928
17145
|
// the actions wrap under the title when the two do not fit on one line (round 11: a search Input in a 284 px
|
|
16929
17146
|
// pane's actions slot squeezed "Inbox" to "I."); below sm they always stack
|
|
16930
|
-
isPhone && actions ? "flex-col" : "flex-wrap items-
|
|
17147
|
+
isPhone && actions ? "flex-col" : cn("flex-wrap justify-between", editable && !description ? "items-center" : "items-start")
|
|
16931
17148
|
), children: [
|
|
16932
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
17149
|
+
/* @__PURE__ */ jsxs("div", { className: cn("min-w-0", editable && !(isPhone && actions) && "flex-[1_1_20ch] text-lg"), children: [
|
|
16933
17150
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
|
|
16934
|
-
|
|
17151
|
+
editable ? (
|
|
17152
|
+
// the field is the title: the heading holds it, so the page's headings still name the view by its title
|
|
17153
|
+
/* @__PURE__ */ jsx("h2", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
17154
|
+
Input,
|
|
17155
|
+
{
|
|
17156
|
+
size: "md",
|
|
17157
|
+
"aria-label": titleLabel,
|
|
17158
|
+
value: title,
|
|
17159
|
+
onChange: (e) => onTitleChange(e.target.value),
|
|
17160
|
+
className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]"
|
|
17161
|
+
}
|
|
17162
|
+
) })
|
|
17163
|
+
) : /* @__PURE__ */ jsx("h2", { className: cn("font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", pane ? "truncate" : "min-w-0 break-words"), children: title }),
|
|
16935
17164
|
badge,
|
|
16936
17165
|
count !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "neutral", size: "sm", children: count })
|
|
16937
17166
|
] }),
|
|
@@ -17038,6 +17267,6 @@ var TextOverflow = forwardRef(function TextOverflow2({
|
|
|
17038
17267
|
return /* @__PURE__ */ jsx(Tooltip, { content: resolvedTooltipContent, children: content });
|
|
17039
17268
|
});
|
|
17040
17269
|
|
|
17041
|
-
export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav,
|
|
17270
|
+
export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, DropdownMenu, EmptyState, EntityCell, FileUpload, FlowSaved, FormWrapper, Gantt, HoverCard, Kbd, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, PageActions, PageContainer, PageHeader, PinInput, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sheet, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, Toast, ToastProvider, Tour, TransferList, TreeView, dateOfDay, dayOf, endDayOf, fitLabel, fitLabels, formatDateRange, readFlowProgress, timeExtent, useContentWidth, useDestructiveAction, useFittedLabels, useFlowSteps, useSidebar, useTextMeasure, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
|
|
17042
17271
|
//# sourceMappingURL=index.js.map
|
|
17043
17272
|
//# sourceMappingURL=index.js.map
|