gridsmith-ui 0.31.1 → 0.33.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/README.md +4 -2
  3. package/dist/charts.d.ts +111 -31
  4. package/dist/charts.js +288 -148
  5. package/dist/charts.js.map +1 -1
  6. package/dist/chat.js +6 -6
  7. package/dist/{chunk-EZ3ZGFGA.js → chunk-2724SJO2.js} +12 -4
  8. package/dist/chunk-2724SJO2.js.map +1 -0
  9. package/dist/{chunk-I6JJ7KKP.js → chunk-6NRLTG5W.js} +16 -11
  10. package/dist/chunk-6NRLTG5W.js.map +1 -0
  11. package/dist/{chunk-BHTAVJIG.js → chunk-6XCWKLJZ.js} +41 -6
  12. package/dist/chunk-6XCWKLJZ.js.map +1 -0
  13. package/dist/{chunk-TH272DIC.js → chunk-AB4UQ4G5.js} +125 -235
  14. package/dist/chunk-AB4UQ4G5.js.map +1 -0
  15. package/dist/{chunk-IOHGE4EW.js → chunk-AVSP6NDX.js} +8 -8
  16. package/dist/chunk-AVSP6NDX.js.map +1 -0
  17. package/dist/chunk-F2XMZOUP.js +81 -0
  18. package/dist/chunk-F2XMZOUP.js.map +1 -0
  19. package/dist/{chunk-HQFTP7Y5.js → chunk-FF57N3P7.js} +10 -8
  20. package/dist/chunk-FF57N3P7.js.map +1 -0
  21. package/dist/chunk-GIA4BMGI.js +18 -0
  22. package/dist/chunk-GIA4BMGI.js.map +1 -0
  23. package/dist/{chunk-DR6WEI3A.js → chunk-HCEHTJ5E.js} +3 -3
  24. package/dist/{chunk-DR6WEI3A.js.map → chunk-HCEHTJ5E.js.map} +1 -1
  25. package/dist/{chunk-IZW5XHKA.js → chunk-OWGF362U.js} +10 -8
  26. package/dist/chunk-OWGF362U.js.map +1 -0
  27. package/dist/chunk-P3NUUIL6.js +9 -0
  28. package/dist/chunk-P3NUUIL6.js.map +1 -0
  29. package/dist/{chunk-W3GY5ROH.js → chunk-R2IAK3J3.js} +3 -3
  30. package/dist/{chunk-W3GY5ROH.js.map → chunk-R2IAK3J3.js.map} +1 -1
  31. package/dist/chunk-R7FG4ZQ5.js +16 -0
  32. package/dist/chunk-R7FG4ZQ5.js.map +1 -0
  33. package/dist/{chunk-V73LHNRL.js → chunk-RS624TD5.js} +29 -10
  34. package/dist/chunk-RS624TD5.js.map +1 -0
  35. package/dist/{chunk-DBHVJ7Z3.js → chunk-SS3C24IJ.js} +3 -2
  36. package/dist/chunk-SS3C24IJ.js.map +1 -0
  37. package/dist/{chunk-K3NAFQ4S.js → chunk-TMPPBXX3.js} +3 -3
  38. package/dist/{chunk-K3NAFQ4S.js.map → chunk-TMPPBXX3.js.map} +1 -1
  39. package/dist/{chunk-NDL2JGQ7.js → chunk-UBLBVCQN.js} +5 -5
  40. package/dist/{chunk-NDL2JGQ7.js.map → chunk-UBLBVCQN.js.map} +1 -1
  41. package/dist/{chunk-2TCCSKL3.js → chunk-WD6T57ZJ.js} +5 -5
  42. package/dist/{chunk-2TCCSKL3.js.map → chunk-WD6T57ZJ.js.map} +1 -1
  43. package/dist/{chunk-SLGGZ3MU.js → chunk-WSKPESAX.js} +12 -10
  44. package/dist/chunk-WSKPESAX.js.map +1 -0
  45. package/dist/chunk-ZQV26NND.js +213 -0
  46. package/dist/chunk-ZQV26NND.js.map +1 -0
  47. package/dist/dashboard.d.ts +207 -0
  48. package/dist/dashboard.js +1210 -0
  49. package/dist/dashboard.js.map +1 -0
  50. package/dist/data-grid.js +11 -10
  51. package/dist/data-grid.js.map +1 -1
  52. package/dist/editor-mentions.js +2 -2
  53. package/dist/editor.js +3 -2
  54. package/dist/editor.js.map +1 -1
  55. package/dist/index.d.ts +94 -12
  56. package/dist/index.js +601 -316
  57. package/dist/index.js.map +1 -1
  58. package/dist/kanban.js +9 -9
  59. package/dist/resizable.d.ts +11 -2
  60. package/dist/resizable.js +97 -22
  61. package/dist/resizable.js.map +1 -1
  62. package/dist/roots.css +2 -2
  63. package/dist/tokens.css +6 -6
  64. package/dist/utils.d.ts +51 -1
  65. package/dist/utils.js +55 -4
  66. package/dist/utils.js.map +1 -1
  67. package/dist/virtualized.js +9 -8
  68. package/dist/virtualized.js.map +1 -1
  69. package/dist-static/tokens.css +6 -6
  70. package/package.json +6 -1
  71. package/dist/chunk-BHTAVJIG.js.map +0 -1
  72. package/dist/chunk-DBHVJ7Z3.js.map +0 -1
  73. package/dist/chunk-EZ3ZGFGA.js.map +0 -1
  74. package/dist/chunk-HQFTP7Y5.js.map +0 -1
  75. package/dist/chunk-I6JJ7KKP.js.map +0 -1
  76. package/dist/chunk-IOHGE4EW.js.map +0 -1
  77. package/dist/chunk-IZW5XHKA.js.map +0 -1
  78. package/dist/chunk-KSJTMSYA.js +0 -71
  79. package/dist/chunk-KSJTMSYA.js.map +0 -1
  80. package/dist/chunk-LJYSVZMI.js +0 -25
  81. package/dist/chunk-LJYSVZMI.js.map +0 -1
  82. package/dist/chunk-SLGGZ3MU.js.map +0 -1
  83. package/dist/chunk-TH272DIC.js.map +0 -1
  84. package/dist/chunk-V73LHNRL.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,71 +1,219 @@
1
1
  "use client";
