efficient-shell 4.134.0 → 4.137.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/README.md +81 -7
- package/dist/{Browser-O3QZGUF2.js → Browser-ZNX4WFUH.js} +11 -11
- package/dist/{Browser-O3QZGUF2.js.map → Browser-ZNX4WFUH.js.map} +1 -1
- package/dist/{Calculator-L6N5X3KU.js → Calculator-6FGNKOXU.js} +10 -10
- package/dist/{Calculator-L6N5X3KU.js.map → Calculator-6FGNKOXU.js.map} +1 -1
- package/dist/ConfirmDialog-NPQMIGUR.js +4 -0
- package/dist/{ConfirmDialog-LYSSZSUD.js.map → ConfirmDialog-NPQMIGUR.js.map} +1 -1
- package/dist/{CurrencyConverter-64MKXB3D.js → CurrencyConverter-FF7EXRYL.js} +10 -10
- package/dist/{CurrencyConverter-64MKXB3D.js.map → CurrencyConverter-FF7EXRYL.js.map} +1 -1
- package/dist/{Documents-5WXXYCLI.js → Documents-H3R7XSBH.js} +12 -12
- package/dist/{Documents-5WXXYCLI.js.map → Documents-H3R7XSBH.js.map} +1 -1
- package/dist/{Files-AUURUUDN.js → Files-ZHJIAUC2.js} +15 -15
- package/dist/{Files-AUURUUDN.js.map → Files-ZHJIAUC2.js.map} +1 -1
- package/dist/{Notepad-GPXJVPB7.js → Notepad-VE7ISWRQ.js} +13 -13
- package/dist/{Notepad-GPXJVPB7.js.map → Notepad-VE7ISWRQ.js.map} +1 -1
- package/dist/PdfViewer-SQBFYAGW.js +5 -0
- package/dist/{PdfViewer-HKO6P4SR.js.map → PdfViewer-SQBFYAGW.js.map} +1 -1
- package/dist/{PomodoroTimer-4TQBWLP2.js → PomodoroTimer-IR3WREED.js} +12 -12
- package/dist/{PomodoroTimer-4TQBWLP2.js.map → PomodoroTimer-IR3WREED.js.map} +1 -1
- package/dist/{Preview-FOZYPKM2.js → Preview-DAQGRNRM.js} +14 -14
- package/dist/{Preview-FOZYPKM2.js.map → Preview-DAQGRNRM.js.map} +1 -1
- package/dist/{Sidebar-BPU7RCZP.js → Sidebar-YW6H4NDJ.js} +3 -3
- package/dist/{Sidebar-BPU7RCZP.js.map → Sidebar-YW6H4NDJ.js.map} +1 -1
- package/dist/{Spreadsheet-3C66BBBF.js → Spreadsheet-HOCPHJOC.js} +12 -12
- package/dist/{Spreadsheet-3C66BBBF.js.map → Spreadsheet-HOCPHJOC.js.map} +1 -1
- package/dist/{Stock-IF4IHYLU.js → Stock-LVRQPURG.js} +10 -10
- package/dist/{Stock-IF4IHYLU.js.map → Stock-LVRQPURG.js.map} +1 -1
- package/dist/{Weather-725PFR7T.js → Weather-LZQGVDJL.js} +10 -10
- package/dist/{Weather-725PFR7T.js.map → Weather-LZQGVDJL.js.map} +1 -1
- package/dist/{WorldClock-UU4NZIQ7.js → WorldClock-XPD7WOZT.js} +10 -10
- package/dist/{WorldClock-UU4NZIQ7.js.map → WorldClock-XPD7WOZT.js.map} +1 -1
- package/dist/apps/index.js +23 -23
- package/dist/brand.css +1 -1
- package/dist/{chunk-GIGV2ZRW.js → chunk-5RPTS3BT.js} +3 -3
- package/dist/{chunk-GIGV2ZRW.js.map → chunk-5RPTS3BT.js.map} +1 -1
- package/dist/{chunk-D276EMXS.js → chunk-6XJEJWNJ.js} +7 -3
- package/dist/chunk-6XJEJWNJ.js.map +1 -0
- package/dist/{chunk-IULP5BCD.js → chunk-COWYSHG2.js} +4 -4
- package/dist/{chunk-IULP5BCD.js.map → chunk-COWYSHG2.js.map} +1 -1
- package/dist/{chunk-R4OQIQYX.js → chunk-E7TB6WD2.js} +4 -4
- package/dist/{chunk-R4OQIQYX.js.map → chunk-E7TB6WD2.js.map} +1 -1
- package/dist/{chunk-X4Q6G253.js → chunk-FIHOGVUP.js} +3 -3
- package/dist/{chunk-X4Q6G253.js.map → chunk-FIHOGVUP.js.map} +1 -1
- package/dist/{chunk-2TPTHAKI.js → chunk-HUBJAUGG.js} +3 -3
- package/dist/{chunk-2TPTHAKI.js.map → chunk-HUBJAUGG.js.map} +1 -1
- package/dist/{chunk-W622KQTD.js → chunk-I2TAAJHS.js} +3 -3
- package/dist/{chunk-W622KQTD.js.map → chunk-I2TAAJHS.js.map} +1 -1
- package/dist/{chunk-Q3LT745N.js → chunk-ICTRCKUE.js} +7 -7
- package/dist/{chunk-Q3LT745N.js.map → chunk-ICTRCKUE.js.map} +1 -1
- package/dist/{chunk-QRL64J5F.js → chunk-JOPU6WPY.js} +7 -6
- package/dist/chunk-JOPU6WPY.js.map +1 -0
- package/dist/{chunk-PIGDNN5F.js → chunk-PVPPAWVM.js} +3 -3
- package/dist/{chunk-PIGDNN5F.js.map → chunk-PVPPAWVM.js.map} +1 -1
- package/dist/{chunk-ET6ID4LP.js → chunk-R7QGMK6N.js} +3 -3
- package/dist/{chunk-ET6ID4LP.js.map → chunk-R7QGMK6N.js.map} +1 -1
- package/dist/{chunk-4P44JXDS.js → chunk-UTYKLGGT.js} +3 -3
- package/dist/{chunk-4P44JXDS.js.map → chunk-UTYKLGGT.js.map} +1 -1
- package/dist/{chunk-T4VQHMG4.js → chunk-VNJJCH5A.js} +3 -3
- package/dist/{chunk-T4VQHMG4.js.map → chunk-VNJJCH5A.js.map} +1 -1
- package/dist/{chunk-QSKCQUZE.js → chunk-XJHZWSKV.js} +3 -3
- package/dist/{chunk-QSKCQUZE.js.map → chunk-XJHZWSKV.js.map} +1 -1
- package/dist/{chunk-SHQM5CK3.js → chunk-Y3GYJ7YR.js} +4 -4
- package/dist/{chunk-SHQM5CK3.js.map → chunk-Y3GYJ7YR.js.map} +1 -1
- package/dist/{chunk-OLJDJYSU.js → chunk-YA4EE7ST.js} +574 -145
- package/dist/chunk-YA4EE7ST.js.map +1 -0
- package/dist/{chunk-QAGQRNKI.js → chunk-YDHXWCCJ.js} +3 -3
- package/dist/{chunk-QAGQRNKI.js.map → chunk-YDHXWCCJ.js.map} +1 -1
- package/dist/{chunk-72CQWN7O.js → chunk-YE6GUDGP.js} +3 -2
- package/dist/chunk-YE6GUDGP.js.map +1 -0
- package/dist/chunk-ZS7PMGUW.js +7 -0
- package/dist/{chunk-Q2MJVSJT.js.map → chunk-ZS7PMGUW.js.map} +1 -1
- package/dist/file-intake/index.js +2 -2
- package/dist/{index-DZ7E7bCl.d.ts → index-DVI9DMSu.d.ts} +189 -18
- package/dist/index.d.ts +2 -2
- package/dist/index.js +31 -31
- package/dist/page-tabs/index.js +5 -5
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +13 -13
- package/dist/ui.css +78 -10
- package/package.json +1 -1
- package/dist/ConfirmDialog-LYSSZSUD.js +0 -4
- package/dist/PdfViewer-HKO6P4SR.js +0 -5
- package/dist/chunk-72CQWN7O.js.map +0 -1
- package/dist/chunk-D276EMXS.js.map +0 -1
- package/dist/chunk-OLJDJYSU.js.map +0 -1
- package/dist/chunk-Q2MJVSJT.js +0 -7
- package/dist/chunk-QRL64J5F.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Breadcrumbs } from './chunk-
|
|
2
|
-
import { SidebarLayout } from './chunk-
|
|
1
|
+
import { Breadcrumbs } from './chunk-5RPTS3BT.js';
|
|
2
|
+
import { SidebarLayout } from './chunk-R7QGMK6N.js';
|
|
3
3
|
import { BrandMark } from './chunk-TRCWINHF.js';
|
|
4
|
-
import { toast_default } from './chunk-
|
|
5
|
-
import { useIsMobile, useShortcutLabel, useShellPrefs } from './chunk-
|
|
6
|
-
import { useFileIntake, humanSize, FileIntakeAlert } from './chunk-
|
|
4
|
+
import { toast_default } from './chunk-UTYKLGGT.js';
|
|
5
|
+
import { useIsMobile, useShortcutLabel, useShellPrefs } from './chunk-HUBJAUGG.js';
|
|
6
|
+
import { useFileIntake, humanSize, FileIntakeAlert } from './chunk-YDHXWCCJ.js';
|
|
7
7
|
import { iconButtonClasses, Button_default } from './chunk-RT6DSB5Y.js';
|
|
8
|
-
import { PopupMenu,
|
|
9
|
-
import { registerModalEscapeInterceptor, onOverlayOpen, Z_LAYERS, useDismissPopupsOnOpen, useFocusTrap, useScrollLock } from './chunk-
|
|
10
|
-
import { glassStyle } from './chunk-
|
|
11
|
-
import { useShellLocale, useShellStrings, DEFAULT_SHELL_STRINGS, currentShellStrings, formatPlain, formatFixed, formatPercent, splitAround } from './chunk-
|
|
8
|
+
import { PopupMenu, PopupMenuDivider, PopupMenuLabel, itemLook } from './chunk-JOPU6WPY.js';
|
|
9
|
+
import { registerModalEscapeInterceptor, onOverlayOpen, Z_LAYERS, useDismissPopupsOnOpen, useFocusTrap, useScrollLock } from './chunk-I2TAAJHS.js';
|
|
10
|
+
import { glassStyle, glassFill } from './chunk-6XJEJWNJ.js';
|
|
11
|
+
import { useShellLocale, useShellStrings, DEFAULT_SHELL_STRINGS, currentShellStrings, formatPlain, formatFixed, formatPercent, splitAround } from './chunk-YE6GUDGP.js';
|
|
12
12
|
import { useBrowserLayoutEffect, useBrowserValue, useBrowserValueOnce } from './chunk-IRWSRJ4K.js';
|
|
13
13
|
import { forwardRef, useCallback, useState, useRef, useId, useEffect, createContext, useMemo, Children, isValidElement, cloneElement, useContext, Fragment as Fragment$1, Component, useSyncExternalStore, useLayoutEffect } from 'react';
|
|
14
14
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -133,13 +133,17 @@ var ACROSS = {
|
|
|
133
133
|
left: ["top", "bottom"],
|
|
134
134
|
right: ["top", "bottom"]
|
|
135
135
|
};
|
|
136
|
-
function
|
|
137
|
-
|
|
136
|
+
function roomAround(anchor, bounds, gap) {
|
|
137
|
+
return {
|
|
138
138
|
top: anchor.top - gap - (bounds.top + VIEWPORT_MARGIN),
|
|
139
139
|
bottom: bounds.bottom - VIEWPORT_MARGIN - (anchor.bottom + gap),
|
|
140
140
|
left: anchor.left - gap - (bounds.left + VIEWPORT_MARGIN),
|
|
141
141
|
right: bounds.right - VIEWPORT_MARGIN - (anchor.right + gap)
|
|
142
142
|
};
|
|
143
|
+
}
|
|
144
|
+
var within = (value, lo, hi) => Math.max(lo, Math.min(value, hi));
|
|
145
|
+
function placeBeside(anchor, size, side, bounds, gap) {
|
|
146
|
+
const room = roomAround(anchor, bounds, gap);
|
|
143
147
|
const spare = (s) => room[s] - (s === "top" || s === "bottom" ? size.height : size.width);
|
|
144
148
|
const order = [side, OPPOSITE[side], ...ACROSS[side]];
|
|
145
149
|
const chosen = order.find((s) => spare(s) >= 0) ?? order.reduce((best, s) => spare(s) > spare(best) ? s : best);
|
|
@@ -165,18 +169,94 @@ function placeBeside(anchor, size, side, bounds, gap) {
|
|
|
165
169
|
top = centreY - size.height / 2;
|
|
166
170
|
break;
|
|
167
171
|
}
|
|
168
|
-
const within = (value, lo, hi) => Math.max(lo, Math.min(value, hi));
|
|
169
172
|
return {
|
|
170
173
|
side: chosen,
|
|
171
174
|
left: within(left, bounds.left + VIEWPORT_MARGIN, bounds.right - VIEWPORT_MARGIN - size.width),
|
|
172
175
|
top: within(top, bounds.top + VIEWPORT_MARGIN, bounds.bottom - VIEWPORT_MARGIN - size.height)
|
|
173
176
|
};
|
|
174
177
|
}
|
|
178
|
+
function placeArrow(anchor, placed, size, inset, depth) {
|
|
179
|
+
const { side, left, top } = placed;
|
|
180
|
+
const right = left + size.width;
|
|
181
|
+
const bottom = top + size.height;
|
|
182
|
+
const clearance = {
|
|
183
|
+
top: anchor.top - bottom,
|
|
184
|
+
bottom: top - anchor.bottom,
|
|
185
|
+
left: anchor.left - right,
|
|
186
|
+
right: left - anchor.right
|
|
187
|
+
}[side];
|
|
188
|
+
if (clearance < depth) return null;
|
|
189
|
+
const along = (target, start, length) => length < 2 * inset ? start + length / 2 : Math.max(start + inset, Math.min(target, start + length - inset));
|
|
190
|
+
const centreX = (anchor.left + anchor.right) / 2;
|
|
191
|
+
const centreY = (anchor.top + anchor.bottom) / 2;
|
|
192
|
+
switch (side) {
|
|
193
|
+
case "top":
|
|
194
|
+
return { side, x: along(centreX, left, size.width), y: bottom };
|
|
195
|
+
case "bottom":
|
|
196
|
+
return { side, x: along(centreX, left, size.width), y: top };
|
|
197
|
+
case "left":
|
|
198
|
+
return { side, x: right, y: along(centreY, top, size.height) };
|
|
199
|
+
case "right":
|
|
200
|
+
return { side, x: left, y: along(centreY, top, size.height) };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function followAnchor(anchor, onMove, watch) {
|
|
204
|
+
let lastLeft = NaN, lastTop = NaN, lastRight = NaN, lastBottom = NaN, lastWatched = NaN;
|
|
205
|
+
const remember = () => {
|
|
206
|
+
const rect = anchor()?.getBoundingClientRect();
|
|
207
|
+
if (!rect) return false;
|
|
208
|
+
const watched = watch ? watch() : NaN;
|
|
209
|
+
const moved = rect.left !== lastLeft || rect.top !== lastTop || rect.right !== lastRight || rect.bottom !== lastBottom || watched !== lastWatched && !(Number.isNaN(watched) && Number.isNaN(lastWatched));
|
|
210
|
+
lastLeft = rect.left;
|
|
211
|
+
lastTop = rect.top;
|
|
212
|
+
lastRight = rect.right;
|
|
213
|
+
lastBottom = rect.bottom;
|
|
214
|
+
lastWatched = watched;
|
|
215
|
+
return moved;
|
|
216
|
+
};
|
|
217
|
+
remember();
|
|
218
|
+
const run = () => {
|
|
219
|
+
remember();
|
|
220
|
+
onMove();
|
|
221
|
+
};
|
|
222
|
+
let raf = requestAnimationFrame(function tick() {
|
|
223
|
+
if (remember()) onMove();
|
|
224
|
+
raf = requestAnimationFrame(tick);
|
|
225
|
+
});
|
|
226
|
+
window.addEventListener("scroll", run, true);
|
|
227
|
+
window.addEventListener("resize", run);
|
|
228
|
+
return () => {
|
|
229
|
+
cancelAnimationFrame(raf);
|
|
230
|
+
window.removeEventListener("scroll", run, true);
|
|
231
|
+
window.removeEventListener("resize", run);
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function placeMenu({ trigger, menu, bounds, align, side }) {
|
|
235
|
+
const room = roomAround(trigger, bounds, MENU_GAP);
|
|
236
|
+
const other = side === "bottom" ? "top" : "bottom";
|
|
237
|
+
const chosen = menu.height > room[side] && (menu.height <= room[other] || room[other] > room[side]) ? other : side;
|
|
238
|
+
const maxHeight = Math.max(Math.min(menu.height, 96), room[chosen]);
|
|
239
|
+
const height = Math.min(menu.height, maxHeight);
|
|
240
|
+
const top = within(
|
|
241
|
+
chosen === "bottom" ? trigger.bottom + MENU_GAP : trigger.top - MENU_GAP - height,
|
|
242
|
+
bounds.top + VIEWPORT_MARGIN,
|
|
243
|
+
bounds.bottom - VIEWPORT_MARGIN - height
|
|
244
|
+
);
|
|
245
|
+
const maxWidth = Math.max(0, bounds.right - bounds.left - 2 * VIEWPORT_MARGIN);
|
|
246
|
+
const width = Math.min(menu.width, maxWidth);
|
|
247
|
+
const left = within(
|
|
248
|
+
align === "start" ? trigger.left : trigger.right - width,
|
|
249
|
+
bounds.left + VIEWPORT_MARGIN,
|
|
250
|
+
bounds.right - VIEWPORT_MARGIN - width
|
|
251
|
+
);
|
|
252
|
+
return { left, top, side: chosen, maxHeight, maxWidth };
|
|
253
|
+
}
|
|
175
254
|
function useDropdownPosition(triggerRef, open, options = {}) {
|
|
176
255
|
const {
|
|
177
256
|
matchTriggerWidth = false,
|
|
178
257
|
preferredMaxWidth = POPUP_MAX_WIDTH,
|
|
179
|
-
preferredMaxHeight = MENU_MAX_HEIGHT
|
|
258
|
+
preferredMaxHeight = MENU_MAX_HEIGHT,
|
|
259
|
+
popupRef
|
|
180
260
|
} = options;
|
|
181
261
|
const [pos, setPos] = useState(null);
|
|
182
262
|
useBrowserLayoutEffect(() => {
|
|
@@ -184,15 +264,10 @@ function useDropdownPosition(triggerRef, open, options = {}) {
|
|
|
184
264
|
setPos(null);
|
|
185
265
|
return;
|
|
186
266
|
}
|
|
187
|
-
let lastLeft = NaN, lastTop = NaN, lastRight = NaN, lastBottom = NaN;
|
|
188
267
|
const compute = () => {
|
|
189
268
|
const trigger = triggerRef.current;
|
|
190
269
|
const rect = trigger?.getBoundingClientRect();
|
|
191
270
|
if (!rect) return;
|
|
192
|
-
lastLeft = rect.left;
|
|
193
|
-
lastTop = rect.top;
|
|
194
|
-
lastRight = rect.right;
|
|
195
|
-
lastBottom = rect.bottom;
|
|
196
271
|
const bounds = popupBounds(trigger);
|
|
197
272
|
const spaceBelow = bounds.bottom - rect.bottom - MENU_GAP - VIEWPORT_MARGIN;
|
|
198
273
|
const spaceAbove = rect.top - bounds.top - MENU_GAP - VIEWPORT_MARGIN;
|
|
@@ -212,6 +287,13 @@ function useDropdownPosition(triggerRef, open, options = {}) {
|
|
|
212
287
|
Math.max(bounds.left + VIEWPORT_MARGIN, rect.left),
|
|
213
288
|
bounds.right - VIEWPORT_MARGIN - width
|
|
214
289
|
);
|
|
290
|
+
} else if (popupRef && bounds.right - VIEWPORT_MARGIN - rect.left < next.maxWidth && Math.min(rect.right, bounds.right - VIEWPORT_MARGIN) - bounds.left - VIEWPORT_MARGIN < next.maxWidth) {
|
|
291
|
+
const measured = popupRef.current?.offsetWidth ?? 0;
|
|
292
|
+
const width = measured > 0 ? Math.min(measured, next.maxWidth) : next.maxWidth;
|
|
293
|
+
next.left = Math.max(
|
|
294
|
+
bounds.left + VIEWPORT_MARGIN,
|
|
295
|
+
Math.min(rect.left, bounds.right - VIEWPORT_MARGIN - width)
|
|
296
|
+
);
|
|
215
297
|
} else if (bounds.right - VIEWPORT_MARGIN - rect.left < next.maxWidth) {
|
|
216
298
|
const rightEdge = Math.min(rect.right, bounds.right - VIEWPORT_MARGIN);
|
|
217
299
|
next.right = window.innerWidth - rightEdge;
|
|
@@ -227,21 +309,12 @@ function useDropdownPosition(triggerRef, open, options = {}) {
|
|
|
227
309
|
setPos(next);
|
|
228
310
|
};
|
|
229
311
|
compute();
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
});
|
|
237
|
-
window.addEventListener("scroll", compute, true);
|
|
238
|
-
window.addEventListener("resize", compute);
|
|
239
|
-
return () => {
|
|
240
|
-
cancelAnimationFrame(raf);
|
|
241
|
-
window.removeEventListener("scroll", compute, true);
|
|
242
|
-
window.removeEventListener("resize", compute);
|
|
243
|
-
};
|
|
244
|
-
}, [open, triggerRef, matchTriggerWidth, preferredMaxWidth, preferredMaxHeight]);
|
|
312
|
+
return followAnchor(
|
|
313
|
+
() => triggerRef.current,
|
|
314
|
+
compute,
|
|
315
|
+
popupRef ? () => popupRef.current?.offsetWidth ?? NaN : void 0
|
|
316
|
+
);
|
|
317
|
+
}, [open, triggerRef, matchTriggerWidth, preferredMaxWidth, preferredMaxHeight, popupRef]);
|
|
245
318
|
return pos;
|
|
246
319
|
}
|
|
247
320
|
|
|
@@ -1577,6 +1650,22 @@ function calendarNames(locale) {
|
|
|
1577
1650
|
localeNames.set(locale, names);
|
|
1578
1651
|
return names;
|
|
1579
1652
|
}
|
|
1653
|
+
var weekStarts = /* @__PURE__ */ new Map();
|
|
1654
|
+
function firstDayOfWeek(locale) {
|
|
1655
|
+
if (!locale) return 0;
|
|
1656
|
+
let first = weekStarts.get(locale);
|
|
1657
|
+
if (first === void 0) {
|
|
1658
|
+
first = 0;
|
|
1659
|
+
try {
|
|
1660
|
+
const tag = new Intl.Locale(locale);
|
|
1661
|
+
const info = typeof tag.getWeekInfo === "function" ? tag.getWeekInfo() : tag.weekInfo;
|
|
1662
|
+
if (info?.firstDay === 1) first = 1;
|
|
1663
|
+
} catch {
|
|
1664
|
+
}
|
|
1665
|
+
weekStarts.set(locale, first);
|
|
1666
|
+
}
|
|
1667
|
+
return first;
|
|
1668
|
+
}
|
|
1580
1669
|
var pad = (n) => String(n).padStart(2, "0");
|
|
1581
1670
|
function toKey(d) {
|
|
1582
1671
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
@@ -1618,7 +1707,7 @@ function Calendar({
|
|
|
1618
1707
|
month,
|
|
1619
1708
|
defaultMonth,
|
|
1620
1709
|
onMonthChange,
|
|
1621
|
-
weekStartsOn
|
|
1710
|
+
weekStartsOn: weekStartsOnProp,
|
|
1622
1711
|
quickJump = true,
|
|
1623
1712
|
"aria-label": ariaLabel,
|
|
1624
1713
|
className = ""
|
|
@@ -1627,7 +1716,10 @@ function Calendar({
|
|
|
1627
1716
|
const todayKey = useBrowserValue(readTodayKey, null);
|
|
1628
1717
|
const today = fromKey(todayKey);
|
|
1629
1718
|
const strings = useShellStrings().calendar;
|
|
1630
|
-
const
|
|
1719
|
+
const locale = useShellLocale();
|
|
1720
|
+
const names = calendarNames(locale);
|
|
1721
|
+
const localeWeekStart = useBrowserValue(() => firstDayOfWeek(locale), 0);
|
|
1722
|
+
const weekStartsOn = weekStartsOnProp ?? localeWeekStart;
|
|
1631
1723
|
const openingMonth = () => {
|
|
1632
1724
|
if (!today) return null;
|
|
1633
1725
|
const here = monthKey(today);
|
|
@@ -1876,7 +1968,13 @@ function DateRangePicker({
|
|
|
1876
1968
|
to,
|
|
1877
1969
|
onChange,
|
|
1878
1970
|
formatDisplay: formatDisplayProp,
|
|
1879
|
-
clearable
|
|
1971
|
+
clearable: clearableProp,
|
|
1972
|
+
required = false,
|
|
1973
|
+
name,
|
|
1974
|
+
id,
|
|
1975
|
+
"aria-labelledby": ariaLabelledBy,
|
|
1976
|
+
"aria-label": ariaLabel,
|
|
1977
|
+
weekStartsOn,
|
|
1880
1978
|
placeholder: placeholderProp,
|
|
1881
1979
|
fullWidth = false
|
|
1882
1980
|
}) {
|
|
@@ -1884,16 +1982,44 @@ function DateRangePicker({
|
|
|
1884
1982
|
const locale = useShellLocale();
|
|
1885
1983
|
const formatDisplay = formatDisplayProp ?? (locale ? localeFormatDisplay(locale) : defaultFormatDisplay);
|
|
1886
1984
|
const placeholder = placeholderProp ?? strings.placeholder;
|
|
1985
|
+
const clearable = clearableProp ?? !required;
|
|
1887
1986
|
const [open, setOpen] = useState(false);
|
|
1888
1987
|
const [tempFrom, setTempFrom] = useState(from);
|
|
1889
1988
|
const [tempTo, setTempTo] = useState(to);
|
|
1890
1989
|
const [activePreset, setActivePreset] = useState(null);
|
|
1891
1990
|
const ref = useRef(null);
|
|
1991
|
+
const triggerRef = useRef(null);
|
|
1892
1992
|
const panelRef = useRef(null);
|
|
1993
|
+
const panelId = useId();
|
|
1994
|
+
const descriptionId = useId();
|
|
1995
|
+
const [stacked, setStacked] = useState(false);
|
|
1893
1996
|
const pos = useDropdownPosition(ref, open, {
|
|
1894
1997
|
preferredMaxWidth: 520,
|
|
1895
|
-
preferredMaxHeight: 560
|
|
1998
|
+
preferredMaxHeight: stacked ? 720 : 560,
|
|
1999
|
+
popupRef: panelRef
|
|
2000
|
+
});
|
|
2001
|
+
const sideRowRef = useRef(null);
|
|
2002
|
+
const sideWidth = useRef(null);
|
|
2003
|
+
useBrowserLayoutEffect(() => {
|
|
2004
|
+
const panel = panelRef.current;
|
|
2005
|
+
if (!open || !pos || !panel) return;
|
|
2006
|
+
const style = getComputedStyle(panel);
|
|
2007
|
+
const room = pos.maxWidth - (panel.offsetWidth - panel.clientWidth) - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
|
|
2008
|
+
if (!stacked) {
|
|
2009
|
+
const natural = sideRowRef.current?.offsetWidth ?? 0;
|
|
2010
|
+
if (natural === 0) return;
|
|
2011
|
+
sideWidth.current = natural;
|
|
2012
|
+
if (natural > room + 0.5) setStacked(true);
|
|
2013
|
+
} else if (sideWidth.current !== null && sideWidth.current <= room) {
|
|
2014
|
+
setStacked(false);
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
const [hasLabelElement, setHasLabelElement] = useState(false);
|
|
2018
|
+
useBrowserLayoutEffect(() => {
|
|
2019
|
+
const labelled = !!id && (triggerRef.current?.labels?.length ?? 0) > 0;
|
|
2020
|
+
if (labelled !== hasLabelElement) setHasLabelElement(labelled);
|
|
1896
2021
|
});
|
|
2022
|
+
const namedElsewhere = !!ariaLabel || !!ariaLabelledBy || hasLabelElement;
|
|
1897
2023
|
const now = /* @__PURE__ */ new Date();
|
|
1898
2024
|
const [viewMonth, setViewMonth] = useState(() => monthKeyOf(from ? parseDate(from) : now));
|
|
1899
2025
|
const displayDate = (s) => s ? formatDisplay(s) : "";
|
|
@@ -1973,6 +2099,37 @@ function DateRangePicker({
|
|
|
1973
2099
|
setOpen(false);
|
|
1974
2100
|
};
|
|
1975
2101
|
const displayText = from && to ? `${displayDate(from)} \u2014 ${displayDate(to)}` : from ? strings.fromOnly(displayDate(from)) : to ? strings.toOnly(displayDate(to)) : "";
|
|
2102
|
+
const names = calendarNames(locale);
|
|
2103
|
+
const spoken = (iso) => {
|
|
2104
|
+
const d = fromKey(iso);
|
|
2105
|
+
return d ? names.longDate(d.getFullYear(), d.getMonth(), d.getDate()) : iso;
|
|
2106
|
+
};
|
|
2107
|
+
const description = from && to ? strings.range(spoken(from), spoken(to)) : from ? strings.fromOnly(spoken(from)) : to ? strings.toOnly(spoken(to)) : placeholder;
|
|
2108
|
+
const presetClass = (key) => stacked ? `rounded-md border px-2.5 py-1 text-sm transition-colors ${activePreset === key ? "border-blue-300 bg-blue-50 text-blue-700 font-medium" : "border-gray-200 text-gray-700 hover:bg-gray-50"}` : `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === key ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`;
|
|
2109
|
+
const presets = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2110
|
+
PRESETS.map((label) => /* @__PURE__ */ jsx("button", { type: "button", onClick: () => handlePreset(label), className: presetClass(label), children: strings[label] }, label)),
|
|
2111
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setActivePreset("Custom"), className: presetClass("Custom"), children: strings.custom })
|
|
2112
|
+
] });
|
|
2113
|
+
const calendar = (
|
|
2114
|
+
// The grid, its keyboard model and its ARIA all come from Calendar, which
|
|
2115
|
+
// is also what DatePicker draws — so a range and a single date look and
|
|
2116
|
+
// behave like the same control. This used to be 95 lines of hand-built
|
|
2117
|
+
// cells here with no arrow keys and a day whose accessible name was its
|
|
2118
|
+
// number.
|
|
2119
|
+
/* @__PURE__ */ jsx(
|
|
2120
|
+
Calendar,
|
|
2121
|
+
{
|
|
2122
|
+
mode: "range",
|
|
2123
|
+
value: tempFrom || null,
|
|
2124
|
+
endValue: tempTo || null,
|
|
2125
|
+
month: viewMonth,
|
|
2126
|
+
onMonthChange: setViewMonth,
|
|
2127
|
+
onSelect: handleCalendarSelect,
|
|
2128
|
+
weekStartsOn,
|
|
2129
|
+
"aria-label": strings.dialog
|
|
2130
|
+
}
|
|
2131
|
+
)
|
|
2132
|
+
);
|
|
1976
2133
|
return /* @__PURE__ */ jsxs("div", { className: `relative${fullWidth ? " w-full" : ""}`, ref, children: [
|
|
1977
2134
|
/* @__PURE__ */ jsxs(
|
|
1978
2135
|
"div",
|
|
@@ -1982,13 +2139,20 @@ function DateRangePicker({
|
|
|
1982
2139
|
/* @__PURE__ */ jsxs(
|
|
1983
2140
|
"button",
|
|
1984
2141
|
{
|
|
2142
|
+
ref: triggerRef,
|
|
1985
2143
|
type: "button",
|
|
1986
2144
|
onClick: handleOpen,
|
|
1987
2145
|
"aria-haspopup": "dialog",
|
|
1988
2146
|
"aria-expanded": open,
|
|
2147
|
+
id,
|
|
2148
|
+
"aria-label": ariaLabel,
|
|
2149
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2150
|
+
"aria-describedby": namedElsewhere ? descriptionId : void 0,
|
|
2151
|
+
"aria-controls": open ? panelId : void 0,
|
|
2152
|
+
"aria-required": required || void 0,
|
|
1989
2153
|
className: `inline-flex items-center gap-2 rosh-focus-ring${fullWidth ? " min-w-0 flex-1 justify-start" : ""}`,
|
|
1990
2154
|
children: [
|
|
1991
|
-
/* @__PURE__ */ jsx("svg", { className: "w-4 h-4 shrink-0", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
2155
|
+
/* @__PURE__ */ jsx("svg", { className: "w-4 h-4 shrink-0", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
1992
2156
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: displayText || placeholder })
|
|
1993
2157
|
]
|
|
1994
2158
|
}
|
|
@@ -2006,13 +2170,20 @@ function DateRangePicker({
|
|
|
2006
2170
|
]
|
|
2007
2171
|
}
|
|
2008
2172
|
),
|
|
2173
|
+
namedElsewhere && /* @__PURE__ */ jsx("span", { id: descriptionId, className: "sr-only", children: description }),
|
|
2174
|
+
name && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2175
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: name.from, value: from }),
|
|
2176
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: name.to, value: to })
|
|
2177
|
+
] }),
|
|
2009
2178
|
open && createPortal(
|
|
2010
2179
|
/* @__PURE__ */ jsxs(
|
|
2011
2180
|
"div",
|
|
2012
2181
|
{
|
|
2013
2182
|
ref: panelRef,
|
|
2183
|
+
id: panelId,
|
|
2014
2184
|
role: "dialog",
|
|
2015
2185
|
"aria-label": strings.dialog,
|
|
2186
|
+
"data-layout": stacked ? "stacked" : "side",
|
|
2016
2187
|
className: "fixed rounded-2xl p-4",
|
|
2017
2188
|
style: {
|
|
2018
2189
|
zIndex: Z_LAYERS.popup,
|
|
@@ -2022,8 +2193,9 @@ function DateRangePicker({
|
|
|
2022
2193
|
bottom: pos?.bottom,
|
|
2023
2194
|
// The panel states its own size. `max-content` is the calendar plus
|
|
2024
2195
|
// the presets column at whatever font size the reader has, and the
|
|
2025
|
-
// cap is what the owning window allows.
|
|
2026
|
-
|
|
2196
|
+
// cap is what the owning window allows. Stacked, it is the cap
|
|
2197
|
+
// itself: the calendar fills it, and its days are bigger targets.
|
|
2198
|
+
width: stacked && pos ? pos.maxWidth : "max-content",
|
|
2027
2199
|
maxWidth: pos?.maxWidth,
|
|
2028
2200
|
maxHeight: pos?.maxHeight,
|
|
2029
2201
|
overflowY: "auto",
|
|
@@ -2033,53 +2205,29 @@ function DateRangePicker({
|
|
|
2033
2205
|
...glassStyle()
|
|
2034
2206
|
},
|
|
2035
2207
|
children: [
|
|
2036
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
|
|
2037
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2208
|
+
/* @__PURE__ */ jsxs("div", { className: stacked ? "mb-3 flex flex-wrap items-center gap-x-4 gap-y-2" : "flex items-center gap-3 mb-3", children: [
|
|
2209
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 whitespace-nowrap", children: [
|
|
2038
2210
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500", children: strings.from }),
|
|
2039
2211
|
/* @__PURE__ */ jsx("span", { className: `text-sm px-2 py-1 rounded border min-w-[90px] ${tempFrom ? "border-blue-300 bg-blue-50 text-blue-700" : "border-gray-200 bg-gray-50 text-gray-400"}`, children: tempFrom ? displayDate(tempFrom) : strings.start })
|
|
2040
2212
|
] }),
|
|
2041
|
-
/* @__PURE__ */ jsx("span", { className: "text-gray-300", children: "\u2014" }),
|
|
2042
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2213
|
+
!stacked && /* @__PURE__ */ jsx("span", { className: "text-gray-300", children: "\u2014" }),
|
|
2214
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 whitespace-nowrap", children: [
|
|
2043
2215
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500", children: strings.to }),
|
|
2044
2216
|
/* @__PURE__ */ jsx("span", { className: `text-sm px-2 py-1 rounded border min-w-[90px] ${tempTo ? "border-blue-300 bg-blue-50 text-blue-700" : "border-gray-200 bg-gray-50 text-gray-400"}`, children: tempTo ? displayDate(tempTo) : strings.end })
|
|
2045
2217
|
] })
|
|
2046
2218
|
] }),
|
|
2047
|
-
/* @__PURE__ */ jsxs(
|
|
2048
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
onSelect: handleCalendarSelect,
|
|
2057
|
-
"aria-label": strings.dialog
|
|
2058
|
-
}
|
|
2059
|
-
) }),
|
|
2060
|
-
/* @__PURE__ */ jsxs("div", { className: "border-l border-gray-200 pl-4 flex flex-col gap-1 min-w-[130px]", children: [
|
|
2061
|
-
PRESETS.map((label) => /* @__PURE__ */ jsx(
|
|
2062
|
-
"button",
|
|
2063
|
-
{
|
|
2064
|
-
type: "button",
|
|
2065
|
-
onClick: () => handlePreset(label),
|
|
2066
|
-
className: `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === label ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
2067
|
-
children: strings[label]
|
|
2068
|
-
},
|
|
2069
|
-
label
|
|
2070
|
-
)),
|
|
2071
|
-
/* @__PURE__ */ jsx(
|
|
2072
|
-
"button",
|
|
2073
|
-
{
|
|
2074
|
-
type: "button",
|
|
2075
|
-
onClick: () => setActivePreset("Custom"),
|
|
2076
|
-
className: `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === "Custom" ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
2077
|
-
children: strings.custom
|
|
2078
|
-
}
|
|
2079
|
-
)
|
|
2219
|
+
stacked ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2220
|
+
/* @__PURE__ */ jsx("div", { className: "mb-3 flex flex-wrap gap-1.5", children: presets }),
|
|
2221
|
+
/* @__PURE__ */ jsx("div", { className: "w-full", children: calendar })
|
|
2222
|
+
] }) : (
|
|
2223
|
+
// `w-max`: the row is drawn at its natural width even in a panel
|
|
2224
|
+
// capped narrower, which is what the measurement above reads.
|
|
2225
|
+
/* @__PURE__ */ jsxs("div", { ref: sideRowRef, className: "flex w-max gap-4", children: [
|
|
2226
|
+
/* @__PURE__ */ jsx("div", { className: "w-64", children: calendar }),
|
|
2227
|
+
/* @__PURE__ */ jsx("div", { className: "border-l border-gray-200 pl-4 flex flex-col gap-1 min-w-[130px]", children: presets })
|
|
2080
2228
|
] })
|
|
2081
|
-
|
|
2082
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 mt-4 pt-3 border-t border-gray-200", children: [
|
|
2229
|
+
),
|
|
2230
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap justify-end gap-2 mt-4 pt-3 border-t border-gray-200", children: [
|
|
2083
2231
|
clearable && /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClear, className: "px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700", children: strings.clear }),
|
|
2084
2232
|
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(false), className: "px-3 py-1.5 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50", children: strings.cancel }),
|
|
2085
2233
|
/* @__PURE__ */ jsx(
|
|
@@ -2133,6 +2281,7 @@ var TimePicker = forwardRef(function TimePicker2({ value, onChange, min, max, in
|
|
|
2133
2281
|
});
|
|
2134
2282
|
var TimePicker_default = TimePicker;
|
|
2135
2283
|
var ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
2284
|
+
var GLOBAL_ATTRIBUTE = /^(aria|data)-/;
|
|
2136
2285
|
function toInputValue2(value) {
|
|
2137
2286
|
if (value === null || value === void 0 || value === "") return "";
|
|
2138
2287
|
if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : toISODate(value);
|
|
@@ -2162,12 +2311,22 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2162
2311
|
className = "",
|
|
2163
2312
|
"aria-label": ariaLabel,
|
|
2164
2313
|
"aria-describedby": describedBy,
|
|
2314
|
+
"aria-labelledby": labelledBy,
|
|
2165
2315
|
id,
|
|
2166
2316
|
name,
|
|
2167
2317
|
disabled,
|
|
2168
2318
|
placeholder,
|
|
2319
|
+
required,
|
|
2320
|
+
clearable: clearableProp,
|
|
2321
|
+
form,
|
|
2322
|
+
title,
|
|
2323
|
+
tabIndex,
|
|
2324
|
+
autoFocus,
|
|
2325
|
+
onFocus,
|
|
2326
|
+
onBlur,
|
|
2169
2327
|
...rest
|
|
2170
2328
|
}, ref) {
|
|
2329
|
+
const clearable = clearableProp ?? !required;
|
|
2171
2330
|
const current = toInputValue2(value);
|
|
2172
2331
|
const lo = toInputValue2(min);
|
|
2173
2332
|
const hi = toInputValue2(max);
|
|
@@ -2179,7 +2338,14 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2179
2338
|
const triggerRef = useRef(null);
|
|
2180
2339
|
const panelRef = useRef(null);
|
|
2181
2340
|
const panelId = useId();
|
|
2182
|
-
const
|
|
2341
|
+
const valueId = useId();
|
|
2342
|
+
const pos = useDropdownPosition(triggerRef, open, { popupRef: panelRef });
|
|
2343
|
+
const [hasLabelElement, setHasLabelElement] = useState(false);
|
|
2344
|
+
useBrowserLayoutEffect(() => {
|
|
2345
|
+
const labelled = !!id && (triggerRef.current?.labels?.length ?? 0) > 0;
|
|
2346
|
+
if (labelled !== hasLabelElement) setHasLabelElement(labelled);
|
|
2347
|
+
});
|
|
2348
|
+
const describeValue = !ariaLabel && (!!labelledBy || hasLabelElement);
|
|
2183
2349
|
useEffect(() => {
|
|
2184
2350
|
if (!open) return;
|
|
2185
2351
|
const onPointerDown = (e) => {
|
|
@@ -2221,33 +2387,56 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2221
2387
|
max: hi || void 0,
|
|
2222
2388
|
onChange: (event) => onChange?.(fromInputValue(event.target.value)),
|
|
2223
2389
|
className: inputClasses({ invalid, size, className }),
|
|
2390
|
+
"aria-labelledby": labelledBy,
|
|
2391
|
+
required,
|
|
2392
|
+
form,
|
|
2393
|
+
title,
|
|
2394
|
+
tabIndex,
|
|
2395
|
+
autoFocus,
|
|
2396
|
+
onFocus,
|
|
2397
|
+
onBlur,
|
|
2224
2398
|
...rest
|
|
2225
2399
|
}
|
|
2226
2400
|
);
|
|
2227
2401
|
}
|
|
2402
|
+
const triggerAttributes = Object.fromEntries(
|
|
2403
|
+
Object.entries(rest).filter(([key]) => GLOBAL_ATTRIBUTE.test(key))
|
|
2404
|
+
);
|
|
2405
|
+
const todayKey = toISODate(/* @__PURE__ */ new Date());
|
|
2406
|
+
const todayAllowed = (!lo || todayKey >= lo) && (!hi || todayKey <= hi);
|
|
2407
|
+
const placeholderText = placeholder ?? strings.placeholder;
|
|
2228
2408
|
return /* @__PURE__ */ jsxs("div", { ref: wrapRef, className: "relative", children: [
|
|
2229
|
-
/* @__PURE__ */ jsx("input", { ref, type: "hidden", name, value: current }),
|
|
2409
|
+
/* @__PURE__ */ jsx("input", { ref, type: "hidden", name, form, value: current }),
|
|
2230
2410
|
/* @__PURE__ */ jsxs(
|
|
2231
2411
|
"button",
|
|
2232
2412
|
{
|
|
2233
2413
|
ref: triggerRef,
|
|
2234
2414
|
type: "button",
|
|
2415
|
+
...triggerAttributes,
|
|
2235
2416
|
id,
|
|
2236
2417
|
disabled,
|
|
2418
|
+
title,
|
|
2419
|
+
tabIndex,
|
|
2420
|
+
autoFocus,
|
|
2421
|
+
onFocus,
|
|
2422
|
+
onBlur,
|
|
2237
2423
|
"aria-haspopup": "dialog",
|
|
2238
2424
|
"aria-expanded": open,
|
|
2239
2425
|
"aria-controls": open ? panelId : void 0,
|
|
2240
|
-
"aria-
|
|
2426
|
+
"aria-labelledby": labelledBy,
|
|
2427
|
+
"aria-describedby": [describeValue ? valueId : void 0, describedBy].filter(Boolean).join(" ") || void 0,
|
|
2241
2428
|
"aria-invalid": invalid || void 0,
|
|
2429
|
+
"aria-required": required || void 0,
|
|
2242
2430
|
"aria-label": ariaLabel ? `${ariaLabel}${current ? `, ${display(current, names)}` : ""}` : void 0,
|
|
2243
2431
|
onClick: () => setOpen((o) => !o),
|
|
2244
2432
|
className: `${inputClasses({ invalid, size, className })} flex items-center justify-between text-left`,
|
|
2245
2433
|
children: [
|
|
2246
|
-
/* @__PURE__ */ jsx("span", { className: current ? "text-gray-900" : "text-gray-400", children: current ? display(current, names) :
|
|
2434
|
+
/* @__PURE__ */ jsx("span", { className: current ? "text-gray-900" : "text-gray-400", children: current ? display(current, names) : placeholderText }),
|
|
2247
2435
|
/* @__PURE__ */ jsx("svg", { className: "h-4 w-4 shrink-0 text-gray-400", fill: "none", stroke: "currentColor", strokeWidth: "1.75", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8 7V3m8 4V3M4 11h16M5 7h14a1 1 0 011 1v11a1 1 0 01-1 1H5a1 1 0 01-1-1V8a1 1 0 011-1z" }) })
|
|
2248
2436
|
]
|
|
2249
2437
|
}
|
|
2250
2438
|
),
|
|
2439
|
+
describeValue && /* @__PURE__ */ jsx("span", { id: valueId, className: "sr-only", children: current ? display(current, names) : placeholderText }),
|
|
2251
2440
|
open && createPortal(
|
|
2252
2441
|
/* @__PURE__ */ jsxs(
|
|
2253
2442
|
"div",
|
|
@@ -2263,6 +2452,9 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2263
2452
|
right: pos?.right,
|
|
2264
2453
|
top: pos?.top,
|
|
2265
2454
|
bottom: pos?.bottom,
|
|
2455
|
+
// 288 px where it fits; narrower, never past the box's margins,
|
|
2456
|
+
// in a box that cannot hold that.
|
|
2457
|
+
maxWidth: pos?.maxWidth,
|
|
2266
2458
|
// Hidden for the first paint until the layout effect measures the
|
|
2267
2459
|
// trigger, so the panel never flashes at (0,0).
|
|
2268
2460
|
visibility: pos ? void 0 : "hidden"
|
|
@@ -2282,8 +2474,8 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2282
2474
|
}
|
|
2283
2475
|
}
|
|
2284
2476
|
),
|
|
2285
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex justify-between border-t border-gray-100 pt-2", children: [
|
|
2286
|
-
/* @__PURE__ */ jsx(
|
|
2477
|
+
(clearable || todayAllowed) && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex justify-between border-t border-gray-100 pt-2", children: [
|
|
2478
|
+
clearable && /* @__PURE__ */ jsx(
|
|
2287
2479
|
"button",
|
|
2288
2480
|
{
|
|
2289
2481
|
type: "button",
|
|
@@ -2296,7 +2488,7 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2296
2488
|
children: strings.clear
|
|
2297
2489
|
}
|
|
2298
2490
|
),
|
|
2299
|
-
/* @__PURE__ */ jsx(
|
|
2491
|
+
todayAllowed && /* @__PURE__ */ jsx(
|
|
2300
2492
|
"button",
|
|
2301
2493
|
{
|
|
2302
2494
|
type: "button",
|
|
@@ -2305,7 +2497,7 @@ var DatePicker = forwardRef(function DatePicker2({
|
|
|
2305
2497
|
triggerRef.current?.focus();
|
|
2306
2498
|
onChange?.(/* @__PURE__ */ new Date());
|
|
2307
2499
|
},
|
|
2308
|
-
className: "rounded-md px-2 py-1 text-sm font-medium text-blue-600 hover:bg-blue-50",
|
|
2500
|
+
className: "ml-auto rounded-md px-2 py-1 text-sm font-medium text-blue-600 hover:bg-blue-50",
|
|
2309
2501
|
children: strings.today
|
|
2310
2502
|
}
|
|
2311
2503
|
)
|
|
@@ -4269,12 +4461,15 @@ function Accordion({
|
|
|
4269
4461
|
}) });
|
|
4270
4462
|
}
|
|
4271
4463
|
var SIDE_POS = {
|
|
4272
|
-
top: "bottom-full left-1/2 -translate-x-1/2 mb-
|
|
4273
|
-
bottom: "top-full left-1/2 -translate-x-1/2 mt-
|
|
4274
|
-
left: "right-full top-1/2 -translate-y-1/2 mr-
|
|
4275
|
-
right: "left-full top-1/2 -translate-y-1/2 ml-
|
|
4464
|
+
top: "bottom-full left-1/2 -translate-x-1/2 mb-3",
|
|
4465
|
+
bottom: "top-full left-1/2 -translate-x-1/2 mt-3",
|
|
4466
|
+
left: "right-full top-1/2 -translate-y-1/2 mr-3",
|
|
4467
|
+
right: "left-full top-1/2 -translate-y-1/2 ml-3"
|
|
4276
4468
|
};
|
|
4277
4469
|
var GAP2 = 6;
|
|
4470
|
+
var ARROW_DEPTH = 6;
|
|
4471
|
+
var ARROW_INSET = 16;
|
|
4472
|
+
var samePlace = (a, b) => a.left === b.left && a.top === b.top && a.maxWidth === b.maxWidth && a.maxHeight === b.maxHeight && a.side === b.side && a.arrow?.left === b.arrow?.left && a.arrow?.top === b.arrow?.top;
|
|
4278
4473
|
function Tooltip({ content, side = "top", delay = 200, children }) {
|
|
4279
4474
|
const [show, setShow] = useState(false);
|
|
4280
4475
|
const [placed, setPlaced] = useState(null);
|
|
@@ -4301,13 +4496,23 @@ function Tooltip({ content, side = "top", delay = 200, children }) {
|
|
|
4301
4496
|
if (!wrap || !tip) return;
|
|
4302
4497
|
const bounds = popupBounds(wrap);
|
|
4303
4498
|
const maxWidth = Math.max(0, bounds.right - bounds.left - 2 * VIEWPORT_MARGIN);
|
|
4499
|
+
const maxHeight = Math.max(0, bounds.bottom - bounds.top - 2 * VIEWPORT_MARGIN);
|
|
4304
4500
|
tip.style.maxWidth = `${maxWidth}px`;
|
|
4501
|
+
tip.style.maxHeight = `${maxHeight}px`;
|
|
4305
4502
|
const size = tip.getBoundingClientRect();
|
|
4306
4503
|
if (size.width <= 0 || size.height <= 0) return;
|
|
4307
4504
|
const anchor = wrap.getBoundingClientRect();
|
|
4308
|
-
const at = placeBeside(anchor, size, side, bounds, GAP2);
|
|
4309
|
-
const
|
|
4310
|
-
|
|
4505
|
+
const at = placeBeside(anchor, size, side, bounds, GAP2 + ARROW_DEPTH);
|
|
4506
|
+
const point = placeArrow(anchor, at, size, ARROW_INSET, ARROW_DEPTH);
|
|
4507
|
+
const next = {
|
|
4508
|
+
left: at.left - anchor.left,
|
|
4509
|
+
top: at.top - anchor.top,
|
|
4510
|
+
maxWidth,
|
|
4511
|
+
maxHeight,
|
|
4512
|
+
side: at.side,
|
|
4513
|
+
arrow: point && { left: point.x - anchor.left, top: point.y - anchor.top }
|
|
4514
|
+
};
|
|
4515
|
+
setPlaced((prev) => prev && samePlace(prev, next) ? prev : next);
|
|
4311
4516
|
};
|
|
4312
4517
|
place();
|
|
4313
4518
|
window.addEventListener("scroll", place, true);
|
|
@@ -4329,6 +4534,8 @@ function Tooltip({ content, side = "top", delay = 200, children }) {
|
|
|
4329
4534
|
const trigger = isValidElement(children) ? cloneElement(children, {
|
|
4330
4535
|
"aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" ") || void 0
|
|
4331
4536
|
}) : children;
|
|
4537
|
+
const glass = show ? glassStyle() : void 0;
|
|
4538
|
+
const fill = show ? glassFill() : void 0;
|
|
4332
4539
|
return /* @__PURE__ */ jsxs(
|
|
4333
4540
|
"span",
|
|
4334
4541
|
{
|
|
@@ -4347,6 +4554,8 @@ function Tooltip({ content, side = "top", delay = 200, children }) {
|
|
|
4347
4554
|
// its window is wide wraps inside it instead of running past both
|
|
4348
4555
|
// edges. `whitespace-normal` and `text-start` so a trigger inside a
|
|
4349
4556
|
// `nowrap` or right-aligned cell does not hand the bubble its own.
|
|
4557
|
+
// `box-border` so the caps measure the whole bubble, padding and
|
|
4558
|
+
// border included, in a host without Tailwind's preflight.
|
|
4350
4559
|
// Nothing here animates, so there is no motion to reduce.
|
|
4351
4560
|
/* @__PURE__ */ jsx(
|
|
4352
4561
|
"span",
|
|
@@ -4354,13 +4563,46 @@ function Tooltip({ content, side = "top", delay = 200, children }) {
|
|
|
4354
4563
|
ref: tipRef,
|
|
4355
4564
|
id,
|
|
4356
4565
|
role: "tooltip",
|
|
4357
|
-
className: `pointer-events-none absolute z-[300] w-max whitespace-normal break-words text-start rounded-md px-2 py-1 text-xs text-gray-800 ${placed ? "" : SIDE_POS[side]}`,
|
|
4566
|
+
className: `pointer-events-none absolute z-[300] box-border w-max overflow-hidden whitespace-normal break-words text-start rounded-md px-2 py-1 text-xs text-gray-800 ${placed ? "" : SIDE_POS[side]}`,
|
|
4358
4567
|
style: {
|
|
4359
|
-
...
|
|
4360
|
-
...placed && {
|
|
4568
|
+
...glass,
|
|
4569
|
+
...placed && {
|
|
4570
|
+
left: placed.left,
|
|
4571
|
+
top: placed.top,
|
|
4572
|
+
maxWidth: placed.maxWidth,
|
|
4573
|
+
maxHeight: placed.maxHeight
|
|
4574
|
+
}
|
|
4361
4575
|
},
|
|
4362
4576
|
children: content
|
|
4363
4577
|
}
|
|
4578
|
+
),
|
|
4579
|
+
show && (!placed || placed.arrow) && // The arrow is the bubble's SIBLING, not its child: the bubble is
|
|
4580
|
+
// `overflow: hidden` for its height cap, and an arrow inside it would
|
|
4581
|
+
// be cut off at the very edge it is meant to stand out from. Drawn after
|
|
4582
|
+
// the bubble on the same layer, so it lies over the bubble's border
|
|
4583
|
+
// where the two meet and there is no seam.
|
|
4584
|
+
//
|
|
4585
|
+
// `data-side` is the side the BUBBLE is on, after any flip; ui.css
|
|
4586
|
+
// turns it into which way the arrow points and which two of its edges
|
|
4587
|
+
// carry the border. Unmeasured, it is the side asked for and ui.css
|
|
4588
|
+
// centres the arrow there, as `SIDE_POS` centres the bubble.
|
|
4589
|
+
//
|
|
4590
|
+
// Decorative: the bubble's text is the description, and the arrow says
|
|
4591
|
+
// nothing a screen reader needs.
|
|
4592
|
+
/* @__PURE__ */ jsx(
|
|
4593
|
+
"span",
|
|
4594
|
+
{
|
|
4595
|
+
"aria-hidden": "true",
|
|
4596
|
+
className: "rosh-tooltip-arrow",
|
|
4597
|
+
"data-side": placed?.side ?? side,
|
|
4598
|
+
style: {
|
|
4599
|
+
background: fill,
|
|
4600
|
+
// The bubble's border as one value, for ui.css to put on the two
|
|
4601
|
+
// edges that face outward — the side's own rule picks which.
|
|
4602
|
+
["--rosh-tooltip-edge"]: glass?.border,
|
|
4603
|
+
...placed?.arrow && { left: placed.arrow.left, top: placed.arrow.top }
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4364
4606
|
)
|
|
4365
4607
|
]
|
|
4366
4608
|
}
|
|
@@ -8419,6 +8661,12 @@ function TopNav({ items, activeKey, onSelect, brand, actions, className }) {
|
|
|
8419
8661
|
}
|
|
8420
8662
|
);
|
|
8421
8663
|
}
|
|
8664
|
+
var TRIGGER_CLASS = "inline-flex items-center justify-center rounded-md text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 rosh-focus-ring focus-visible:ring-2 focus-visible:ring-[color:var(--rosh-focus-ring-solid)] disabled:cursor-not-allowed disabled:opacity-60";
|
|
8665
|
+
var OWNS_Z = /(^|[\s:])!?z-/;
|
|
8666
|
+
var TYPEAHEAD_MS = 500;
|
|
8667
|
+
var CHECK = /* @__PURE__ */ jsx("svg", { "aria-hidden": true, className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4.5 12.75l6 6 9-13.5" }) });
|
|
8668
|
+
var isLink = (entry) => entry.type === "link" || entry.type === void 0 && typeof entry.href === "string";
|
|
8669
|
+
var isFocusable = (entry) => !!entry && entry.type !== "label" && entry.type !== "divider" && !entry.disabled;
|
|
8422
8670
|
function DropdownMenu({
|
|
8423
8671
|
trigger,
|
|
8424
8672
|
items,
|
|
@@ -8426,35 +8674,84 @@ function DropdownMenu({
|
|
|
8426
8674
|
side = "bottom",
|
|
8427
8675
|
"aria-label": ariaLabel,
|
|
8428
8676
|
className = "",
|
|
8677
|
+
triggerClassName,
|
|
8678
|
+
menuClassName = "",
|
|
8679
|
+
minWidth = 180,
|
|
8680
|
+
linkAs,
|
|
8429
8681
|
disabled
|
|
8430
8682
|
}) {
|
|
8431
8683
|
const [open, setOpen] = useState(false);
|
|
8432
|
-
const [active, setActive] = useState(
|
|
8684
|
+
const [active, setActive] = useState(-1);
|
|
8433
8685
|
const wrapRef = useRef(null);
|
|
8434
8686
|
const triggerRef = useRef(null);
|
|
8435
|
-
const
|
|
8687
|
+
const menuRef = useRef(null);
|
|
8688
|
+
const typed = useRef({ text: "", at: 0 });
|
|
8436
8689
|
const menuId = useId();
|
|
8690
|
+
const triggerId = useId();
|
|
8437
8691
|
const close = useCallback((restoreFocus) => {
|
|
8438
8692
|
setOpen(false);
|
|
8439
8693
|
if (restoreFocus) triggerRef.current?.focus();
|
|
8440
8694
|
}, []);
|
|
8441
|
-
const
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8695
|
+
const focusableFrom = (from, step) => {
|
|
8696
|
+
const n = items.length;
|
|
8697
|
+
for (let i = 0; i < n; i += 1) {
|
|
8698
|
+
const at = ((from + step * i) % n + n) % n;
|
|
8699
|
+
if (isFocusable(items[at])) return at;
|
|
8445
8700
|
}
|
|
8446
|
-
return
|
|
8701
|
+
return -1;
|
|
8447
8702
|
};
|
|
8703
|
+
const surface = () => menuRef.current?.closest("[data-popup-menu-tree]") ?? null;
|
|
8448
8704
|
useEffect(() => {
|
|
8449
8705
|
if (!open) return;
|
|
8450
8706
|
const onPointerDown = (e) => {
|
|
8451
|
-
|
|
8707
|
+
const target = e.target;
|
|
8708
|
+
if (wrapRef.current?.contains(target) || surface()?.contains(target)) return;
|
|
8709
|
+
close(false);
|
|
8452
8710
|
};
|
|
8453
8711
|
document.addEventListener("pointerdown", onPointerDown, true);
|
|
8454
|
-
|
|
8712
|
+
const offOverlay = onOverlayOpen(() => close(false));
|
|
8713
|
+
return () => {
|
|
8714
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
8715
|
+
offOverlay();
|
|
8716
|
+
};
|
|
8455
8717
|
}, [open, close]);
|
|
8718
|
+
const place = useCallback(() => {
|
|
8719
|
+
const el = surface();
|
|
8720
|
+
const anchor = triggerRef.current;
|
|
8721
|
+
if (!el || !anchor) return;
|
|
8722
|
+
const s = el.style;
|
|
8723
|
+
s.left = "0px";
|
|
8724
|
+
s.top = "0px";
|
|
8725
|
+
s.maxWidth = "none";
|
|
8726
|
+
s.maxHeight = "none";
|
|
8727
|
+
const size = { width: el.offsetWidth, height: el.offsetHeight };
|
|
8728
|
+
const at = placeMenu({
|
|
8729
|
+
trigger: anchor.getBoundingClientRect(),
|
|
8730
|
+
menu: size,
|
|
8731
|
+
bounds: popupBounds(anchor),
|
|
8732
|
+
align,
|
|
8733
|
+
side
|
|
8734
|
+
});
|
|
8735
|
+
s.left = `${at.left}px`;
|
|
8736
|
+
s.top = `${at.top}px`;
|
|
8737
|
+
s.maxWidth = `${at.maxWidth}px`;
|
|
8738
|
+
s.maxHeight = `${at.maxHeight}px`;
|
|
8739
|
+
s.overflowY = size.height > at.maxHeight ? "auto" : "";
|
|
8740
|
+
el.dataset.side = at.side;
|
|
8741
|
+
el.dataset.align = align;
|
|
8742
|
+
}, [align, side]);
|
|
8743
|
+
useBrowserLayoutEffect(() => {
|
|
8744
|
+
if (open) place();
|
|
8745
|
+
});
|
|
8746
|
+
useEffect(() => {
|
|
8747
|
+
if (!open) return;
|
|
8748
|
+
return followAnchor(() => triggerRef.current, place);
|
|
8749
|
+
}, [open, place]);
|
|
8456
8750
|
useEffect(() => {
|
|
8457
|
-
if (open)
|
|
8751
|
+
if (!open) return;
|
|
8752
|
+
const menu = menuRef.current;
|
|
8753
|
+
const target = isFocusable(items[active]) ? menu?.querySelector(`[data-dropdown-index="${active}"]`) : null;
|
|
8754
|
+
(target ?? menu)?.focus({ preventScroll: true });
|
|
8458
8755
|
}, [open, active]);
|
|
8459
8756
|
useEffect(() => {
|
|
8460
8757
|
if (!open) return;
|
|
@@ -8471,80 +8768,212 @@ function DropdownMenu({
|
|
|
8471
8768
|
const onTriggerKeyDown = (e) => {
|
|
8472
8769
|
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
8473
8770
|
e.preventDefault();
|
|
8474
|
-
openAt(
|
|
8771
|
+
openAt(focusableFrom(0, 1));
|
|
8475
8772
|
} else if (e.key === "ArrowUp") {
|
|
8476
8773
|
e.preventDefault();
|
|
8477
|
-
openAt(
|
|
8774
|
+
openAt(focusableFrom(items.length - 1, -1));
|
|
8775
|
+
}
|
|
8776
|
+
};
|
|
8777
|
+
const typeahead = (e) => {
|
|
8778
|
+
const now = Date.now();
|
|
8779
|
+
const char = e.key.toLowerCase();
|
|
8780
|
+
const text = now - typed.current.at < TYPEAHEAD_MS ? typed.current.text + char : char;
|
|
8781
|
+
typed.current = { text, at: now };
|
|
8782
|
+
const repeated = [...text].every((c) => c === text[0]);
|
|
8783
|
+
const query = repeated ? text[0] : text;
|
|
8784
|
+
const from = repeated ? active + 1 : Math.max(active, 0);
|
|
8785
|
+
const menu = menuRef.current;
|
|
8786
|
+
const n = items.length;
|
|
8787
|
+
for (let i = 0; i < n; i += 1) {
|
|
8788
|
+
const at = ((from + i) % n + n) % n;
|
|
8789
|
+
if (!isFocusable(items[at])) continue;
|
|
8790
|
+
const label = menu?.querySelector(`[data-dropdown-index="${at}"]`)?.textContent?.trim().toLowerCase() ?? "";
|
|
8791
|
+
if (label.startsWith(query)) {
|
|
8792
|
+
e.preventDefault();
|
|
8793
|
+
setActive(at);
|
|
8794
|
+
return;
|
|
8795
|
+
}
|
|
8478
8796
|
}
|
|
8479
8797
|
};
|
|
8480
8798
|
const onMenuKeyDown = (e) => {
|
|
8481
8799
|
if (e.key === "ArrowDown") {
|
|
8482
8800
|
e.preventDefault();
|
|
8483
|
-
setActive(
|
|
8801
|
+
setActive(focusableFrom(active + 1, 1));
|
|
8484
8802
|
} else if (e.key === "ArrowUp") {
|
|
8485
8803
|
e.preventDefault();
|
|
8486
|
-
setActive(
|
|
8804
|
+
setActive(focusableFrom(active - 1, -1));
|
|
8487
8805
|
} else if (e.key === "Home") {
|
|
8488
8806
|
e.preventDefault();
|
|
8489
|
-
setActive(
|
|
8807
|
+
setActive(focusableFrom(0, 1));
|
|
8490
8808
|
} else if (e.key === "End") {
|
|
8491
8809
|
e.preventDefault();
|
|
8492
|
-
setActive(
|
|
8810
|
+
setActive(focusableFrom(items.length - 1, -1));
|
|
8493
8811
|
} else if (e.key === "Tab") {
|
|
8494
8812
|
e.preventDefault();
|
|
8495
8813
|
close(true);
|
|
8814
|
+
} else if (e.key === " ") {
|
|
8815
|
+
const target = e.target;
|
|
8816
|
+
if (target.matches?.("a[href]")) {
|
|
8817
|
+
e.preventDefault();
|
|
8818
|
+
target.click();
|
|
8819
|
+
}
|
|
8820
|
+
} else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
8821
|
+
typeahead(e);
|
|
8496
8822
|
}
|
|
8497
8823
|
};
|
|
8498
|
-
const
|
|
8499
|
-
if (
|
|
8824
|
+
const choose = (entry) => {
|
|
8825
|
+
if (entry.disabled) return;
|
|
8500
8826
|
close(true);
|
|
8501
|
-
|
|
8827
|
+
entry.onSelect();
|
|
8828
|
+
};
|
|
8829
|
+
const Link = linkAs ?? "a";
|
|
8830
|
+
const rowProps = (i, entry) => ({
|
|
8831
|
+
"data-dropdown-index": i,
|
|
8832
|
+
// One tab stop for the whole menu; the arrows move inside it.
|
|
8833
|
+
tabIndex: i === active ? 0 : -1,
|
|
8834
|
+
onMouseEnter: () => {
|
|
8835
|
+
if (!entry.disabled) setActive(i);
|
|
8836
|
+
}
|
|
8837
|
+
});
|
|
8838
|
+
const renderEntry = (entry, i) => {
|
|
8839
|
+
if (entry.type === "divider") {
|
|
8840
|
+
return /* @__PURE__ */ jsx("div", { role: "separator", children: /* @__PURE__ */ jsx(PopupMenuDivider, {}) }, entry.key);
|
|
8841
|
+
}
|
|
8842
|
+
if (entry.type === "label") {
|
|
8843
|
+
return /* @__PURE__ */ jsx("div", { id: `${menuId}-label-${i}`, children: /* @__PURE__ */ jsx(PopupMenuLabel, { children: entry.label }) }, entry.key);
|
|
8844
|
+
}
|
|
8845
|
+
if (entry.type === "radio") {
|
|
8846
|
+
const look2 = itemLook(false, entry.disabled, "");
|
|
8847
|
+
return /* @__PURE__ */ jsxs(
|
|
8848
|
+
"button",
|
|
8849
|
+
{
|
|
8850
|
+
type: "button",
|
|
8851
|
+
role: "menuitemradio",
|
|
8852
|
+
"aria-checked": entry.checked,
|
|
8853
|
+
disabled: entry.disabled,
|
|
8854
|
+
className: look2.className,
|
|
8855
|
+
style: look2.style,
|
|
8856
|
+
onClick: () => choose(entry),
|
|
8857
|
+
...rowProps(i, entry),
|
|
8858
|
+
children: [
|
|
8859
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "inline-flex h-4 w-4 shrink-0 items-center justify-center", children: entry.checked && CHECK }),
|
|
8860
|
+
entry.icon,
|
|
8861
|
+
entry.label
|
|
8862
|
+
]
|
|
8863
|
+
},
|
|
8864
|
+
entry.key
|
|
8865
|
+
);
|
|
8866
|
+
}
|
|
8867
|
+
if (isLink(entry)) {
|
|
8868
|
+
const look2 = itemLook(false, entry.disabled, `no-underline ${entry.current ? "font-medium" : ""}`);
|
|
8869
|
+
if (entry.disabled) {
|
|
8870
|
+
return /* @__PURE__ */ jsxs("a", { role: "menuitem", "aria-disabled": "true", className: look2.className, style: look2.style, ...rowProps(i, entry), children: [
|
|
8871
|
+
entry.icon,
|
|
8872
|
+
entry.label
|
|
8873
|
+
] }, entry.key);
|
|
8874
|
+
}
|
|
8875
|
+
return /* @__PURE__ */ jsxs(
|
|
8876
|
+
Link,
|
|
8877
|
+
{
|
|
8878
|
+
href: entry.href,
|
|
8879
|
+
role: "menuitem",
|
|
8880
|
+
"aria-current": entry.current ? "page" : void 0,
|
|
8881
|
+
className: look2.className,
|
|
8882
|
+
style: look2.style,
|
|
8883
|
+
onClick: () => close(true),
|
|
8884
|
+
...rowProps(i, entry),
|
|
8885
|
+
children: [
|
|
8886
|
+
entry.icon,
|
|
8887
|
+
entry.label
|
|
8888
|
+
]
|
|
8889
|
+
},
|
|
8890
|
+
entry.key
|
|
8891
|
+
);
|
|
8892
|
+
}
|
|
8893
|
+
const look = itemLook(entry.danger, entry.disabled, "");
|
|
8894
|
+
return /* @__PURE__ */ jsxs(
|
|
8895
|
+
"button",
|
|
8896
|
+
{
|
|
8897
|
+
type: "button",
|
|
8898
|
+
role: "menuitem",
|
|
8899
|
+
disabled: entry.disabled,
|
|
8900
|
+
className: look.className,
|
|
8901
|
+
style: look.style,
|
|
8902
|
+
onClick: () => choose(entry),
|
|
8903
|
+
...rowProps(i, entry),
|
|
8904
|
+
children: [
|
|
8905
|
+
entry.icon,
|
|
8906
|
+
entry.label
|
|
8907
|
+
]
|
|
8908
|
+
},
|
|
8909
|
+
entry.key
|
|
8910
|
+
);
|
|
8911
|
+
};
|
|
8912
|
+
const renderEntries = () => {
|
|
8913
|
+
const out = [];
|
|
8914
|
+
for (let i = 0; i < items.length; ) {
|
|
8915
|
+
const entry = items[i];
|
|
8916
|
+
if (entry.type !== "radio") {
|
|
8917
|
+
out.push(renderEntry(entry, i));
|
|
8918
|
+
i += 1;
|
|
8919
|
+
continue;
|
|
8920
|
+
}
|
|
8921
|
+
const start = i;
|
|
8922
|
+
const run = [];
|
|
8923
|
+
while (i < items.length && items[i].type === "radio") {
|
|
8924
|
+
run.push(renderEntry(items[i], i));
|
|
8925
|
+
i += 1;
|
|
8926
|
+
}
|
|
8927
|
+
const heading = items[start - 1]?.type === "label" ? `${menuId}-label-${start - 1}` : void 0;
|
|
8928
|
+
out.push(/* @__PURE__ */ jsx("div", { role: "group", "aria-labelledby": heading, children: run }, `group:${entry.key}`));
|
|
8929
|
+
}
|
|
8930
|
+
return out;
|
|
8931
|
+
};
|
|
8932
|
+
const menuStyle = {
|
|
8933
|
+
// The popup layer, as every portalled kit popup: above dialogs and the
|
|
8934
|
+
// window stack, so a menu opened in either is drawn over it. A caller that
|
|
8935
|
+
// layered it with a `z-…` class keeps its own.
|
|
8936
|
+
...OWNS_Z.test(menuClassName) ? {} : { zIndex: Z_LAYERS.popup },
|
|
8937
|
+
minWidth
|
|
8502
8938
|
};
|
|
8503
8939
|
return /* @__PURE__ */ jsxs("div", { ref: wrapRef, className: `relative inline-flex ${className}`.trim(), children: [
|
|
8504
8940
|
/* @__PURE__ */ jsx(
|
|
8505
8941
|
"button",
|
|
8506
8942
|
{
|
|
8507
8943
|
ref: triggerRef,
|
|
8944
|
+
id: triggerId,
|
|
8508
8945
|
type: "button",
|
|
8509
8946
|
"aria-haspopup": "menu",
|
|
8510
8947
|
"aria-expanded": open,
|
|
8511
8948
|
"aria-controls": open ? menuId : void 0,
|
|
8512
8949
|
"aria-label": ariaLabel,
|
|
8513
8950
|
disabled,
|
|
8514
|
-
onClick: () => open ? close(false) : openAt(
|
|
8951
|
+
onClick: () => open ? close(false) : openAt(focusableFrom(0, 1)),
|
|
8515
8952
|
onKeyDown: onTriggerKeyDown,
|
|
8516
|
-
className:
|
|
8953
|
+
className: triggerClassName ?? TRIGGER_CLASS,
|
|
8517
8954
|
children: trigger
|
|
8518
8955
|
}
|
|
8519
8956
|
),
|
|
8520
|
-
open &&
|
|
8957
|
+
open && // No `onClose`: PopupMenu's own dismissal calls the same callback for
|
|
8958
|
+
// Escape and for a click elsewhere, and those want opposite things.
|
|
8959
|
+
// Escape is the user putting the menu away, so focus goes back to the
|
|
8960
|
+
// trigger; a click elsewhere is them going somewhere, and dragging
|
|
8961
|
+
// focus back would take them off what they just clicked. The handlers
|
|
8962
|
+
// above tell the two apart.
|
|
8963
|
+
/* @__PURE__ */ jsx(PopupMenu, { portal: true, className: menuClassName, style: menuStyle, children: /* @__PURE__ */ jsx(
|
|
8521
8964
|
"div",
|
|
8522
8965
|
{
|
|
8523
|
-
|
|
8966
|
+
ref: menuRef,
|
|
8967
|
+
id: menuId,
|
|
8968
|
+
role: "menu",
|
|
8969
|
+
"aria-orientation": "vertical",
|
|
8970
|
+
"aria-label": ariaLabel,
|
|
8971
|
+
"aria-labelledby": ariaLabel ? void 0 : triggerId,
|
|
8972
|
+
tabIndex: -1,
|
|
8524
8973
|
onKeyDown: onMenuKeyDown,
|
|
8525
|
-
children:
|
|
8526
|
-
PopupMenuItem,
|
|
8527
|
-
{
|
|
8528
|
-
ref: (el) => {
|
|
8529
|
-
itemRefs.current[i] = el;
|
|
8530
|
-
},
|
|
8531
|
-
role: "menuitem",
|
|
8532
|
-
tabIndex: i === active ? 0 : -1,
|
|
8533
|
-
danger: item.danger,
|
|
8534
|
-
disabled: item.disabled,
|
|
8535
|
-
onMouseEnter: () => {
|
|
8536
|
-
if (!item.disabled) setActive(i);
|
|
8537
|
-
},
|
|
8538
|
-
onClick: () => select(item),
|
|
8539
|
-
children: [
|
|
8540
|
-
item.icon,
|
|
8541
|
-
item.label
|
|
8542
|
-
]
|
|
8543
|
-
},
|
|
8544
|
-
item.key
|
|
8545
|
-
)) }) })
|
|
8974
|
+
children: renderEntries()
|
|
8546
8975
|
}
|
|
8547
|
-
)
|
|
8976
|
+
) })
|
|
8548
8977
|
] });
|
|
8549
8978
|
}
|
|
8550
8979
|
var APP_UPDATE_POLL_MS = 6e4;
|
|
@@ -13673,6 +14102,6 @@ function ChordChart({
|
|
|
13673
14102
|
] });
|
|
13674
14103
|
}
|
|
13675
14104
|
|
|
13676
|
-
export { APP_UPDATE_POLL_MS, Accordion, AppUpdateBanner, AttachButton, AttachmentDropZone, AttachmentList, AuthScreen, Avatar, AvatarGroup, Banner, BarChart, BoxPlotChart, BrandAssetEditor, BudgetBar, CHART_INK, Calendar, CandlestickChart, Card, CartesianPlot, ChartBrush, ChartDefs, ChartDot, ChartFrame, ChartHighlightProvider, ChartSkeleton, ChartTooltip, ChatTemplate, Checkbox_default, CheckoutTemplate, ChordChart, ColoredBadge, ColumnChart, ComposerAttachments, ContainerFillChart, CountBadge, DAY_MS, DashboardTemplate, DataTable, DataTablePage, DatePicker_default, DateRangePicker, DateTimePicker_default, DescriptionList, Divider, DonutChart, Drawer, DropdownMenu, EmailTemplate, EmptyState, ErrorBoundary, ErrorPage, FilePicker_default, FormErrorSummary, FormField, FormLayoutPage, FunnelChart, GROUP_COLORS, GROUP_COLORS_SOLID, GalleryTemplate, GlobalSearch, Grid, HeatmapChart, HelpCenter, HistogramChart, INPUT_BASE, INPUT_SIZES, IconButton_default, Inline, InputNumber_default, Input_default, Kanban, Label, LineChart, ListFooter, ListLoadError, MAX_FRACTION_DIGITS, MENU_MAX_HEIGHT, MOTION, Markdown, MediaUploadField, MediaUploadGrid, Meter, MetricBar, MilestoneTimeline, NativeSelect, NumericKeypad, POPUP_MAX_WIDTH, POST_PRODUCTION_STATUSES, PageHeader, Pagination, PaperclipGlyph, Paragraph, PieChart, PortalBrandingProvider, ProductionTimeline, RADAR_SERIES_CAP, RadarChart, RadialBarChart, RadioGroup, Radio_default, RangeChart, RankedBars, SCATTER_SERIES_CAP, SERIES_SLOT_COUNT, SERIES_VARS, STAGES, STATUS_VARS, SankeyChart, ScatterChart, SearchableSelect, Segmented, Select_default, SettingRow, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, Skeleton, Snippet, Sparkline, Stack, StatCard, StatTile, Statistic, StatusBadge, StatusBadgeProvider, Stepper, SunburstChart, Switch_default, Tabs, TagInput, Text, Textarea_default, TileButton_default, TimePicker_default, TimeSeriesChart, TimelineTrack, Title, Tooltip, TopNav, TreemapChart, WaterfallChart, angleScale, appendKey, applyThemePrefs, arcPath, areaBetween, areaFrom, autoHighlightIndex, backspace, bandScale, binValues, budgetState, bumpPath, calcOverall, calcReportOverall, copyToClipboard, curvePath, dashFor, fillFor, fillId, firstEnabledIndex, fmtSliderDate, formatDate, fromKey, glowId, groundId, groupColors, highlightOpacity, inputClasses, isSeverityTone, ladderScale, lastEnabledIndex, linearPath, linearScale, logScale, maskId, matchTypeahead, mediaFileName, monotonePath, nextEnabledIndex, niceMax, polygonPoints, popupBounds, radiusScale, resolvePortalBrandAsset, resolveSeriesColor, resolveTheme, selectionAt, seriesColor, severityOf, splinePath, squarify, stagger, stepPath, tabButtonId, tabPanelId, toDayMs, toISODate, toKey, useAppUpdate, useClickOutside, useDropdownPosition, useHighlight, usePlotWidth, usePortalBranding, useProductionTimeline, useTheme };
|
|
13677
|
-
//# sourceMappingURL=chunk-
|
|
13678
|
-
//# sourceMappingURL=chunk-
|
|
14105
|
+
export { APP_UPDATE_POLL_MS, Accordion, AppUpdateBanner, AttachButton, AttachmentDropZone, AttachmentList, AuthScreen, Avatar, AvatarGroup, Banner, BarChart, BoxPlotChart, BrandAssetEditor, BudgetBar, CHART_INK, Calendar, CandlestickChart, Card, CartesianPlot, ChartBrush, ChartDefs, ChartDot, ChartFrame, ChartHighlightProvider, ChartSkeleton, ChartTooltip, ChatTemplate, Checkbox_default, CheckoutTemplate, ChordChart, ColoredBadge, ColumnChart, ComposerAttachments, ContainerFillChart, CountBadge, DAY_MS, DashboardTemplate, DataTable, DataTablePage, DatePicker_default, DateRangePicker, DateTimePicker_default, DescriptionList, Divider, DonutChart, Drawer, DropdownMenu, EmailTemplate, EmptyState, ErrorBoundary, ErrorPage, FilePicker_default, FormErrorSummary, FormField, FormLayoutPage, FunnelChart, GROUP_COLORS, GROUP_COLORS_SOLID, GalleryTemplate, GlobalSearch, Grid, HeatmapChart, HelpCenter, HistogramChart, INPUT_BASE, INPUT_SIZES, IconButton_default, Inline, InputNumber_default, Input_default, Kanban, Label, LineChart, ListFooter, ListLoadError, MAX_FRACTION_DIGITS, MENU_MAX_HEIGHT, MOTION, Markdown, MediaUploadField, MediaUploadGrid, Meter, MetricBar, MilestoneTimeline, NativeSelect, NumericKeypad, POPUP_MAX_WIDTH, POST_PRODUCTION_STATUSES, PageHeader, Pagination, PaperclipGlyph, Paragraph, PieChart, PortalBrandingProvider, ProductionTimeline, RADAR_SERIES_CAP, RadarChart, RadialBarChart, RadioGroup, Radio_default, RangeChart, RankedBars, SCATTER_SERIES_CAP, SERIES_SLOT_COUNT, SERIES_VARS, STAGES, STATUS_VARS, SankeyChart, ScatterChart, SearchableSelect, Segmented, Select_default, SettingRow, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, Skeleton, Snippet, Sparkline, Stack, StatCard, StatTile, Statistic, StatusBadge, StatusBadgeProvider, Stepper, SunburstChart, Switch_default, Tabs, TagInput, Text, Textarea_default, TileButton_default, TimePicker_default, TimeSeriesChart, TimelineTrack, Title, Tooltip, TopNav, TreemapChart, WaterfallChart, angleScale, appendKey, applyThemePrefs, arcPath, areaBetween, areaFrom, autoHighlightIndex, backspace, bandScale, binValues, budgetState, bumpPath, calcOverall, calcReportOverall, copyToClipboard, curvePath, dashFor, fillFor, fillId, firstDayOfWeek, firstEnabledIndex, fmtSliderDate, formatDate, fromKey, glowId, groundId, groupColors, highlightOpacity, inputClasses, isSeverityTone, ladderScale, lastEnabledIndex, linearPath, linearScale, logScale, maskId, matchTypeahead, mediaFileName, monotonePath, nextEnabledIndex, niceMax, polygonPoints, popupBounds, radiusScale, resolvePortalBrandAsset, resolveSeriesColor, resolveTheme, selectionAt, seriesColor, severityOf, splinePath, squarify, stagger, stepPath, tabButtonId, tabPanelId, toDayMs, toISODate, toKey, useAppUpdate, useClickOutside, useDropdownPosition, useHighlight, usePlotWidth, usePortalBranding, useProductionTimeline, useTheme };
|
|
14106
|
+
//# sourceMappingURL=chunk-YA4EE7ST.js.map
|
|
14107
|
+
//# sourceMappingURL=chunk-YA4EE7ST.js.map
|