gridsmith-ui 0.31.1 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -1
- package/dist/charts.d.ts +101 -30
- package/dist/charts.js +180 -105
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +6 -6
- package/dist/{chunk-EZ3ZGFGA.js → chunk-2724SJO2.js} +12 -4
- package/dist/chunk-2724SJO2.js.map +1 -0
- package/dist/{chunk-IZW5XHKA.js → chunk-DO6DLTFK.js} +10 -8
- package/dist/chunk-DO6DLTFK.js.map +1 -0
- package/dist/{chunk-KSJTMSYA.js → chunk-H732QL56.js} +4 -4
- package/dist/{chunk-KSJTMSYA.js.map → chunk-H732QL56.js.map} +1 -1
- package/dist/{chunk-DR6WEI3A.js → chunk-HCEHTJ5E.js} +3 -3
- package/dist/{chunk-DR6WEI3A.js.map → chunk-HCEHTJ5E.js.map} +1 -1
- package/dist/{chunk-2TCCSKL3.js → chunk-HUVZQOU4.js} +5 -5
- package/dist/{chunk-2TCCSKL3.js.map → chunk-HUVZQOU4.js.map} +1 -1
- package/dist/{chunk-TH272DIC.js → chunk-JHZ22HQP.js} +75 -24
- package/dist/chunk-JHZ22HQP.js.map +1 -0
- package/dist/{chunk-I6JJ7KKP.js → chunk-NGZJK57C.js} +14 -10
- package/dist/chunk-NGZJK57C.js.map +1 -0
- package/dist/{chunk-BHTAVJIG.js → chunk-OVHM55JF.js} +5 -5
- package/dist/{chunk-BHTAVJIG.js.map → chunk-OVHM55JF.js.map} +1 -1
- package/dist/{chunk-NDL2JGQ7.js → chunk-QY2RA2HO.js} +5 -5
- package/dist/{chunk-NDL2JGQ7.js.map → chunk-QY2RA2HO.js.map} +1 -1
- package/dist/{chunk-W3GY5ROH.js → chunk-R2IAK3J3.js} +3 -3
- package/dist/{chunk-W3GY5ROH.js.map → chunk-R2IAK3J3.js.map} +1 -1
- package/dist/{chunk-V73LHNRL.js → chunk-RS624TD5.js} +29 -10
- package/dist/chunk-RS624TD5.js.map +1 -0
- package/dist/{chunk-IOHGE4EW.js → chunk-SIEU4H3H.js} +8 -8
- package/dist/chunk-SIEU4H3H.js.map +1 -0
- package/dist/{chunk-DBHVJ7Z3.js → chunk-SS3C24IJ.js} +3 -2
- package/dist/chunk-SS3C24IJ.js.map +1 -0
- package/dist/{chunk-K3NAFQ4S.js → chunk-TMPPBXX3.js} +3 -3
- package/dist/{chunk-K3NAFQ4S.js.map → chunk-TMPPBXX3.js.map} +1 -1
- package/dist/{chunk-SLGGZ3MU.js → chunk-WSKPESAX.js} +12 -10
- package/dist/chunk-WSKPESAX.js.map +1 -0
- package/dist/{chunk-HQFTP7Y5.js → chunk-XBVZIN26.js} +4 -4
- package/dist/{chunk-HQFTP7Y5.js.map → chunk-XBVZIN26.js.map} +1 -1
- package/dist/data-grid.js +9 -9
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +2 -2
- package/dist/editor.js +3 -2
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +44 -6
- package/dist/index.js +436 -213
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +9 -9
- package/dist/resizable.d.ts +11 -2
- package/dist/resizable.js +96 -22
- package/dist/resizable.js.map +1 -1
- package/dist/roots.css +2 -2
- package/dist/tokens.css +6 -6
- package/dist/virtualized.js +9 -8
- package/dist/virtualized.js.map +1 -1
- package/dist-static/tokens.css +6 -6
- package/package.json +1 -1
- package/dist/chunk-DBHVJ7Z3.js.map +0 -1
- package/dist/chunk-EZ3ZGFGA.js.map +0 -1
- package/dist/chunk-I6JJ7KKP.js.map +0 -1
- package/dist/chunk-IOHGE4EW.js.map +0 -1
- package/dist/chunk-IZW5XHKA.js.map +0 -1
- package/dist/chunk-SLGGZ3MU.js.map +0 -1
- package/dist/chunk-TH272DIC.js.map +0 -1
- package/dist/chunk-V73LHNRL.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,71 +1,216 @@
|
|
|
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-
|
|
3
|
-
export { AppShell, Breadcrumbs, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-
|
|
4
|
-
import { Skeleton, TITLE_TEXT, SegmentedControl } from './chunk-
|
|
5
|
-
export { SegmentedControl, Skeleton } from './chunk-
|
|
2
|
+
import { useAppShell, REACT_VERSION_PROBLEM, Breadcrumbs, useCrumbFollow, crumbGoes, useCornerInset, NAVBAR_INSET_PRIORITY, useOverlayMark, useDirtyGuard, useScrollbarInset, useBulkBarHost, DrawerFooterCtx, OverlayMarkScope, OverlayCloseCtx, BulkBarHostCtx, BulkBarSpacer, bulkBarRoom, insetLessScrollbar, BULK_BAR_LAYER, DiscardConfirm, OVERLAY_ROOT_ATTR, BulkBarPresenceCtx, BULK_BAR_WINDOW_LAYER, OverlayMarkCtx, useCompact, useElementWidth, DrawerPanel, useCloseSettle, besideRoom, PANEL_INSET_PRIORITY, Drawer, useRememberedWidth, pxOf, ResizeEdge, LAUNCHER_INSET_PRIORITY, TOAST_INSET_VARS, defaultMaxWidth } from './chunk-JHZ22HQP.js';
|
|
3
|
+
export { AppShell, Breadcrumbs, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-JHZ22HQP.js';
|
|
4
|
+
import { Skeleton, TITLE_TEXT, SegmentedControl } from './chunk-OVHM55JF.js';
|
|
5
|
+
export { SegmentedControl, Skeleton } from './chunk-OVHM55JF.js';
|
|
6
6
|
import { useScrollEdges, EDGE_FADE } from './chunk-3BRQRKDO.js';
|
|
7
|
-
import { Avatar, foldForSearch, useActiveOptionInView, shownMentions, matchMentions, mentionOptionId, MentionList, initialsOf } from './chunk-
|
|
8
|
-
export { Avatar } from './chunk-
|
|
9
|
-
import { Link } from './chunk-
|
|
10
|
-
export { CodeBlock, Divider, Link } from './chunk-
|
|
11
|
-
import { DropdownMenu } from './chunk-
|
|
12
|
-
export { DropdownMenu } from './chunk-
|
|
13
|
-
import { useFillHeight, FillContext } from './chunk-
|
|
14
|
-
import { Badge } from './chunk-
|
|
15
|
-
export { Badge } from './chunk-
|
|
16
|
-
import { useKeyboardScroll } from './chunk-
|
|
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-
|
|
18
|
-
export { Checkbox, CheckboxGroup, CheckboxGroupItem, DatePicker, HoverCard, TextOverflow } from './chunk-
|
|
19
|
-
import { useWholeListCheck, pagerPart, Pagination, NumberInput } from './chunk-
|
|
20
|
-
export { NumberInput, Pagination, Popover, usePagination } from './chunk-
|
|
7
|
+
import { Avatar, foldForSearch, useActiveOptionInView, shownMentions, matchMentions, mentionOptionId, MentionList, initialsOf } from './chunk-TMPPBXX3.js';
|
|
8
|
+
export { Avatar } from './chunk-TMPPBXX3.js';
|
|
9
|
+
import { Link } from './chunk-QY2RA2HO.js';
|
|
10
|
+
export { CodeBlock, Divider, Link } from './chunk-QY2RA2HO.js';
|
|
11
|
+
import { DropdownMenu } from './chunk-HUVZQOU4.js';
|
|
12
|
+
export { DropdownMenu } from './chunk-HUVZQOU4.js';
|
|
13
|
+
import { useFillHeight, FillContext } from './chunk-SS3C24IJ.js';
|
|
14
|
+
import { Badge } from './chunk-WSKPESAX.js';
|
|
15
|
+
export { Badge } from './chunk-WSKPESAX.js';
|
|
16
|
+
import { useKeyboardScroll } from './chunk-H732QL56.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-NGZJK57C.js';
|
|
18
|
+
export { Checkbox, CheckboxGroup, CheckboxGroupItem, DatePicker, HoverCard, TextOverflow } from './chunk-NGZJK57C.js';
|
|
19
|
+
import { useWholeListCheck, pagerPart, Pagination, NumberInput } from './chunk-SIEU4H3H.js';
|
|
20
|
+
export { NumberInput, Pagination, Popover, usePagination } from './chunk-SIEU4H3H.js';
|
|
21
21
|
import { useShellPreferences, PREFERENCE_HOUSE_DEFAULTS, formatRelativeTime, thresholdOf, toMillis, formatFullTime, datedMillis, preferenceActionKey, DAY, HOUR, MINUTE } from './chunk-QOMP4D6V.js';
|
|
22
22
|
export { PreferencesContext, formatFullTime, formatRelativeTime, preferenceActionKey, usePreferences } from './chunk-QOMP4D6V.js';
|
|
23
23
|
import { useFormatLocale, useHydrated, useToday, LocaleContext } from './chunk-LJYSVZMI.js';
|
|
24
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-
|
|
26
|
-
export { Dropdown, Field, InlineFieldError, Input, Label, Textarea, Toggle } from './chunk-
|
|
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-DO6DLTFK.js';
|
|
26
|
+
export { Dropdown, Field, InlineFieldError, Input, Label, Textarea, Toggle } from './chunk-DO6DLTFK.js';
|
|
27
27
|
import { formatLocale, localeChoice } from './chunk-7QLXYRPD.js';
|
|
28
28
|
import { FormChangeCtx, useReportedChange, useOptionalFormContext, FormCtx } from './chunk-72SDAX54.js';
|
|
29
29
|
export { useFormContext } from './chunk-72SDAX54.js';
|
|
30
|
-
import { CardSurfaceCtx, useScrollsInside, SplitPaneCtx, RowsCtx, PageActionsCtx, SurfaceBoundary, useFramesItself, TableCardCtx } from './chunk-
|
|
31
|
-
import { Button, elementType, ControlSizeContext, triggerType, Spinner } from './chunk-
|
|
32
|
-
export { Button, ButtonSizeContext, ControlSizeContext, Spinner } from './chunk-
|
|
30
|
+
import { CardSurfaceCtx, useScrollsInside, useRunsEdgeToEdge, SplitPaneCtx, PanePaddedCtx, RowsCtx, PageActionsCtx, PANE_HEADING_CANCEL, SurfaceBoundary, useFramesItself, TableCardCtx, useWantsInset } from './chunk-RS624TD5.js';
|
|
31
|
+
import { Button, elementType, ControlSizeContext, triggerType, Spinner } from './chunk-XBVZIN26.js';
|
|
32
|
+
export { Button, ButtonSizeContext, ControlSizeContext, Spinner } from './chunk-XBVZIN26.js';
|
|
33
33
|
import { useBreakpoint, readBreakpointPx } from './chunk-ZHUVLBCC.js';
|
|
34
34
|
export { BreakpointWidthProvider, useBreakpoint } from './chunk-ZHUVLBCC.js';
|
|
35
|
-
import {
|
|
35
|
+
import { inputModality, useInputModality } from './chunk-7RKC5C7G.js';
|
|
36
36
|
export { INPUT_MODALITY_ATTR, inputModality, installInputModality, useInputModality } from './chunk-7RKC5C7G.js';
|
|
37
|
-
import { useTextOverflow } from './chunk-
|
|
38
|
-
export { useTextOverflow } from './chunk-
|
|
39
|
-
import { AutoTooltip, mergeRefs, useRevealFocus } from './chunk-
|
|
40
|
-
export { Tooltip, useRevealFocus } from './chunk-
|
|
37
|
+
import { useTextOverflow } from './chunk-R2IAK3J3.js';
|
|
38
|
+
export { useTextOverflow } from './chunk-R2IAK3J3.js';
|
|
39
|
+
import { AutoTooltip, mergeRefs, useRevealFocus } from './chunk-HCEHTJ5E.js';
|
|
40
|
+
export { Tooltip, useRevealFocus } from './chunk-HCEHTJ5E.js';
|
|
41
41
|
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-
|
|
43
|
-
export { useGridKeyboard } from './chunk-
|
|
44
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
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, 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';
|
|
43
|
+
export { useGridKeyboard } from './chunk-2724SJO2.js';
|
|
45
44
|
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
45
|
import { createPortal, flushSync } from 'react-dom';
|
|
46
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
var selectionControlIn = (table) => table.querySelector("[data-ds-select-all] input") ?? table.querySelector("[data-ds-select-card] input");
|
|
49
|
+
function holdsSelection(table) {
|
|
50
|
+
const all = table.querySelector("[data-ds-select-all]");
|
|
51
|
+
return all ? all.getAttribute("data-selection") !== "none" : !!table.querySelector("[data-ds-select-card] input:checked");
|
|
52
|
+
}
|
|
53
|
+
var tablesIn = (box) => Array.from(box.querySelectorAll('[data-gs="table"]')).filter((t) => selectionControlIn(t));
|
|
54
|
+
function selectionAt(point) {
|
|
55
|
+
const from = point.startContainer;
|
|
56
|
+
for (let box = from instanceof HTMLElement ? from : from.parentElement; box && box !== document.body; box = box.parentElement) {
|
|
57
|
+
const tables = tablesIn(box);
|
|
58
|
+
if (!tables.length) continue;
|
|
59
|
+
const pick = (list2) => list2.filter((t) => point.comparePoint(t, 0) < 0).at(-1) ?? list2.find((t) => point.comparePoint(t, 0) > 0);
|
|
60
|
+
const table = pick(tables.filter(holdsSelection)) ?? pick(tables);
|
|
61
|
+
const control = table && selectionControlIn(table);
|
|
62
|
+
return control ? { box, control } : null;
|
|
52
63
|
}
|
|
53
64
|
return null;
|
|
54
65
|
}
|
|
66
|
+
function selectionIn(box, point) {
|
|
67
|
+
const tables = tablesIn(box);
|
|
68
|
+
const at = (t) => point ? point.comparePoint(t, 0) : 0;
|
|
69
|
+
const table = tables.filter((t) => at(t) < 0).at(-1) ?? tables.find((t) => at(t) > 0) ?? tables[0];
|
|
70
|
+
return table ? selectionControlIn(table) : null;
|
|
71
|
+
}
|
|
72
|
+
var CONTROL = "[data-bulk-bar-control]";
|
|
55
73
|
function BulkActionBar({ selectedCount, actions, onClearSelection, className }) {
|
|
56
|
-
const
|
|
57
|
-
|
|
74
|
+
const isPhone = useBreakpoint("sm");
|
|
75
|
+
const host = useContext(BulkBarHostCtx);
|
|
76
|
+
const presence = useContext(BulkBarPresenceCtx);
|
|
77
|
+
const [anchor, setAnchor] = useState(null);
|
|
78
|
+
const [bearing, setBearing] = useState(null);
|
|
79
|
+
const [bar, setBar] = useState(null);
|
|
80
|
+
const [stop, setStop] = useState(0);
|
|
81
|
+
const labels = actions.map((action) => action.label).join("\0");
|
|
82
|
+
const [fit, setFit] = useState(null);
|
|
83
|
+
const tooWide = !!fit && fit.labels === labels && fit.room > 0 && fit.full > fit.room;
|
|
84
|
+
const compact = isPhone || tooWide;
|
|
85
|
+
const shown = selectedCount > 0;
|
|
86
|
+
const target = host ? host.layer : typeof document === "undefined" ? null : document.body;
|
|
87
|
+
const selection = useRef({ control: null, box: null, page: "" });
|
|
88
|
+
const point = useRef(null);
|
|
89
|
+
const movedOn = useRef(true);
|
|
90
|
+
const quitWatch = useRef(null);
|
|
91
|
+
const watching = useRef(null);
|
|
92
|
+
const watch = (control) => {
|
|
93
|
+
quitWatch.current?.();
|
|
94
|
+
movedOn.current = false;
|
|
95
|
+
watching.current = control;
|
|
96
|
+
quitWatch.current = onMovingOn(control, () => {
|
|
97
|
+
movedOn.current = true;
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
useLayoutEffect(() => {
|
|
101
|
+
if (shown && !bearing && anchor?.isConnected) setBearing(pointOf(anchor));
|
|
102
|
+
else if (!shown && bearing) setBearing(null);
|
|
103
|
+
}, [shown, bearing, anchor]);
|
|
104
|
+
useLayoutEffect(() => {
|
|
105
|
+
if (!shown || !bearing) return;
|
|
106
|
+
point.current = bearing;
|
|
107
|
+
const found = selectionAt(bearing);
|
|
108
|
+
selection.current = { control: found?.control ?? null, box: found?.box ?? null, page: pageAddress() };
|
|
109
|
+
});
|
|
110
|
+
useEffect(() => () => quitWatch.current?.(), []);
|
|
111
|
+
const onToolbar = useCallback((el) => {
|
|
112
|
+
setBar(el);
|
|
113
|
+
const unregister = registerOpenerRoot(el, () => selection.current.control?.isConnected ? rememberFocus(selection.current.control) : null);
|
|
114
|
+
return () => {
|
|
115
|
+
unregister();
|
|
116
|
+
setBar(null);
|
|
117
|
+
const active = document.activeElement;
|
|
118
|
+
const moved = movedOn.current;
|
|
119
|
+
const watched = watching.current;
|
|
120
|
+
quitWatch.current?.();
|
|
121
|
+
quitWatch.current = null;
|
|
122
|
+
watching.current = null;
|
|
123
|
+
movedOn.current = true;
|
|
124
|
+
if (!(active instanceof HTMLElement) || !(el.contains(active) || active === watched) || moved || inputModality() === "pointer") return;
|
|
125
|
+
const { control, box, page } = selection.current;
|
|
126
|
+
const at = point.current;
|
|
127
|
+
if (pageAddress() !== page) return;
|
|
128
|
+
focusAfterSelfRemoval(active, {
|
|
129
|
+
group: null,
|
|
130
|
+
point: at ?? void 0,
|
|
131
|
+
to: () => control?.isConnected ? control : box?.isConnected ? selectionIn(box, at) : null,
|
|
132
|
+
samePage: true,
|
|
133
|
+
removedOnly: true
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
}, []);
|
|
137
|
+
useLayoutEffect(() => {
|
|
138
|
+
if (!bar) return;
|
|
139
|
+
const report = () => {
|
|
140
|
+
if (host) host.setRoom(bar, bar.offsetHeight);
|
|
141
|
+
else presence?.room(bar, bulkBarRoom(bar.offsetHeight));
|
|
142
|
+
};
|
|
143
|
+
report();
|
|
144
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(report);
|
|
145
|
+
observer?.observe(bar);
|
|
146
|
+
return () => {
|
|
147
|
+
observer?.disconnect();
|
|
148
|
+
if (host) host.setRoom(bar, 0);
|
|
149
|
+
else presence?.room(bar, 0);
|
|
150
|
+
};
|
|
151
|
+
}, [bar, host, presence]);
|
|
152
|
+
useLayoutEffect(() => {
|
|
153
|
+
const layer = bar?.parentElement;
|
|
154
|
+
if (!bar || !layer) return;
|
|
155
|
+
const measure = () => {
|
|
156
|
+
const style = getComputedStyle(layer);
|
|
157
|
+
const room = layer.clientWidth - (parseFloat(style.paddingLeft) || 0) - (parseFloat(style.paddingRight) || 0);
|
|
158
|
+
setFit((was) => {
|
|
159
|
+
const full = !compact || !was || was.labels !== labels ? bar.scrollWidth : was.full;
|
|
160
|
+
return was && was.labels === labels && was.full === full && was.room === room ? was : { labels, full, room };
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
measure();
|
|
164
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
165
|
+
const observer = new ResizeObserver(measure);
|
|
166
|
+
observer.observe(layer);
|
|
167
|
+
return () => observer.disconnect();
|
|
168
|
+
}, [bar, compact, labels]);
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
if (!bar || inputModality() !== "keyboard") return;
|
|
171
|
+
const frame = requestAnimationFrame(() => {
|
|
172
|
+
const active = document.activeElement;
|
|
173
|
+
if (!(active instanceof HTMLElement) || active === document.body || bar.contains(active)) return;
|
|
174
|
+
if (active.getBoundingClientRect().bottom > bar.getBoundingClientRect().top) active.scrollIntoView({ block: "nearest" });
|
|
175
|
+
});
|
|
176
|
+
return () => cancelAnimationFrame(frame);
|
|
177
|
+
}, [bar]);
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
if (shown) presence?.say(`${selectedCount} selected`);
|
|
180
|
+
}, [presence, shown, selectedCount]);
|
|
181
|
+
if (!shown) return null;
|
|
58
182
|
const dropdownItems = actions.map((action) => ({
|
|
59
183
|
label: action.label,
|
|
60
184
|
icon: action.icon,
|
|
61
185
|
onClick: action.onClick,
|
|
62
186
|
variant: action.variant
|
|
63
187
|
}));
|
|
64
|
-
|
|
188
|
+
const count = (compact ? Math.min(actions.length, 1) : actions.length) + 1;
|
|
189
|
+
const current = Math.min(stop, count - 1);
|
|
190
|
+
const controls = () => bar ? Array.from(bar.querySelectorAll(CONTROL)) : [];
|
|
191
|
+
const tab = (i) => ({ "data-bulk-bar-control": "", tabIndex: i === current ? 0 : -1 });
|
|
192
|
+
const onKeyDown = (e) => {
|
|
193
|
+
const list2 = controls();
|
|
194
|
+
const at = list2.indexOf(e.target);
|
|
195
|
+
if (at < 0) return;
|
|
196
|
+
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;
|
|
197
|
+
if (to < 0) return;
|
|
198
|
+
e.preventDefault();
|
|
199
|
+
list2[to].focus();
|
|
200
|
+
watch(list2[to]);
|
|
201
|
+
};
|
|
202
|
+
const onFocus = (e) => {
|
|
203
|
+
const at = controls().indexOf(e.target);
|
|
204
|
+
if (at >= 0) setStop(at);
|
|
205
|
+
watch(e.target);
|
|
206
|
+
};
|
|
207
|
+
const toolbar = /* @__PURE__ */ jsxs(
|
|
65
208
|
"div",
|
|
66
209
|
{
|
|
210
|
+
ref: onToolbar,
|
|
211
|
+
"data-bulk-bar": "",
|
|
67
212
|
className: cn(
|
|
68
|
-
"flex items-center gap-ds-3 rounded-[var(--ds-radius-md)]",
|
|
213
|
+
"pointer-events-auto max-w-full flex items-center gap-ds-3 rounded-[var(--ds-radius-md)]",
|
|
69
214
|
"bg-[var(--ds-bg-surface-elevated)] border-[length:var(--ds-border-width)] border-[var(--ds-accent-ink)]",
|
|
70
215
|
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
|
|
71
216
|
"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
|
|
@@ -74,16 +219,18 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
|
|
|
74
219
|
style: { padding: "var(--ds-space-3) var(--ds-space-4)" },
|
|
75
220
|
role: "toolbar",
|
|
76
221
|
"aria-label": `${selectedCount} items selected`,
|
|
222
|
+
onKeyDown,
|
|
223
|
+
onFocus,
|
|
77
224
|
children: [
|
|
78
225
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-[var(--ds-accent-ink)] tabular-nums whitespace-nowrap", children: [
|
|
79
226
|
selectedCount,
|
|
80
227
|
" selected"
|
|
81
228
|
] }),
|
|
82
|
-
/* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-[var(--ds-border-subtle)]" }),
|
|
83
|
-
|
|
229
|
+
actions.length > 0 && /* @__PURE__ */ jsx("div", { className: "h-4 w-px shrink-0 bg-[var(--ds-border-subtle)]" }),
|
|
230
|
+
actions.length > 0 && (compact ? /* @__PURE__ */ jsx(
|
|
84
231
|
DropdownMenu,
|
|
85
232
|
{
|
|
86
|
-
trigger: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "more-vertical", size: 14 }), children: "Actions" }),
|
|
233
|
+
trigger: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "more-vertical", size: 14 }), ...tab(0), children: "Actions" }),
|
|
87
234
|
items: dropdownItems,
|
|
88
235
|
align: "start"
|
|
89
236
|
}
|
|
@@ -93,28 +240,31 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
|
|
|
93
240
|
type: "button",
|
|
94
241
|
variant: "secondary",
|
|
95
242
|
size: "sm",
|
|
243
|
+
className: "whitespace-nowrap",
|
|
96
244
|
onClick: action.onClick,
|
|
245
|
+
...tab(i),
|
|
97
246
|
children: action.label
|
|
98
247
|
},
|
|
99
248
|
i
|
|
100
|
-
)) }),
|
|
249
|
+
)) })),
|
|
101
250
|
/* @__PURE__ */ jsx(
|
|
102
251
|
"button",
|
|
103
252
|
{
|
|
104
253
|
type: "button",
|
|
105
|
-
onClick: (
|
|
106
|
-
|
|
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),
|
|
254
|
+
onClick: () => onClearSelection(),
|
|
255
|
+
className: cn("ml-auto shrink-0 text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer", FOCUS_RING),
|
|
111
256
|
"aria-label": "Clear selection",
|
|
257
|
+
...tab(count - 1),
|
|
112
258
|
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 16 })
|
|
113
259
|
}
|
|
114
260
|
)
|
|
115
261
|
]
|
|
116
262
|
}
|
|
117
263
|
);
|
|
264
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
265
|
+
!bearing && /* @__PURE__ */ jsx("span", { ref: setAnchor, hidden: true, "data-bulk-bar-anchor": "" }),
|
|
266
|
+
target && createPortal(host ? toolbar : /* @__PURE__ */ jsx("div", { className: BULK_BAR_WINDOW_LAYER, "data-bulk-bar-layer": "", children: toolbar }), target)
|
|
267
|
+
] });
|
|
118
268
|
}
|
|
119
269
|
var CONTROL_HEIGHT = {
|
|
120
270
|
sm: "h-[var(--ds-control-height-sm)]",
|
|
@@ -1734,6 +1884,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
|
|
|
1734
1884
|
setBodyEl(el);
|
|
1735
1885
|
}, [bodyInset]);
|
|
1736
1886
|
useKeyboardScroll(bodyEl, title, open);
|
|
1887
|
+
const { setLayer: setBarLayer, room: barStack, value: barHost } = useBulkBarHost();
|
|
1737
1888
|
const onCloseRef = useLatest(onClose);
|
|
1738
1889
|
const onSubmitRef = useLatest(onSubmit);
|
|
1739
1890
|
const isTopLayer = useOverlayLayer(open);
|
|
@@ -1868,19 +2019,28 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
|
|
|
1868
2019
|
}
|
|
1869
2020
|
) })
|
|
1870
2021
|
] }),
|
|
1871
|
-
children &&
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
2022
|
+
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
|
|
2023
|
+
// fills down to the footer, so that foot is the screen's, not the middle of it (the fix pass of 25.33)
|
|
2024
|
+
/* @__PURE__ */ jsxs("div", { className: cn("relative min-h-0 flex flex-col", isMobile ? "flex-1" : "flex-[0_1_auto]"), children: [
|
|
2025
|
+
/* @__PURE__ */ jsxs(
|
|
2026
|
+
"div",
|
|
2027
|
+
{
|
|
2028
|
+
ref: bodyRef,
|
|
2029
|
+
className: cn("min-h-0 flex-[0_1_auto] overflow-y-auto pb-ds-6", FOCUS_INSET),
|
|
2030
|
+
style: {
|
|
2031
|
+
paddingLeft: variant === "destructive" ? "calc(var(--ds-page-gutter) + 2.5rem + var(--ds-space-3))" : "var(--ds-page-gutter)",
|
|
2032
|
+
paddingRight: insetLessScrollbar("var(--ds-page-gutter)"),
|
|
2033
|
+
...barStack ? { scrollPaddingBottom: bulkBarRoom(barStack) } : {}
|
|
2034
|
+
},
|
|
2035
|
+
children: [
|
|
2036
|
+
/* @__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 }) }) }) }) }),
|
|
2037
|
+
/* @__PURE__ */ jsx(BulkBarSpacer, { room: barStack })
|
|
2038
|
+
]
|
|
2039
|
+
}
|
|
2040
|
+
),
|
|
2041
|
+
/* @__PURE__ */ jsx("div", { ref: setBarLayer, "data-bulk-bar-layer": "", className: BULK_BAR_LAYER })
|
|
2042
|
+
] }),
|
|
2043
|
+
isMobile && !children && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "flex-1 min-h-0" }),
|
|
1884
2044
|
/* @__PURE__ */ jsx(DiscardConfirm, { open: guard.confirming, onKeep: guard.keep, onDiscard: guard.discard }),
|
|
1885
2045
|
footer && /* @__PURE__ */ jsx("div", { className: cn(
|
|
1886
2046
|
"shrink-0 flex justify-end gap-ds-2 py-ds-4 px-[var(--ds-page-gutter)]",
|
|
@@ -2279,101 +2439,104 @@ function FileUpload({ onFiles, files, upload, onCancel, onRetry, onRemove, accep
|
|
|
2279
2439
|
const canCancel = !controlled || !!onCancel;
|
|
2280
2440
|
const canRetry = !controlled || !!onRetry;
|
|
2281
2441
|
const canRemove = (item) => !!onRemove || !controlled && item.status === "error";
|
|
2282
|
-
return
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
/* @__PURE__ */ jsxs(
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
"
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
/* @__PURE__ */ jsx("
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
e
|
|
2442
|
+
return (
|
|
2443
|
+
// a wide control: in a form, its row fills the form rather than keeping a field's reading width (Sprint 25.33)
|
|
2444
|
+
/* @__PURE__ */ jsxs("div", { "data-wide-control": "", className: cn("space-y-ds-3", className), children: [
|
|
2445
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-ds-1.5", children: [
|
|
2446
|
+
showLabel && /* @__PURE__ */ jsx(Label, { htmlFor: inputId, children: label }),
|
|
2447
|
+
/* @__PURE__ */ jsxs(
|
|
2448
|
+
"div",
|
|
2449
|
+
{
|
|
2450
|
+
onDragOver: (e) => {
|
|
2451
|
+
e.preventDefault();
|
|
2452
|
+
setDragOver(true);
|
|
2453
|
+
},
|
|
2454
|
+
onDragLeave: () => setDragOver(false),
|
|
2455
|
+
onDrop: handleDrop,
|
|
2456
|
+
onClick: () => inputRef.current?.click(),
|
|
2457
|
+
className: cn(
|
|
2458
|
+
"flex flex-col items-center justify-center gap-ds-2 cursor-pointer group",
|
|
2459
|
+
"border-2 border-dashed rounded-[var(--ds-radius-md)]",
|
|
2460
|
+
"transition-colors",
|
|
2461
|
+
// The real file input is visually hidden inside; Tab lands on it and
|
|
2462
|
+
// Enter/Space open the picker natively, so the zone shows its focus.
|
|
2463
|
+
invalid ? ERROR_HAS_FOCUS_RING : FIELD_HAS_FOCUS_RING,
|
|
2464
|
+
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)]"
|
|
2465
|
+
),
|
|
2466
|
+
style: { padding: "var(--ds-space-8) var(--ds-space-4)" },
|
|
2467
|
+
children: [
|
|
2468
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
2469
|
+
"flex items-center justify-center w-10 h-10 rounded-[var(--ds-radius-full)] transition-colors",
|
|
2470
|
+
"bg-[var(--ds-bg-muted)] group-hover:bg-[var(--ds-accent-subtle)]"
|
|
2471
|
+
), children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 20, className: "text-[var(--ds-text-muted)] group-hover:text-[var(--ds-accent-subtle-text)] transition-colors" }) }),
|
|
2472
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2473
|
+
/* @__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" }),
|
|
2474
|
+
constraints && /* @__PURE__ */ jsx("p", { id: constraintsId, className: "text-xs text-[var(--ds-text-muted)] mt-ds-1", children: constraints })
|
|
2475
|
+
] }),
|
|
2476
|
+
/* @__PURE__ */ jsx(
|
|
2477
|
+
"input",
|
|
2478
|
+
{
|
|
2479
|
+
ref: inputRef,
|
|
2480
|
+
id: inputId,
|
|
2481
|
+
type: "file",
|
|
2482
|
+
accept,
|
|
2483
|
+
multiple,
|
|
2484
|
+
className: "sr-only",
|
|
2485
|
+
"aria-label": control.labelId ? void 0 : control.label,
|
|
2486
|
+
"aria-labelledby": control.labelId,
|
|
2487
|
+
"aria-describedby": describedBy,
|
|
2488
|
+
"aria-invalid": invalid || void 0,
|
|
2489
|
+
onChange: (e) => {
|
|
2490
|
+
if (e.target.files?.length) addFiles(e.target.files);
|
|
2491
|
+
e.target.value = "";
|
|
2492
|
+
}
|
|
2330
2493
|
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2494
|
+
)
|
|
2495
|
+
]
|
|
2496
|
+
}
|
|
2497
|
+
),
|
|
2498
|
+
rejected && /* @__PURE__ */ jsx(InlineFieldError, { id: rejectedId, message: rejected, className: "mt-0" }),
|
|
2499
|
+
waiting && /* @__PURE__ */ jsx(InlineFieldError, { id: waitingId, message: waiting, className: "mt-0" })
|
|
2500
|
+
] }),
|
|
2501
|
+
shown.length > 0 && /* @__PURE__ */ jsx("ul", { ref: listRef, className: "space-y-ds-2", children: shown.map((item) => {
|
|
2502
|
+
const progress = percentOf(item.progress);
|
|
2503
|
+
const words = item.status === "queued" ? "Waiting" : item.status === "uploading" ? `${Math.round(progress)}%` : item.status === "done" ? "Uploaded" : item.status === "error" ? "Failed" : null;
|
|
2504
|
+
return /* @__PURE__ */ jsxs(
|
|
2505
|
+
"li",
|
|
2506
|
+
{
|
|
2507
|
+
"data-upload-id": item.id,
|
|
2508
|
+
"data-upload-status": item.status,
|
|
2509
|
+
onFocus: (e) => {
|
|
2510
|
+
if (e.target instanceof HTMLButtonElement) lastAction.current = { id: item.id, el: e.target };
|
|
2511
|
+
},
|
|
2512
|
+
className: cn(
|
|
2513
|
+
"flex items-center gap-ds-3 text-sm",
|
|
2514
|
+
"border-[length:var(--ds-border-width)]",
|
|
2515
|
+
item.status === "error" ? "border-[var(--ds-status-error)]" : "border-[var(--ds-border-subtle)]",
|
|
2516
|
+
"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]"
|
|
2517
|
+
),
|
|
2518
|
+
style: { padding: "var(--ds-space-3)" },
|
|
2519
|
+
children: [
|
|
2520
|
+
/* @__PURE__ */ jsx(Icon, { name: "folder", size: 16, className: "text-[var(--ds-text-muted)] shrink-0" }),
|
|
2521
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2522
|
+
/* @__PURE__ */ jsx(TruncFileName, { className: "text-[var(--ds-text-primary)]", children: item.name }),
|
|
2523
|
+
(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 ") }),
|
|
2524
|
+
item.status === "uploading" && /* @__PURE__ */ jsx(Progress, { value: progress, size: "sm", label: `Uploading ${item.name}`, className: "mt-ds-1" }),
|
|
2525
|
+
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." })
|
|
2526
|
+
] }),
|
|
2527
|
+
item.status === "done" && /* @__PURE__ */ jsx(Icon, { name: "check", size: 16, className: "text-[var(--ds-status-success)] shrink-0", "aria-hidden": "true" }),
|
|
2528
|
+
running(item) && canCancel && // the visible word starts the name, which says which file (WCAG 2.5.3)
|
|
2529
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => cancel(item), "aria-label": `Cancel ${item.name}`, children: "Cancel" }),
|
|
2530
|
+
item.status === "error" && canRetry && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => retry(item), "aria-label": `Retry ${item.name}`, children: "Retry" }),
|
|
2531
|
+
!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 }) })
|
|
2532
|
+
]
|
|
2349
2533
|
},
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
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
|
-
] });
|
|
2534
|
+
item.id
|
|
2535
|
+
);
|
|
2536
|
+
}) }),
|
|
2537
|
+
/* @__PURE__ */ jsx("div", { role: "status", className: "sr-only", children: /* @__PURE__ */ jsx("span", { children: heard.text }, heard.n) })
|
|
2538
|
+
] })
|
|
2539
|
+
);
|
|
2377
2540
|
}
|
|
2378
2541
|
function SliderRange({
|
|
2379
2542
|
value,
|
|
@@ -3064,6 +3227,7 @@ var Tag = forwardRef(function Tag2({
|
|
|
3064
3227
|
size = "md",
|
|
3065
3228
|
color,
|
|
3066
3229
|
maxWidth,
|
|
3230
|
+
width,
|
|
3067
3231
|
onRemove,
|
|
3068
3232
|
onClick,
|
|
3069
3233
|
selected,
|
|
@@ -3098,8 +3262,9 @@ var Tag = forwardRef(function Tag2({
|
|
|
3098
3262
|
"aria-disabled": !clickable && disabled || void 0,
|
|
3099
3263
|
"data-selected": isSelected ? "" : void 0,
|
|
3100
3264
|
className: cn(
|
|
3101
|
-
"inline-flex items-center font-medium max-w-full min-w-0 whitespace-nowrap",
|
|
3265
|
+
"inline-flex items-center font-medium w-fit max-w-full min-w-0 whitespace-nowrap",
|
|
3102
3266
|
"rounded-[var(--ds-radius-sm)]",
|
|
3267
|
+
width && "justify-center",
|
|
3103
3268
|
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
3104
3269
|
sizeStyles[size],
|
|
3105
3270
|
colorClasses,
|
|
@@ -3107,7 +3272,7 @@ var Tag = forwardRef(function Tag2({
|
|
|
3107
3272
|
disabled && "opacity-disabled cursor-not-allowed",
|
|
3108
3273
|
className
|
|
3109
3274
|
),
|
|
3110
|
-
style: maxWidth ? { maxWidth } : void 0,
|
|
3275
|
+
style: maxWidth || width ? { ...width ? { width } : {}, ...maxWidth ? { maxWidth } : {} } : void 0,
|
|
3111
3276
|
children: [
|
|
3112
3277
|
clickable ? /* @__PURE__ */ jsx(
|
|
3113
3278
|
"button",
|
|
@@ -4057,6 +4222,15 @@ var Alert = forwardRef(function Alert2({
|
|
|
4057
4222
|
}
|
|
4058
4223
|
);
|
|
4059
4224
|
});
|
|
4225
|
+
var FORM_ROWS = cn(
|
|
4226
|
+
"[--gs-form-default:calc(var(--ds-bp-md)_-_2*var(--ds-space-6))]",
|
|
4227
|
+
"[:where(&)>*]:max-w-[var(--gs-row-cap,var(--ds-form-max,var(--gs-form-default)))]",
|
|
4228
|
+
// the row is the wide control itself (a FileUpload with its own label, written straight into the form), or holds one
|
|
4229
|
+
"[&>[data-wide-control]]:[--gs-row-cap:none]",
|
|
4230
|
+
"[&>*:has([data-wide-control])]:[--gs-row-cap:none]",
|
|
4231
|
+
"[&:has([data-wide-control])>[data-form-actions]]:[--gs-row-cap:none]"
|
|
4232
|
+
);
|
|
4233
|
+
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
4234
|
var isThenable = (value) => !!value && typeof value.then === "function";
|
|
4061
4235
|
function stampFormId(node, formId) {
|
|
4062
4236
|
return Children.map(node, (child) => {
|
|
@@ -4246,8 +4420,9 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
4246
4420
|
": ",
|
|
4247
4421
|
f.message
|
|
4248
4422
|
] }, f.id || f.label)) }) }) : null;
|
|
4423
|
+
const callerWidth = /(?:^|[\s:!])max-w-/.test(className ?? "");
|
|
4249
4424
|
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
|
|
4425
|
+
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
4426
|
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
4427
|
children,
|
|
4253
4428
|
actionsNode
|
|
@@ -4381,7 +4556,7 @@ function TransferList({
|
|
|
4381
4556
|
setCheckedSelected(allChecked ? /* @__PURE__ */ new Set() : new Set(enabledIds));
|
|
4382
4557
|
}, [filteredSelected, checkedSelected]);
|
|
4383
4558
|
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: [
|
|
4559
|
+
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
4560
|
/* @__PURE__ */ jsx(
|
|
4386
4561
|
Panel,
|
|
4387
4562
|
{
|
|
@@ -5757,9 +5932,16 @@ var PIN_FOCUS_END = "[tr:focus-visible>&]:after:right-[3px] [tr:focus-visible>&]
|
|
|
5757
5932
|
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
5933
|
var PINNED_LAYERS = cn(
|
|
5759
5934
|
"[--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
5935
|
"supports-[color:oklch(from_red_l_c_h)]:[--gs-pinned-canvas:oklch(from_var(--ds-bg-canvas)_l_c_h_/_1)]"
|
|
5762
5936
|
);
|
|
5937
|
+
function drawnText(el) {
|
|
5938
|
+
const copy = el.cloneNode(true);
|
|
5939
|
+
copy.querySelectorAll(".sr-only").forEach((n) => n.remove());
|
|
5940
|
+
return copy.textContent ?? "";
|
|
5941
|
+
}
|
|
5942
|
+
var CELL_ACTION = "button, a[href], [role='button'], [role='link']";
|
|
5943
|
+
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'])";
|
|
5944
|
+
var iconActionsOnly = (td) => !td.querySelector(CELL_READ_OR_SET) && !!td.querySelector(CELL_ACTION);
|
|
5763
5945
|
var PIN_SHADOW = "oklch(0 0 0 / 0.18)";
|
|
5764
5946
|
var ROW_CONTROL = `${FOCUSABLE}, label, [role="button"], [role="checkbox"], [role="switch"], [role="menuitem"], [role="link"]`;
|
|
5765
5947
|
function clickIsCard(e) {
|
|
@@ -6312,7 +6494,7 @@ function Table({
|
|
|
6312
6494
|
const endColumns = columns.filter((c) => c.pin === "end").length;
|
|
6313
6495
|
const endCount = endColumns + trail;
|
|
6314
6496
|
const nameIndex = columns.length > endColumns ? lead : -1;
|
|
6315
|
-
const { ref: scrollRef, elRef: scrollEl, measure: measureScroll, scrollable, edges, fadeProps } = useScrollEdges({
|
|
6497
|
+
const { ref: scrollRef, elRef: scrollEl, measure: measureScroll, scrollable, overflowing, edges, fadeProps } = useScrollEdges({
|
|
6316
6498
|
enabled: !isMobile,
|
|
6317
6499
|
noFade: { left: lead + (pins.nameFits ? 1 : 0) > 0, right: endCount > 0 }
|
|
6318
6500
|
});
|
|
@@ -6358,6 +6540,7 @@ function Table({
|
|
|
6358
6540
|
}, [isMobile, lead, trail, endCount, nameIndex, scrollEl, columns, drawn.length, visibleKeys.length]);
|
|
6359
6541
|
const pinnedStart = lead + (pins.nameFits ? 1 : 0);
|
|
6360
6542
|
const pinStyle = (position, total) => {
|
|
6543
|
+
if (!overflowing) return void 0;
|
|
6361
6544
|
if (position < pinnedStart && pins.start[position] !== void 0) {
|
|
6362
6545
|
const inner = position === pinnedStart - 1;
|
|
6363
6546
|
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 +6559,22 @@ function Table({
|
|
|
6376
6559
|
};
|
|
6377
6560
|
const fade = fadeProps;
|
|
6378
6561
|
const [renderedKinds, setRenderedKinds] = useState(() => /* @__PURE__ */ new Map());
|
|
6562
|
+
const [iconOnlyCols, setIconOnlyCols] = useState(() => /* @__PURE__ */ new Set());
|
|
6379
6563
|
useLayoutEffect(() => {
|
|
6380
6564
|
const table2 = tableRef.current;
|
|
6381
6565
|
if (!table2 || isMobile) return;
|
|
6382
6566
|
const next = /* @__PURE__ */ new Map();
|
|
6567
|
+
const icons = /* @__PURE__ */ new Set();
|
|
6383
6568
|
for (const col of columns) {
|
|
6569
|
+
const cells = Array.from(table2.querySelectorAll(`:scope > tbody > tr > td[data-col="${CSS.escape(col.key)}"]`)).slice(0, 50);
|
|
6570
|
+
const texts = cells.map(drawnText);
|
|
6571
|
+
if (cells.length && cells.every((td, i) => !texts[i].trim() && iconActionsOnly(td))) icons.add(col.key);
|
|
6384
6572
|
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
6573
|
const kind = texts.length ? kindOfRenderedText(texts) : void 0;
|
|
6387
6574
|
if (kind) next.set(col.key, kind);
|
|
6388
6575
|
}
|
|
6389
6576
|
setRenderedKinds((prev) => prev.size === next.size && [...next].every(([k, v]) => prev.get(k) === v) ? prev : next);
|
|
6577
|
+
setIconOnlyCols((prev) => prev.size === icons.size && [...icons].every((k) => prev.has(k)) ? prev : icons);
|
|
6390
6578
|
}, [columns, kindOf2, drawn, isMobile, visibleKeys.length]);
|
|
6391
6579
|
const [focusKey, setFocusKey] = useState(null);
|
|
6392
6580
|
const visibleSet = new Set(visibleKeys);
|
|
@@ -6676,7 +6864,7 @@ function Table({
|
|
|
6676
6864
|
scrollToRow(key);
|
|
6677
6865
|
}, [drawnStart, drawn.length, visibleKeys.length, scrollToRow]);
|
|
6678
6866
|
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: [
|
|
6867
|
+
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
6868
|
cardHeading,
|
|
6681
6869
|
body
|
|
6682
6870
|
] });
|
|
@@ -6730,11 +6918,11 @@ function Table({
|
|
|
6730
6918
|
] }, col.key)) }, r)) })
|
|
6731
6919
|
] });
|
|
6732
6920
|
if (title) return titledCards(skeletonCards);
|
|
6733
|
-
return /* @__PURE__ */ jsx("div", { ref: setRoot, "data-ds-list": "", "data-gs": "table", className, children: skeletonCards });
|
|
6921
|
+
return /* @__PURE__ */ jsx("div", { ref: setRoot, "data-ds-list": "", "data-gs": "table", "data-wide-control": "", className, children: skeletonCards });
|
|
6734
6922
|
}
|
|
6735
6923
|
if (data.length === 0 && emptyState) {
|
|
6736
6924
|
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 });
|
|
6925
|
+
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
6926
|
}
|
|
6739
6927
|
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
6928
|
loading && data.length > 0 && /* @__PURE__ */ jsx(RefreshLine, { className: "inset-x-[4px] rounded-full" }),
|
|
@@ -6789,8 +6977,10 @@ function Table({
|
|
|
6789
6977
|
}
|
|
6790
6978
|
} : void 0,
|
|
6791
6979
|
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
|
-
|
|
6980
|
+
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
|
|
6981
|
+
// the card's selection box: with no select-all on a phone, the first card's is where a BulkActionBar's
|
|
6982
|
+
// handover finds the selection (the fix pass of 25.33)
|
|
6983
|
+
/* @__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
6984
|
columns.map((col, c) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-ds-2 text-sm", children: [
|
|
6795
6985
|
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider", children: col.header }),
|
|
6796
6986
|
/* @__PURE__ */ jsx(CardValue, { value: row[col.key], id: lead + c === nameIndex ? `${headingId}-card-name-${idPart(id)}` : void 0 })
|
|
@@ -6864,8 +7054,9 @@ function Table({
|
|
|
6864
7054
|
// a tree table is a treegrid (item 14): its rows have levels, and the arrow keys move between them
|
|
6865
7055
|
/* @__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
7056
|
/* @__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
|
-
|
|
7057
|
+
selectable && // data-ds-select-all: the selection's own control, where a BulkActionBar's Clear selection sends focus; and
|
|
7058
|
+
// whether the table holds a selection, said as it renders (the box's mixed state is set a moment later)
|
|
7059
|
+
/* @__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
7060
|
Checkbox,
|
|
6870
7061
|
{
|
|
6871
7062
|
ref: selectAllRef,
|
|
@@ -6922,6 +7113,9 @@ function Table({
|
|
|
6922
7113
|
]
|
|
6923
7114
|
}
|
|
6924
7115
|
)
|
|
7116
|
+
) : iconOnlyCols.has(col.key) ? (
|
|
7117
|
+
// a column of icon buttons: its name for a screen reader, its width its buttons' (Sprint 25.33)
|
|
7118
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: col.header })
|
|
6925
7119
|
) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-ds-1", children: col.header })
|
|
6926
7120
|
},
|
|
6927
7121
|
col.key
|
|
@@ -7104,6 +7298,7 @@ function Table({
|
|
|
7104
7298
|
ref: listRoot,
|
|
7105
7299
|
"data-ds-list": "",
|
|
7106
7300
|
"data-gs": "table",
|
|
7301
|
+
"data-wide-control": "",
|
|
7107
7302
|
className: cn("relative w-full min-w-0 flex flex-col", FRAME_CLASSES, FRAME_FOCUS_RING, control && "min-h-0", listClass),
|
|
7108
7303
|
onFocus: noteFocus,
|
|
7109
7304
|
onBlur: forgetFocus,
|
|
@@ -9268,38 +9463,42 @@ function ExpandableDescription({ children, className }) {
|
|
|
9268
9463
|
function HorizontalLayout({ items, minItemWidth, label, className }) {
|
|
9269
9464
|
const [row, setRow] = useState(null);
|
|
9270
9465
|
useKeyboardScroll(row, label, true, false, "x");
|
|
9271
|
-
return
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
{
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
/* @__PURE__ */
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9466
|
+
return (
|
|
9467
|
+
// 4 px of room inside its edges, and snapping that keeps it, so the first marker and the row's own keyboard outline
|
|
9468
|
+
// never meet (Sprint 25.33: the owner's answer to Sprint 25.30's look question)
|
|
9469
|
+
/* @__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) => {
|
|
9470
|
+
const isFirst = i === 0;
|
|
9471
|
+
const isLast = i === items.length - 1;
|
|
9472
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 shrink-0 flex-col items-center snap-start", style: { minWidth: minItemWidth }, children: [
|
|
9473
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center w-full", children: [
|
|
9474
|
+
/* @__PURE__ */ jsx(
|
|
9475
|
+
"div",
|
|
9476
|
+
{
|
|
9477
|
+
className: cn(
|
|
9478
|
+
"flex-1 h-[2px] transition-colors",
|
|
9479
|
+
isFirst ? "bg-transparent" : "bg-[var(--ds-border-subtle)]"
|
|
9480
|
+
)
|
|
9481
|
+
}
|
|
9482
|
+
),
|
|
9483
|
+
/* @__PURE__ */ jsx(Marker, { item, vertical: false }),
|
|
9484
|
+
/* @__PURE__ */ jsx(
|
|
9485
|
+
"div",
|
|
9486
|
+
{
|
|
9487
|
+
className: cn(
|
|
9488
|
+
"flex-1 h-[2px] transition-colors",
|
|
9489
|
+
isLast ? "bg-transparent" : "bg-[var(--ds-border-subtle)]"
|
|
9490
|
+
)
|
|
9491
|
+
}
|
|
9492
|
+
)
|
|
9493
|
+
] }),
|
|
9494
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mt-ds-2 px-ds-3", children: [
|
|
9495
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: item.title }),
|
|
9496
|
+
item.description && /* @__PURE__ */ jsx(ExpandableDescription, { className: "text-center", children: item.description }),
|
|
9497
|
+
/* @__PURE__ */ jsx(ItemTime, { item })
|
|
9498
|
+
] })
|
|
9499
|
+
] }, i);
|
|
9500
|
+
}) })
|
|
9501
|
+
);
|
|
9303
9502
|
}
|
|
9304
9503
|
var exactFormat = (locale, d) => new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(d);
|
|
9305
9504
|
var exactDayFormat = (locale, d) => new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(d);
|
|
@@ -9606,6 +9805,7 @@ function TreeView({
|
|
|
9606
9805
|
"aria-label": ariaLabel,
|
|
9607
9806
|
"aria-labelledby": ariaLabelledBy
|
|
9608
9807
|
}) {
|
|
9808
|
+
useWantsInset();
|
|
9609
9809
|
const [ownSelected, setOwnSelected] = useState(() => new Set(defaultSelected));
|
|
9610
9810
|
const selected = useMemo(() => selectedProp ? new Set(selectedProp) : ownSelected, [selectedProp, ownSelected]);
|
|
9611
9811
|
const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set([...defaultExpanded, ...foldersHolding(nodes, selected)]));
|
|
@@ -9760,7 +9960,7 @@ function TreeNodeRow({
|
|
|
9760
9960
|
const hasChildren = !!node.children?.length;
|
|
9761
9961
|
const isExpanded = expanded.has(node.id);
|
|
9762
9962
|
const isSelected = selected.has(node.id);
|
|
9763
|
-
const
|
|
9963
|
+
const holdsSelection2 = !isSelected && holding.has(node.id);
|
|
9764
9964
|
const checkState = checkable ? getCheckState(node) : "unchecked";
|
|
9765
9965
|
return /* @__PURE__ */ jsxs("div", { role: "treeitem", "aria-expanded": hasChildren ? isExpanded : void 0, "aria-selected": selectable ? isSelected : void 0, children: [
|
|
9766
9966
|
/* @__PURE__ */ jsxs(
|
|
@@ -9778,7 +9978,7 @@ function TreeNodeRow({
|
|
|
9778
9978
|
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
9979
|
// A folder holding the selection, as SidebarNav draws a parent of the current page (Sprint 25.16 A18): no
|
|
9780
9980
|
// fill, so it reads the plain tokens, never the active set (pill's on-primary text would vanish here).
|
|
9781
|
-
|
|
9981
|
+
holdsSelection2 && "font-medium",
|
|
9782
9982
|
node.disabled && "opacity-disabled pointer-events-none"
|
|
9783
9983
|
),
|
|
9784
9984
|
style: { paddingLeft: `calc(var(--ds-space-3) * ${depth} + var(--ds-space-2))` },
|
|
@@ -9805,7 +10005,7 @@ function TreeNodeRow({
|
|
|
9805
10005
|
{
|
|
9806
10006
|
name: "chevron-right",
|
|
9807
10007
|
size: 14,
|
|
9808
|
-
className: cn(isSelected ? "text-[var(--ds-tree-active-muted)]" :
|
|
10008
|
+
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
10009
|
}
|
|
9810
10010
|
)
|
|
9811
10011
|
}
|
|
@@ -9821,7 +10021,7 @@ function TreeNodeRow({
|
|
|
9821
10021
|
}
|
|
9822
10022
|
}
|
|
9823
10023
|
),
|
|
9824
|
-
node.icon && /* @__PURE__ */ jsx(Icon, { name: node.icon, size: 16, className: cn("shrink-0", isSelected ? "text-[var(--ds-tree-active-text)]" :
|
|
10024
|
+
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
10025
|
/* @__PURE__ */ jsx(TruncLabel2, { children: node.label })
|
|
9826
10026
|
]
|
|
9827
10027
|
}
|
|
@@ -10795,9 +10995,12 @@ var StackedList = forwardRef(function StackedList2({
|
|
|
10795
10995
|
pager
|
|
10796
10996
|
}, ref) {
|
|
10797
10997
|
useScrollsInside();
|
|
10998
|
+
useRunsEdgeToEdge();
|
|
10798
10999
|
const isPhone = useBreakpoint("sm");
|
|
10799
11000
|
const inCard = useContext(CardSurfaceCtx);
|
|
10800
|
-
const
|
|
11001
|
+
const pane = useContext(SplitPaneCtx);
|
|
11002
|
+
const panePadded = useContext(PanePaddedCtx);
|
|
11003
|
+
const inPane = !!pane && !panePadded;
|
|
10801
11004
|
const articles = variant === "articles";
|
|
10802
11005
|
useWholeListCheck("StackedList", items.length, pager);
|
|
10803
11006
|
const shown = pagerPart(items, pager);
|
|
@@ -12056,6 +12259,7 @@ function Gantt({
|
|
|
12056
12259
|
className
|
|
12057
12260
|
}) {
|
|
12058
12261
|
useScrollsInside();
|
|
12262
|
+
useRunsEdgeToEdge();
|
|
12059
12263
|
const [zoomState, setZoomState] = useState(defaultZoom);
|
|
12060
12264
|
const zoom = zoomProp ?? zoomState;
|
|
12061
12265
|
const changeZoom = (next) => {
|
|
@@ -13362,7 +13566,8 @@ function ScrollArea({
|
|
|
13362
13566
|
orientation = "vertical",
|
|
13363
13567
|
maxHeight,
|
|
13364
13568
|
maxWidth,
|
|
13365
|
-
"aria-label": ariaLabel = "Scrollable content"
|
|
13569
|
+
"aria-label": ariaLabel = "Scrollable content",
|
|
13570
|
+
flush = false
|
|
13366
13571
|
}) {
|
|
13367
13572
|
const viewportRef = useRef(null);
|
|
13368
13573
|
const [viewport, setViewport] = useState(null);
|
|
@@ -13463,6 +13668,8 @@ function ScrollArea({
|
|
|
13463
13668
|
className: cn(
|
|
13464
13669
|
// the frame's corners, so the inset ring follows them rather than being cut by them (as the Table's region)
|
|
13465
13670
|
"h-full w-full scroll-p-[4px] rounded-[inherit]",
|
|
13671
|
+
// room for an outline at its edges (FOCUS_ROOM), unless the content insets itself
|
|
13672
|
+
!flush && "p-[4px]",
|
|
13466
13673
|
FOCUS_INSET,
|
|
13467
13674
|
orientation === "vertical" && "overflow-y-auto overflow-x-hidden",
|
|
13468
13675
|
orientation === "horizontal" && "overflow-x-auto overflow-y-hidden",
|
|
@@ -13612,7 +13819,7 @@ var Sidebar = forwardRef(function Sidebar2({
|
|
|
13612
13819
|
children: header
|
|
13613
13820
|
}
|
|
13614
13821
|
),
|
|
13615
|
-
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", children }),
|
|
13822
|
+
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", flush: true, children }),
|
|
13616
13823
|
showCollapse && (() => {
|
|
13617
13824
|
const isSm = navSize === "sm";
|
|
13618
13825
|
const collapseButton = /* @__PURE__ */ jsxs(
|
|
@@ -14520,6 +14727,16 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
|
|
|
14520
14727
|
clearTimers.current.add(timer);
|
|
14521
14728
|
}, 0);
|
|
14522
14729
|
}, []);
|
|
14730
|
+
const barRooms = useRef(/* @__PURE__ */ new Map());
|
|
14731
|
+
const [barRoom, setBarRoom] = useState(0);
|
|
14732
|
+
const bulkBar = useMemo(() => ({
|
|
14733
|
+
room: (bar, room) => {
|
|
14734
|
+
if (room > 0) barRooms.current.set(bar, room);
|
|
14735
|
+
else barRooms.current.delete(bar);
|
|
14736
|
+
setBarRoom(Math.max(0, ...barRooms.current.values()));
|
|
14737
|
+
},
|
|
14738
|
+
say: (text) => announce({ id: "bulk-bar", message: text, variant: "default", duration: 0, shown: false, version: 0 })
|
|
14739
|
+
}), [announce]);
|
|
14523
14740
|
useEffect(() => () => {
|
|
14524
14741
|
if (heardTimer.current) clearTimeout(heardTimer.current);
|
|
14525
14742
|
heardTimer.current = void 0;
|
|
@@ -14707,8 +14924,10 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
|
|
|
14707
14924
|
const waiting = list2.length - shown.length;
|
|
14708
14925
|
const isTop = position.startsWith("top");
|
|
14709
14926
|
const hasBottomNav = isMobile && bottomNavs > 0;
|
|
14927
|
+
const navFoot = "var(--ds-space-12) + var(--ds-space-2) + env(safe-area-inset-bottom)";
|
|
14928
|
+
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
14929
|
return /* @__PURE__ */ jsx(ToastContext.Provider, { value: api, children: /* @__PURE__ */ jsxs(ToastLedgerCtx.Provider, { value: ledger, children: [
|
|
14711
|
-
/* @__PURE__ */ jsx(BottomNavPresenceCtx.Provider, { value: registerBottomNav, children }),
|
|
14930
|
+
/* @__PURE__ */ jsx(BottomNavPresenceCtx.Provider, { value: registerBottomNav, children: /* @__PURE__ */ jsx(BulkBarPresenceCtx, { value: bulkBar, children }) }),
|
|
14712
14931
|
/* @__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
14932
|
/* @__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
14933
|
shown.length > 0 && createPortal(
|
|
@@ -14740,7 +14959,7 @@ function ToastProvider({ children, maxVisible = 3, position = "bottom-right", du
|
|
|
14740
14959
|
isTop ? "flex-col" : "flex-col-reverse",
|
|
14741
14960
|
isMobile ? cn("left-ds-4 right-ds-4", !hasBottomNav && "bottom-ds-4") : TOAST_POSITION_CLASSES[position]
|
|
14742
14961
|
),
|
|
14743
|
-
style:
|
|
14962
|
+
style: stackBottom ? { bottom: stackBottom } : void 0,
|
|
14744
14963
|
children: [
|
|
14745
14964
|
shown.map((t) => /* @__PURE__ */ jsx("div", { "data-toast-id": t.id, className: "pointer-events-auto", children: /* @__PURE__ */ jsx(
|
|
14746
14965
|
Toast,
|
|
@@ -15186,6 +15405,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
15186
15405
|
{
|
|
15187
15406
|
ref: setRoot,
|
|
15188
15407
|
"data-page-container": wrappedHeader ? "" : void 0,
|
|
15408
|
+
"data-page-column": "",
|
|
15189
15409
|
"data-width": dataWidth,
|
|
15190
15410
|
className: cn(
|
|
15191
15411
|
"w-full",
|
|
@@ -15217,7 +15437,7 @@ var PageContainer = forwardRef(function PageContainer2({
|
|
|
15217
15437
|
...floatingHeader ? { paddingRight: "var(--ds-space-3)", paddingLeft: r.sidebarFloating ? 0 : "var(--ds-space-3)" } : {},
|
|
15218
15438
|
...overlapActive ? { marginTop: "calc(-1 * var(--ds-overlap, 0px))", position: "relative", zIndex: 1 } : {}
|
|
15219
15439
|
} : 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) }) });
|
|
15440
|
+
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
15441
|
return /* @__PURE__ */ jsx(PageActionsCtx, { value: pageActions, children: /* @__PURE__ */ jsxs("div", { ref: setRoot, "data-page-container": "", "data-width": dataWidth, className: "w-full", children: [
|
|
15222
15442
|
placement === "block" ? /* @__PURE__ */ jsx("div", { style: floatingBlockPadding(r.navbarFloating, r.sidebarFloating, overlapActive), children: /* @__PURE__ */ jsxs("div", { className: FLOATING_BLOCK, children: [
|
|
15223
15443
|
strip,
|
|
@@ -18304,7 +18524,10 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
18304
18524
|
}, ref) {
|
|
18305
18525
|
const isPhone = useBreakpoint("sm");
|
|
18306
18526
|
const pane = variant === "pane";
|
|
18307
|
-
const
|
|
18527
|
+
const paneKind = useContext(SplitPaneCtx);
|
|
18528
|
+
const inDetail = paneKind === "detail";
|
|
18529
|
+
const panePadded = useContext(PanePaddedCtx);
|
|
18530
|
+
const cancel = pane && panePadded && (paneKind === "list" || paneKind === "detail") ? PANE_HEADING_CANCEL[paneKind] : void 0;
|
|
18308
18531
|
const editable = !!onTitleChange;
|
|
18309
18532
|
return /* @__PURE__ */ jsxs(
|
|
18310
18533
|
"div",
|
|
@@ -18313,7 +18536,7 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
18313
18536
|
"data-gs": "section-heading",
|
|
18314
18537
|
"data-variant": variant,
|
|
18315
18538
|
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)]",
|
|
18539
|
+
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
18540
|
!pane && bordered && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] pb-ds-4",
|
|
18318
18541
|
className
|
|
18319
18542
|
),
|