2
- import { useAppShell, REACT_VERSION_PROBLEM, Breadcrumbs, useCrumbFollow, crumbGoes, useCornerInset, NAVBAR_INSET_PRIORITY, useOverlayMark, useDirtyGuard, useScrollbarInset, DrawerFooterCtx, OverlayMarkScope, OverlayCloseCtx, insetLessScrollbar, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, useCompact, useElementWidth, DrawerPanel, useCloseSettle, besideRoom, PANEL_INSET_PRIORITY, Drawer, useRememberedWidth, pxOf, ResizeEdge, LAUNCHER_INSET_PRIORITY, defaultMaxWidth } from './chunk-TH272DIC.js';
3
- export { AppShell, Breadcrumbs, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-TH272DIC.js';
4
- import { Skeleton, TITLE_TEXT, SegmentedControl } from './chunk-BHTAVJIG.js';
5
- export { SegmentedControl, Skeleton } from './chunk-BHTAVJIG.js';
6
- import { useScrollEdges, EDGE_FADE } from './chunk-3BRQRKDO.js';
7
- import { Avatar, foldForSearch, useActiveOptionInView, shownMentions, matchMentions, mentionOptionId, MentionList, initialsOf } from './chunk-K3NAFQ4S.js';
8
- export { Avatar } from './chunk-K3NAFQ4S.js';
9
- import { Link } from './chunk-NDL2JGQ7.js';
10
- export { CodeBlock, Divider, Link } from './chunk-NDL2JGQ7.js';
11
- import { DropdownMenu } from './chunk-2TCCSKL3.js';
12
- export { DropdownMenu } from './chunk-2TCCSKL3.js';
13
- import { useFillHeight, FillContext } from './chunk-DBHVJ7Z3.js';
14
- import { Badge } from './chunk-SLGGZ3MU.js';
15
- export { Badge } from './chunk-SLGGZ3MU.js';
16
- import { useKeyboardScroll } from './chunk-KSJTMSYA.js';
17
- import { localeCache, startOfDay, addDays, useWeekStart, useDateWords, localeDayFirst, dayKey, moveDay, addMonths, DateSegmentFields, getMonthGrid, isSameMonth, isSameDay, DatePicker, timeSegments, pad2, inferColumnKinds, useCardsSwitch, CARDS_BELOW, kindOfRenderedText, Checkbox, CardValue, SortIndicator, startOfWeek, endOfWeek, addMonthsClamped, isExcludedDay, CutCell, CutEmail, stepValue, separatorMovesOn, TIME_SEPARATORS, typeDigit, getEventsForDay, layoutWeek, isWeekend, getWeekDays, isBarEvent, layoutPieces, dayPieces, groupEventsByDay, timeToFraction } from './chunk-I6JJ7KKP.js';
18
- export { Checkbox, CheckboxGroup, CheckboxGroupItem, DatePicker, HoverCard, TextOverflow } from './chunk-I6JJ7KKP.js';
19
- import { useWholeListCheck, pagerPart, Pagination, NumberInput } from './chunk-IOHGE4EW.js';
20
- export { NumberInput, Pagination, Popover, usePagination } from './chunk-IOHGE4EW.js';
2
+ import { localeCache, startOfDay, addDays, useWeekStart, useDateWords, localeDayFirst, dayKey, moveDay, addMonths, DateSegmentFields, getMonthGrid, isSameMonth, isSameDay, DatePicker, timeSegments, pad2, inferColumnKinds, useCardsSwitch, CARDS_BELOW, kindOfRenderedText, Checkbox, CardValue, SortIndicator, startOfWeek, endOfWeek, addMonthsClamped, isExcludedDay, CutCell, CutEmail, stepValue, separatorMovesOn, TIME_SEPARATORS, typeDigit, getEventsForDay, layoutWeek, isWeekend, getWeekDays, isBarEvent, layoutPieces, dayPieces, groupEventsByDay, timeToFraction } from './chunk-6NRLTG5W.js';
3
+ export { Checkbox, CheckboxGroup, CheckboxGroupItem, DatePicker, HoverCard, TextOverflow } from './chunk-6NRLTG5W.js';
4
+ import { useWholeListCheck, pagerPart, Pagination, NumberInput } from './chunk-AVSP6NDX.js';
5
+ export { NumberInput, Pagination, Popover, usePagination } from './chunk-AVSP6NDX.js';
6
+ import { useAppShell, REACT_VERSION_PROBLEM, Breadcrumbs, useCrumbFollow, crumbGoes, useCornerInset, NAVBAR_INSET_PRIORITY, useScrollbarInset, useBulkBarHost, DrawerFooterCtx, BulkBarHostCtx, AsideSlotContext, BulkBarSpacer, bulkBarRoom, insetLessScrollbar, BULK_BAR_LAYER, BulkBarPresenceCtx, BULK_BAR_WINDOW_LAYER, DrawerPanel, useCloseSettle, besideRoom, PANEL_INSET_PRIORITY, Drawer, LAUNCHER_INSET_PRIORITY, TOAST_INSET_VARS, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-AB4UQ4G5.js';
7
+ export { AppShell, Breadcrumbs, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-AB4UQ4G5.js';
21
8
  import { useShellPreferences, PREFERENCE_HOUSE_DEFAULTS, formatRelativeTime, thresholdOf, toMillis, formatFullTime, datedMillis, preferenceActionKey, DAY, HOUR, MINUTE } from './chunk-QOMP4D6V.js';
22
9
  export { PreferencesContext, formatFullTime, formatRelativeTime, preferenceActionKey, usePreferences } from './chunk-QOMP4D6V.js';
23
- import { useFormatLocale, useHydrated, useToday, LocaleContext } from './chunk-LJYSVZMI.js';
24
- export { useFormatLocale, useHydrated } from './chunk-LJYSVZMI.js';
25
- import { Input, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, OutsideField, InlineFieldError, Label, AddAnotherRowCtx, Field } from './chunk-IZW5XHKA.js';
26
- export { Dropdown, Field, InlineFieldError, Input, Label, Textarea, Toggle } from './chunk-IZW5XHKA.js';
10
+ import { CELL_FRAME, Skeleton, CELL_HIDE, TITLE_FLOOR, CELL_ROOM, TITLE_TEXT, CELL_STAT_ROOM, CELL_STAT_ROOM_END, CELL_STAT_TILE, CELL_ROOM_INNER, SegmentedControl } from './chunk-6XCWKLJZ.js';
11
+ export { SegmentedControl, Skeleton } from './chunk-6XCWKLJZ.js';
12
+ import { useFormatLocale, LocaleContext } from './chunk-R7FG4ZQ5.js';
13
+ export { useFormatLocale } from './chunk-R7FG4ZQ5.js';
14
+ import { Input, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, OutsideField, InlineFieldError, Label, AddAnotherRowCtx, Field } from './chunk-OWGF362U.js';
15
+ export { Dropdown, Field, InlineFieldError, Input, Label, Textarea, Toggle } from './chunk-OWGF362U.js';
27
16
  import { formatLocale, localeChoice } from './chunk-7QLXYRPD.js';
17
+ import { useScrollEdges, EDGE_FADE } from './chunk-3BRQRKDO.js';
18
+ import { Avatar, foldForSearch, useActiveOptionInView, shownMentions, matchMentions, mentionOptionId, MentionList, initialsOf } from './chunk-TMPPBXX3.js';
19
+ export { Avatar } from './chunk-TMPPBXX3.js';
20
+ import { Link } from './chunk-UBLBVCQN.js';
21
+ export { CodeBlock, Divider, Link } from './chunk-UBLBVCQN.js';
22
+ import { CardSurfaceCtx, useScrollsInside, useRunsEdgeToEdge, SplitPaneCtx, PanePaddedCtx, RowsCtx, PageActionsCtx, PANE_HEADING_CANCEL, SurfaceBoundary, useFramesItself, TableCardCtx, useWantsInset } from './chunk-RS624TD5.js';
23
+ import { Badge } from './chunk-WSKPESAX.js';
24
+ export { Badge } from './chunk-WSKPESAX.js';
25
+ import { useTextOverflow } from './chunk-R2IAK3J3.js';
26
+ export { useTextOverflow } from './chunk-R2IAK3J3.js';
27
+ import { useOverlayMark, useDirtyGuard, OverlayMarkScope, OverlayCloseCtx, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, useCompact, useElementWidth } from './chunk-ZQV26NND.js';
28
+ import { useHydrated, useToday } from './chunk-GIA4BMGI.js';
29
+ export { useHydrated } from './chunk-GIA4BMGI.js';
28
30
  import { FormChangeCtx, useReportedChange, useOptionalFormContext, FormCtx } from './chunk-72SDAX54.js';
29
31
  export { useFormContext } from './chunk-72SDAX54.js';
30
- import { CardSurfaceCtx, useScrollsInside, SplitPaneCtx, RowsCtx, PageActionsCtx, SurfaceBoundary, useFramesItself, TableCardCtx } from './chunk-V73LHNRL.js';
31
- import { Button, elementType, ControlSizeContext, triggerType, Spinner } from './chunk-HQFTP7Y5.js';
32
- export { Button, ButtonSizeContext, ControlSizeContext, Spinner } from './chunk-HQFTP7Y5.js';
32
+ import { DropdownMenu } from './chunk-WD6T57ZJ.js';
33
+ export { DropdownMenu } from './chunk-WD6T57ZJ.js';
34
+ import { useFillHeight, FillContext } from './chunk-SS3C24IJ.js';
35
+ import { Button, elementType, ControlSizeContext, triggerType, Spinner } from './chunk-FF57N3P7.js';
36
+ export { Button, ButtonSizeContext, ControlSizeContext, Spinner } from './chunk-FF57N3P7.js';
33
37
  import { useBreakpoint, readBreakpointPx } from './chunk-ZHUVLBCC.js';
34
38
  export { BreakpointWidthProvider, useBreakpoint } from './chunk-ZHUVLBCC.js';
35
- import { useInputModality, inputModality } from './chunk-7RKC5C7G.js';
39
+ import { inputModality, useInputModality } from './chunk-7RKC5C7G.js';
36
40
  export { INPUT_MODALITY_ATTR, inputModality, installInputModality, useInputModality } from './chunk-7RKC5C7G.js';
37
- import { useTextOverflow } from './chunk-W3GY5ROH.js';
38
- export { useTextOverflow } from './chunk-W3GY5ROH.js';
39
- import { AutoTooltip, mergeRefs, useRevealFocus } from './chunk-DR6WEI3A.js';
40
- export { Tooltip, useRevealFocus } from './chunk-DR6WEI3A.js';
41
+ import { useKeyboardScroll } from './chunk-F2XMZOUP.js';
42
+ import { AutoTooltip, mergeRefs, useRevealFocus } from './chunk-HCEHTJ5E.js';
43
+ export { Tooltip, useRevealFocus } from './chunk-HCEHTJ5E.js';
41
44
  import { Icon, slotIcon, warnOnce } from './chunk-53F7GVBQ.js';
42
- import { cn, FOCUS_RING, focusAfterSelfRemoval, FOCUSABLE, GLASS_SURFACE, useFocusKeptInList, FOCUS_INSET, useLatest, PEER_FOCUS_RING, GLASS_BACKDROP, OPEN_TO_FOCUS, focusOutOf, FIELD, ZOOM_KEYS, rovingTabStop, FOCUS_ROOM, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberOpener, focusInitial, lockBodyScroll, unlockBodyScroll, OVERLAY_CLOSE_ATTR, OVERLAY_SURFACE, GLASS_OVERLAY, usePopupFocus, usePosition, ERROR_HAS_FOCUS_RING, FIELD_HAS_FOCUS_RING, CONTROL_ANCESTOR, GROUP_FOCUS_RING, useGridKeyboard, ERROR_ACTIVE_RING, ACTIVE_RING, ERROR_FOCUS_WITHIN_RING, FIELD_FOCUS_WITHIN_RING, focusAfterRemoval, GLASS_DROPDOWN, ERROR_FOCUS_RING, FIELD_FOCUS_RING, openToFocus, atLeastFocusRoom, useNonModalDialog, useReturnFocus } from './chunk-EZ3ZGFGA.js';
43
- export { useGridKeyboard } from './chunk-EZ3ZGFGA.js';
44
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
45
+ import { cn, FOCUS_RING, focusAfterSelfRemoval, FOCUSABLE, GLASS_SURFACE, FOCUS_INSET_WHILE_STOP, useFocusKeptInList, FOCUS_INSET, useLatest, PEER_FOCUS_RING, GLASS_BACKDROP, OPEN_TO_FOCUS, focusOutOf, FIELD, ZOOM_KEYS, rovingTabStop, FOCUS_ROOM, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberOpener, focusInitial, lockBodyScroll, unlockBodyScroll, OVERLAY_CLOSE_ATTR, OVERLAY_SURFACE, GLASS_OVERLAY, usePopupFocus, pointOf, pageAddress, registerOpenerRoot, rememberFocus, usePosition, ERROR_HAS_FOCUS_RING, FIELD_HAS_FOCUS_RING, CONTROL_ANCESTOR, GROUP_FOCUS_RING, useGridKeyboard, ERROR_ACTIVE_RING, ACTIVE_RING, ERROR_FOCUS_WITHIN_RING, FIELD_FOCUS_WITHIN_RING, focusAfterRemoval, GLASS_DROPDOWN, ERROR_FOCUS_RING, FIELD_FOCUS_RING, openToFocus, atLeastFocusRoom, useNonModalDialog, useReturnFocus, onMovingOn } from './chunk-2724SJO2.js';
46
+ export { useGridKeyboard } from './chunk-2724SJO2.js';
45
47
  import { forwardRef, useRef, useId, useEffect, useState, createContext, useCallback, useLayoutEffect, useMemo, useContext, isValidElement, memo, useImperativeHandle, useSyncExternalStore, Children, Fragment as Fragment$1, cloneElement, useReducer } from 'react';
46
48
  import { createPortal, flushSync } from 'react-dom';
49
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
47
50
 
48
- function selectAllFor(bar) {
49
- for (let box = bar?.parentElement; bar && box && box !== document.body; box = box.parentElement) {
50
- const all = Array.from(box.querySelectorAll("[data-ds-select-all] input"));
51
- if (all.length) return all.find((el) => bar.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING) ?? all[all.length - 1];
51
+ var selectionControlIn = (table) => table.querySelector("[data-ds-select-all] input") ?? table.querySelector("[data-ds-select-card] input");
52
+ function holdsSelection(table) {
53
+ const all = table.querySelector("[data-ds-select-all]");
54
+ return all ? all.getAttribute("data-selection") !== "none" : !!table.querySelector("[data-ds-select-card] input:checked");
55
+ }
56
+ var tablesIn = (box) => Array.from(box.querySelectorAll('[data-gs="table"]')).filter((t) => selectionControlIn(t));
57
+ function selectionAt(point) {
58
+ const from = point.startContainer;
59
+ for (let box = from instanceof HTMLElement ? from : from.parentElement; box && box !== document.body; box = box.parentElement) {
60
+ const tables = tablesIn(box);
61
+ if (!tables.length) continue;
62
+ const pick = (list2) => list2.filter((t) => point.comparePoint(t, 0) < 0).at(-1) ?? list2.find((t) => point.comparePoint(t, 0) > 0);
63
+ const table = pick(tables.filter(holdsSelection)) ?? pick(tables);
64
+ const control = table && selectionControlIn(table);
65
+ return control ? { box, control } : null;
52
66
  }
53
67
  return null;
54
68
  }
69
+ function selectionIn(box, point) {
70
+ const tables = tablesIn(box);
71
+ const at = (t) => point ? point.comparePoint(t, 0) : 0;
72
+ const table = tables.filter((t) => at(t) < 0).at(-1) ?? tables.find((t) => at(t) > 0) ?? tables[0];
73
+ return table ? selectionControlIn(table) : null;
74
+ }
75
+ var CONTROL = "[data-bulk-bar-control]";
55
76
  function BulkActionBar({ selectedCount, actions, onClearSelection, className }) {
56
- const isMobile = useBreakpoint("sm");
57
- if (selectedCount === 0) return null;
77
+ const isPhone = useBreakpoint("sm");
78
+ const host = useContext(BulkBarHostCtx);
79
+ const presence = useContext(BulkBarPresenceCtx);
80
+ const [anchor, setAnchor] = useState(null);
81
+ const [bearing, setBearing] = useState(null);
82
+ const [bar, setBar] = useState(null);
83
+ const [stop, setStop] = useState(0);
84
+ const labels = actions.map((action) => action.label).join("\0");
85
+ const [fit, setFit] = useState(null);
86
+ const tooWide = !!fit && fit.labels === labels && fit.room > 0 && fit.full > fit.room;
87
+ const compact = isPhone || tooWide;
88
+ const shown = selectedCount > 0;
89
+ const target = host ? host.layer : typeof document === "undefined" ? null : document.body;
90
+ const selection = useRef({ control: null, box: null, page: "" });
91
+ const point = useRef(null);
92
+ const movedOn = useRef(true);
93
+ const quitWatch = useRef(null);
94
+ const watching = useRef(null);
95
+ const watch = (control) => {
96
+ quitWatch.current?.();
97
+ movedOn.current = false;
98
+ watching.current = control;
99
+ quitWatch.current = onMovingOn(control, () => {
100
+ movedOn.current = true;
101
+ });
102
+ };
103
+ useLayoutEffect(() => {
104
+ if (shown && !bearing && anchor?.isConnected) setBearing(pointOf(anchor));
105
+ else if (!shown && bearing) setBearing(null);
106
+ }, [shown, bearing, anchor]);
107
+ useLayoutEffect(() => {
108
+ if (!shown || !bearing) return;
109
+ point.current = bearing;
110
+ const found = selectionAt(bearing);
111
+ selection.current = { control: found?.control ?? null, box: found?.box ?? null, page: pageAddress() };
112
+ });
113
+ useEffect(() => () => quitWatch.current?.(), []);
114
+ const onToolbar = useCallback((el) => {
115
+ setBar(el);
116
+ const unregister = registerOpenerRoot(el, () => selection.current.control?.isConnected ? rememberFocus(selection.current.control) : null);
117
+ return () => {
118
+ unregister();
119
+ setBar(null);
120
+ const active = document.activeElement;
121
+ const moved = movedOn.current;
122
+ const watched = watching.current;
123
+ quitWatch.current?.();
124
+ quitWatch.current = null;
125
+ watching.current = null;
126
+ movedOn.current = true;
127
+ if (!(active instanceof HTMLElement) || !(el.contains(active) || active === watched) || moved || inputModality() === "pointer") return;
128
+ const { control, box, page } = selection.current;
129
+ const at = point.current;
130
+ if (pageAddress() !== page) return;
131
+ focusAfterSelfRemoval(active, {
132
+ group: null,
133
+ point: at ?? void 0,
134
+ to: () => control?.isConnected ? control : box?.isConnected ? selectionIn(box, at) : null,
135
+ samePage: true,
136
+ removedOnly: true
137
+ });
138
+ };
139
+ }, []);
140
+ useLayoutEffect(() => {
141
+ if (!bar) return;
142
+ const report = () => {
143
+ if (host) host.setRoom(bar, bar.offsetHeight);
144
+ else presence?.room(bar, bulkBarRoom(bar.offsetHeight));
145
+ };
146
+ report();
147
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(report);
148
+ observer?.observe(bar);
149
+ return () => {
150
+ observer?.disconnect();
151
+ if (host) host.setRoom(bar, 0);
152
+ else presence?.room(bar, 0);
153
+ };
154
+ }, [bar, host, presence]);
155
+ useLayoutEffect(() => {
156
+ const layer = bar?.parentElement;
157
+ if (!bar || !layer) return;
158
+ const measure = () => {
159
+ const style = getComputedStyle(layer);
160
+ const room = layer.clientWidth - (parseFloat(style.paddingLeft) || 0) - (parseFloat(style.paddingRight) || 0);
161
+ setFit((was) => {
162
+ const full = !compact || !was || was.labels !== labels ? bar.scrollWidth : was.full;
163
+ return was && was.labels === labels && was.full === full && was.room === room ? was : { labels, full, room };
164
+ });
165
+ };
166
+ measure();
167
+ if (typeof ResizeObserver === "undefined") return;
168
+ const observer = new ResizeObserver(measure);
169
+ observer.observe(layer);
170
+ return () => observer.disconnect();
171
+ }, [bar, compact, labels]);
172
+ useEffect(() => {
173
+ if (!bar || inputModality() !== "keyboard") return;
174
+ const frame = requestAnimationFrame(() => {
175
+ const active = document.activeElement;
176
+ if (!(active instanceof HTMLElement) || active === document.body || bar.contains(active)) return;
177
+ if (active.getBoundingClientRect().bottom > bar.getBoundingClientRect().top) active.scrollIntoView({ block: "nearest" });
178
+ });
179
+ return () => cancelAnimationFrame(frame);
180
+ }, [bar]);
181
+ useEffect(() => {
182
+ if (shown) presence?.say(`${selectedCount} selected`);
183
+ }, [presence, shown, selectedCount]);
184
+ if (!shown) return null;
58
185
  const dropdownItems = actions.map((action) => ({
59
186
  label: action.label,
60
187
  icon: action.icon,
61
188
  onClick: action.onClick,
62
189
  variant: action.variant
63
190
  }));
64
- return /* @__PURE__ */ jsxs(
191
+ const count = (compact ? Math.min(actions.length, 1) : actions.length) + 1;
192
+ const current = Math.min(stop, count - 1);
193
+ const controls = () => bar ? Array.from(bar.querySelectorAll(CONTROL)) : [];
194
+ const tab = (i) => ({ "data-bulk-bar-control": "", tabIndex: i === current ? 0 : -1 });
195
+ const onKeyDown = (e) => {
196
+ const list2 = controls();
197
+ const at = list2.indexOf(e.target);
198
+ if (at < 0) return;
199
+ const to = e.key === "ArrowRight" ? (at + 1) % list2.length : e.key === "ArrowLeft" ? (at - 1 + list2.length) % list2.length : e.key === "Home" ? 0 : e.key === "End" ? list2.length - 1 : -1;
200
+ if (to < 0) return;
201
+ e.preventDefault();
202
+ list2[to].focus();
203
+ watch(list2[to]);
204
+ };
205
+ const onFocus = (e) => {
206
+ const at = controls().indexOf(e.target);
207
+ if (at >= 0) setStop(at);
208
+ watch(e.target);
209
+ };
210
+ const toolbar = /* @__PURE__ */ jsxs(
65
211
  "div",
66
212
  {
213
+ ref: onToolbar,
214
+ "data-bulk-bar": "",
67
215
  className: cn(
68
- "flex items-center gap-ds-3 rounded-[var(--ds-radius-md)]",
216
+ "pointer-events-auto max-w-full flex items-center gap-ds-3 rounded-[var(--ds-radius-md)]",
69
217
  "bg-[var(--ds-bg-surface-elevated)] border-[length:var(--ds-border-width)] border-[var(--ds-accent-ink)]",
70
218
  "shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
71
219
  "[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
@@ -74,16 +222,18 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
74
222
  style: { padding: "var(--ds-space-3) var(--ds-space-4)" },
75
223
  role: "toolbar",
76
224
  "aria-label": `${selectedCount} items selected`,
225
+ onKeyDown,
226
+ onFocus,
77
227
  children: [
78
228
  /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-[var(--ds-accent-ink)] tabular-nums whitespace-nowrap", children: [
79
229
  selectedCount,
80
230
  " selected"
81
231
  ] }),
82
- /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-[var(--ds-border-subtle)]" }),
83
- isMobile ? /* @__PURE__ */ jsx(
232
+ actions.length > 0 && /* @__PURE__ */ jsx("div", { className: "h-4 w-px shrink-0 bg-[var(--ds-border-subtle)]" }),
233
+ actions.length > 0 && (compact ? /* @__PURE__ */ jsx(
84
234
  DropdownMenu,
85
235
  {
86
- trigger: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "more-vertical", size: 14 }), children: "Actions" }),
236
+ trigger: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "more-vertical", size: 14 }), ...tab(0), children: "Actions" }),
87
237
  items: dropdownItems,
88
238
  align: "start"
89
239
  }
@@ -93,28 +243,31 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
93
243
  type: "button",
94
244
  variant: "secondary",
95
245
  size: "sm",
246
+ className: "whitespace-nowrap",
96
247
  onClick: action.onClick,
248
+ ...tab(i),
97
249
  children: action.label
98
250
  },
99
251
  i
100
- )) }),
252
+ )) })),
101
253
  /* @__PURE__ */ jsx(
102
254
  "button",
103
255
  {
104
256
  type: "button",
105
- onClick: (e) => {
106
- const bar = e.currentTarget.closest('[role="toolbar"]');
107
- focusAfterSelfRemoval(e.currentTarget, { item: bar, to: selectAllFor(bar) });
108
- onClearSelection();
109
- },
110
- className: cn("ml-auto text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer", FOCUS_RING),
257
+ onClick: () => onClearSelection(),
258
+ className: cn("ml-auto shrink-0 text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer", FOCUS_RING),
111
259
  "aria-label": "Clear selection",
260
+ ...tab(count - 1),
112
261
  children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 16 })
113
262
  }
114
263
  )
115
264
  ]
116
265
  }
117
266
  );
267
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
268
+ !bearing && /* @__PURE__ */ jsx("span", { ref: setAnchor, hidden: true, "data-bulk-bar-anchor": "" }),
269
+ target && createPortal(host ? toolbar : /* @__PURE__ */ jsx("div", { className: BULK_BAR_WINDOW_LAYER, "data-bulk-bar-layer": "", children: toolbar }), target)
270
+ ] });
118
271
  }
119
272
  var CONTROL_HEIGHT = {
120
273
  sm: "h-[var(--ds-control-height-sm)]",
@@ -1734,6 +1887,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
1734
1887
  setBodyEl(el);
1735
1888
  }, [bodyInset]);
1736
1889
  useKeyboardScroll(bodyEl, title, open);
1890
+ const { setLayer: setBarLayer, room: barStack, value: barHost } = useBulkBarHost();
1737
1891
  const onCloseRef = useLatest(onClose);
1738
1892
  const onSubmitRef = useLatest(onSubmit);
1739
1893
  const isTopLayer = useOverlayLayer(open);
@@ -1868,19 +2022,28 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
1868
2022
  }
1869
2023
  ) })
1870
2024
  ] }),
1871
- children && /* @__PURE__ */ jsx(
1872
- "div",
1873
- {
1874
- ref: bodyRef,
1875
- className: cn("min-h-0 flex-[0_1_auto] overflow-y-auto pb-ds-6", FOCUS_INSET),
1876
- style: {
1877
- paddingLeft: variant === "destructive" ? "calc(var(--ds-page-gutter) + 2.5rem + var(--ds-space-3))" : "var(--ds-page-gutter)",
1878
- paddingRight: insetLessScrollbar("var(--ds-page-gutter)")
1879
- },
1880
- children: /* @__PURE__ */ jsx(SurfaceBoundary, { children: /* @__PURE__ */ jsx(DrawerFooterCtx, { value: null, children: /* @__PURE__ */ jsx(OverlayMarkScope, { mark, children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: onClose, children }) }) }) })
1881
- }
1882
- ),
1883
- isMobile && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "flex-1 min-h-0" }),
2025
+ children && // the body's box hosts a bulk-action bar from inside: at its foot, above the footer (Sprint 25.33). On a phone it
2026
+ // fills down to the footer, so that foot is the screen's, not the middle of it (the fix pass of 25.33)
2027
+ /* @__PURE__ */ jsxs("div", { className: cn("relative min-h-0 flex flex-col", isMobile ? "flex-1" : "flex-[0_1_auto]"), children: [
2028
+ /* @__PURE__ */ jsxs(
2029
+ "div",
2030
+ {
2031
+ ref: bodyRef,
2032
+ className: cn("min-h-0 flex-[0_1_auto] overflow-y-auto pb-ds-6", FOCUS_INSET),
2033
+ style: {
2034
+ paddingLeft: variant === "destructive" ? "calc(var(--ds-page-gutter) + 2.5rem + var(--ds-space-3))" : "var(--ds-page-gutter)",
2035
+ paddingRight: insetLessScrollbar("var(--ds-page-gutter)"),
2036
+ ...barStack ? { scrollPaddingBottom: bulkBarRoom(barStack) } : {}
2037
+ },
2038
+ children: [
2039
+ /* @__PURE__ */ jsx(SurfaceBoundary, { children: /* @__PURE__ */ jsx(DrawerFooterCtx, { value: null, children: /* @__PURE__ */ jsx(OverlayMarkScope, { mark, children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: onClose, children: /* @__PURE__ */ jsx(BulkBarHostCtx, { value: barHost, children: /* @__PURE__ */ jsx(AsideSlotContext, { value: true, children }) }) }) }) }) }),
2040
+ /* @__PURE__ */ jsx(BulkBarSpacer, { room: barStack })
2041
+ ]
2042
+ }
2043
+ ),
2044
+ /* @__PURE__ */ jsx("div", { ref: setBarLayer, "data-bulk-bar-layer": "", className: BULK_BAR_LAYER })
2045
+ ] }),
2046
+ isMobile && !children && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "flex-1 min-h-0" }),
1884
2047
  /* @__PURE__ */ jsx(DiscardConfirm, { open: guard.confirming, onKeep: guard.keep, onDiscard: guard.discard }),
1885
2048
  footer && /* @__PURE__ */ jsx("div", { className: cn(
1886
2049
  "shrink-0 flex justify-end gap-ds-2 py-ds-4 px-[var(--ds-page-gutter)]",
@@ -2279,101 +2442,104 @@ function FileUpload({ onFiles, files, upload, onCancel, onRetry, onRemove, accep
2279
2442
  const canCancel = !controlled || !!onCancel;
2280
2443
  const canRetry = !controlled || !!onRetry;
2281
2444
  const canRemove = (item) => !!onRemove || !controlled && item.status === "error";
2282
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-ds-3", className), children: [
2283
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-ds-1.5", children: [
2284
- showLabel && /* @__PURE__ */ jsx(Label, { htmlFor: inputId, children: label }),
2285
- /* @__PURE__ */ jsxs(
2286
- "div",
2287
- {
2288
- onDragOver: (e) => {
2289
- e.preventDefault();
2290
- setDragOver(true);
2291
- },
2292
- onDragLeave: () => setDragOver(false),
2293
- onDrop: handleDrop,
2294
- onClick: () => inputRef.current?.click(),
2295
- className: cn(
2296
- "flex flex-col items-center justify-center gap-ds-2 cursor-pointer group",
2297
- "border-2 border-dashed rounded-[var(--ds-radius-md)]",
2298
- "transition-colors",
2299
- // The real file input is visually hidden inside; Tab lands on it and
2300
- // Enter/Space open the picker natively, so the zone shows its focus.
2301
- invalid ? ERROR_HAS_FOCUS_RING : FIELD_HAS_FOCUS_RING,
2302
- dragOver ? `${ACTIVE_RING} bg-[var(--ds-accent-whisper)]` : invalid ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)] hover:border-[var(--ds-accent-primary)] hover:bg-[var(--ds-accent-whisper)]"
2303
- ),
2304
- style: { padding: "var(--ds-space-8) var(--ds-space-4)" },
2305
- children: [
2306
- /* @__PURE__ */ jsx("div", { className: cn(
2307
- "flex items-center justify-center w-10 h-10 rounded-[var(--ds-radius-full)] transition-colors",
2308
- "bg-[var(--ds-bg-muted)] group-hover:bg-[var(--ds-accent-subtle)]"
2309
- ), children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 20, className: "text-[var(--ds-text-muted)] group-hover:text-[var(--ds-accent-subtle-text)] transition-colors" }) }),
2310
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2311
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: multiple ? "Drop files here or browse" : "Drop a file here or browse" }),
2312
- constraints && /* @__PURE__ */ jsx("p", { id: constraintsId, className: "text-xs text-[var(--ds-text-muted)] mt-ds-1", children: constraints })
2313
- ] }),
2314
- /* @__PURE__ */ jsx(
2315
- "input",
2316
- {
2317
- ref: inputRef,
2318
- id: inputId,
2319
- type: "file",
2320
- accept,
2321
- multiple,
2322
- className: "sr-only",
2323
- "aria-label": control.labelId ? void 0 : control.label,
2324
- "aria-labelledby": control.labelId,
2325
- "aria-describedby": describedBy,
2326
- "aria-invalid": invalid || void 0,
2327
- onChange: (e) => {
2328
- if (e.target.files?.length) addFiles(e.target.files);
2329
- e.target.value = "";
2445
+ return (
2446
+ // a wide control: in a form, its row fills the form rather than keeping a field's reading width (Sprint 25.33)
2447
+ /* @__PURE__ */ jsxs("div", { "data-wide-control": "", className: cn("space-y-ds-3", className), children: [
2448
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-ds-1.5", children: [
2449
+ showLabel && /* @__PURE__ */ jsx(Label, { htmlFor: inputId, children: label }),
2450
+ /* @__PURE__ */ jsxs(
2451
+ "div",
2452
+ {
2453
+ onDragOver: (e) => {
2454
+ e.preventDefault();
2455
+ setDragOver(true);
2456
+ },
2457
+ onDragLeave: () => setDragOver(false),
2458
+ onDrop: handleDrop,
2459
+ onClick: () => inputRef.current?.click(),
2460
+ className: cn(
2461
+ "flex flex-col items-center justify-center gap-ds-2 cursor-pointer group",
2462
+ "border-2 border-dashed rounded-[var(--ds-radius-md)]",
2463
+ "transition-colors",
2464
+ // The real file input is visually hidden inside; Tab lands on it and
2465
+ // Enter/Space open the picker natively, so the zone shows its focus.
2466
+ invalid ? ERROR_HAS_FOCUS_RING : FIELD_HAS_FOCUS_RING,
2467
+ dragOver ? `${ACTIVE_RING} bg-[var(--ds-accent-whisper)]` : invalid ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)] hover:border-[var(--ds-accent-primary)] hover:bg-[var(--ds-accent-whisper)]"
2468
+ ),
2469
+ style: { padding: "var(--ds-space-8) var(--ds-space-4)" },
2470
+ children: [
2471
+ /* @__PURE__ */ jsx("div", { className: cn(
2472
+ "flex items-center justify-center w-10 h-10 rounded-[var(--ds-radius-full)] transition-colors",
2473
+ "bg-[var(--ds-bg-muted)] group-hover:bg-[var(--ds-accent-subtle)]"
2474
+ ), children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 20, className: "text-[var(--ds-text-muted)] group-hover:text-[var(--ds-accent-subtle-text)] transition-colors" }) }),
2475
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2476
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: multiple ? "Drop files here or browse" : "Drop a file here or browse" }),
2477
+ constraints && /* @__PURE__ */ jsx("p", { id: constraintsId, className: "text-xs text-[var(--ds-text-muted)] mt-ds-1", children: constraints })
2478
+ ] }),
2479
+ /* @__PURE__ */ jsx(
2480
+ "input",
2481
+ {
2482
+ ref: inputRef,
2483
+ id: inputId,
2484
+ type: "file",
2485
+ accept,
2486
+ multiple,
2487
+ className: "sr-only",
2488
+ "aria-label": control.labelId ? void 0 : control.label,
2489
+ "aria-labelledby": control.labelId,
2490
+ "aria-describedby": describedBy,
2491
+ "aria-invalid": invalid || void 0,
2492
+ onChange: (e) => {
2493
+ if (e.target.files?.length) addFiles(e.target.files);
2494
+ e.target.value = "";
2495
+ }
2330
2496
  }
2331
- }
2332
- )
2333
- ]
2334
- }
2335
- ),
2336
- rejected && /* @__PURE__ */ jsx(InlineFieldError, { id: rejectedId, message: rejected, className: "mt-0" }),
2337
- waiting && /* @__PURE__ */ jsx(InlineFieldError, { id: waitingId, message: waiting, className: "mt-0" })
2338
- ] }),
2339
- shown.length > 0 && /* @__PURE__ */ jsx("ul", { ref: listRef, className: "space-y-ds-2", children: shown.map((item) => {
2340
- const progress = percentOf(item.progress);
2341
- const words = item.status === "queued" ? "Waiting" : item.status === "uploading" ? `${Math.round(progress)}%` : item.status === "done" ? "Uploaded" : item.status === "error" ? "Failed" : null;
2342
- return /* @__PURE__ */ jsxs(
2343
- "li",
2344
- {
2345
- "data-upload-id": item.id,
2346
- "data-upload-status": item.status,
2347
- onFocus: (e) => {
2348
- if (e.target instanceof HTMLButtonElement) lastAction.current = { id: item.id, el: e.target };
2497
+ )
2498
+ ]
2499
+ }
2500
+ ),
2501
+ rejected && /* @__PURE__ */ jsx(InlineFieldError, { id: rejectedId, message: rejected, className: "mt-0" }),
2502
+ waiting && /* @__PURE__ */ jsx(InlineFieldError, { id: waitingId, message: waiting, className: "mt-0" })
2503
+ ] }),
2504
+ shown.length > 0 && /* @__PURE__ */ jsx("ul", { ref: listRef, className: "space-y-ds-2", children: shown.map((item) => {
2505
+ const progress = percentOf(item.progress);
2506
+ const words = item.status === "queued" ? "Waiting" : item.status === "uploading" ? `${Math.round(progress)}%` : item.status === "done" ? "Uploaded" : item.status === "error" ? "Failed" : null;
2507
+ return /* @__PURE__ */ jsxs(
2508
+ "li",
2509
+ {
2510
+ "data-upload-id": item.id,
2511
+ "data-upload-status": item.status,
2512
+ onFocus: (e) => {
2513
+ if (e.target instanceof HTMLButtonElement) lastAction.current = { id: item.id, el: e.target };
2514
+ },
2515
+ className: cn(
2516
+ "flex items-center gap-ds-3 text-sm",
2517
+ "border-[length:var(--ds-border-width)]",
2518
+ item.status === "error" ? "border-[var(--ds-status-error)]" : "border-[var(--ds-border-subtle)]",
2519
+ "rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]"
2520
+ ),
2521
+ style: { padding: "var(--ds-space-3)" },
2522
+ children: [
2523
+ /* @__PURE__ */ jsx(Icon, { name: "folder", size: 16, className: "text-[var(--ds-text-muted)] shrink-0" }),
2524
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2525
+ /* @__PURE__ */ jsx(TruncFileName, { className: "text-[var(--ds-text-primary)]", children: item.name }),
2526
+ (item.size != null || words) && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-muted)]", children: [item.size != null ? formatSize(item.size) : null, words].filter(Boolean).join(" \xB7 ") }),
2527
+ item.status === "uploading" && /* @__PURE__ */ jsx(Progress, { value: progress, size: "sm", label: `Uploading ${item.name}`, className: "mt-ds-1" }),
2528
+ item.status === "error" && /* @__PURE__ */ jsx("p", { className: "mt-ds-1 text-xs text-[var(--ds-status-error-text)]", children: item.error ?? "The upload didn't work." })
2529
+ ] }),
2530
+ item.status === "done" && /* @__PURE__ */ jsx(Icon, { name: "check", size: 16, className: "text-[var(--ds-status-success)] shrink-0", "aria-hidden": "true" }),
2531
+ running(item) && canCancel && // the visible word starts the name, which says which file (WCAG 2.5.3)
2532
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => cancel(item), "aria-label": `Cancel ${item.name}`, children: "Cancel" }),
2533
+ item.status === "error" && canRetry && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => retry(item), "aria-label": `Retry ${item.name}`, children: "Retry" }),
2534
+ !running(item) && canRemove(item) && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => remove(item), "aria-label": `Remove ${item.name}`, children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 14 }) })
2535
+ ]
2349
2536
  },
2350
- className: cn(
2351
- "flex items-center gap-ds-3 text-sm",
2352
- "border-[length:var(--ds-border-width)]",
2353
- item.status === "error" ? "border-[var(--ds-status-error)]" : "border-[var(--ds-border-subtle)]",
2354
- "rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]"
2355
- ),
2356
- style: { padding: "var(--ds-space-3)" },
2357
- children: [
2358
- /* @__PURE__ */ jsx(Icon, { name: "folder", size: 16, className: "text-[var(--ds-text-muted)] shrink-0" }),
2359
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2360
- /* @__PURE__ */ jsx(TruncFileName, { className: "text-[var(--ds-text-primary)]", children: item.name }),
2361
- (item.size != null || words) && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-muted)]", children: [item.size != null ? formatSize(item.size) : null, words].filter(Boolean).join(" \xB7 ") }),
2362
- item.status === "uploading" && /* @__PURE__ */ jsx(Progress, { value: progress, size: "sm", label: `Uploading ${item.name}`, className: "mt-ds-1" }),
2363
- item.status === "error" && /* @__PURE__ */ jsx("p", { className: "mt-ds-1 text-xs text-[var(--ds-status-error-text)]", children: item.error ?? "The upload didn't work." })
2364
- ] }),
2365
- item.status === "done" && /* @__PURE__ */ jsx(Icon, { name: "check", size: 16, className: "text-[var(--ds-status-success)] shrink-0", "aria-hidden": "true" }),
2366
- running(item) && canCancel && // the visible word starts the name, which says which file (WCAG 2.5.3)
2367
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => cancel(item), "aria-label": `Cancel ${item.name}`, children: "Cancel" }),
2368
- item.status === "error" && canRetry && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => retry(item), "aria-label": `Retry ${item.name}`, children: "Retry" }),
2369
- !running(item) && canRemove(item) && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => remove(item), "aria-label": `Remove ${item.name}`, children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 14 }) })
2370
- ]
2371
- },
2372
- item.id
2373
- );
2374
- }) }),
2375
- /* @__PURE__ */ jsx("div", { role: "status", className: "sr-only", children: /* @__PURE__ */ jsx("span", { children: heard.text }, heard.n) })
2376
- ] });
2537
+ item.id
2538
+ );
2539
+ }) }),
2540
+ /* @__PURE__ */ jsx("div", { role: "status", className: "sr-only", children: /* @__PURE__ */ jsx("span", { children: heard.text }, heard.n) })
2541
+ ] })
2542
+ );
2377
2543
  }
2378
2544
  function SliderRange({
2379
2545
  value,
@@ -3064,6 +3230,7 @@ var Tag = forwardRef(function Tag2({
3064
3230
  size = "md",
3065
3231
  color,
3066
3232
  maxWidth,
3233
+ width,
3067
3234
  onRemove,
3068
3235
  onClick,
3069
3236
  selected,
@@ -3098,8 +3265,9 @@ var Tag = forwardRef(function Tag2({
3098
3265
  "aria-disabled": !clickable && disabled || void 0,
3099
3266
  "data-selected": isSelected ? "" : void 0,
3100
3267
  className: cn(
3101
- "inline-flex items-center font-medium max-w-full min-w-0 whitespace-nowrap",
3268
+ "inline-flex items-center font-medium w-fit max-w-full min-w-0 whitespace-nowrap",
3102
3269
  "rounded-[var(--ds-radius-sm)]",
3270
+ width && "justify-center",
3103
3271
  "transition-colors duration-[var(--ds-transition-speed)]",
3104
3272
  sizeStyles[size],
3105
3273
  colorClasses,
@@ -3107,7 +3275,7 @@ var Tag = forwardRef(function Tag2({
3107
3275
  disabled && "opacity-disabled cursor-not-allowed",
3108
3276
  className
3109
3277
  ),
3110
- style: maxWidth ? { maxWidth } : void 0,
3278
+ style: maxWidth || width ? { ...width ? { width } : {}, ...maxWidth ? { maxWidth } : {} } : void 0,
3111
3279
  children: [
3112
3280
  clickable ? /* @__PURE__ */ jsx(
3113
3281
  "button",
@@ -4057,6 +4225,15 @@ var Alert = forwardRef(function Alert2({
4057
4225
  }
4058
4226
  );
4059
4227
  });
4228
+ var FORM_ROWS = cn(
4229
+ "[--gs-form-default:calc(var(--ds-bp-md)_-_2*var(--ds-space-6))]",
4230
+ "[:where(&)>*]:max-w-[var(--gs-row-cap,var(--ds-form-max,var(--gs-form-default)))]",
4231
+ // the row is the wide control itself (a FileUpload with its own label, written straight into the form), or holds one
4232
+ "[&>[data-wide-control]]:[--gs-row-cap:none]",
4233
+ "[&>*:has([data-wide-control])]:[--gs-row-cap:none]",
4234
+ "[&:has([data-wide-control])>[data-form-actions]]:[--gs-row-cap:none]"
4235
+ );
4236
+ var FORM_CAP = "max-w-[var(--gs-form-cap,var(--ds-form-max,var(--gs-form-default)))] has-[[data-wide-control]]:[--gs-form-cap:none]";
4060
4237
  var isThenable = (value) => !!value && typeof value.then === "function";
4061
4238
  function stampFormId(node, formId) {
4062
4239
  return Children.map(node, (child) => {
@@ -4246,8 +4423,9 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
4246
4423
  ": ",
4247
4424
  f.message
4248
4425
  ] }, f.id || f.label)) }) }) : null;
4426
+ const callerWidth = /(?:^|[\s:!])max-w-/.test(className ?? "");
4249
4427
  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;
4250
- 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: [
4428
+ 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", FORM_ROWS, FORM_CAP, className), style: fullWidth || callerWidth ? { "--ds-form-max": "none" } : void 0, noValidate: true, children: [
4251
4429
  summaryNode && /* @__PURE__ */ jsx("div", { ref: summaryRef, "data-form-error-summary": "", tabIndex: -1, className: cn("rounded-[var(--ds-radius-md)] focus-visible:*:shadow-none", FOCUS_RING), children: summaryNode }),
4252
4430
  children,
4253
4431
  actionsNode
@@ -4381,7 +4559,7 @@ function TransferList({
4381
4559
  setCheckedSelected(allChecked ? /* @__PURE__ */ new Set() : new Set(enabledIds));
4382
4560
  }, [filteredSelected, checkedSelected]);
4383
4561
  const isStacked = useBreakpoint("sm");
4384
- return /* @__PURE__ */ jsxs("div", { ref, className: cn(isStacked ? "flex flex-col gap-ds-2" : "flex items-stretch gap-ds-3", className), children: [
4562
+ return /* @__PURE__ */ jsxs("div", { ref, "data-wide-control": "", className: cn(isStacked ? "flex flex-col gap-ds-2" : "flex items-stretch gap-ds-3", className), children: [
4385
4563
  /* @__PURE__ */ jsx(
4386
4564
  Panel,
4387
4565
  {
@@ -4901,8 +5079,8 @@ var Card = forwardRef(function Card2({
4901
5079
  useLayoutEffect(() => {
4902
5080
  const root = rootRef.current;
4903
5081
  if (!root || !isAction && !checkable) return;
4904
- const controls = Array.from(root.querySelectorAll(FOCUSABLE)).some((el) => !el.hasAttribute(CARD_ACTION_ATTR));
4905
5082
  const titleId = root.querySelector("[data-card-title]")?.id || null;
5083
+ const controls = Array.from(root.querySelectorAll(FOCUSABLE)).some((el) => !el.hasAttribute(CARD_ACTION_ATTR)) || !!titleId && root.matches(CELL_FRAME);
4906
5084
  setInner((cur) => cur.controls === controls && cur.titleId === titleId ? cur : { controls, titleId });
4907
5085
  }, [isAction, checkable, loading, children]);
4908
5086
  const holdsControls = isAction && inner.controls;
@@ -5088,7 +5266,6 @@ function splitTitle(children) {
5088
5266
  if (at < 0) return { lead: [], title: parts[0] ?? null, rest: parts.slice(1) };
5089
5267
  return { lead: parts.slice(0, at), title: parts[at], rest: parts.slice(at + 1) };
5090
5268
  }
5091
- var TITLE_FLOOR = "basis-[calc(var(--ds-font-size-lg)*4.5)]";
5092
5269
  var TITLE_ROW = cn(
5093
5270
  "flex flex-wrap items-start justify-end gap-x-ds-2 gap-y-ds-2 min-w-0 grow basis-0",
5094
5271
  "[&>[data-header-actions]>*]:order-5",
@@ -5130,13 +5307,13 @@ var CardHeader = forwardRef(function CardHeader2(allProps, ref) {
5130
5307
  const band = (order) => cn("shrink-0 self-start flex items-center", TITLE_LINE, order);
5131
5308
  const checkbox = owns && row.checkbox ? /* @__PURE__ */ jsx("span", { className: band("order-5"), children: row.checkbox }) : null;
5132
5309
  const check = owns && row.check ? /* @__PURE__ */ jsx("span", { "data-card-selection": "", className: band("order-4"), children: row.check }) : null;
5133
- const menuPart = menu ? /* @__PURE__ */ jsx("span", { className: band("order-6"), children: menu }) : null;
5310
+ const menuPart = menu ? /* @__PURE__ */ jsx("span", { className: cn(band("order-6"), CELL_HIDE), children: menu }) : null;
5134
5311
  const { lead, title, rest } = splitTitle(children);
5135
5312
  const leadBlock = lead.length > 0 ? /* @__PURE__ */ jsx("div", { "data-card-lead": "", className: "flex flex-col space-y-ds-1.5 min-w-0 grow", children: lead }) : null;
5136
5313
  const topLine = iconBlock ?? leadBlock;
5137
5314
  const ownBlock = title !== null && !(isValidElement(title) && elementType(title.type) === CardTitle);
5138
- const actionsSlot = "actions" in allProps ? /* @__PURE__ */ jsx("div", { "data-header-actions": "", className: "contents", children: partsOf(actions).map((item, i) => /* @__PURE__ */ jsx("span", { className: cn("flex items-center shrink-0", TITLE_LINE), children: item }, isValidElement(item) && item.key !== null ? item.key : i)) }) : null;
5139
- return /* @__PURE__ */ jsxs("div", { ref, "data-card-header": "", className: cn("flex flex-col px-ds-5 pt-ds-4 last:pb-ds-4 min-w-0", className), ...props, children: [
5315
+ const actionsSlot = "actions" in allProps ? /* @__PURE__ */ jsx("div", { "data-header-actions": "", className: cn("contents", CELL_HIDE), children: partsOf(actions).map((item, i) => /* @__PURE__ */ jsx("span", { className: cn("flex items-center shrink-0", TITLE_LINE), children: item }, isValidElement(item) && item.key !== null ? item.key : i)) }) : null;
5316
+ return /* @__PURE__ */ jsxs("div", { ref, "data-card-header": "", className: cn("flex flex-col px-ds-5 pt-ds-4 last:pb-ds-4 min-w-0", CELL_ROOM, className), ...props, children: [
5140
5317
  topLine && /* @__PURE__ */ jsxs("div", { "data-card-icon-row": iconBlock ? "" : void 0, "data-card-lead-row": iconBlock ? void 0 : "", className: cn("flex items-start gap-ds-2", iconBlock ? "mb-ds-2.5" : "mb-ds-1.5"), children: [
5141
5318
  topLine,
5142
5319
  iconBlock && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "grow -ml-ds-2" }),
@@ -5237,8 +5414,9 @@ var CardDescription = forwardRef(function CardDescription2({ className, children
5237
5414
  );
5238
5415
  return /* @__PURE__ */ jsx(AutoTooltip, { content: children, disabled: !isTruncated, children: el });
5239
5416
  });
5417
+ var CELL_CARD_BODY = "[[data-dashboard-content]>[data-card]>&]:min-h-0 [[data-dashboard-content]>[data-card]>&]:overflow-y-auto [[data-dashboard-content]>[data-card]>&]:scroll-p-[4px]";
5240
5418
  var CardContent = forwardRef(function CardContent2({ className, children, ...props }, ref) {
5241
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex-1 px-ds-5 py-ds-4", className), ...props, children });
5419
+ return /* @__PURE__ */ jsx("div", { ref, "data-card-content": "", className: cn("flex-1 px-ds-5 py-ds-4", CELL_CARD_BODY, FOCUS_INSET_WHILE_STOP, className), ...props, children });
5242
5420
  });
5243
5421
  var CardFooter = forwardRef(function CardFooter2({ className, children, ...props }, ref) {
5244
5422
  return (
@@ -5246,9 +5424,14 @@ var CardFooter = forwardRef(function CardFooter2({ className, children, ...props
5246
5424
  /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center gap-ds-2 px-ds-5 pb-ds-4 pt-ds-2 mt-auto min-w-0 [&:not(:has(>:not(button)))]:justify-end", className), ...props, children })
5247
5425
  );
5248
5426
  });
5249
- function TruncLabel({ children }) {
5427
+ var CELL_STAT = "[[data-dashboard-content]>&]:overflow-y-auto [[data-dashboard-content]>&]:scroll-p-[4px]";
5428
+ var STAT_CONTAINER = "@container/stat [contain-intrinsic-inline-size:12rem]";
5429
+ var STAT_VALUE_STEPS = "@max-[11.25rem]/stat:text-xl @max-[7.25rem]/stat:text-lg";
5430
+ var STAT_NARROW_LINE = "@max-[10.375rem]/stat:col-span-2";
5431
+ var STAT_NARROW_TILE = "@max-[10.375rem]/stat:row-[1]";
5432
+ function TruncLabel({ children, className }) {
5250
5433
  const { ref, isTruncated } = useTextOverflow({ lines: 1 });
5251
- const el = /* @__PURE__ */ jsx("span", { ref, className: "block text-xs font-medium text-[var(--ds-text-muted)] uppercase tracking-wider truncate min-w-0", children });
5434
+ const el = /* @__PURE__ */ jsx("span", { ref, className: cn("block text-xs font-medium text-[var(--ds-text-muted)] uppercase tracking-wider truncate min-w-0", className), children });
5252
5435
  if (!isTruncated) return el;
5253
5436
  return /* @__PURE__ */ jsx(AutoTooltip, { content: children, children: el });
5254
5437
  }
@@ -5266,6 +5449,7 @@ function StatsCard({ value, label, trend, icon, layout = "card", interactive, on
5266
5449
  "div",
5267
5450
  {
5268
5451
  "data-card": "",
5452
+ "data-stats-card": "",
5269
5453
  className: cn(
5270
5454
  "flex flex-col p-ds-3 sm:p-ds-5 min-w-0",
5271
5455
  "bg-[var(--ds-bg-surface)] rounded-[var(--ds-radius-md)]",
@@ -5280,8 +5464,10 @@ function StatsCard({ value, label, trend, icon, layout = "card", interactive, on
5280
5464
  "hover:scale-[var(--ds-ambient-hover-scale)] hover:-translate-y-[var(--ds-ambient-hover-lift)]"
5281
5465
  ],
5282
5466
  GLASS_SURFACE,
5283
- // a clickable card is a Tab stop
5284
- onClick && FOCUS_RING,
5467
+ STAT_CONTAINER,
5468
+ CELL_STAT,
5469
+ // a clickable card is a Tab stop; a plain one is while it scrolls in a dashboard's widget
5470
+ onClick ? FOCUS_RING : FOCUS_INSET_WHILE_STOP,
5285
5471
  className
5286
5472
  ),
5287
5473
  onClick,
@@ -5294,15 +5480,13 @@ function StatsCard({ value, label, trend, icon, layout = "card", interactive, on
5294
5480
  }
5295
5481
  } : void 0,
5296
5482
  children: [
5297
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-ds-2 min-w-0", children: [
5298
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
5299
- /* @__PURE__ */ jsx(TruncLabel, { children: label }),
5300
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-ds-2 mt-ds-2 flex-wrap", children: [
5301
- /* @__PURE__ */ jsx("span", { className: "font-[family-name:var(--ds-font-display)] text-2xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] leading-none tabular-nums", children: value }),
5302
- trend && /* @__PURE__ */ jsx(TrendBadge, { trend })
5303
- ] })
5483
+ /* @__PURE__ */ jsxs("div", { className: cn("grid gap-ds-2 min-w-0", icon ? "grid-cols-[minmax(0,1fr)_auto]" : "grid-cols-[minmax(0,1fr)]", CELL_ROOM_INNER), children: [
5484
+ /* @__PURE__ */ jsx(TruncLabel, { className: cn("self-start", CELL_STAT_ROOM, !icon && CELL_STAT_ROOM_END), children: label }),
5485
+ /* @__PURE__ */ jsxs("div", { className: cn("col-start-1 flex items-baseline gap-ds-2 flex-wrap", icon && STAT_NARROW_LINE), children: [
5486
+ /* @__PURE__ */ jsx("span", { className: cn("font-[family-name:var(--ds-font-display)] text-2xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] leading-none tabular-nums", STAT_VALUE_STEPS), children: value }),
5487
+ trend && /* @__PURE__ */ jsx(TrendBadge, { trend })
5304
5488
  ] }),
5305
- icon && /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center justify-center w-8 h-8 rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)]", children: /* @__PURE__ */ jsx(Icon, { name: icon, size: 16, className: "text-[var(--ds-text-muted)]" }) })
5489
+ icon && /* @__PURE__ */ jsx("div", { className: cn("col-start-2 row-[1/span_2] self-start flex items-center justify-center w-8 h-8 rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)]", STAT_NARROW_TILE, CELL_STAT_TILE), children: /* @__PURE__ */ jsx(Icon, { name: icon, size: 16, className: "text-[var(--ds-text-muted)]" }) })
5306
5490
  ] }),
5307
5491
  children && /* @__PURE__ */ jsx("div", { className: "mt-ds-3 text-xs text-[var(--ds-text-muted)]", children })
5308
5492
  ]
@@ -5757,9 +5941,16 @@ var PIN_FOCUS_END = "[tr:focus-visible>&]:after:right-[3px] [tr:focus-visible>&]
5757
5941
  var PINNED_BACKGROUND = "linear-gradient(var(--gs-row-tint, transparent), var(--gs-row-tint, transparent)), linear-gradient(var(--gs-pinned-surface), var(--gs-pinned-surface)), var(--gs-pinned-canvas)";
5758
5942
  var PINNED_LAYERS = cn(
5759
5943
  "[--gs-pinned-surface:var(--ds-bg-surface)] [--gs-pinned-canvas:var(--ds-bg-canvas)]",
5760
- "supports-[color:oklch(from_red_l_c_h)]:[--gs-pinned-surface:oklch(from_var(--ds-bg-surface)_l_c_h_/_max(alpha,min(1,alpha*1000)))]",
5761
5944
  "supports-[color:oklch(from_red_l_c_h)]:[--gs-pinned-canvas:oklch(from_var(--ds-bg-canvas)_l_c_h_/_1)]"
5762
5945
  );
5946
+ function drawnText(el) {
5947
+ const copy = el.cloneNode(true);
5948
+ copy.querySelectorAll(".sr-only").forEach((n) => n.remove());
5949
+ return copy.textContent ?? "";
5950
+ }
5951
+ var CELL_ACTION = "button, a[href], [role='button'], [role='link']";
5952
+ var CELL_READ_OR_SET = "input:not([type='hidden']), select, textarea, img:not([alt='']), [role='switch'], [role='checkbox'], [role='radio'], [role='slider'], [role='spinbutton'], [role='combobox'], [role='img']:not([aria-hidden='true'])";
5953
+ var iconActionsOnly = (td) => !td.querySelector(CELL_READ_OR_SET) && !!td.querySelector(CELL_ACTION);
5763
5954
  var PIN_SHADOW = "oklch(0 0 0 / 0.18)";
5764
5955
  var ROW_CONTROL = `${FOCUSABLE}, label, [role="button"], [role="checkbox"], [role="switch"], [role="menuitem"], [role="link"]`;
5765
5956
  function clickIsCard(e) {
@@ -5981,12 +6172,12 @@ var CARD_TOGGLE = cn(
5981
6172
  );
5982
6173
  function TableHeading({ title, description, actions, titleId, descriptionId, inset }) {
5983
6174
  const heading = /* @__PURE__ */ jsx("h3", { id: titleId, className: TITLE_CLASSES, children: title });
5984
- const actionsBlock = actions ? /* @__PURE__ */ jsx("div", { className: HEADER_LAYOUT.actions, children: actions }) : null;
6175
+ const actionsBlock = actions ? /* @__PURE__ */ jsx("div", { className: cn(HEADER_LAYOUT.actions, CELL_HIDE), children: actions }) : null;
5985
6176
  const titleLeads = !actions || actionsAreBadges(actions);
5986
6177
  const leadRowRef = useRef(null);
5987
6178
  const leadFloorFits = useTitleFloorFits(leadRowRef, titleLeads);
5988
6179
  const descriptionText = (className) => description ? /* @__PURE__ */ jsx("p", { id: descriptionId, className: cn(className, "text-sm text-[var(--ds-text-muted)] break-words"), children: description }) : null;
5989
- return /* @__PURE__ */ jsx("div", { "data-table-heading": "", className: cn(inset ? "px-ds-5 py-ds-4" : "pb-ds-4"), children: !titleLeads ? /* @__PURE__ */ jsxs("div", { className: HEADER_LAYOUT.row, children: [
6180
+ return /* @__PURE__ */ jsx("div", { "data-table-heading": "", className: cn(inset ? "px-ds-5 py-ds-4" : "pb-ds-4", CELL_ROOM), children: !titleLeads ? /* @__PURE__ */ jsxs("div", { className: HEADER_LAYOUT.row, children: [
5990
6181
  /* @__PURE__ */ jsxs("div", { className: HEADER_LAYOUT.block, children: [
5991
6182
  heading,
5992
6183
  descriptionText()
@@ -6295,7 +6486,8 @@ function Table({
6295
6486
  const preferences = useShellPreferences();
6296
6487
  const mobileBreakpoint = mobileBreakpointProp ?? preferences.tableToCardsBreakpoint ?? "md";
6297
6488
  const narrowScreen = useBreakpoint(mobileBreakpoint);
6298
- const { cards: isMobile, rootRef } = useCardsSwitch(narrowScreen, cardsBelow, title);
6489
+ const [inCell, setInCell] = useState(false);
6490
+ const { cards: isMobile, rootRef } = useCardsSwitch(narrowScreen && !inCell, inCell ? 0 : cardsBelow, title);
6299
6491
  useRevealFocus(rootRef, isMobile);
6300
6492
  useFocusKeptInList(rootRef);
6301
6493
  const [cardsEl, setCardsEl] = useState(null);
@@ -6304,6 +6496,7 @@ function Table({
6304
6496
  rootRef.current = node;
6305
6497
  if (typeof ref === "function") ref(node);
6306
6498
  else if (ref) ref.current = node;
6499
+ if (node) setInCell(node.matches(CELL_FRAME));
6307
6500
  }, [ref, rootRef]);
6308
6501
  const tableRef = useRef(null);
6309
6502
  const [pins, setPins] = useState(NO_PINS);
@@ -6312,7 +6505,7 @@ function Table({
6312
6505
  const endColumns = columns.filter((c) => c.pin === "end").length;
6313
6506
  const endCount = endColumns + trail;
6314
6507
  const nameIndex = columns.length > endColumns ? lead : -1;
6315
- const { ref: scrollRef, elRef: scrollEl, measure: measureScroll, scrollable, edges, fadeProps } = useScrollEdges({
6508
+ const { ref: scrollRef, elRef: scrollEl, measure: measureScroll, scrollable, overflowing, edges, fadeProps } = useScrollEdges({
6316
6509
  enabled: !isMobile,
6317
6510
  noFade: { left: lead + (pins.nameFits ? 1 : 0) > 0, right: endCount > 0 }
6318
6511
  });
@@ -6358,6 +6551,7 @@ function Table({
6358
6551
  }, [isMobile, lead, trail, endCount, nameIndex, scrollEl, columns, drawn.length, visibleKeys.length]);
6359
6552
  const pinnedStart = lead + (pins.nameFits ? 1 : 0);
6360
6553
  const pinStyle = (position, total) => {
6554
+ if (!overflowing) return void 0;
6361
6555
  if (position < pinnedStart && pins.start[position] !== void 0) {
6362
6556
  const inner = position === pinnedStart - 1;
6363
6557
  return { position: "sticky", left: pins.start[position], zIndex: 1, background: PINNED_BACKGROUND, boxShadow: inner && edges.left ? `6px 0 6px -6px ${PIN_SHADOW}` : void 0 };
@@ -6376,17 +6570,22 @@ function Table({
6376
6570
  };
6377
6571
  const fade = fadeProps;
6378
6572
  const [renderedKinds, setRenderedKinds] = useState(() => /* @__PURE__ */ new Map());
6573
+ const [iconOnlyCols, setIconOnlyCols] = useState(() => /* @__PURE__ */ new Set());
6379
6574
  useLayoutEffect(() => {
6380
6575
  const table2 = tableRef.current;
6381
6576
  if (!table2 || isMobile) return;
6382
6577
  const next = /* @__PURE__ */ new Map();
6578
+ const icons = /* @__PURE__ */ new Set();
6383
6579
  for (const col of columns) {
6580
+ const cells = Array.from(table2.querySelectorAll(`:scope > tbody > tr > td[data-col="${CSS.escape(col.key)}"]`)).slice(0, 50);
6581
+ const texts = cells.map(drawnText);
6582
+ if (cells.length && cells.every((td, i) => !texts[i].trim() && iconActionsOnly(td))) icons.add(col.key);
6384
6583
  if (kindOf2(col)) continue;
6385
- const texts = Array.from(table2.querySelectorAll(`:scope > tbody > tr > td[data-col="${CSS.escape(col.key)}"]`)).slice(0, 50).map((td) => td.textContent ?? "");
6386
6584
  const kind = texts.length ? kindOfRenderedText(texts) : void 0;
6387
6585
  if (kind) next.set(col.key, kind);
6388
6586
  }
6389
6587
  setRenderedKinds((prev) => prev.size === next.size && [...next].every(([k, v]) => prev.get(k) === v) ? prev : next);
6588
+ setIconOnlyCols((prev) => prev.size === icons.size && [...icons].every((k) => prev.has(k)) ? prev : icons);
6390
6589
  }, [columns, kindOf2, drawn, isMobile, visibleKeys.length]);
6391
6590
  const [focusKey, setFocusKey] = useState(null);
6392
6591
  const visibleSet = new Set(visibleKeys);
@@ -6676,7 +6875,7 @@ function Table({
6676
6875
  scrollToRow(key);
6677
6876
  }, [drawnStart, drawn.length, visibleKeys.length, scrollToRow]);
6678
6877
  const cardHeading = title ? /* @__PURE__ */ jsx(TableHeading, { title, description, actions, titleId, descriptionId, inset: false }) : null;
6679
- const titledCards = (body) => /* @__PURE__ */ jsxs("div", { ref: listRoot, "data-ds-list": "", "data-gs": "table", className: cn("flex flex-col", listClass), onFocus: noteFocus, onBlur: forgetFocus, children: [
6878
+ const titledCards = (body) => /* @__PURE__ */ jsxs("div", { ref: listRoot, "data-ds-list": "", "data-gs": "table", "data-wide-control": "", className: cn("flex flex-col", listClass), onFocus: noteFocus, onBlur: forgetFocus, children: [
6680
6879
  cardHeading,
6681
6880
  body
6682
6881
  ] });
@@ -6730,11 +6929,11 @@ function Table({
6730
6929
  ] }, col.key)) }, r)) })
6731
6930
  ] });
6732
6931
  if (title) return titledCards(skeletonCards);
6733
- return /* @__PURE__ */ jsx("div", { ref: setRoot, "data-ds-list": "", "data-gs": "table", className, children: skeletonCards });
6932
+ return /* @__PURE__ */ jsx("div", { ref: setRoot, "data-ds-list": "", "data-gs": "table", "data-wide-control": "", className, children: skeletonCards });
6734
6933
  }
6735
6934
  if (data.length === 0 && emptyState) {
6736
6935
  if (title) return titledCards(/* @__PURE__ */ jsx("div", { className: "py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", children: emptyState }));
6737
- return /* @__PURE__ */ jsx("div", { ref: setRoot, "data-ds-list": "", "data-gs": "table", className: cn("py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", className), children: emptyState });
6936
+ return /* @__PURE__ */ jsx("div", { ref: setRoot, "data-ds-list": "", "data-gs": "table", "data-wide-control": "", className: cn("py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", className), children: emptyState });
6738
6937
  }
6739
6938
  const cards = /* @__PURE__ */ jsx(TableCardCtx, { value: true, children: /* @__PURE__ */ jsx(RowsCtx, { value: true, children: /* @__PURE__ */ jsxs("div", { ref: setCards, "data-ds-list": title ? void 0 : "", "data-gs": title ? void 0 : "table", className: cn("relative flex flex-col gap-ds-3 overflow-y-auto -m-[4px] p-[4px] scroll-p-[4px]", FOCUS_INSET, title ? "min-h-0" : listClass), onFocus: title ? void 0 : noteFocus, onBlur: title ? void 0 : forgetFocus, children: [
6740
6939
  loading && data.length > 0 && /* @__PURE__ */ jsx(RefreshLine, { className: "inset-x-[4px] rounded-full" }),
@@ -6789,8 +6988,10 @@ function Table({
6789
6988
  }
6790
6989
  } : void 0,
6791
6990
  children: [
6792
- selectable && box && // "Select" and the row's name, as in the table (T15); a parent with some of its rows chosen is mixed
6793
- /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, indeterminate: box.mixed, onChange: (_, { shiftKey: shiftKey2 }) => toggleBox(originalIdx, id, shiftKey2), "aria-labelledby": nameIndex >= 0 ? `${headingId}-select ${headingId}-card-name-${idPart(id)}` : `${headingId}-select` }),
6991
+ selectable && box && // "Select" and the row's name, as in the table (T15); a parent with some of its rows chosen is mixed. Marked as
6992
+ // the card's selection box: with no select-all on a phone, the first card's is where a BulkActionBar's
6993
+ // handover finds the selection (the fix pass of 25.33)
6994
+ /* @__PURE__ */ jsx("div", { "data-ds-select-card": "", children: /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, indeterminate: box.mixed, onChange: (_, { shiftKey: shiftKey2 }) => toggleBox(originalIdx, id, shiftKey2), "aria-labelledby": nameIndex >= 0 ? `${headingId}-select ${headingId}-card-name-${idPart(id)}` : `${headingId}-select` }) }),
6794
6995
  columns.map((col, c) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-ds-2 text-sm", children: [
6795
6996
  /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider", children: col.header }),
6796
6997
  /* @__PURE__ */ jsx(CardValue, { value: row[col.key], id: lead + c === nameIndex ? `${headingId}-card-name-${idPart(id)}` : void 0 })
@@ -6864,8 +7065,9 @@ function Table({
6864
7065
  // a tree table is a treegrid (item 14): its rows have levels, and the arrow keys move between them
6865
7066
  /* @__PURE__ */ jsxs("table", { ref: tableRef, role: nested ? "treegrid" : void 0, "aria-busy": loading || void 0, className: cn("w-full text-sm", PINNED_LAYERS), ...title ? { "aria-labelledby": titleId, "aria-describedby": description ? descriptionId : void 0 } : ariaLabel ? { "aria-label": ariaLabel } : {}, children: [
6866
7067
  /* @__PURE__ */ jsx("thead", { className: cn("bg-[var(--ds-bg-muted)]", stickyHeader && "sticky top-0 z-10"), onKeyDown: nested ? onHeadKeyDown : void 0, onFocus: nested ? onHeadFocus : void 0, children: /* @__PURE__ */ jsxs("tr", { className: "border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] [--gs-row-tint:var(--ds-bg-muted)]", children: [
6867
- selectable && // data-ds-select-all: the selection's own control, where a BulkActionBar's Clear selection sends focus
6868
- /* @__PURE__ */ jsx("th", { "data-ds-select-all": "", className: cn("w-10", density === "compact" ? "px-ds-2 py-ds-2" : "px-ds-3 py-ds-3"), style: pinStyle(0, cellCount), children: /* @__PURE__ */ jsx(
7068
+ selectable && // data-ds-select-all: the selection's own control, where a BulkActionBar's Clear selection sends focus; and
7069
+ // whether the table holds a selection, said as it renders (the box's mixed state is set a moment later)
7070
+ /* @__PURE__ */ jsx("th", { "data-ds-select-all": "", "data-selection": allSelected ? "all" : someSelected ? "some" : "none", className: cn("w-10", density === "compact" ? "px-ds-2 py-ds-2" : "px-ds-3 py-ds-3"), style: pinStyle(0, cellCount), children: /* @__PURE__ */ jsx(
6869
7071
  Checkbox,
6870
7072
  {
6871
7073
  ref: selectAllRef,
@@ -6922,6 +7124,9 @@ function Table({
6922
7124
  ]
6923
7125
  }
6924
7126
  )
7127
+ ) : iconOnlyCols.has(col.key) ? (
7128
+ // a column of icon buttons: its name for a screen reader, its width its buttons' (Sprint 25.33)
7129
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: col.header })
6925
7130
  ) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-ds-1", children: col.header })
6926
7131
  },
6927
7132
  col.key
@@ -7104,6 +7309,7 @@ function Table({
7104
7309
  ref: listRoot,
7105
7310
  "data-ds-list": "",
7106
7311
  "data-gs": "table",
7312
+ "data-wide-control": "",
7107
7313
  className: cn("relative w-full min-w-0 flex flex-col", FRAME_CLASSES, FRAME_FOCUS_RING, control && "min-h-0", listClass),
7108
7314
  onFocus: noteFocus,
7109
7315
  onBlur: forgetFocus,
@@ -7128,7 +7334,7 @@ function Table({
7128
7334
  },
7129
7335
  ...fade,
7130
7336
  ...region,
7131
- className: cn("relative min-h-0 overflow-x-auto focus-visible:outline-none", title ? "rounded-b-[inherit]" : "rounded-[inherit]"),
7337
+ className: cn("relative min-h-0 overflow-x-auto focus-visible:outline-none", title ? "rounded-b-[inherit]" : "rounded-[inherit]", inCell && "scroll-p-[4px]"),
7132
7338
  children: table
7133
7339
  }
7134
7340
  )
@@ -9268,38 +9474,42 @@ function ExpandableDescription({ children, className }) {
9268
9474
  function HorizontalLayout({ items, minItemWidth, label, className }) {
9269
9475
  const [row, setRow] = useState(null);
9270
9476
  useKeyboardScroll(row, label, true, false, "x");
9271
- return /* @__PURE__ */ jsx("div", { ref: setRow, "data-timeline-row": "", className: cn("relative flex items-start overflow-x-auto snap-x", FOCUS_INSET, className), children: items.map((item, i) => {
9272
- const isFirst = i === 0;
9273
- const isLast = i === items.length - 1;
9274
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 shrink-0 flex-col items-center snap-start", style: { minWidth: minItemWidth }, children: [
9275
- /* @__PURE__ */ jsxs("div", { className: "flex items-center w-full", children: [
9276
- /* @__PURE__ */ jsx(
9277
- "div",
9278
- {
9279
- className: cn(
9280
- "flex-1 h-[2px] transition-colors",
9281
- isFirst ? "bg-transparent" : "bg-[var(--ds-border-subtle)]"
9282
- )
9283
- }
9284
- ),
9285
- /* @__PURE__ */ jsx(Marker, { item, vertical: false }),
9286
- /* @__PURE__ */ jsx(
9287
- "div",
9288
- {
9289
- className: cn(
9290
- "flex-1 h-[2px] transition-colors",
9291
- isLast ? "bg-transparent" : "bg-[var(--ds-border-subtle)]"
9292
- )
9293
- }
9294
- )
9295
- ] }),
9296
- /* @__PURE__ */ jsxs("div", { className: "text-center mt-ds-2 px-ds-3", children: [
9297
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: item.title }),
9298
- item.description && /* @__PURE__ */ jsx(ExpandableDescription, { className: "text-center", children: item.description }),
9299
- /* @__PURE__ */ jsx(ItemTime, { item })
9300
- ] })
9301
- ] }, i);
9302
- }) });
9477
+ return (
9478
+ // 4 px of room inside its edges, and snapping that keeps it, so the first marker and the row's own keyboard outline
9479
+ // never meet (Sprint 25.33: the owner's answer to Sprint 25.30's look question)
9480
+ /* @__PURE__ */ jsx("div", { ref: setRow, "data-timeline-row": "", className: cn("relative flex items-start overflow-x-auto snap-x p-[4px] scroll-px-[4px]", FOCUS_INSET, className), children: items.map((item, i) => {
9481
+ const isFirst = i === 0;
9482
+ const isLast = i === items.length - 1;
9483
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 shrink-0 flex-col items-center snap-start", style: { minWidth: minItemWidth }, children: [
9484
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center w-full", children: [
9485
+ /* @__PURE__ */ jsx(
9486
+ "div",
9487
+ {
9488
+ className: cn(
9489
+ "flex-1 h-[2px] transition-colors",
9490
+ isFirst ? "bg-transparent" : "bg-[var(--ds-border-subtle)]"
9491
+ )
9492
+ }
9493
+ ),
9494
+ /* @__PURE__ */ jsx(Marker, { item, vertical: false }),
9495
+ /* @__PURE__ */ jsx(
9496
+ "div",
9497
+ {
9498
+ className: cn(
9499
+ "flex-1 h-[2px] transition-colors",
9500
+ isLast ? "bg-transparent" : "bg-[var(--ds-border-subtle)]"
9501
+ )
9502
+ }
9503
+ )
9504
+ ] }),
9505
+ /* @__PURE__ */ jsxs("div", { className: "text-center mt-ds-2 px-ds-3", children: [
9506
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: item.title }),
9507
+ item.description && /* @__PURE__ */ jsx(ExpandableDescription, { className: "text-center", children: item.description }),
9508
+ /* @__PURE__ */ jsx(ItemTime, { item })
9509
+ ] })
9510
+ ] }, i);
9511
+ }) })
9512
+ );
9303
9513
  }
9304
9514
  var exactFormat = (locale, d) => new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(d);
9305
9515
  var exactDayFormat = (locale, d) => new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(d);
@@ -9606,6 +9816,7 @@ function TreeView({
9606
9816
  "aria-label": ariaLabel,
9607
9817
  "aria-labelledby": ariaLabelledBy
9608
9818
  }) {
9819
+ useWantsInset();
9609
9820
  const [ownSelected, setOwnSelected] = useState(() => new Set(defaultSelected));
9610
9821
  const selected = useMemo(() => selectedProp ? new Set(selectedProp) : ownSelected, [selectedProp, ownSelected]);
9611
9822
  const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set([...defaultExpanded, ...foldersHolding(nodes, selected)]));
@@ -9760,7 +9971,7 @@ function TreeNodeRow({
9760
9971
  const hasChildren = !!node.children?.length;
9761
9972
  const isExpanded = expanded.has(node.id);
9762
9973
  const isSelected = selected.has(node.id);
9763
- const holdsSelection = !isSelected && holding.has(node.id);
9974
+ const holdsSelection2 = !isSelected && holding.has(node.id);
9764
9975
  const checkState = checkable ? getCheckState(node) : "unchecked";
9765
9976
  return /* @__PURE__ */ jsxs("div", { role: "treeitem", "aria-expanded": hasChildren ? isExpanded : void 0, "aria-selected": selectable ? isSelected : void 0, children: [
9766
9977
  /* @__PURE__ */ jsxs(
@@ -9778,7 +9989,7 @@ function TreeNodeRow({
9778
9989
  isSelected ? "bg-[var(--ds-tree-active-bg)] text-[var(--ds-tree-active-text)] font-medium border-[var(--ds-accent-ink)]" : "border-transparent text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)] hover:text-[var(--ds-text-primary)]",
9779
9990
  // A folder holding the selection, as SidebarNav draws a parent of the current page (Sprint 25.16 A18): no
9780
9991
  // fill, so it reads the plain tokens, never the active set (pill's on-primary text would vanish here).
9781
- holdsSelection && "font-medium",
9992
+ holdsSelection2 && "font-medium",
9782
9993
  node.disabled && "opacity-disabled pointer-events-none"
9783
9994
  ),
9784
9995
  style: { paddingLeft: `calc(var(--ds-space-3) * ${depth} + var(--ds-space-2))` },
@@ -9805,7 +10016,7 @@ function TreeNodeRow({
9805
10016
  {
9806
10017
  name: "chevron-right",
9807
10018
  size: 14,
9808
- className: cn(isSelected ? "text-[var(--ds-tree-active-muted)]" : holdsSelection ? "text-[var(--ds-accent-ink)]" : "text-[var(--ds-text-muted)]", "transition-transform", isExpanded && "rotate-90")
10019
+ className: cn(isSelected ? "text-[var(--ds-tree-active-muted)]" : holdsSelection2 ? "text-[var(--ds-accent-ink)]" : "text-[var(--ds-text-muted)]", "transition-transform", isExpanded && "rotate-90")
9809
10020
  }
9810
10021
  )
9811
10022
  }
@@ -9821,7 +10032,7 @@ function TreeNodeRow({
9821
10032
  }
9822
10033
  }
9823
10034
  ),
9824
- 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-ink)]" : "text-[var(--ds-text-muted)]") }),
10035
+ node.icon && /* @__PURE__ */ jsx(Icon, { name: node.icon, size: 16, className: cn("shrink-0", isSelected ? "text-[var(--ds-tree-active-text)]" : holdsSelection2 ? "text-[var(--ds-accent-ink)]" : "text-[var(--ds-text-muted)]") }),
9825
10036
  /* @__PURE__ */ jsx(TruncLabel2, { children: node.label })
9826
10037
  ]
9827
10038
  }
@@ -10646,19 +10857,20 @@ function AsidePanel({
10646
10857
  }) {
10647
10858
  const collapsed = useBreakpoint(collapseBelow);
10648
10859
  const shell = useAppShell();
10860
+ const inSlot = useContext(AsideSlotContext);
10649
10861
  const navbarFloating = navbarFloatingProp ?? shell?.navbarFloating ?? false;
10650
10862
  const sidebarFloating = sidebarFloatingProp ?? shell?.sidebarFloating ?? false;
10651
- const setAsideOpen = shell?.setAsideOpen;
10652
- const setAsideFloating = shell?.setAsideFloating;
10653
10863
  const floating = position === "floating";
10654
- useEffect(() => {
10655
- setAsideOpen?.(open && !collapsed);
10656
- setAsideFloating?.(floating);
10657
- return () => {
10658
- setAsideOpen?.(false);
10659
- setAsideFloating?.(false);
10660
- };
10661
- }, [open, collapsed, floating, setAsideOpen, setAsideFloating]);
10864
+ const reportAside = shell?.reportAside;
10865
+ const close = useLatest(onClose);
10866
+ const wasOpen = useRef(false);
10867
+ useLayoutEffect(() => {
10868
+ if (!reportAside) return;
10869
+ const opened = open && !wasOpen.current;
10870
+ wasOpen.current = open;
10871
+ reportAside(close, { open, opened, page: !inSlot, docked: !collapsed, floating, side, name: labelledBy });
10872
+ return () => reportAside(close, null);
10873
+ }, [reportAside, close, open, inSlot, collapsed, floating, side, labelledBy]);
10662
10874
  if (collapsed) {
10663
10875
  return /* @__PURE__ */ jsx(
10664
10876
  Drawer,
@@ -10677,7 +10889,7 @@ function AsidePanel({
10677
10889
  }
10678
10890
  );
10679
10891
  }
10680
- return /* @__PURE__ */ jsx(
10892
+ const docked = /* @__PURE__ */ jsx(
10681
10893
  DockedColumn,
10682
10894
  {
10683
10895
  open,
@@ -10696,6 +10908,9 @@ function AsidePanel({
10696
10908
  children
10697
10909
  }
10698
10910
  );
10911
+ if (!shell || inSlot) return docked;
10912
+ const host = shell.asideHosts[side];
10913
+ return host ? createPortal(docked, host) : null;
10699
10914
  }
10700
10915
  function DockedColumn({ open, onClose, side, width, floating, navbarFloating, sidebarFloating, keepMounted, resizable, maxWidth, labelledBy, id, children, className }) {
10701
10916
  const asideRef = useRef(null);
@@ -10760,7 +10975,7 @@ function DockedColumn({ open, onClose, side, width, floating, navbarFloating, si
10760
10975
  ),
10761
10976
  style: { width: currentWidth },
10762
10977
  children: [
10763
- children,
10978
+ /* @__PURE__ */ jsx(OverlayCloseCtx, { value: null, children }),
10764
10979
  resizable && open && /* @__PURE__ */ jsx(
10765
10980
  ResizeEdge,
10766
10981
  {
@@ -10795,9 +11010,12 @@ var StackedList = forwardRef(function StackedList2({
10795
11010
  pager
10796
11011
  }, ref) {
10797
11012
  useScrollsInside();
11013
+ useRunsEdgeToEdge();
10798
11014
  const isPhone = useBreakpoint("sm");
10799
11015
  const inCard = useContext(CardSurfaceCtx);
10800
- const inPane = !!useContext(SplitPaneCtx);
11016
+ const pane = useContext(SplitPaneCtx);
11017
+ const panePadded = useContext(PanePaddedCtx);
11018
+ const inPane = !!pane && !panePadded;
10801
11019
  const articles = variant === "articles";
10802
11020
  useWholeListCheck("StackedList", items.length, pager);
10803
11021
  const shown = pagerPart(items, pager);
@@ -12056,6 +12274,7 @@ function Gantt({
12056
12274
  className
12057
12275
  }) {
12058
12276
  useScrollsInside();
12277
+ useRunsEdgeToEdge();
12059
12278
  const [zoomState, setZoomState] = useState(defaultZoom);
12060
12279
  const zoom = zoomProp ?? zoomState;
12061
12280
  const changeZoom = (next) => {
@@ -13362,7 +13581,8 @@ function ScrollArea({
13362
13581
  orientation = "vertical",
13363
13582
  maxHeight,
13364
13583
  maxWidth,
13365
- "aria-label": ariaLabel = "Scrollable content"
13584
+ "aria-label": ariaLabel = "Scrollable content",
13585
+ flush = false
13366
13586
  }) {
13367
13587
  const viewportRef = useRef(null);
13368
13588
  const [viewport, setViewport] = useState(null);
@@ -13463,6 +13683,8 @@ function ScrollArea({
13463
13683
  className: cn(
13464
13684
  // the frame's corners, so the inset ring follows them rather than being cut by them (as the Table's region)
13465
13685
  "h-full w-full scroll-p-[4px] rounded-[inherit]",
13686
+ // room for an outline at its edges (FOCUS_ROOM), unless the content insets itself
13687
+ !flush && "p-[4px]",
13466
13688
  FOCUS_INSET,
13467
13689
  orientation === "vertical" && "overflow-y-auto overflow-x-hidden",
13468
13690
  orientation === "horizontal" && "overflow-x-auto overflow-y-hidden",
@@ -13612,7 +13834,7 @@ var Sidebar = forwardRef(function Sidebar2({
13612
13834
  children: header
13613
13835
  }
13614
13836
  ),
13615
- /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", children }),
13837
+ /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", flush: true, children }),
13616
13838
  showCollapse && (() => {
13617
13839
  const isSm = navSize === "sm";
13618
13840
  const collapseButton = /* @__PURE__ */ jsxs(
@@ -14520,6 +14742,16 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
14520
14742
  clearTimers.current.add(timer);
14521
14743
  }, 0);
14522
14744
  }, []);
14745
+ const barRooms = useRef(/* @__PURE__ */ new Map());
14746
+ const [barRoom, setBarRoom] = useState(0);
14747
+ const bulkBar = useMemo(() => ({
14748
+ room: (bar, room) => {
14749
+ if (room > 0) barRooms.current.set(bar, room);
14750
+ else barRooms.current.delete(bar);
14751
+ setBarRoom(Math.max(0, ...barRooms.current.values()));
14752
+ },
14753
+ say: (text) => announce({ id: "bulk-bar", message: text, variant: "default", duration: 0, shown: false, version: 0 })
14754
+ }), [announce]);
14523
14755
  useEffect(() => () => {
14524
14756
  if (heardTimer.current) clearTimeout(heardTimer.current);
14525
14757
  heardTimer.current = void 0;
@@ -14707,8 +14939,10 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
14707
14939
  const waiting = list2.length - shown.length;
14708
14940
  const isTop = position.startsWith("top");
14709
14941
  const hasBottomNav = isMobile && bottomNavs > 0;
14942
+ const navFoot = "var(--ds-space-12) + var(--ds-space-2) + env(safe-area-inset-bottom)";
14943
+ const stackBottom = barRoom > 0 && (isMobile || !isTop) ? hasBottomNav ? `calc(${navFoot} + ${barRoom}px)` : isMobile ? `calc(env(safe-area-inset-bottom) + ${barRoom}px)` : `max(var(${TOAST_INSET_VARS[position]}), calc(env(safe-area-inset-bottom) + ${barRoom}px))` : hasBottomNav ? `calc(${navFoot} + var(--ds-space-4))` : void 0;
14710
14944
  return /* @__PURE__ */ jsx(ToastContext.Provider, { value: api, children: /* @__PURE__ */ jsxs(ToastLedgerCtx.Provider, { value: ledger, children: [
14711
- /* @__PURE__ */ jsx(BottomNavPresenceCtx.Provider, { value: registerBottomNav, children }),
14945
+ /* @__PURE__ */ jsx(BottomNavPresenceCtx.Provider, { value: registerBottomNav, children: /* @__PURE__ */ jsx(BulkBarPresenceCtx, { value: bulkBar, children }) }),
14712
14946
  /* @__PURE__ */ jsx("div", { className: "sr-only", "aria-live": "polite", "data-toast-announcer": "polite", children: heard.filter((h) => !h.assertive).map((h) => /* @__PURE__ */ jsx("p", { children: h.text }, h.id)) }),
14713
14947
  /* @__PURE__ */ jsx("div", { className: "sr-only", "aria-live": "assertive", "data-toast-announcer": "assertive", children: heard.filter((h) => h.assertive).map((h) => /* @__PURE__ */ jsx("p", { children: h.text }, h.id)) }),
14714
14948
  shown.length > 0 && createPortal(
@@ -14740,7 +14974,7 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
14740
14974
  isTop ? "flex-col" : "flex-col-reverse",
14741
14975
  isMobile ? cn("left-ds-4 right-ds-4", !hasBottomNav && "bottom-ds-4") : TOAST_POSITION_CLASSES[position]
14742
14976
  ),
14743
- style: hasBottomNav ? { bottom: "calc(var(--ds-space-12) + var(--ds-space-2) + var(--ds-space-4) + env(safe-area-inset-bottom))" } : void 0,
14977
+ style: stackBottom ? { bottom: stackBottom } : void 0,
14744
14978
  children: [
14745
14979
  shown.map((t) => /* @__PURE__ */ jsx("div", { "data-toast-id": t.id, className: "pointer-events-auto", children: /* @__PURE__ */ jsx(
14746
14980
  Toast,
@@ -15186,6 +15420,7 @@ var PageContainer = forwardRef(function PageContainer2({
15186
15420
  {
15187
15421
  ref: setRoot,
15188
15422
  "data-page-container": wrappedHeader ? "" : void 0,
15423
+ "data-page-column": "",
15189
15424
  "data-width": dataWidth,
15190
15425
  className: cn(
15191
15426
  "w-full",
@@ -15217,7 +15452,7 @@ var PageContainer = forwardRef(function PageContainer2({
15217
15452
  ...floatingHeader ? { paddingRight: "var(--ds-space-3)", paddingLeft: r.sidebarFloating ? 0 : "var(--ds-space-3)" } : {},
15218
15453
  ...overlapActive ? { marginTop: "calc(-1 * var(--ds-overlap, 0px))", position: "relative", zIndex: 1 } : {}
15219
15454
  } : void 0;
15220
- 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) }) });
15455
+ 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, "data-page-column": "", className: cn(columnClass(contentPadding), bottomPaddingClasses[vPad], className), style: { ...columnStyle, ...launcherPadding }, children: capped(rest) }) });
15221
15456
  return /* @__PURE__ */ jsx(PageActionsCtx, { value: pageActions, children: /* @__PURE__ */ jsxs("div", { ref: setRoot, "data-page-container": "", "data-width": dataWidth, className: "w-full", children: [
15222
15457
  placement === "block" ? /* @__PURE__ */ jsx("div", { style: floatingBlockPadding(r.navbarFloating, r.sidebarFloating, overlapActive), children: /* @__PURE__ */ jsxs("div", { className: FLOATING_BLOCK, children: [
15223
15458
  strip,
@@ -15380,6 +15615,16 @@ var FLOATING_HEADER = cn(
15380
15615
  "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
15381
15616
  GLASS_SURFACE
15382
15617
  );
15618
+ var HEAD_LINE = "flex flex-col @sm:flex-row flex-wrap @sm:items-center justify-between gap-ds-4";
15619
+ var HEAD_LEAD = "flex items-center gap-ds-4 min-w-0 @sm:contents";
15620
+ var HEAD_BLOCK = "min-w-0 @sm:grow @sm:max-w-max @sm:me-auto @sm:basis-[calc(var(--ds-font-size-3xl)*4.5)]";
15621
+ var MINIMAL_LINE = "flex flex-wrap items-center justify-between gap-ds-4";
15622
+ var TITLE_GROUP = "flex flex-wrap items-center gap-x-ds-2 gap-y-ds-1 min-w-0";
15623
+ var FLOOR_XL = "basis-[calc(var(--ds-font-size-xl)*4.5)]";
15624
+ var MINIMAL_LEAD = cn(TITLE_GROUP, "grow max-w-max", FLOOR_XL);
15625
+ var TITLE_KEEPS = "min-w-0 grow max-w-max";
15626
+ var FLOOR_3XL = "basis-[calc(var(--ds-font-size-3xl)*4.5)]";
15627
+ var HEAD_ACTIONS = "flex flex-wrap items-center gap-ds-2";
15383
15628
  function computeFloatingPadding(navbarFloating, sidebarFloating, overlapActive, asideFloatingSide) {
15384
15629
  return {
15385
15630
  paddingTop: navbarFloating ? 0 : "var(--ds-space-3)",
@@ -15445,7 +15690,7 @@ var PageHeader = forwardRef(function PageHeader2({
15445
15690
  }, { isHome: shell?.isHome ?? false, isMobile: shell?.isMobile ?? false, navbarFloating: shell?.navbarFloating ?? false, sidebarFloating: shell?.sidebarFloating ?? false });
15446
15691
  const { variant, behavior, position, intensity, navbarFloating, sidebarFloating } = r;
15447
15692
  const isFloating = position === "floating";
15448
- const asideFloatingSide = shell?.asideOpen && shell.asideFloating ? shell.asideSide : null;
15693
+ const asideFloatingSide = shell?.asideFloatingSide ?? null;
15449
15694
  const bcPill = r.breadcrumbStyle === "pill";
15450
15695
  const bcSep = r.breadcrumbSeparator;
15451
15696
  const contentMaxWidth = contentMaxWidthProp ?? container?.contentMaxWidth;
@@ -15648,23 +15893,20 @@ function DefaultHeader({
15648
15893
  /* @__PURE__ */ jsxs("div", { className: inner.className, style: inner.style, children: [
15649
15894
  focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
15650
15895
  hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
15651
- /* @__PURE__ */ jsxs("div", { className: cn(
15652
- "flex flex-col @sm:flex-row @sm:items-center justify-between gap-ds-4",
15653
- hasBreadcrumbs && "mt-ds-1"
15654
- ), children: [
15655
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 min-w-0", children: [
15896
+ /* @__PURE__ */ jsxs("div", { className: cn(HEAD_LINE, hasBreadcrumbs && "mt-ds-1"), children: [
15897
+ /* @__PURE__ */ jsxs("div", { className: HEAD_LEAD, children: [
15656
15898
  onBack && /* @__PURE__ */ jsx(BackButton, { onClick: onBack }),
15657
15899
  avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: avatar }),
15658
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
15900
+ /* @__PURE__ */ jsxs("div", { className: HEAD_BLOCK, children: [
15659
15901
  caption && /* @__PURE__ */ jsx(Caption, { children: caption }),
15660
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
15661
- /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: "font-[family-name:var(--ds-font-display)] text-3xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: title }),
15902
+ /* @__PURE__ */ jsxs("div", { className: TITLE_GROUP, children: [
15903
+ /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: cn(TITLE_KEEPS, FLOOR_3XL, "font-[family-name:var(--ds-font-display)] text-3xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]"), children: title }),
15662
15904
  badge
15663
15905
  ] }),
15664
15906
  description && /* @__PURE__ */ jsx(ClampedText, { className: "mt-ds-1 text-sm text-[var(--ds-text-secondary)]", children: description })
15665
15907
  ] })
15666
15908
  ] }),
15667
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
15909
+ actions && /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions })
15668
15910
  ] }),
15669
15911
  filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-4", children: filters }),
15670
15912
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-4 -mx-ds-1", children: tabs })
@@ -15695,12 +15937,12 @@ function MinimalHeader({
15695
15937
  focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
15696
15938
  hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
15697
15939
  caption && /* @__PURE__ */ jsx(Caption, { children: caption }),
15698
- /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-ds-4", hasBreadcrumbs && "mt-ds-0.5"), children: [
15699
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2 min-w-0", children: [
15700
- /* @__PURE__ */ jsx(TruncHeading, { as: Heading, lines: 1, className: "font-[family-name:var(--ds-font-display)] text-xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: title }),
15940
+ /* @__PURE__ */ jsxs("div", { className: cn(MINIMAL_LINE, hasBreadcrumbs && "mt-ds-0.5"), children: [
15941
+ /* @__PURE__ */ jsxs("div", { className: MINIMAL_LEAD, children: [
15942
+ /* @__PURE__ */ jsx(TruncHeading, { as: Heading, lines: 1, className: cn(TITLE_KEEPS, FLOOR_XL, "font-[family-name:var(--ds-font-display)] text-xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]"), children: title }),
15701
15943
  badge
15702
15944
  ] }),
15703
- actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
15945
+ actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions }) })
15704
15946
  ] }),
15705
15947
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-3 -mx-ds-1", children: tabs })
15706
15948
  ] }) });
@@ -15785,17 +16027,16 @@ function ColourfulHeader({
15785
16027
  children: [
15786
16028
  focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack, onLight: isBold }),
15787
16029
  hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, onLight: isBold, onTint: !isBold, pill: breadcrumbPill, separator: breadcrumbSeparator }),
15788
- /* @__PURE__ */ jsxs("div", { className: cn(
15789
- "flex flex-col @sm:flex-row @sm:items-center justify-between gap-ds-4",
15790
- hasBreadcrumbs && "mt-ds-1"
15791
- ), children: [
15792
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 min-w-0", children: [
16030
+ /* @__PURE__ */ jsxs("div", { className: cn(HEAD_LINE, hasBreadcrumbs && "mt-ds-1"), children: [
16031
+ /* @__PURE__ */ jsxs("div", { className: HEAD_LEAD, children: [
15793
16032
  onBack && /* @__PURE__ */ jsx(BackButton, { onClick: onBack, onLight: isBold }),
15794
16033
  avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: avatar }),
15795
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
16034
+ /* @__PURE__ */ jsxs("div", { className: HEAD_BLOCK, children: [
15796
16035
  caption && /* @__PURE__ */ jsx(Caption, { onLight: isBold, onTint: !isBold, children: caption }),
15797
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
16036
+ /* @__PURE__ */ jsxs("div", { className: TITLE_GROUP, children: [
15798
16037
  /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: cn(
16038
+ TITLE_KEEPS,
16039
+ FLOOR_3XL,
15799
16040
  "font-[family-name:var(--ds-font-display)] text-3xl font-[var(--ds-weight-heading)]",
15800
16041
  isBold ? "text-[var(--ds-text-on-primary)]" : "text-[var(--ds-text-primary)]"
15801
16042
  ), children: title }),
@@ -15807,7 +16048,7 @@ function ColourfulHeader({
15807
16048
  ), children: description })
15808
16049
  ] })
15809
16050
  ] }),
15810
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
16051
+ actions && /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions })
15811
16052
  ] }),
15812
16053
  filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-4", onBand: isBold, children: filters }),
15813
16054
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-4 -mx-ds-1", onBand: isBold, children: tabs })
@@ -16007,12 +16248,12 @@ function SnappingHeader({
16007
16248
  focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
16008
16249
  hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
16009
16250
  caption && /* @__PURE__ */ jsx(Caption, { children: caption }),
16010
- /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-ds-4", hasBreadcrumbs && !hideExpandedBreadcrumbs && "mt-ds-0.5"), children: [
16011
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2 min-w-0", children: [
16012
- /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: "font-[family-name:var(--ds-font-display)] text-xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: title }),
16251
+ /* @__PURE__ */ jsxs("div", { className: cn(MINIMAL_LINE, hasBreadcrumbs && !hideExpandedBreadcrumbs && "mt-ds-0.5"), children: [
16252
+ /* @__PURE__ */ jsxs("div", { className: MINIMAL_LEAD, children: [
16253
+ /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: cn(TITLE_KEEPS, FLOOR_XL, "font-[family-name:var(--ds-font-display)] text-xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]"), children: title }),
16013
16254
  badge
16014
16255
  ] }),
16015
- actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
16256
+ actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions }) })
16016
16257
  ] }),
16017
16258
  filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-3", children: filters }),
16018
16259
  expandedContent && /* @__PURE__ */ jsx("div", { className: "mt-ds-3", children: expandedContent }),
@@ -16035,40 +16276,41 @@ function SnappingHeader({
16035
16276
  !collapsed && focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack, onLight }),
16036
16277
  !collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, onLight, onTint, pill: breadcrumbPill, separator: breadcrumbSeparator }),
16037
16278
  /* @__PURE__ */ jsxs("div", { className: cn(
16038
- "flex justify-between gap-ds-4",
16039
- collapsed ? "items-center" : "flex-col @sm:flex-row @sm:items-center",
16040
- !collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && "mt-ds-1",
16041
- collapsed && "w-full"
16279
+ collapsed ? cn(MINIMAL_LINE, "w-full") : HEAD_LINE,
16280
+ !collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && "mt-ds-1"
16042
16281
  ), children: [
16043
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 min-w-0", children: [
16282
+ /* @__PURE__ */ jsxs("div", { className: collapsed ? "contents" : HEAD_LEAD, children: [
16044
16283
  onBack && !collapsed && /* @__PURE__ */ jsx(BackButton, { onClick: onBack, onLight }),
16045
16284
  avatar && !collapsed && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: avatar }),
16046
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
16285
+ collapsed && hasBreadcrumbs && (() => {
16286
+ const lastCrumb = breadcrumbs[breadcrumbs.length - 1];
16287
+ const isClickable = !!lastCrumb && crumbGoes(lastCrumb);
16288
+ const Tag3 = isClickable ? "a" : "span";
16289
+ return /* @__PURE__ */ jsxs(
16290
+ Tag3,
16291
+ {
16292
+ ...isClickable ? {
16293
+ href: lastCrumb.href ?? "#",
16294
+ onClick: (e) => followCrumb(e, lastCrumb)
16295
+ } : {},
16296
+ className: cn(
16297
+ // the title's group's gap from it, not the line's
16298
+ "text-sm hidden @sm:inline-flex items-center gap-ds-1 -me-ds-2",
16299
+ isClickable ? cn("text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] transition-colors duration-[var(--ds-transition-speed)] cursor-pointer", FOCUS_RING) : "text-[var(--ds-text-secondary)]"
16300
+ ),
16301
+ children: [
16302
+ lastCrumb?.label,
16303
+ breadcrumbSeparator === "slash" ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "/" }) : breadcrumbSeparator === "dot" ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\xB7" }) : breadcrumbSeparator === "arrow" ? /* @__PURE__ */ jsx(Icon, { name: "arrow-right", size: 12 }) : /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 12 })
16304
+ ]
16305
+ }
16306
+ );
16307
+ })(),
16308
+ /* @__PURE__ */ jsxs("div", { className: collapsed ? cn("min-w-0 grow max-w-max me-auto", TITLE_FLOOR) : HEAD_BLOCK, children: [
16047
16309
  !collapsed && caption && /* @__PURE__ */ jsx(Caption, { onLight, onTint, children: caption }),
16048
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
16049
- collapsed && hasBreadcrumbs && (() => {
16050
- const lastCrumb = breadcrumbs[breadcrumbs.length - 1];
16051
- const isClickable = !!lastCrumb && crumbGoes(lastCrumb);
16052
- const Tag3 = isClickable ? "a" : "span";
16053
- return /* @__PURE__ */ jsxs(
16054
- Tag3,
16055
- {
16056
- ...isClickable ? {
16057
- href: lastCrumb.href ?? "#",
16058
- onClick: (e) => followCrumb(e, lastCrumb)
16059
- } : {},
16060
- className: cn(
16061
- "text-sm hidden @sm:inline-flex items-center gap-ds-1",
16062
- isClickable ? cn("text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] transition-colors duration-[var(--ds-transition-speed)] cursor-pointer", FOCUS_RING) : "text-[var(--ds-text-secondary)]"
16063
- ),
16064
- children: [
16065
- lastCrumb?.label,
16066
- breadcrumbSeparator === "slash" ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "/" }) : breadcrumbSeparator === "dot" ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\xB7" }) : breadcrumbSeparator === "arrow" ? /* @__PURE__ */ jsx(Icon, { name: "arrow-right", size: 12 }) : /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 12 })
16067
- ]
16068
- }
16069
- );
16070
- })(),
16310
+ /* @__PURE__ */ jsxs("div", { className: TITLE_GROUP, children: [
16071
16311
  /* @__PURE__ */ jsx(TruncHeading, { as: Heading, lines: collapsed ? 1 : void 0, className: cn(
16312
+ TITLE_KEEPS,
16313
+ collapsed ? TITLE_FLOOR : FLOOR_3XL,
16072
16314
  "font-[family-name:var(--ds-font-display)] font-[var(--ds-weight-heading)]",
16073
16315
  collapsed ? "text-lg text-[var(--ds-text-primary)]" : cn("text-3xl", onLight ? "text-[var(--ds-text-on-primary)]" : "text-[var(--ds-text-primary)]")
16074
16316
  ), children: title }),
@@ -16080,7 +16322,7 @@ function SnappingHeader({
16080
16322
  ), children: description })
16081
16323
  ] })
16082
16324
  ] }),
16083
- actions && (collapsed ? /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) }) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }))
16325
+ actions && (collapsed ? /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions }) }) : /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions }))
16084
16326
  ] }),
16085
16327
  !collapsed && filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-4", onBand: isBoldColourful, children: filters }),
16086
16328
  !collapsed && expandedContent && /* @__PURE__ */ jsx("div", { className: "mt-ds-4", children: expandedContent }),
@@ -16153,23 +16395,20 @@ function TabsIntegratedHeader({
16153
16395
  return /* @__PURE__ */ jsx("header", { "data-gs": "page-header", ref: headerRef, className: cn(hasBreadcrumbs ? "pt-ds-3" : "pt-ds-6", "pb-ds-6", isFloating && cn(FLOATING_HEADER, "overflow-hidden"), className), children: /* @__PURE__ */ jsxs("div", { className: inner.className, style: inner.style, children: [
16154
16396
  focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack }),
16155
16397
  hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs2, { items: breadcrumbs, pill: breadcrumbPill, separator: breadcrumbSeparator }),
16156
- /* @__PURE__ */ jsxs("div", { className: cn(
16157
- "flex flex-col @sm:flex-row @sm:items-center justify-between gap-ds-4",
16158
- hasBreadcrumbs && "mt-ds-1"
16159
- ), children: [
16160
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 min-w-0", children: [
16398
+ /* @__PURE__ */ jsxs("div", { className: cn(HEAD_LINE, hasBreadcrumbs && "mt-ds-1"), children: [
16399
+ /* @__PURE__ */ jsxs("div", { className: HEAD_LEAD, children: [
16161
16400
  onBack && /* @__PURE__ */ jsx(BackButton, { onClick: onBack }),
16162
16401
  avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: avatar }),
16163
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
16402
+ /* @__PURE__ */ jsxs("div", { className: HEAD_BLOCK, children: [
16164
16403
  caption && /* @__PURE__ */ jsx(Caption, { children: caption }),
16165
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
16166
- /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: "font-[family-name:var(--ds-font-display)] text-3xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: title }),
16404
+ /* @__PURE__ */ jsxs("div", { className: TITLE_GROUP, children: [
16405
+ /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: cn(TITLE_KEEPS, FLOOR_3XL, "font-[family-name:var(--ds-font-display)] text-3xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]"), children: title }),
16167
16406
  badge
16168
16407
  ] }),
16169
16408
  description && /* @__PURE__ */ jsx(ClampedText, { className: "mt-ds-1 text-sm text-[var(--ds-text-secondary)]", children: description })
16170
16409
  ] })
16171
16410
  ] }),
16172
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
16411
+ actions && /* @__PURE__ */ jsx("div", { className: HEAD_ACTIONS, children: actions })
16173
16412
  ] }),
16174
16413
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-4 -mx-ds-1", children: tabs })
16175
16414
  ] }) });
@@ -18304,7 +18543,10 @@ var SectionHeading = forwardRef(function SectionHeading2({
18304
18543
  }, ref) {
18305
18544
  const isPhone = useBreakpoint("sm");
18306
18545
  const pane = variant === "pane";
18307
- const inDetail = useContext(SplitPaneCtx) === "detail";
18546
+ const paneKind = useContext(SplitPaneCtx);
18547
+ const inDetail = paneKind === "detail";
18548
+ const panePadded = useContext(PanePaddedCtx);
18549
+ const cancel = pane && panePadded && (paneKind === "list" || paneKind === "detail") ? PANE_HEADING_CANCEL[paneKind] : void 0;
18308
18550
  const editable = !!onTitleChange;
18309
18551
  return /* @__PURE__ */ jsxs(
18310
18552
  "div",
@@ -18313,7 +18555,7 @@ var SectionHeading = forwardRef(function SectionHeading2({
18313
18555
  "data-gs": "section-heading",
18314
18556
  "data-variant": variant,
18315
18557
  className: cn(
18316
- 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)]",
18558
+ 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", cancel) : "mb-[var(--ds-heading-gap)]",
18317
18559
  !pane && bordered && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] pb-ds-4",
18318
18560
  className
18319
18561
  ),
@@ -18411,7 +18653,50 @@ function DangerZone({ title = "Danger zone", description, children, className })
18411
18653
  )
18412
18654
  ] });
18413
18655
  }
18656
+ var byte = (n) => n.toString(16).padStart(2, "0");
18657
+ function readColours(el, names) {
18658
+ const doc = el.ownerDocument;
18659
+ const style = getComputedStyle(el);
18660
+ const probe = el.appendChild(doc.createElement("span"));
18661
+ const ctx = doc.createElement("canvas").getContext("2d", { willReadFrequently: true });
18662
+ const out = {};
18663
+ for (const name of names) {
18664
+ const raw = style.getPropertyValue(name).trim();
18665
+ if (!ctx || !raw || !CSS.supports("color", raw)) {
18666
+ out[name] = "#00000000";
18667
+ continue;
18668
+ }
18669
+ probe.style.color = `var(${name})`;
18670
+ const computed = getComputedStyle(probe).color;
18671
+ const see = /^rgba|\s\//.test(computed) ? /[,/]\s*([\d.]+)(%?)\s*\)$/.exec(computed) : null;
18672
+ const alpha = see ? +see[1] / (see[2] ? 100 : 1) : 1;
18673
+ ctx.clearRect(0, 0, 1, 1);
18674
+ ctx.fillStyle = see ? `${computed.slice(0, see.index)})` : computed;
18675
+ ctx.fillRect(0, 0, 1, 1);
18676
+ const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data;
18677
+ out[name] = `#${byte(r)}${byte(g)}${byte(b)}${alpha < 1 ? byte(Math.round(alpha * 255)) : ""}`;
18678
+ }
18679
+ probe.remove();
18680
+ return out;
18681
+ }
18682
+ function useThemeColors(ref, names) {
18683
+ const key = names.join(" ");
18684
+ const [colours, setColours] = useState(null);
18685
+ useLayoutEffect(() => {
18686
+ const el = ref.current;
18687
+ if (!el || !key || typeof CSS === "undefined") return;
18688
+ const read = () => {
18689
+ const next = readColours(el, key.split(" "));
18690
+ setColours((was) => JSON.stringify(was) === JSON.stringify(next) ? was : next);
18691
+ };
18692
+ read();
18693
+ const watch = new MutationObserver(read);
18694
+ watch.observe(el.ownerDocument.documentElement, { attributes: true, attributeFilter: ["data-mode"], subtree: true });
18695
+ return () => watch.disconnect();
18696
+ }, [ref, key]);
18697
+ return colours;
18698
+ }
18414
18699
 
18415
- export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, AvatarGroup, BottomNav, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DangerZone, DataList, DateRangePicker, DescriptionList, Dialog, Dock, EmptyState, EntityCell, FileUpload, FlowSaved, FormWrapper, Gantt, Kbd, Launcher, LocaleProvider, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, PageActions, PageContainer, PageHeader, PinInput, Progress, RadioGroup, Rating, RecurrencePicker, RecurrenceScopeDialog, RelativeTime, ScrollArea, SectionHeading, SettingsLayout, Sheet, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TagInput, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, TimezoneSelect, Toast, ToastProvider, Tour, TransferList, TreeView, browserTimeZone, canonicalTimeZone, countEdited, dateOfDay, dayOf, deleteOccurrence, describeRecurrence, endDayOf, fitLabel, fitLabels, formatDateRange, nthOf, occurrenceOn, occurrences, parseRRule, readFlowProgress, readRecurrence, recurrencePresets, sameRecurrence, saveOccurrence, timeExtent, timeZoneOffset, toRRule, useBrowserTimeZone, useContentWidth, useDestructiveAction, useFittedLabels, useFlowSteps, useRelativeTimeFormat, useSidebar, useTextMeasure, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
18700
+ export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, AvatarGroup, BottomNav, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DangerZone, DataList, DateRangePicker, DescriptionList, Dialog, Dock, EmptyState, EntityCell, FileUpload, FlowSaved, FormWrapper, Gantt, Kbd, Launcher, LocaleProvider, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, PageActions, PageContainer, PageHeader, PinInput, Progress, RadioGroup, Rating, RecurrencePicker, RecurrenceScopeDialog, RelativeTime, ScrollArea, SectionHeading, SettingsLayout, Sheet, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TagInput, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, TimezoneSelect, Toast, ToastProvider, Tour, TransferList, TreeView, browserTimeZone, canonicalTimeZone, countEdited, dateOfDay, dayOf, deleteOccurrence, describeRecurrence, endDayOf, fitLabel, fitLabels, formatDateRange, nthOf, occurrenceOn, occurrences, parseRRule, readFlowProgress, readRecurrence, recurrencePresets, sameRecurrence, saveOccurrence, timeExtent, timeZoneOffset, toRRule, useBrowserTimeZone, useContentWidth, useDestructiveAction, useFittedLabels, useFlowSteps, useRelativeTimeFormat, useSidebar, useTextMeasure, useThemeColors, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
18416
18701
  //# sourceMappingURL=index.js.map
18417
18702
  //# sourceMappingURL=index.js.map