gridsmith-ui 0.24.0 → 0.26.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 +8 -6
- package/dist/MentionList-CoNBRFGR.d.ts +8 -0
- package/dist/charts.d.ts +42 -1
- package/dist/charts.js +320 -89
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +5 -4
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-6XAU44U4.js → chunk-CYN5O567.js} +10 -23
- package/dist/chunk-CYN5O567.js.map +1 -0
- package/dist/{chunk-SBTBMAIU.js → chunk-EX64MN2U.js} +6 -6
- package/dist/{chunk-SBTBMAIU.js.map → chunk-EX64MN2U.js.map} +1 -1
- package/dist/chunk-HP7WUZPK.js +80 -0
- package/dist/chunk-HP7WUZPK.js.map +1 -0
- package/dist/{chunk-4LDYR7QP.js → chunk-HXVXJUGV.js} +53 -13
- package/dist/chunk-HXVXJUGV.js.map +1 -0
- package/dist/{chunk-MV7JXWXK.js → chunk-KWLNEH53.js} +8 -7
- package/dist/chunk-KWLNEH53.js.map +1 -0
- package/dist/{chunk-CXMV7SXJ.js → chunk-MD2EFMES.js} +5 -77
- package/dist/chunk-MD2EFMES.js.map +1 -0
- package/dist/{chunk-SVP2IG4S.js → chunk-MYIJNVTK.js} +7 -7
- package/dist/chunk-MYIJNVTK.js.map +1 -0
- package/dist/{chunk-IVCVNAXG.js → chunk-OTCEJN64.js} +3 -3
- package/dist/{chunk-IVCVNAXG.js.map → chunk-OTCEJN64.js.map} +1 -1
- package/dist/{chunk-2PWGJ4PK.js → chunk-QM4SJKWV.js} +11 -6
- package/dist/chunk-QM4SJKWV.js.map +1 -0
- package/dist/chunk-RWKCAKN3.js +209 -0
- package/dist/chunk-RWKCAKN3.js.map +1 -0
- package/dist/{chunk-2YSEME33.js → chunk-SFY2KMHG.js} +63 -6
- package/dist/chunk-SFY2KMHG.js.map +1 -0
- package/dist/{chunk-NCIZQYXQ.js → chunk-X2HEV7FB.js} +33 -3
- package/dist/chunk-X2HEV7FB.js.map +1 -0
- package/dist/{chunk-JXANCXK6.js → chunk-ZI3OQDET.js} +18 -4
- package/dist/chunk-ZI3OQDET.js.map +1 -0
- package/dist/{chunk-7TOJ4G7S.js → chunk-ZYVXV4WC.js} +14 -9
- package/dist/chunk-ZYVXV4WC.js.map +1 -0
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +13 -12
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.d.ts +30 -0
- package/dist/editor-mentions.js +160 -0
- package/dist/editor-mentions.js.map +1 -0
- package/dist/editor.d.ts +23 -3
- package/dist/editor.js +58 -9
- package/dist/editor.js.map +1 -1
- package/dist/{feather-2JFSFLXN.js → feather-VFWLAILO.js} +12 -3
- package/dist/feather-VFWLAILO.js.map +1 -0
- package/dist/{heroicons-4AQ4YBVG.js → heroicons-H3Z7DFCF.js} +22 -7
- package/dist/heroicons-H3Z7DFCF.js.map +1 -0
- package/dist/icons.d.ts +11 -4
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +202 -31
- package/dist/index.js +1473 -1181
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +8 -8
- package/dist/kanban.js.map +1 -1
- package/dist/{lucide-RZC2FEMS.js → lucide-MR32KM4G.js} +12 -3
- package/dist/lucide-MR32KM4G.js.map +1 -0
- package/dist/{phosphor-CEN25FLM.js → phosphor-ABQQL5N5.js} +12 -3
- package/dist/phosphor-ABQQL5N5.js.map +1 -0
- package/dist/resizable.js +8 -8
- package/dist/roots.css +28 -0
- package/dist/{tabler-YXXC7Y6B.js → tabler-ANUSY4D2.js} +12 -3
- package/dist/tabler-ANUSY4D2.js.map +1 -0
- package/dist/tokens.css +6 -0
- package/dist/{use-pagination-DiJo0aW5.d.ts → use-pagination-BnKOnBdz.d.ts} +3 -0
- package/dist/virtualized.d.ts +1 -1
- package/dist/virtualized.js +7 -6
- package/dist/virtualized.js.map +1 -1
- package/dist-static/tokens.css +6 -0
- package/package.json +29 -21
- package/dist/chunk-2PWGJ4PK.js.map +0 -1
- package/dist/chunk-2YSEME33.js.map +0 -1
- package/dist/chunk-4LDYR7QP.js.map +0 -1
- package/dist/chunk-6XAU44U4.js.map +0 -1
- package/dist/chunk-7TOJ4G7S.js.map +0 -1
- package/dist/chunk-CXMV7SXJ.js.map +0 -1
- package/dist/chunk-JXANCXK6.js.map +0 -1
- package/dist/chunk-MV7JXWXK.js.map +0 -1
- package/dist/chunk-NCIZQYXQ.js.map +0 -1
- package/dist/chunk-SVP2IG4S.js.map +0 -1
- package/dist/chunk-WOVYHFUD.js +0 -50
- package/dist/chunk-WOVYHFUD.js.map +0 -1
- package/dist/feather-2JFSFLXN.js.map +0 -1
- package/dist/heroicons-4AQ4YBVG.js.map +0 -1
- package/dist/lucide-RZC2FEMS.js.map +0 -1
- package/dist/phosphor-CEN25FLM.js.map +0 -1
- package/dist/tabler-YXXC7Y6B.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { inferColumnKinds, useCardsSwitch, CARDS_BELOW, kindOfRenderedText, CardValue } from './chunk-OTCEJN64.js';
|
|
2
|
+
import { useWholeListCheck, pagerPart, Pagination, Input, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, Label, InlineFieldError, AddAnotherRowCtx, Field } from './chunk-CYN5O567.js';
|
|
3
|
+
export { Dropdown, Field, InlineFieldError, Input, Label, NumberInput, Pagination, Popover, Textarea, Toggle, usePagination } from './chunk-CYN5O567.js';
|
|
4
|
+
import { useAppShell, REACT_VERSION_PROBLEM, Breadcrumbs, useCrumbFollow, crumbGoes, useOverlayMark, useDirtyGuard, useScrollbarInset, DrawerFooterCtx, OverlayMarkScope, OverlayCloseCtx, insetLessScrollbar, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, useCompact, useElementWidth, DrawerPanel, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-KWLNEH53.js';
|
|
5
|
+
export { AppShell, Breadcrumbs, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-KWLNEH53.js';
|
|
6
|
+
import { Button, ControlSizeContext, triggerType, Spinner, useShellPreferences, PREFERENCE_HOUSE_DEFAULTS, preferenceActionKey } from './chunk-ZYVXV4WC.js';
|
|
7
|
+
export { Button, ButtonSizeContext, ControlSizeContext, PreferencesContext, Spinner, preferenceActionKey, usePreferences } from './chunk-ZYVXV4WC.js';
|
|
8
|
+
import { Skeleton, TITLE_TEXT, formatLocale } from './chunk-X2HEV7FB.js';
|
|
9
|
+
export { Skeleton } from './chunk-X2HEV7FB.js';
|
|
5
10
|
import { useScrollEdges, EDGE_FADE } from './chunk-3BRQRKDO.js';
|
|
6
|
-
import { Link } from './chunk-SVP2IG4S.js';
|
|
7
|
-
export { CodeBlock, Divider, Link } from './chunk-SVP2IG4S.js';
|
|
8
|
-
import { useFillHeight, FillContext } from './chunk-2YSEME33.js';
|
|
9
|
-
import { Badge } from './chunk-SBTBMAIU.js';
|
|
10
|
-
export { Badge } from './chunk-SBTBMAIU.js';
|
|
11
|
-
import { inferColumnKinds, useCardsSwitch, CARDS_BELOW, kindOfRenderedText, CardValue } from './chunk-IVCVNAXG.js';
|
|
12
|
-
import { useWholeListCheck, pagerPart, Pagination, Input, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, warnOnce, Label, InlineFieldError, AddAnotherRowCtx, Field } from './chunk-6XAU44U4.js';
|
|
13
|
-
export { Dropdown, Field, InlineFieldError, Input, Label, NumberInput, Pagination, Popover, Textarea, Toggle, usePagination } from './chunk-6XAU44U4.js';
|
|
14
|
-
import { Button, ControlSizeContext, triggerType, Spinner, useShellPreferences, preferenceActionKey } from './chunk-7TOJ4G7S.js';
|
|
15
|
-
export { Button, ButtonSizeContext, ControlSizeContext, PreferencesContext, Spinner, preferenceActionKey, usePreferences } from './chunk-7TOJ4G7S.js';
|
|
16
11
|
import { useBreakpoint, readBreakpointPx } from './chunk-CRQ6KCRD.js';
|
|
17
12
|
export { BreakpointWidthProvider, useBreakpoint } from './chunk-CRQ6KCRD.js';
|
|
18
13
|
import { FormChangeCtx, useReportedChange, useOptionalFormContext, FormCtx } from './chunk-XVB55M3N.js';
|
|
19
14
|
export { useFormContext } from './chunk-XVB55M3N.js';
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
import { Avatar, foldForSearch, useActiveOptionInView, shownMentions, matchMentions, mentionOptionId, MentionList, initialsOf } from './chunk-RWKCAKN3.js';
|
|
16
|
+
export { Avatar } from './chunk-RWKCAKN3.js';
|
|
17
|
+
import { Link } from './chunk-MYIJNVTK.js';
|
|
18
|
+
export { CodeBlock, Divider, Link } from './chunk-MYIJNVTK.js';
|
|
19
|
+
import { useFillHeight, FillContext, useKeyboardScroll, FOCUS_INSET } from './chunk-SFY2KMHG.js';
|
|
20
|
+
import { CardSurfaceCtx, useScrollsInside, SplitPaneCtx, RowsCtx, PageActionsCtx, SurfaceBoundary, useFramesItself, TableCardCtx } from './chunk-QM4SJKWV.js';
|
|
21
|
+
import { FOCUSABLE, usePopupFocus, FIELD, ZOOM_KEYS, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberFocus, focusInitial, OVERLAY_CLOSE_ATTR, rovingTabStop, useGridKeyboard, focusAfterRemoval, useNonModalDialog, useReturnFocus } from './chunk-ZI3OQDET.js';
|
|
22
|
+
export { useGridKeyboard } from './chunk-ZI3OQDET.js';
|
|
23
|
+
import { Badge } from './chunk-EX64MN2U.js';
|
|
24
|
+
export { Badge } from './chunk-EX64MN2U.js';
|
|
25
|
+
import { useTextOverflow, Tooltip } from './chunk-MD2EFMES.js';
|
|
26
|
+
export { Tooltip, useTextOverflow } from './chunk-MD2EFMES.js';
|
|
25
27
|
import { mergeRefs, Slot } from './chunk-7Q46JXSK.js';
|
|
28
|
+
import { Icon, slotIcon, warnOnce } from './chunk-HXVXJUGV.js';
|
|
29
|
+
import { usePosition } from './chunk-HP7WUZPK.js';
|
|
26
30
|
import { useLatest } from './chunk-WH2FUFAC.js';
|
|
27
|
-
import { Icon } from './chunk-4LDYR7QP.js';
|
|
28
31
|
import { cn, GLASS_SURFACE, GLASS_BACKDROP, GLASS_DROPDOWN, lockBodyScroll, unlockBodyScroll, OVERLAY_SURFACE, GLASS_OVERLAY, ERROR_HAS_FOCUS_RING, HAS_FOCUS_RING, ACTIVE_RING, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, FOCUS_RING, FOCUS_WITHIN_RING } from './chunk-M2QRNBDQ.js';
|
|
29
32
|
import { createContext, forwardRef, useState, useRef, useCallback, useLayoutEffect, useMemo, useContext, isValidElement, useId, memo, useEffect, useImperativeHandle, Children, Fragment as Fragment$1, cloneElement, useSyncExternalStore } from 'react';
|
|
30
33
|
import { createPortal, flushSync } from 'react-dom';
|
|
@@ -227,7 +230,7 @@ var TEXT_SIZE = {
|
|
|
227
230
|
md: "text-sm",
|
|
228
231
|
lg: "text-base"
|
|
229
232
|
};
|
|
230
|
-
function Combobox({ value, onChange: onChangeProp, options, placeholder = "Search\u2026", disabled, loading = false, className, ref, container, error = false, size: sizeProp, ...wiring }) {
|
|
233
|
+
function Combobox({ value, onChange: onChangeProp, options, placeholder = "Search\u2026", disabled, loading = false, className, ref, container, error = false, size: sizeProp, "aria-label": ariaLabel, ...wiring }) {
|
|
231
234
|
const onChange = useReportedChange(onChangeProp, value);
|
|
232
235
|
const contextSize = useContext(ControlSizeContext);
|
|
233
236
|
const control = useFieldControl({ ...wiring, error: error || void 0 });
|
|
@@ -244,8 +247,9 @@ function Combobox({ value, onChange: onChangeProp, options, placeholder = "Searc
|
|
|
244
247
|
const listboxId = useId();
|
|
245
248
|
const pos = usePosition(triggerRef, listRef, open, { side: "bottom", align: "start", offset: 4, flip: true });
|
|
246
249
|
const filtered = options.filter(
|
|
247
|
-
(o) => !o.disabled && o.label.
|
|
250
|
+
(o) => !o.disabled && foldForSearch(o.keywords ? `${o.label} ${o.keywords}` : o.label).includes(foldForSearch(query))
|
|
248
251
|
);
|
|
252
|
+
useActiveOptionInView(listRef, open && filtered[highlightIdx] ? `${listboxId}-opt-${highlightIdx}` : void 0);
|
|
249
253
|
const selectedLabel = options.find((o) => o.value === value)?.label ?? "";
|
|
250
254
|
const { ref: overflowRef, isTruncated: labelTruncated } = useTextOverflow({ lines: 1, content: selectedLabel, disabled: open });
|
|
251
255
|
const [prevQuery, setPrevQuery] = useState(query);
|
|
@@ -359,6 +363,7 @@ function Combobox({ value, onChange: onChangeProp, options, placeholder = "Searc
|
|
|
359
363
|
id: control.id,
|
|
360
364
|
role: "combobox",
|
|
361
365
|
"aria-labelledby": wiring["aria-labelledby"],
|
|
366
|
+
"aria-label": control.labelId ? void 0 : ariaLabel,
|
|
362
367
|
"aria-describedby": control.describedBy,
|
|
363
368
|
"aria-invalid": control.invalid || void 0,
|
|
364
369
|
"aria-required": control.required || void 0,
|
|
@@ -454,6 +459,183 @@ function Combobox({ value, onChange: onChangeProp, options, placeholder = "Searc
|
|
|
454
459
|
] });
|
|
455
460
|
return /* @__PURE__ */ jsx(Tooltip, { content: selectedLabel, disabled: !labelTruncated || open, children: triggerContent });
|
|
456
461
|
}
|
|
462
|
+
function canonicalTimeZone(zone) {
|
|
463
|
+
try {
|
|
464
|
+
return new Intl.DateTimeFormat("en-US", { timeZone: zone }).resolvedOptions().timeZone;
|
|
465
|
+
} catch {
|
|
466
|
+
return zone;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function browserTimeZone() {
|
|
470
|
+
try {
|
|
471
|
+
return canonicalTimeZone(Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC");
|
|
472
|
+
} catch {
|
|
473
|
+
return "UTC";
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function timeZoneOffset(zone, at = /* @__PURE__ */ new Date()) {
|
|
477
|
+
try {
|
|
478
|
+
return new Intl.DateTimeFormat(formatLocale(), { timeZone: zone, timeZoneName: "shortOffset" }).formatToParts(at).find((p) => p.type === "timeZoneName")?.value ?? "";
|
|
479
|
+
} catch {
|
|
480
|
+
return "";
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function timeZones() {
|
|
484
|
+
const listed = typeof Intl.supportedValuesOf === "function" ? Intl.supportedValuesOf("timeZone") : [];
|
|
485
|
+
const zones = [...new Set(listed.map(canonicalTimeZone))].filter((z) => z !== "UTC").sort((a, b) => a.localeCompare(b));
|
|
486
|
+
return ["UTC", ...zones];
|
|
487
|
+
}
|
|
488
|
+
var RENAMED_CITIES = [
|
|
489
|
+
["Kolkata", ["Asia/Calcutta", "Asia/Kolkata"]],
|
|
490
|
+
["Kyiv", ["Europe/Kiev", "Europe/Kyiv"]],
|
|
491
|
+
["Ho Chi Minh City", ["Asia/Saigon", "Asia/Ho_Chi_Minh"]],
|
|
492
|
+
["Yangon", ["Asia/Rangoon", "Asia/Yangon"]],
|
|
493
|
+
["Kathmandu", ["Asia/Katmandu", "Asia/Kathmandu"]],
|
|
494
|
+
["Nuuk", ["America/Godthab", "America/Nuuk"]],
|
|
495
|
+
["Faroe", ["Atlantic/Faeroe", "Atlantic/Faroe"]],
|
|
496
|
+
["Chuuk", ["Pacific/Truk", "Pacific/Chuuk"]],
|
|
497
|
+
["Pohnpei", ["Pacific/Ponape", "Pacific/Pohnpei"]],
|
|
498
|
+
["Kanton", ["Pacific/Enderbury", "Pacific/Kanton"]],
|
|
499
|
+
["Asmara", ["Africa/Asmera", "Africa/Asmara"]],
|
|
500
|
+
["Atikokan", ["America/Coral_Harbour", "America/Atikokan"]],
|
|
501
|
+
["Thimphu", ["Asia/Thimbu", "Asia/Thimphu"]],
|
|
502
|
+
["Dhaka", ["Asia/Dacca", "Asia/Dhaka"]],
|
|
503
|
+
["Ulaanbaatar", ["Asia/Ulan_Bator", "Asia/Ulaanbaatar"]]
|
|
504
|
+
];
|
|
505
|
+
var CITY_OF = new Map(RENAMED_CITIES.flatMap(([city, zones]) => zones.map((zone) => [zone, city])));
|
|
506
|
+
var labelOf = (zone, at) => {
|
|
507
|
+
const offset = timeZoneOffset(zone, at);
|
|
508
|
+
return offset ? `${zone.replace(/_/g, " ")} (${offset})` : zone.replace(/_/g, " ");
|
|
509
|
+
};
|
|
510
|
+
var HOUR = 36e5;
|
|
511
|
+
var zoneList = null;
|
|
512
|
+
function zoneOptions() {
|
|
513
|
+
const now = Date.now();
|
|
514
|
+
if (!zoneList || now - zoneList.at > HOUR) {
|
|
515
|
+
const at = new Date(now);
|
|
516
|
+
zoneList = { at: now, options: timeZones().map((zone) => ({ value: zone, label: labelOf(zone, at), keywords: CITY_OF.get(zone) })) };
|
|
517
|
+
}
|
|
518
|
+
return zoneList.options;
|
|
519
|
+
}
|
|
520
|
+
function TimezoneSelect({ value, onChange, placeholder = "Search time zones\u2026", ...rest }) {
|
|
521
|
+
const zones = zoneOptions();
|
|
522
|
+
const stored = value ? canonicalTimeZone(value) : "";
|
|
523
|
+
const options = useMemo(() => {
|
|
524
|
+
if (!stored) {
|
|
525
|
+
const mine = browserTimeZone();
|
|
526
|
+
const label = zones.find((o) => o.value === mine)?.label ?? labelOf(mine, /* @__PURE__ */ new Date());
|
|
527
|
+
return [{ value: mine, label: `${label} \xB7 your time zone`, keywords: CITY_OF.get(mine) }, ...zones.filter((o) => o.value !== mine)];
|
|
528
|
+
}
|
|
529
|
+
return zones.some((o) => o.value === stored) ? zones : [{ value: stored, label: labelOf(stored, /* @__PURE__ */ new Date()), keywords: CITY_OF.get(stored) }, ...zones];
|
|
530
|
+
}, [zones, stored]);
|
|
531
|
+
return /* @__PURE__ */ jsx(Combobox, { value: stored, onChange, options, placeholder, ...rest });
|
|
532
|
+
}
|
|
533
|
+
var MINUTE = 6e4;
|
|
534
|
+
var HOUR2 = 60 * MINUTE;
|
|
535
|
+
var DAY = 24 * HOUR2;
|
|
536
|
+
var LONGEST_WAIT = DAY;
|
|
537
|
+
var CONTROL_ANCESTOR = 'a[href], button, summary, label, [role="button"], [role="link"], [role="option"], [role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="tab"], [role="treeitem"], [role="row"], [role="gridcell"], [role="checkbox"], [role="radio"], [role="switch"]';
|
|
538
|
+
var noChange = () => () => {
|
|
539
|
+
};
|
|
540
|
+
var inBrowser = () => true;
|
|
541
|
+
var onServer = () => false;
|
|
542
|
+
function toMillis(time) {
|
|
543
|
+
if (time instanceof Date) return time.getTime();
|
|
544
|
+
if (typeof time === "number") return time;
|
|
545
|
+
if (typeof time !== "string") return NaN;
|
|
546
|
+
const day = /^(\d{4})-(\d{2})-(\d{2})$/.exec(time.trim());
|
|
547
|
+
if (day) return new Date(Number(day[1]), Number(day[2]) - 1, Number(day[3])).getTime();
|
|
548
|
+
return Date.parse(time);
|
|
549
|
+
}
|
|
550
|
+
function thresholdOf(hours, from) {
|
|
551
|
+
if (typeof hours === "number" && Number.isFinite(hours) && hours >= 0) return hours;
|
|
552
|
+
const house = PREFERENCE_HOUSE_DEFAULTS.relativeThresholdHours;
|
|
553
|
+
warnOnce(from, `a threshold of ${String(hours)} isn't a number of hours, so the house's ${house} is used.`);
|
|
554
|
+
return house;
|
|
555
|
+
}
|
|
556
|
+
function midnight(t) {
|
|
557
|
+
const d = new Date(t);
|
|
558
|
+
d.setHours(0, 0, 0, 0);
|
|
559
|
+
return d.getTime();
|
|
560
|
+
}
|
|
561
|
+
function formatRelativeTime(time, options) {
|
|
562
|
+
const at = toMillis(time);
|
|
563
|
+
if (!Number.isFinite(at)) return "";
|
|
564
|
+
const now = options.now ?? Date.now();
|
|
565
|
+
const diff = at - now;
|
|
566
|
+
const age = Math.abs(diff);
|
|
567
|
+
if (age > thresholdOf(options.thresholdHours, "formatRelativeTime") * HOUR2) return new Intl.DateTimeFormat(formatLocale(), { dateStyle: "medium", timeStyle: "short" }).format(at);
|
|
568
|
+
const rtf = new Intl.RelativeTimeFormat(formatLocale(), { numeric: "auto" });
|
|
569
|
+
if (age < MINUTE) return rtf.format(0, "second");
|
|
570
|
+
if (age < HOUR2) return rtf.format(Math.trunc(diff / MINUTE), "minute");
|
|
571
|
+
if (age < DAY) return rtf.format(Math.trunc(diff / HOUR2), "hour");
|
|
572
|
+
return rtf.format(Math.round((midnight(at) - midnight(now)) / DAY), "day");
|
|
573
|
+
}
|
|
574
|
+
function useRelativeTimeFormat() {
|
|
575
|
+
const thresholdHours = useShellPreferences().relativeThresholdHours ?? PREFERENCE_HOUSE_DEFAULTS.relativeThresholdHours;
|
|
576
|
+
return (time) => formatRelativeTime(time, { thresholdHours });
|
|
577
|
+
}
|
|
578
|
+
function formatFullTime(time) {
|
|
579
|
+
const at = toMillis(time);
|
|
580
|
+
return Number.isFinite(at) ? new Intl.DateTimeFormat(formatLocale(), { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "2-digit", timeZoneName: "short" }).format(at) : "";
|
|
581
|
+
}
|
|
582
|
+
function nextChange(at, now, threshold) {
|
|
583
|
+
const diff = at - now;
|
|
584
|
+
const age = Math.abs(diff);
|
|
585
|
+
let wait;
|
|
586
|
+
if (age > threshold) {
|
|
587
|
+
if (diff <= 0) return null;
|
|
588
|
+
wait = age - threshold + 1;
|
|
589
|
+
} else {
|
|
590
|
+
const step = age < HOUR2 ? MINUTE : HOUR2;
|
|
591
|
+
const untilStep = diff > 0 ? age % step + 1 : step - age % step;
|
|
592
|
+
wait = diff > 0 ? untilStep : Math.min(untilStep, threshold - age + 1);
|
|
593
|
+
}
|
|
594
|
+
return Number.isFinite(wait) ? Math.min(Math.max(1e3, wait), LONGEST_WAIT) : null;
|
|
595
|
+
}
|
|
596
|
+
function RelativeTime({ time, thresholdHours, className }) {
|
|
597
|
+
const shellThreshold = useShellPreferences().relativeThresholdHours;
|
|
598
|
+
const hours = thresholdOf(thresholdHours ?? shellThreshold ?? PREFERENCE_HOUSE_DEFAULTS.relativeThresholdHours, "RelativeTime");
|
|
599
|
+
const at = toMillis(time);
|
|
600
|
+
if (!Number.isFinite(at)) {
|
|
601
|
+
warnOnce("RelativeTime", `${JSON.stringify(time) ?? String(time)} isn't a time (an ISO string, a Date or milliseconds), so nothing is drawn.`);
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
return /* @__PURE__ */ jsx(RelativeTimeAt, { at, hours, className }, `${at}:${hours}`);
|
|
605
|
+
}
|
|
606
|
+
function RelativeTimeAt({ at, hours, className }) {
|
|
607
|
+
const inRows = useContext(RowsCtx);
|
|
608
|
+
const [now, setNow] = useState(() => Date.now());
|
|
609
|
+
const [inControl, setInControl] = useState(false);
|
|
610
|
+
const placed = useCallback((el) => {
|
|
611
|
+
const inside = !!el?.parentElement?.closest(CONTROL_ANCESTOR);
|
|
612
|
+
if (inside) el.removeAttribute("tabindex");
|
|
613
|
+
if (el) setInControl(inside);
|
|
614
|
+
}, []);
|
|
615
|
+
const mounted = useSyncExternalStore(noChange, inBrowser, onServer);
|
|
616
|
+
useEffect(() => {
|
|
617
|
+
const wait = nextChange(at, now, hours * HOUR2);
|
|
618
|
+
if (wait === null) return;
|
|
619
|
+
const timer = setTimeout(() => setNow(Date.now()), wait);
|
|
620
|
+
return () => clearTimeout(timer);
|
|
621
|
+
}, [at, now, hours]);
|
|
622
|
+
const full = formatFullTime(at);
|
|
623
|
+
return /* @__PURE__ */ jsx(Tooltip, { content: full, ref: placed, children: /* @__PURE__ */ jsxs(
|
|
624
|
+
"time",
|
|
625
|
+
{
|
|
626
|
+
tabIndex: inRows || inControl ? void 0 : 0,
|
|
627
|
+
dateTime: new Date(at).toISOString(),
|
|
628
|
+
"data-relative-time": "",
|
|
629
|
+
suppressHydrationWarning: true,
|
|
630
|
+
className: cn("rounded-[var(--ds-radius-sm)] focus-visible:outline-2 focus-visible:outline-[var(--ds-accent-primary)] focus-visible:outline-offset-2", className),
|
|
631
|
+
children: [
|
|
632
|
+
formatRelativeTime(at, { thresholdHours: hours, now }),
|
|
633
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", suppressHydrationWarning: true, children: `, ${full}` })
|
|
634
|
+
]
|
|
635
|
+
},
|
|
636
|
+
mounted ? "browser" : "first"
|
|
637
|
+
) });
|
|
638
|
+
}
|
|
457
639
|
var CHECKBOX_SIZES = {
|
|
458
640
|
sm: { box: "h-[16px] w-[16px]", glyph: 10, label: "text-xs" },
|
|
459
641
|
md: { box: "h-[18px] w-[18px]", glyph: 12, label: "text-sm" }
|
|
@@ -713,6 +895,279 @@ function dateSegments(dayFirst, daysInMonth = 31) {
|
|
|
713
895
|
const year = { key: "year", label: "Year", min: 1, max: 9999, maxDigits: 4, placeholder: "yyyy" };
|
|
714
896
|
return dayFirst ? [day, month, year] : [month, day, year];
|
|
715
897
|
}
|
|
898
|
+
|
|
899
|
+
// ../../showcase/src/components/Calendar/calendar-utils.ts
|
|
900
|
+
var formatters = /* @__PURE__ */ new Map();
|
|
901
|
+
function dtf(options) {
|
|
902
|
+
const locale = formatLocale();
|
|
903
|
+
const key = `${locale ?? ""}|${JSON.stringify(options)}`;
|
|
904
|
+
let f = formatters.get(key);
|
|
905
|
+
if (!f) {
|
|
906
|
+
f = new Intl.DateTimeFormat(locale, options);
|
|
907
|
+
formatters.set(key, f);
|
|
908
|
+
}
|
|
909
|
+
return f;
|
|
910
|
+
}
|
|
911
|
+
function monthName(month, width = "long") {
|
|
912
|
+
return dtf({ month: width }).format(new Date(2026, month, 1));
|
|
913
|
+
}
|
|
914
|
+
function weekdayNames(weekStartsOn, width = "short") {
|
|
915
|
+
const f = dtf({ weekday: width });
|
|
916
|
+
return Array.from({ length: 7 }, (_, i) => f.format(new Date(2026, 0, 4 + weekStartsOn + i)));
|
|
917
|
+
}
|
|
918
|
+
function isSameDay(a, b) {
|
|
919
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
920
|
+
}
|
|
921
|
+
function isSameMonth(a, b) {
|
|
922
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
923
|
+
}
|
|
924
|
+
function isToday(d) {
|
|
925
|
+
return isSameDay(d, /* @__PURE__ */ new Date());
|
|
926
|
+
}
|
|
927
|
+
function isWeekend(d) {
|
|
928
|
+
const day = d.getDay();
|
|
929
|
+
return day === 0 || day === 6;
|
|
930
|
+
}
|
|
931
|
+
function startOfDay(d) {
|
|
932
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
933
|
+
}
|
|
934
|
+
function startOfWeek(d, weekStartsOn = 0) {
|
|
935
|
+
const date = new Date(d);
|
|
936
|
+
const day = date.getDay();
|
|
937
|
+
const diff = (day - weekStartsOn + 7) % 7;
|
|
938
|
+
date.setDate(date.getDate() - diff);
|
|
939
|
+
return startOfDay(date);
|
|
940
|
+
}
|
|
941
|
+
function endOfWeek(d, weekStartsOn = 0) {
|
|
942
|
+
const start = startOfWeek(d, weekStartsOn);
|
|
943
|
+
const end = new Date(start);
|
|
944
|
+
end.setDate(end.getDate() + 6);
|
|
945
|
+
end.setHours(23, 59, 59, 999);
|
|
946
|
+
return end;
|
|
947
|
+
}
|
|
948
|
+
function addDays2(d, n) {
|
|
949
|
+
const result = new Date(d);
|
|
950
|
+
result.setDate(result.getDate() + n);
|
|
951
|
+
return result;
|
|
952
|
+
}
|
|
953
|
+
function addMonths(d, n) {
|
|
954
|
+
const result = new Date(d);
|
|
955
|
+
const day = result.getDate();
|
|
956
|
+
result.setDate(1);
|
|
957
|
+
result.setMonth(result.getMonth() + n);
|
|
958
|
+
result.setDate(Math.min(day, new Date(result.getFullYear(), result.getMonth() + 1, 0).getDate()));
|
|
959
|
+
return result;
|
|
960
|
+
}
|
|
961
|
+
function getMonthGrid(year, month, weekStartsOn = 0) {
|
|
962
|
+
const firstOfMonth = new Date(year, month, 1);
|
|
963
|
+
const gridStart = startOfWeek(firstOfMonth, weekStartsOn);
|
|
964
|
+
const weeks = [];
|
|
965
|
+
const current = new Date(gridStart);
|
|
966
|
+
for (let w = 0; w < 6; w++) {
|
|
967
|
+
const week = [];
|
|
968
|
+
for (let d = 0; d < 7; d++) {
|
|
969
|
+
week.push(new Date(current));
|
|
970
|
+
current.setDate(current.getDate() + 1);
|
|
971
|
+
}
|
|
972
|
+
weeks.push(week);
|
|
973
|
+
}
|
|
974
|
+
return weeks;
|
|
975
|
+
}
|
|
976
|
+
function getWeekDays(date, weekStartsOn = 0) {
|
|
977
|
+
const start = startOfWeek(date, weekStartsOn);
|
|
978
|
+
const days = [];
|
|
979
|
+
for (let i = 0; i < 7; i++) {
|
|
980
|
+
days.push(addDays2(start, i));
|
|
981
|
+
}
|
|
982
|
+
return days;
|
|
983
|
+
}
|
|
984
|
+
var DAY_MS = 864e5;
|
|
985
|
+
function daysBetween(a, b) {
|
|
986
|
+
return Math.round((startOfDay(b).getTime() - startOfDay(a).getTime()) / DAY_MS);
|
|
987
|
+
}
|
|
988
|
+
function eventSpan(e) {
|
|
989
|
+
const first = startOfDay(e.start);
|
|
990
|
+
if (!e.end) return { first, last: first };
|
|
991
|
+
const lastInstant = e.allDay ? e.end : new Date(e.end.getTime() - 1);
|
|
992
|
+
const last = startOfDay(lastInstant);
|
|
993
|
+
return { first, last: last < first ? first : last };
|
|
994
|
+
}
|
|
995
|
+
function isBarEvent(e) {
|
|
996
|
+
if (e.allDay) return true;
|
|
997
|
+
if (!e.end) return false;
|
|
998
|
+
const dayLater = new Date(e.start);
|
|
999
|
+
dayLater.setDate(dayLater.getDate() + 1);
|
|
1000
|
+
return e.end.getTime() >= dayLater.getTime();
|
|
1001
|
+
}
|
|
1002
|
+
function getEventsForDay(events, date) {
|
|
1003
|
+
const day = startOfDay(date).getTime();
|
|
1004
|
+
return events.filter((e) => {
|
|
1005
|
+
const { first, last } = eventSpan(e);
|
|
1006
|
+
return first.getTime() <= day && day <= last.getTime();
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
function dayPieces(events, date) {
|
|
1010
|
+
const dayStart = startOfDay(date);
|
|
1011
|
+
const next = new Date(dayStart.getFullYear(), dayStart.getMonth(), dayStart.getDate() + 1);
|
|
1012
|
+
const pieces = [];
|
|
1013
|
+
for (const event of events) {
|
|
1014
|
+
if (isBarEvent(event)) continue;
|
|
1015
|
+
const ownDayEnd = new Date(event.start.getFullYear(), event.start.getMonth(), event.start.getDate() + 1);
|
|
1016
|
+
const end = event.end && event.end > event.start ? event.end : new Date(Math.min(event.start.getTime() + 36e5, ownDayEnd.getTime()));
|
|
1017
|
+
const start = event.start < dayStart ? dayStart : event.start;
|
|
1018
|
+
const stop = end > next ? next : end;
|
|
1019
|
+
if (stop > start) pieces.push({ event, start, end: stop });
|
|
1020
|
+
}
|
|
1021
|
+
return pieces.sort((a, b) => a.start.getTime() - b.start.getTime() || b.end.getTime() - a.end.getTime());
|
|
1022
|
+
}
|
|
1023
|
+
function twelveHour() {
|
|
1024
|
+
return /^h1[12]$/.test(dtf({ hour: "numeric" }).resolvedOptions().hourCycle ?? "");
|
|
1025
|
+
}
|
|
1026
|
+
var timeOptions = () => ({ hour: twelveHour() ? "numeric" : "2-digit", minute: "2-digit" });
|
|
1027
|
+
function formatTime(d) {
|
|
1028
|
+
return dtf(timeOptions()).format(d);
|
|
1029
|
+
}
|
|
1030
|
+
function formatHourLabel(hour) {
|
|
1031
|
+
const at = new Date(2026, 0, 5, hour);
|
|
1032
|
+
return twelveHour() ? dtf({ hour: "numeric" }).format(at) : dtf({ hour: "2-digit", minute: "2-digit" }).format(at);
|
|
1033
|
+
}
|
|
1034
|
+
function dayOffset(days) {
|
|
1035
|
+
return new Intl.NumberFormat(formatLocale(), { signDisplay: "always" }).format(days);
|
|
1036
|
+
}
|
|
1037
|
+
function formatTimeRange(start, end) {
|
|
1038
|
+
if (!end) return formatTime(start);
|
|
1039
|
+
const f = dtf(timeOptions());
|
|
1040
|
+
if (daysBetween(start, end) === 0) return f.formatRange(start, end);
|
|
1041
|
+
const sep = f.formatRangeToParts(start, end).find((p) => p.source === "shared" && p.type === "literal")?.value ?? " \u2013 ";
|
|
1042
|
+
const days = endDays(start, end);
|
|
1043
|
+
return days === 0 ? `${f.format(start)}${sep}${f.format(end)}` : `${f.format(start)}${sep}${f.format(end)} (${dayOffset(days)})`;
|
|
1044
|
+
}
|
|
1045
|
+
function endDays(start, end) {
|
|
1046
|
+
return end > start ? daysBetween(start, new Date(end.getTime() - 1)) : daysBetween(start, end);
|
|
1047
|
+
}
|
|
1048
|
+
function speakTimeRange(start, end) {
|
|
1049
|
+
if (!end) return formatTime(start);
|
|
1050
|
+
const days = endDays(start, end);
|
|
1051
|
+
const to = `${formatTime(start)} to ${formatTime(end)}`;
|
|
1052
|
+
return days === 0 ? to : days === 1 ? `${to} the next day` : `${to}, ${days} days later`;
|
|
1053
|
+
}
|
|
1054
|
+
function formatMonthYear(d) {
|
|
1055
|
+
return dtf({ month: "long", year: "numeric" }).format(d);
|
|
1056
|
+
}
|
|
1057
|
+
function formatDayLong(d) {
|
|
1058
|
+
return dtf({ weekday: "long", day: "numeric", month: "long", year: "numeric" }).format(d);
|
|
1059
|
+
}
|
|
1060
|
+
function formatDayShort(d) {
|
|
1061
|
+
return dtf({ weekday: "short", day: "numeric", month: "short" }).format(d);
|
|
1062
|
+
}
|
|
1063
|
+
function formatDayMedium(d) {
|
|
1064
|
+
return dtf({ day: "numeric", month: "short", year: "numeric" }).format(d);
|
|
1065
|
+
}
|
|
1066
|
+
function formatDayRange(start, end) {
|
|
1067
|
+
return dtf({ day: "numeric", month: "short", year: "numeric" }).formatRange(startOfDay(start), startOfDay(end));
|
|
1068
|
+
}
|
|
1069
|
+
function formatMonthRange(start, end) {
|
|
1070
|
+
return dtf({ month: "long", year: "numeric" }).formatRange(new Date(start.getFullYear(), start.getMonth(), 1), new Date(end.getFullYear(), end.getMonth(), 1));
|
|
1071
|
+
}
|
|
1072
|
+
function formatWeekRange(d, weekStartsOn = 0) {
|
|
1073
|
+
return dtf({ day: "numeric", month: "short", year: "numeric" }).formatRange(startOfWeek(d, weekStartsOn), startOfDay(endOfWeek(d, weekStartsOn)));
|
|
1074
|
+
}
|
|
1075
|
+
function formatEventWhen(e, spoken = false) {
|
|
1076
|
+
const { first, last } = eventSpan(e);
|
|
1077
|
+
const multiDay = last > first;
|
|
1078
|
+
if (e.allDay) {
|
|
1079
|
+
if (!multiDay) return spoken ? formatDayLong(first) : formatDayShort(first);
|
|
1080
|
+
return dtf(spoken ? { weekday: "long", day: "numeric", month: "long" } : { day: "numeric", month: "short" }).formatRange(first, last);
|
|
1081
|
+
}
|
|
1082
|
+
if (!e.end || !isBarEvent(e)) {
|
|
1083
|
+
const day = spoken ? formatDayLong(e.start) : formatDayShort(e.start);
|
|
1084
|
+
const end = e.end && e.end > e.start ? e.end : void 0;
|
|
1085
|
+
return `${day}, ${spoken ? speakTimeRange(e.start, end) : formatTimeRange(e.start, end)}`;
|
|
1086
|
+
}
|
|
1087
|
+
return dtf({ weekday: "short", day: "numeric", month: "short", hour: "numeric", minute: "2-digit" }).formatRange(e.start, e.end);
|
|
1088
|
+
}
|
|
1089
|
+
function layoutWeek(events, days, capacity) {
|
|
1090
|
+
const weekStart = startOfDay(days[0]);
|
|
1091
|
+
const weekEnd = startOfDay(days[days.length - 1]);
|
|
1092
|
+
const items = [];
|
|
1093
|
+
for (const event of events) {
|
|
1094
|
+
const { first, last } = eventSpan(event);
|
|
1095
|
+
if (last < weekStart || first > weekEnd) continue;
|
|
1096
|
+
items.push({
|
|
1097
|
+
event,
|
|
1098
|
+
startCol: Math.max(0, daysBetween(weekStart, first)),
|
|
1099
|
+
endCol: Math.min(days.length - 1, daysBetween(weekStart, last)),
|
|
1100
|
+
before: first < weekStart,
|
|
1101
|
+
after: last > weekEnd,
|
|
1102
|
+
length: daysBetween(first, last) + 1
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
items.sort((a, b) => {
|
|
1106
|
+
const barA = isBarEvent(a.event) || a.length > 1, barB = isBarEvent(b.event) || b.length > 1;
|
|
1107
|
+
if (barA !== barB) return barA ? -1 : 1;
|
|
1108
|
+
if (barA && a.length !== b.length) return b.length - a.length;
|
|
1109
|
+
return a.event.start.getTime() - b.event.start.getTime() || a.event.title.localeCompare(b.event.title);
|
|
1110
|
+
});
|
|
1111
|
+
const taken = [];
|
|
1112
|
+
const laneOf = /* @__PURE__ */ new Map();
|
|
1113
|
+
for (const item of items) {
|
|
1114
|
+
let lane = 0;
|
|
1115
|
+
while (Array.from({ length: item.endCol - item.startCol + 1 }, (_, k) => taken[lane]?.[item.startCol + k]).some(Boolean)) lane++;
|
|
1116
|
+
taken[lane] ??= [];
|
|
1117
|
+
for (let c = item.startCol; c <= item.endCol; c++) taken[lane][c] = true;
|
|
1118
|
+
laneOf.set(item, lane);
|
|
1119
|
+
}
|
|
1120
|
+
const cap = Math.max(1, capacity);
|
|
1121
|
+
const overflow = days.map((_, c) => items.some((it) => laneOf.get(it) >= cap && it.startCol <= c && c <= it.endCol));
|
|
1122
|
+
const more = days.map((_, c) => overflow[c] ? items.filter((it) => laneOf.get(it) >= cap - 1 && it.startCol <= c && c <= it.endCol).map((it) => it.event) : []);
|
|
1123
|
+
const segments = [];
|
|
1124
|
+
for (const item of items) {
|
|
1125
|
+
const lane = laneOf.get(item);
|
|
1126
|
+
if (lane >= cap) continue;
|
|
1127
|
+
if (lane < cap - 1) {
|
|
1128
|
+
segments.push({ event: item.event, startCol: item.startCol, span: item.endCol - item.startCol + 1, lane, continuesBefore: item.before, continuesAfter: item.after });
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
let runStart = -1;
|
|
1132
|
+
for (let c = item.startCol; c <= item.endCol + 1; c++) {
|
|
1133
|
+
const free = c <= item.endCol && !overflow[c];
|
|
1134
|
+
if (free && runStart < 0) runStart = c;
|
|
1135
|
+
if (!free && runStart >= 0) {
|
|
1136
|
+
segments.push({ event: item.event, startCol: runStart, span: c - runStart, lane, continuesBefore: runStart > item.startCol || item.before, continuesAfter: c - 1 < item.endCol || item.after });
|
|
1137
|
+
runStart = -1;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
const lanes = Math.min(cap, taken.length);
|
|
1142
|
+
return { segments, more, lanes };
|
|
1143
|
+
}
|
|
1144
|
+
function layoutPieces(pieces, minMinutes = 0) {
|
|
1145
|
+
const out = [];
|
|
1146
|
+
let group = [];
|
|
1147
|
+
let columnEnds = [];
|
|
1148
|
+
let groupEnd = -Infinity;
|
|
1149
|
+
const close = () => {
|
|
1150
|
+
for (const placed of group) placed.columns = columnEnds.length;
|
|
1151
|
+
out.push(...group);
|
|
1152
|
+
group = [];
|
|
1153
|
+
columnEnds = [];
|
|
1154
|
+
};
|
|
1155
|
+
for (const piece of pieces) {
|
|
1156
|
+
const at = piece.start.getTime();
|
|
1157
|
+
const end = Math.max(piece.end.getTime(), at + minMinutes * 6e4);
|
|
1158
|
+
if (group.length && at >= groupEnd) close();
|
|
1159
|
+
let column = columnEnds.findIndex((e) => e <= at);
|
|
1160
|
+
if (column < 0) column = columnEnds.push(0) - 1;
|
|
1161
|
+
columnEnds[column] = end;
|
|
1162
|
+
groupEnd = Math.max(group.length ? groupEnd : -Infinity, end);
|
|
1163
|
+
group.push({ piece, column, columns: 0 });
|
|
1164
|
+
}
|
|
1165
|
+
if (group.length) close();
|
|
1166
|
+
return out;
|
|
1167
|
+
}
|
|
1168
|
+
function timeToFraction(d) {
|
|
1169
|
+
return (d.getHours() * 60 + d.getMinutes()) / (24 * 60);
|
|
1170
|
+
}
|
|
716
1171
|
var CONTROL_HEIGHT2 = {
|
|
717
1172
|
sm: "h-[var(--ds-control-height-sm)]",
|
|
718
1173
|
md: "h-[var(--ds-control-height-md)]",
|
|
@@ -723,21 +1178,19 @@ var TEXT_SIZE2 = {
|
|
|
723
1178
|
md: "text-sm",
|
|
724
1179
|
lg: "text-base"
|
|
725
1180
|
};
|
|
726
|
-
var
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
"
|
|
730
|
-
"
|
|
731
|
-
"
|
|
732
|
-
"
|
|
733
|
-
"
|
|
734
|
-
"
|
|
735
|
-
"
|
|
736
|
-
"
|
|
737
|
-
"
|
|
738
|
-
"
|
|
739
|
-
"November",
|
|
740
|
-
"December"
|
|
1181
|
+
var ENGLISH_MONTHS = [
|
|
1182
|
+
"january",
|
|
1183
|
+
"february",
|
|
1184
|
+
"march",
|
|
1185
|
+
"april",
|
|
1186
|
+
"may",
|
|
1187
|
+
"june",
|
|
1188
|
+
"july",
|
|
1189
|
+
"august",
|
|
1190
|
+
"september",
|
|
1191
|
+
"october",
|
|
1192
|
+
"november",
|
|
1193
|
+
"december"
|
|
741
1194
|
];
|
|
742
1195
|
function getDaysInMonth(year, month) {
|
|
743
1196
|
return new Date(year, month + 1, 0).getDate();
|
|
@@ -745,37 +1198,43 @@ function getDaysInMonth(year, month) {
|
|
|
745
1198
|
function getFirstDayOfWeek(year, month) {
|
|
746
1199
|
return new Date(year, month, 1).getDay();
|
|
747
1200
|
}
|
|
748
|
-
function
|
|
1201
|
+
function isSameDay2(a, b) {
|
|
749
1202
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
750
1203
|
}
|
|
751
|
-
function formatDate(d) {
|
|
752
|
-
return `${MONTHS[d.getMonth()].slice(0, 3)} ${d.getDate()}, ${d.getFullYear()}`;
|
|
753
|
-
}
|
|
754
1204
|
function localeDayFirst() {
|
|
755
1205
|
try {
|
|
756
|
-
const parts = new Intl.DateTimeFormat(
|
|
1206
|
+
const parts = new Intl.DateTimeFormat(formatLocale()).formatToParts(new Date(2e3, 11, 25));
|
|
757
1207
|
return parts.findIndex((p) => p.type === "day") < parts.findIndex((p) => p.type === "month");
|
|
758
1208
|
} catch {
|
|
759
1209
|
return true;
|
|
760
1210
|
}
|
|
761
1211
|
}
|
|
762
|
-
function validDate(year,
|
|
763
|
-
if (
|
|
764
|
-
const d = new Date(year,
|
|
765
|
-
return d.getFullYear() === year && d.getMonth() ===
|
|
1212
|
+
function validDate(year, monthIndex2, day) {
|
|
1213
|
+
if (monthIndex2 < 0 || monthIndex2 > 11 || day < 1) return null;
|
|
1214
|
+
const d = new Date(year, monthIndex2, day);
|
|
1215
|
+
return d.getFullYear() === year && d.getMonth() === monthIndex2 && d.getDate() === day ? d : null;
|
|
1216
|
+
}
|
|
1217
|
+
function monthIndex(name) {
|
|
1218
|
+
const typed = name.toLocaleLowerCase().replace(/\.$/, "");
|
|
1219
|
+
const fold = (m) => m.toLocaleLowerCase().replace(/\.$/, "");
|
|
1220
|
+
const lists = [ENGLISH_MONTHS, Array.from({ length: 12 }, (_, i) => fold(monthName(i, "long"))), Array.from({ length: 12 }, (_, i) => fold(monthName(i, "short")))];
|
|
1221
|
+
for (const list of lists) {
|
|
1222
|
+
const i = list.findIndex((m) => m.startsWith(typed) || typed.length >= 3 && typed.startsWith(m));
|
|
1223
|
+
if (i >= 0) return i;
|
|
1224
|
+
}
|
|
1225
|
+
return -1;
|
|
766
1226
|
}
|
|
767
1227
|
function parseTypedDate(text, dayFirst = localeDayFirst()) {
|
|
768
1228
|
const t = text.trim().replace(/\s+/g, " ");
|
|
769
1229
|
if (!t) return null;
|
|
770
1230
|
let m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(t);
|
|
771
1231
|
if (m) return validDate(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
|
|
772
|
-
|
|
773
|
-
m = /^([A-Za-z]{3,})\.?\s+(\d{1,2}),?\s+(\d{4})$/.exec(t);
|
|
1232
|
+
m = /^(\p{L}{3,})\.?\s+(\d{1,2}),?\s+(\d{4})$/u.exec(t);
|
|
774
1233
|
if (m) {
|
|
775
1234
|
const mi = monthIndex(m[1]);
|
|
776
1235
|
return mi < 0 ? null : validDate(Number(m[3]), mi, Number(m[2]));
|
|
777
1236
|
}
|
|
778
|
-
m = /^(\d{1,2})
|
|
1237
|
+
m = /^(\d{1,2})\.?\s+(\p{L}{3,})\.?,?\s+(\d{4})$/u.exec(t);
|
|
779
1238
|
if (m) {
|
|
780
1239
|
const mi = monthIndex(m[2]);
|
|
781
1240
|
return mi < 0 ? null : validDate(Number(m[3]), mi, Number(m[1]));
|
|
@@ -895,7 +1354,7 @@ function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date"
|
|
|
895
1354
|
const d = validDate(next.year, next.month - 1, next.day);
|
|
896
1355
|
const ok = !!d && (!min || d >= min) && (!max || d <= max);
|
|
897
1356
|
setTypedInvalid(!ok);
|
|
898
|
-
if (d && ok && !(value &&
|
|
1357
|
+
if (d && ok && !(value && isSameDay2(value, d))) {
|
|
899
1358
|
lastCommitted.current = d.getTime();
|
|
900
1359
|
onChange(d);
|
|
901
1360
|
setViewDate(d);
|
|
@@ -975,7 +1434,7 @@ function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date"
|
|
|
975
1434
|
};
|
|
976
1435
|
const rangeA = range2?.start ?? null;
|
|
977
1436
|
const rangeB = range2?.end ?? null;
|
|
978
|
-
const otherEnd = value ? rangeA && !
|
|
1437
|
+
const otherEnd = value ? rangeA && !isSameDay2(rangeA, value) ? rangeA : rangeB : rangeA ?? rangeB;
|
|
979
1438
|
const thisEnd = value ?? (otherEnd && hover ? hover : null);
|
|
980
1439
|
const [bandStart, bandEnd] = otherEnd && thisEnd ? otherEnd <= thisEnd ? [otherEnd, thisEnd] : [thisEnd, otherEnd] : [null, null];
|
|
981
1440
|
const inBand = (d) => !!(bandStart && bandEnd && d > bandStart && d < bandEnd);
|
|
@@ -1092,11 +1551,7 @@ function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date"
|
|
|
1092
1551
|
style: { padding: "var(--ds-space-2) var(--ds-space-3)" },
|
|
1093
1552
|
children: [
|
|
1094
1553
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: prevMonth, "aria-label": "Previous month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14, className: "rotate-180" }) }),
|
|
1095
|
-
/* @__PURE__ */
|
|
1096
|
-
MONTHS[month],
|
|
1097
|
-
" ",
|
|
1098
|
-
year
|
|
1099
|
-
] }),
|
|
1554
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: formatMonthYear(viewDate) }),
|
|
1100
1555
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: nextMonth, "aria-label": "Next month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) })
|
|
1101
1556
|
]
|
|
1102
1557
|
}
|
|
@@ -1106,18 +1561,18 @@ function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date"
|
|
|
1106
1561
|
{
|
|
1107
1562
|
ref: gridRef,
|
|
1108
1563
|
role: "grid",
|
|
1109
|
-
"aria-label":
|
|
1564
|
+
"aria-label": formatMonthYear(viewDate),
|
|
1110
1565
|
onKeyDown: grid.onKeyDown,
|
|
1111
1566
|
className: "flex flex-col gap-ds-0.5 tabular-nums",
|
|
1112
1567
|
style: { padding: "var(--ds-space-2) var(--ds-space-3)" },
|
|
1113
1568
|
children: [
|
|
1114
|
-
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5 mb-ds-0.5", children:
|
|
1569
|
+
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5 mb-ds-0.5", children: weekdayNames(0, "narrow").map((d, i) => /* @__PURE__ */ jsx("div", { role: "columnheader", "aria-label": weekdayNames(0, "long")[i], className: "text-center text-2xs font-medium text-[var(--ds-text-muted)] py-ds-1", children: d }, i)) }),
|
|
1115
1570
|
weeks.map((week, w) => /* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5", onMouseLeave: () => setHover(null), children: week.map((day, i) => {
|
|
1116
1571
|
if (day === null) return /* @__PURE__ */ jsx("div", { role: "gridcell" }, `empty-${i}`);
|
|
1117
1572
|
const dateObj = new Date(year, month, day);
|
|
1118
|
-
const isSelected = !!value &&
|
|
1119
|
-
const isOtherEnd = !!otherEnd &&
|
|
1120
|
-
const isToday2 =
|
|
1573
|
+
const isSelected = !!value && isSameDay2(dateObj, value);
|
|
1574
|
+
const isOtherEnd = !!otherEnd && isSameDay2(dateObj, otherEnd);
|
|
1575
|
+
const isToday2 = isSameDay2(dateObj, today);
|
|
1121
1576
|
const between = inBand(dateObj);
|
|
1122
1577
|
const dis = isDisabledDay(dateObj);
|
|
1123
1578
|
return /* @__PURE__ */ jsx(
|
|
@@ -1130,12 +1585,12 @@ function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date"
|
|
|
1130
1585
|
"aria-disabled": dis || void 0,
|
|
1131
1586
|
onClick: () => selectDay(day),
|
|
1132
1587
|
onFocus: () => {
|
|
1133
|
-
if (!
|
|
1588
|
+
if (!isSameDay2(dateObj, focusDate)) setFocusDate(dateObj);
|
|
1134
1589
|
},
|
|
1135
1590
|
onMouseEnter: () => setHover(dateObj),
|
|
1136
1591
|
"aria-selected": isSelected,
|
|
1137
1592
|
"aria-current": isToday2 ? "date" : void 0,
|
|
1138
|
-
"aria-label":
|
|
1593
|
+
"aria-label": formatDayLong(dateObj),
|
|
1139
1594
|
className: cn(
|
|
1140
1595
|
"w-full aspect-square flex items-center justify-center text-xs",
|
|
1141
1596
|
"transition-colors cursor-pointer",
|
|
@@ -1191,174 +1646,6 @@ function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date"
|
|
|
1191
1646
|
)
|
|
1192
1647
|
] });
|
|
1193
1648
|
}
|
|
1194
|
-
|
|
1195
|
-
// ../../showcase/src/components/Calendar/calendar-utils.ts
|
|
1196
|
-
var MONTH_NAMES = [
|
|
1197
|
-
"January",
|
|
1198
|
-
"February",
|
|
1199
|
-
"March",
|
|
1200
|
-
"April",
|
|
1201
|
-
"May",
|
|
1202
|
-
"June",
|
|
1203
|
-
"July",
|
|
1204
|
-
"August",
|
|
1205
|
-
"September",
|
|
1206
|
-
"October",
|
|
1207
|
-
"November",
|
|
1208
|
-
"December"
|
|
1209
|
-
];
|
|
1210
|
-
var MONTH_NAMES_SHORT = [
|
|
1211
|
-
"Jan",
|
|
1212
|
-
"Feb",
|
|
1213
|
-
"Mar",
|
|
1214
|
-
"Apr",
|
|
1215
|
-
"May",
|
|
1216
|
-
"Jun",
|
|
1217
|
-
"Jul",
|
|
1218
|
-
"Aug",
|
|
1219
|
-
"Sep",
|
|
1220
|
-
"Oct",
|
|
1221
|
-
"Nov",
|
|
1222
|
-
"Dec"
|
|
1223
|
-
];
|
|
1224
|
-
var DAY_NAMES_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1225
|
-
var DAY_NAMES_MIN = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
1226
|
-
function getOrderedDayNames(weekStartsOn) {
|
|
1227
|
-
if (weekStartsOn === 1) return [...DAY_NAMES_MIN.slice(1), DAY_NAMES_MIN[0]];
|
|
1228
|
-
return DAY_NAMES_MIN;
|
|
1229
|
-
}
|
|
1230
|
-
function getOrderedDayNamesShort(weekStartsOn) {
|
|
1231
|
-
if (weekStartsOn === 1) return [...DAY_NAMES_SHORT.slice(1), DAY_NAMES_SHORT[0]];
|
|
1232
|
-
return DAY_NAMES_SHORT;
|
|
1233
|
-
}
|
|
1234
|
-
function isSameDay2(a, b) {
|
|
1235
|
-
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
1236
|
-
}
|
|
1237
|
-
function isSameMonth(a, b) {
|
|
1238
|
-
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
1239
|
-
}
|
|
1240
|
-
function isToday(d) {
|
|
1241
|
-
return isSameDay2(d, /* @__PURE__ */ new Date());
|
|
1242
|
-
}
|
|
1243
|
-
function isWeekend(d) {
|
|
1244
|
-
const day = d.getDay();
|
|
1245
|
-
return day === 0 || day === 6;
|
|
1246
|
-
}
|
|
1247
|
-
function startOfDay(d) {
|
|
1248
|
-
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
1249
|
-
}
|
|
1250
|
-
function startOfWeek(d, weekStartsOn = 0) {
|
|
1251
|
-
const date = new Date(d);
|
|
1252
|
-
const day = date.getDay();
|
|
1253
|
-
const diff = (day - weekStartsOn + 7) % 7;
|
|
1254
|
-
date.setDate(date.getDate() - diff);
|
|
1255
|
-
return startOfDay(date);
|
|
1256
|
-
}
|
|
1257
|
-
function endOfWeek(d, weekStartsOn = 0) {
|
|
1258
|
-
const start = startOfWeek(d, weekStartsOn);
|
|
1259
|
-
const end = new Date(start);
|
|
1260
|
-
end.setDate(end.getDate() + 6);
|
|
1261
|
-
end.setHours(23, 59, 59, 999);
|
|
1262
|
-
return end;
|
|
1263
|
-
}
|
|
1264
|
-
function addDays2(d, n) {
|
|
1265
|
-
const result = new Date(d);
|
|
1266
|
-
result.setDate(result.getDate() + n);
|
|
1267
|
-
return result;
|
|
1268
|
-
}
|
|
1269
|
-
function addMonths(d, n) {
|
|
1270
|
-
const result = new Date(d);
|
|
1271
|
-
result.setMonth(result.getMonth() + n);
|
|
1272
|
-
return result;
|
|
1273
|
-
}
|
|
1274
|
-
function getMonthGrid(year, month, weekStartsOn = 0) {
|
|
1275
|
-
const firstOfMonth = new Date(year, month, 1);
|
|
1276
|
-
const gridStart = startOfWeek(firstOfMonth, weekStartsOn);
|
|
1277
|
-
const weeks = [];
|
|
1278
|
-
const current = new Date(gridStart);
|
|
1279
|
-
for (let w = 0; w < 6; w++) {
|
|
1280
|
-
const week = [];
|
|
1281
|
-
for (let d = 0; d < 7; d++) {
|
|
1282
|
-
week.push(new Date(current));
|
|
1283
|
-
current.setDate(current.getDate() + 1);
|
|
1284
|
-
}
|
|
1285
|
-
weeks.push(week);
|
|
1286
|
-
}
|
|
1287
|
-
return weeks;
|
|
1288
|
-
}
|
|
1289
|
-
function getWeekDays(date, weekStartsOn = 0) {
|
|
1290
|
-
const start = startOfWeek(date, weekStartsOn);
|
|
1291
|
-
const days = [];
|
|
1292
|
-
for (let i = 0; i < 7; i++) {
|
|
1293
|
-
days.push(addDays2(start, i));
|
|
1294
|
-
}
|
|
1295
|
-
return days;
|
|
1296
|
-
}
|
|
1297
|
-
function getEventsForDay(events, date) {
|
|
1298
|
-
const dayStart = startOfDay(date);
|
|
1299
|
-
const dayEnd = new Date(dayStart);
|
|
1300
|
-
dayEnd.setHours(23, 59, 59, 999);
|
|
1301
|
-
return events.filter((e) => {
|
|
1302
|
-
const eStart = new Date(e.start);
|
|
1303
|
-
const eEnd = e.end ? new Date(e.end) : eStart;
|
|
1304
|
-
return eStart <= dayEnd && eEnd >= dayStart;
|
|
1305
|
-
});
|
|
1306
|
-
}
|
|
1307
|
-
function formatTime(d) {
|
|
1308
|
-
const h = d.getHours();
|
|
1309
|
-
const m = d.getMinutes();
|
|
1310
|
-
const ampm = h >= 12 ? "PM" : "AM";
|
|
1311
|
-
const hour = h % 12 || 12;
|
|
1312
|
-
return m === 0 ? `${hour} ${ampm}` : `${hour}:${String(m).padStart(2, "0")} ${ampm}`;
|
|
1313
|
-
}
|
|
1314
|
-
function formatTimeRange(start, end) {
|
|
1315
|
-
if (!end) return formatTime(start);
|
|
1316
|
-
return `${formatTime(start)} \u2013 ${formatTime(end)}`;
|
|
1317
|
-
}
|
|
1318
|
-
function formatWeekRange(d, weekStartsOn = 0) {
|
|
1319
|
-
const start = startOfWeek(d, weekStartsOn);
|
|
1320
|
-
const end = endOfWeek(d, weekStartsOn);
|
|
1321
|
-
const sameMonth = start.getMonth() === end.getMonth();
|
|
1322
|
-
if (sameMonth) {
|
|
1323
|
-
return `${MONTH_NAMES_SHORT[start.getMonth()]} ${start.getDate()} \u2013 ${end.getDate()}, ${start.getFullYear()}`;
|
|
1324
|
-
}
|
|
1325
|
-
const sameYear = start.getFullYear() === end.getFullYear();
|
|
1326
|
-
if (sameYear) {
|
|
1327
|
-
return `${MONTH_NAMES_SHORT[start.getMonth()]} ${start.getDate()} \u2013 ${MONTH_NAMES_SHORT[end.getMonth()]} ${end.getDate()}, ${start.getFullYear()}`;
|
|
1328
|
-
}
|
|
1329
|
-
return `${MONTH_NAMES_SHORT[start.getMonth()]} ${start.getDate()}, ${start.getFullYear()} \u2013 ${MONTH_NAMES_SHORT[end.getMonth()]} ${end.getDate()}, ${end.getFullYear()}`;
|
|
1330
|
-
}
|
|
1331
|
-
function getOverlappingGroups(events) {
|
|
1332
|
-
const timed = events.filter((e) => !e.allDay && e.end).sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
1333
|
-
if (timed.length === 0) return [];
|
|
1334
|
-
const result = [];
|
|
1335
|
-
const columns = [];
|
|
1336
|
-
for (const event of timed) {
|
|
1337
|
-
const eStart = event.start.getTime();
|
|
1338
|
-
const eEnd = (event.end ?? event.start).getTime();
|
|
1339
|
-
let placed = false;
|
|
1340
|
-
for (let col = 0; col < columns.length; col++) {
|
|
1341
|
-
if (columns[col].end <= eStart) {
|
|
1342
|
-
columns[col].end = eEnd;
|
|
1343
|
-
result.push({ event, column: col, totalColumns: 0 });
|
|
1344
|
-
placed = true;
|
|
1345
|
-
break;
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
if (!placed) {
|
|
1349
|
-
columns.push({ end: eEnd });
|
|
1350
|
-
result.push({ event, column: columns.length - 1, totalColumns: 0 });
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
const totalCols = columns.length;
|
|
1354
|
-
for (const item of result) {
|
|
1355
|
-
item.totalColumns = totalCols;
|
|
1356
|
-
}
|
|
1357
|
-
return result;
|
|
1358
|
-
}
|
|
1359
|
-
function timeToFraction(d) {
|
|
1360
|
-
return (d.getHours() * 60 + d.getMinutes()) / (24 * 60);
|
|
1361
|
-
}
|
|
1362
1649
|
var CONTROL_HEIGHT3 = {
|
|
1363
1650
|
sm: "h-[var(--ds-control-height-sm)]",
|
|
1364
1651
|
md: "h-[var(--ds-control-height-md)]",
|
|
@@ -1369,10 +1656,6 @@ var TEXT_SIZE3 = {
|
|
|
1369
1656
|
md: "text-sm",
|
|
1370
1657
|
lg: "text-base"
|
|
1371
1658
|
};
|
|
1372
|
-
var MONTHS2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
1373
|
-
function fmt(d) {
|
|
1374
|
-
return `${MONTHS2[d.getMonth()].slice(0, 3)} ${d.getDate()}, ${d.getFullYear()}`;
|
|
1375
|
-
}
|
|
1376
1659
|
var DEFAULT_DATE_RANGE_PRESETS = [
|
|
1377
1660
|
{ label: "Today", range: () => {
|
|
1378
1661
|
const t = startOfDay(/* @__PURE__ */ new Date());
|
|
@@ -1427,7 +1710,8 @@ function DateRangePicker({
|
|
|
1427
1710
|
const labelledBy = control.labelId ? `${control.labelId} ${triggerId}` : void 0;
|
|
1428
1711
|
const pos = usePosition(triggerRef, panelRef, open, { side: "bottom", align: "start", offset: 4, flip: true });
|
|
1429
1712
|
const today = useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
1430
|
-
const dayNames =
|
|
1713
|
+
const dayNames = weekdayNames(weekStartsOn, "narrow");
|
|
1714
|
+
const dayNamesLong = weekdayNames(weekStartsOn, "long");
|
|
1431
1715
|
const gridRef = useRef(null);
|
|
1432
1716
|
const [focusDate, setFocusDate] = useState(() => startOfDay(value.start ?? /* @__PURE__ */ new Date()));
|
|
1433
1717
|
const [prevOpen, setPrevOpen] = useState(open);
|
|
@@ -1441,8 +1725,8 @@ function DateRangePicker({
|
|
|
1441
1725
|
}
|
|
1442
1726
|
const showDay = (d) => {
|
|
1443
1727
|
setFocusDate(d);
|
|
1444
|
-
const
|
|
1445
|
-
const offset =
|
|
1728
|
+
const monthIndex2 = (x) => x.getFullYear() * 12 + x.getMonth();
|
|
1729
|
+
const offset = monthIndex2(d) - monthIndex2(viewDate);
|
|
1446
1730
|
if (offset < 0) setViewDate(new Date(d.getFullYear(), d.getMonth(), 1));
|
|
1447
1731
|
else if (offset > 1) setViewDate(new Date(d.getFullYear(), d.getMonth() - 1, 1));
|
|
1448
1732
|
};
|
|
@@ -1504,7 +1788,7 @@ function DateRangePicker({
|
|
|
1504
1788
|
const rangeEnd2 = value.end ?? previewEnd;
|
|
1505
1789
|
const inRange = (d) => !!(rangeStart && rangeEnd2 && d > rangeStart && d < rangeEnd2);
|
|
1506
1790
|
const months = [viewDate, addMonths(viewDate, 1)];
|
|
1507
|
-
const summary = value.start && value.end ?
|
|
1791
|
+
const summary = value.start && value.end ? formatDayRange(value.start, value.end) : value.start ? `${formatDayMedium(value.start)} \u2013 \u2026` : null;
|
|
1508
1792
|
return /* @__PURE__ */ jsxs("div", { ref, className: cn(className), children: [
|
|
1509
1793
|
label && /* @__PURE__ */ jsx("label", { htmlFor: triggerId, className: "block text-sm font-medium text-[var(--ds-text-primary)] mb-ds-1", children: label }),
|
|
1510
1794
|
control.requiredNote,
|
|
@@ -1571,23 +1855,15 @@ function DateRangePicker({
|
|
|
1571
1855
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
1572
1856
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between bg-[var(--ds-bg-muted)] rounded-tr-[var(--ds-radius-md)] px-ds-3 py-ds-2", children: [
|
|
1573
1857
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => pageMonths(-1), "aria-label": "Previous month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14, className: "rotate-180" }) }),
|
|
1574
|
-
/* @__PURE__ */
|
|
1575
|
-
MONTHS2[months[0].getMonth()],
|
|
1576
|
-
" ",
|
|
1577
|
-
months[0].getFullYear(),
|
|
1578
|
-
" \u2013 ",
|
|
1579
|
-
MONTHS2[months[1].getMonth()],
|
|
1580
|
-
" ",
|
|
1581
|
-
months[1].getFullYear()
|
|
1582
|
-
] }),
|
|
1858
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: formatMonthRange(months[0], months[1]) }),
|
|
1583
1859
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => pageMonths(1), "aria-label": "Next month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) })
|
|
1584
1860
|
] }),
|
|
1585
|
-
/* @__PURE__ */ jsx("div", { ref: gridRef, onKeyDown: grid.onKeyDown, className: "flex gap-ds-4 px-ds-3 py-ds-2", onMouseLeave: () => setHover(null), children: months.map((m) => /* @__PURE__ */ jsxs("div", { role: "grid", "aria-label":
|
|
1586
|
-
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5 mb-ds-0.5", children: dayNames.map((d) => /* @__PURE__ */ jsx("div", { role: "columnheader", className: "text-center text-2xs font-medium text-[var(--ds-text-muted)] py-ds-1", children: d },
|
|
1861
|
+
/* @__PURE__ */ jsx("div", { ref: gridRef, onKeyDown: grid.onKeyDown, className: "flex gap-ds-4 px-ds-3 py-ds-2", onMouseLeave: () => setHover(null), children: months.map((m) => /* @__PURE__ */ jsxs("div", { role: "grid", "aria-label": formatMonthYear(m), className: "w-[224px] flex flex-col gap-ds-0.5", children: [
|
|
1862
|
+
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5 mb-ds-0.5", children: dayNames.map((d, i) => /* @__PURE__ */ jsx("div", { role: "columnheader", "aria-label": dayNamesLong[i], className: "text-center text-2xs font-medium text-[var(--ds-text-muted)] py-ds-1", children: d }, i)) }),
|
|
1587
1863
|
getMonthGrid(m.getFullYear(), m.getMonth(), weekStartsOn).map((week, w) => /* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5", children: week.map((d) => {
|
|
1588
1864
|
if (!isSameMonth(d, m)) return /* @__PURE__ */ jsx("div", { role: "gridcell" }, d.toISOString());
|
|
1589
|
-
const isStart = !!rangeStart &&
|
|
1590
|
-
const isEnd = !!rangeEnd2 &&
|
|
1865
|
+
const isStart = !!rangeStart && isSameDay(d, rangeStart);
|
|
1866
|
+
const isEnd = !!rangeEnd2 && isSameDay(d, rangeEnd2);
|
|
1591
1867
|
const between = inRange(d);
|
|
1592
1868
|
const dis = isDisabledDay(d);
|
|
1593
1869
|
return /* @__PURE__ */ jsx(
|
|
@@ -1600,17 +1876,17 @@ function DateRangePicker({
|
|
|
1600
1876
|
"aria-disabled": dis || void 0,
|
|
1601
1877
|
onClick: () => selectDay(d),
|
|
1602
1878
|
onFocus: () => {
|
|
1603
|
-
if (!
|
|
1879
|
+
if (!isSameDay(d, focusDate)) setFocusDate(d);
|
|
1604
1880
|
},
|
|
1605
1881
|
onMouseEnter: () => setHover(d),
|
|
1606
1882
|
"aria-selected": isStart || isEnd || between,
|
|
1607
|
-
"aria-current":
|
|
1608
|
-
"aria-label":
|
|
1883
|
+
"aria-current": isSameDay(d, today) ? "date" : void 0,
|
|
1884
|
+
"aria-label": formatDayLong(d),
|
|
1609
1885
|
className: cn(
|
|
1610
1886
|
"w-full aspect-square flex items-center justify-center text-xs",
|
|
1611
1887
|
"transition-colors cursor-pointer",
|
|
1612
1888
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
1613
|
-
isStart || isEnd ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-bold rounded-[var(--ds-radius-sm)]" : between ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-subtle-text)] rounded-none" :
|
|
1889
|
+
isStart || isEnd ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-bold rounded-[var(--ds-radius-sm)]" : between ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-subtle-text)] rounded-none" : isSameDay(d, today) ? "border-[length:var(--ds-border-width)] border-[var(--ds-accent-primary)] text-[var(--ds-accent-primary)] font-medium rounded-[var(--ds-radius-sm)]" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-emphasis)] rounded-[var(--ds-radius-sm)]",
|
|
1614
1890
|
dis && "opacity-disabled cursor-not-allowed hover:bg-transparent"
|
|
1615
1891
|
),
|
|
1616
1892
|
children: d.getDate()
|
|
@@ -3515,7 +3791,7 @@ var Alert = forwardRef(function Alert2({
|
|
|
3515
3791
|
isAccent ? cn("border-[length:var(--ds-border-width)] border-current", actionColorsByVariant[variant]) : cn("border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]", "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)]")
|
|
3516
3792
|
),
|
|
3517
3793
|
children: [
|
|
3518
|
-
a.iconLeft && /* @__PURE__ */ jsx("span", { className: "inline-flex mr-ds-1", children: a.iconLeft }),
|
|
3794
|
+
a.iconLeft && /* @__PURE__ */ jsx("span", { className: "inline-flex mr-ds-1", children: slotIcon(a.iconLeft, 14, "an Alert action's iconLeft") }),
|
|
3519
3795
|
a.label
|
|
3520
3796
|
]
|
|
3521
3797
|
},
|
|
@@ -4065,102 +4341,6 @@ function PanelCheckbox({ checked, indeterminate, onClick, label }) {
|
|
|
4065
4341
|
}
|
|
4066
4342
|
);
|
|
4067
4343
|
}
|
|
4068
|
-
|
|
4069
|
-
// ../../showcase/src/lib/initials.ts
|
|
4070
|
-
function initialsOf(name) {
|
|
4071
|
-
return name.trim().split(/\s+/).filter(Boolean).slice(0, 2).map((word) => Array.from(word)[0] ?? "").join("").toUpperCase();
|
|
4072
|
-
}
|
|
4073
|
-
function toInitials(value) {
|
|
4074
|
-
const s = value.trim();
|
|
4075
|
-
if (!s) return "";
|
|
4076
|
-
if (!/\s/.test(s) && Array.from(s).length <= 3) return s;
|
|
4077
|
-
return initialsOf(s);
|
|
4078
|
-
}
|
|
4079
|
-
var sizeStyles2 = {
|
|
4080
|
-
sm: "h-8 w-8 text-xs",
|
|
4081
|
-
md: "h-10 w-10 text-sm",
|
|
4082
|
-
lg: "h-12 w-12 text-base"
|
|
4083
|
-
};
|
|
4084
|
-
var paletteStyles = {
|
|
4085
|
-
1: "bg-[var(--ds-palette-1-bg,var(--ds-bg-muted))] text-[var(--ds-palette-1-text,var(--ds-text-secondary))]",
|
|
4086
|
-
2: "bg-[var(--ds-palette-2-bg,var(--ds-bg-muted))] text-[var(--ds-palette-2-text,var(--ds-text-secondary))]",
|
|
4087
|
-
3: "bg-[var(--ds-palette-3-bg,var(--ds-bg-muted))] text-[var(--ds-palette-3-text,var(--ds-text-secondary))]",
|
|
4088
|
-
4: "bg-[var(--ds-palette-4-bg,var(--ds-bg-muted))] text-[var(--ds-palette-4-text,var(--ds-text-secondary))]",
|
|
4089
|
-
5: "bg-[var(--ds-palette-5-bg,var(--ds-bg-muted))] text-[var(--ds-palette-5-text,var(--ds-text-secondary))]"
|
|
4090
|
-
};
|
|
4091
|
-
function paletteFor(seed) {
|
|
4092
|
-
let h = 0;
|
|
4093
|
-
for (const ch of seed) h = h * 31 + ch.charCodeAt(0) >>> 0;
|
|
4094
|
-
return h % 5 + 1;
|
|
4095
|
-
}
|
|
4096
|
-
function colorStyles(color, seed) {
|
|
4097
|
-
if (color === "accent") return "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]";
|
|
4098
|
-
if (color === "neutral") return "bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)]";
|
|
4099
|
-
return paletteStyles[color === "auto" ? paletteFor(seed) : color];
|
|
4100
|
-
}
|
|
4101
|
-
function PresenceMark({ status }) {
|
|
4102
|
-
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 10 10", width: "10", height: "10", "aria-hidden": "true", focusable: "false", "data-presence": status, className: "block", children: [
|
|
4103
|
-
status === "online" && /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "5", className: "fill-[var(--ds-status-success)]" }),
|
|
4104
|
-
status === "away" && /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "4", fill: "none", strokeWidth: "2", className: "stroke-[var(--ds-status-warning)]" }),
|
|
4105
|
-
status === "busy" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4106
|
-
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "5", className: "fill-[var(--ds-status-error)]" }),
|
|
4107
|
-
/* @__PURE__ */ jsx("rect", { x: "2.5", y: "4.1", width: "5", height: "1.8", rx: "0.9", className: "fill-[var(--ds-bg-canvas)]" })
|
|
4108
|
-
] }),
|
|
4109
|
-
status === "offline" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4110
|
-
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "4", fill: "none", strokeWidth: "2", className: "stroke-[var(--ds-text-muted)]" }),
|
|
4111
|
-
/* @__PURE__ */ jsx("line", { x1: "3.1", y1: "6.9", x2: "6.9", y2: "3.1", strokeWidth: "1.5", strokeLinecap: "round", className: "stroke-[var(--ds-text-muted)]" })
|
|
4112
|
-
] })
|
|
4113
|
-
] });
|
|
4114
|
-
}
|
|
4115
|
-
function Avatar({ initials, src, alt, size = "md", status, color = "auto", className }) {
|
|
4116
|
-
const who = alt ?? initials ?? "";
|
|
4117
|
-
const named = status ? [who, status].filter(Boolean).join(", ") : void 0;
|
|
4118
|
-
const base = cn(
|
|
4119
|
-
"inline-flex items-center justify-center font-medium shrink-0",
|
|
4120
|
-
"rounded-[var(--ds-radius-full)]",
|
|
4121
|
-
sizeStyles2[size],
|
|
4122
|
-
className
|
|
4123
|
-
);
|
|
4124
|
-
const avatarElement = src ? /* @__PURE__ */ jsx(
|
|
4125
|
-
"img",
|
|
4126
|
-
{
|
|
4127
|
-
"data-avatar": "",
|
|
4128
|
-
src,
|
|
4129
|
-
alt: named ?? alt ?? initials ?? "",
|
|
4130
|
-
className: cn(base, "object-cover")
|
|
4131
|
-
}
|
|
4132
|
-
) : /* @__PURE__ */ jsx(
|
|
4133
|
-
"div",
|
|
4134
|
-
{
|
|
4135
|
-
"data-avatar": "",
|
|
4136
|
-
role: named ? "img" : void 0,
|
|
4137
|
-
"aria-label": named,
|
|
4138
|
-
className: cn(
|
|
4139
|
-
base,
|
|
4140
|
-
colorStyles(color, alt ?? initials ?? ""),
|
|
4141
|
-
"border-[length:var(--ds-border-width)] border-transparent"
|
|
4142
|
-
),
|
|
4143
|
-
children: initials != null ? toInitials(initials) : null
|
|
4144
|
-
}
|
|
4145
|
-
);
|
|
4146
|
-
if (!status) return avatarElement;
|
|
4147
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative inline-flex", children: [
|
|
4148
|
-
avatarElement,
|
|
4149
|
-
/* @__PURE__ */ jsx(
|
|
4150
|
-
"span",
|
|
4151
|
-
{
|
|
4152
|
-
className: cn(
|
|
4153
|
-
"absolute",
|
|
4154
|
-
size === "sm" && "bottom-[-4px] right-[-4px]",
|
|
4155
|
-
size === "md" && "bottom-[-2px] right-[-2px]",
|
|
4156
|
-
size === "lg" && "bottom-[0px] right-[0px]"
|
|
4157
|
-
),
|
|
4158
|
-
"aria-hidden": "true",
|
|
4159
|
-
children: /* @__PURE__ */ jsx("span", { className: "block rounded-[var(--ds-radius-full)] bg-[var(--ds-bg-canvas)] shadow-[0_0_0_2px_var(--ds-bg-canvas)]", children: /* @__PURE__ */ jsx(PresenceMark, { status }) })
|
|
4160
|
-
}
|
|
4161
|
-
)
|
|
4162
|
-
] });
|
|
4163
|
-
}
|
|
4164
4344
|
function MentionInput({
|
|
4165
4345
|
value: controlledValue,
|
|
4166
4346
|
onChange: onChangeProp,
|
|
@@ -4168,8 +4348,12 @@ function MentionInput({
|
|
|
4168
4348
|
trigger = "@",
|
|
4169
4349
|
placeholder,
|
|
4170
4350
|
disabled,
|
|
4171
|
-
className
|
|
4351
|
+
className,
|
|
4352
|
+
error = false,
|
|
4353
|
+
"aria-label": ariaLabel,
|
|
4354
|
+
...wiring
|
|
4172
4355
|
}) {
|
|
4356
|
+
const control = useFieldControl({ ...wiring, error: error || void 0 });
|
|
4173
4357
|
const [internalValue, setInternalValue] = useState("");
|
|
4174
4358
|
const value = controlledValue ?? internalValue;
|
|
4175
4359
|
const onChange = useReportedChange(onChangeProp, value);
|
|
@@ -4177,14 +4361,14 @@ function MentionInput({
|
|
|
4177
4361
|
const [showPopup, setShowPopup] = useState(false);
|
|
4178
4362
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
4179
4363
|
const [triggerStart, setTriggerStart] = useState(-1);
|
|
4180
|
-
const [
|
|
4364
|
+
const [anchor, setAnchor] = useState(null);
|
|
4181
4365
|
const inputRef = useRef(null);
|
|
4182
4366
|
const popupRef = useRef(null);
|
|
4183
4367
|
const mirrorRef = useRef(null);
|
|
4184
|
-
const
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
useOverlayLayer(
|
|
4368
|
+
const listId = useId();
|
|
4369
|
+
const { items: filtered, more } = shownMentions(matchMentions(suggestions, query));
|
|
4370
|
+
const listShown = showPopup && filtered.length > 0;
|
|
4371
|
+
useOverlayLayer(listShown);
|
|
4188
4372
|
const updateValue = useCallback(
|
|
4189
4373
|
(v) => {
|
|
4190
4374
|
if (controlledValue === void 0) setInternalValue(v);
|
|
@@ -4227,13 +4411,15 @@ function MentionInput({
|
|
|
4227
4411
|
const span = document.createElement("span");
|
|
4228
4412
|
span.textContent = trigger;
|
|
4229
4413
|
mirror.appendChild(span);
|
|
4230
|
-
const rect = el.getBoundingClientRect();
|
|
4231
4414
|
const spanRect = span.getBoundingClientRect();
|
|
4232
4415
|
const mirrorRect = mirror.getBoundingClientRect();
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4416
|
+
setAnchor({ x: spanRect.left - mirrorRect.left, y: spanRect.top - mirrorRect.top, width: spanRect.width, height: span.offsetHeight });
|
|
4417
|
+
};
|
|
4418
|
+
const anchorRect = () => {
|
|
4419
|
+
const el = inputRef.current;
|
|
4420
|
+
if (!el || !anchor) return null;
|
|
4421
|
+
const field = el.getBoundingClientRect();
|
|
4422
|
+
return new DOMRect(field.left + anchor.x, field.top + anchor.y - el.scrollTop, anchor.width, anchor.height);
|
|
4237
4423
|
};
|
|
4238
4424
|
const insertMention = (suggestion) => {
|
|
4239
4425
|
const el = inputRef.current;
|
|
@@ -4252,13 +4438,15 @@ function MentionInput({
|
|
|
4252
4438
|
});
|
|
4253
4439
|
};
|
|
4254
4440
|
const handleKeyDown = (e) => {
|
|
4255
|
-
if (!
|
|
4441
|
+
if (!listShown) return;
|
|
4256
4442
|
if (e.key === "ArrowDown") {
|
|
4257
4443
|
e.preventDefault();
|
|
4258
4444
|
setActiveIndex((i) => (i + 1) % filtered.length);
|
|
4259
4445
|
} else if (e.key === "ArrowUp") {
|
|
4260
4446
|
e.preventDefault();
|
|
4261
4447
|
setActiveIndex((i) => (i - 1 + filtered.length) % filtered.length);
|
|
4448
|
+
} else if (e.key === "Tab" && e.shiftKey) {
|
|
4449
|
+
flushSync(() => setShowPopup(false));
|
|
4262
4450
|
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
4263
4451
|
e.preventDefault();
|
|
4264
4452
|
insertMention(filtered[activeIndex]);
|
|
@@ -4282,21 +4470,30 @@ function MentionInput({
|
|
|
4282
4470
|
"textarea",
|
|
4283
4471
|
{
|
|
4284
4472
|
ref: inputRef,
|
|
4473
|
+
id: control.id,
|
|
4474
|
+
"aria-labelledby": wiring["aria-labelledby"],
|
|
4475
|
+
"aria-label": control.labelId ? void 0 : ariaLabel,
|
|
4476
|
+
"aria-describedby": control.describedBy,
|
|
4477
|
+
"aria-invalid": control.invalid || void 0,
|
|
4478
|
+
"aria-required": control.required || void 0,
|
|
4285
4479
|
value,
|
|
4286
4480
|
onChange: handleInput,
|
|
4287
4481
|
onKeyDown: handleKeyDown,
|
|
4482
|
+
"aria-autocomplete": "list",
|
|
4483
|
+
"aria-controls": listShown ? listId : void 0,
|
|
4484
|
+
"aria-activedescendant": listShown ? mentionOptionId(listId, activeIndex) : void 0,
|
|
4288
4485
|
placeholder,
|
|
4289
4486
|
disabled,
|
|
4290
4487
|
rows: 3,
|
|
4291
4488
|
className: cn(
|
|
4292
4489
|
"flex w-full px-ds-3 py-ds-2 text-sm resize-none",
|
|
4293
4490
|
"bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]",
|
|
4294
|
-
"border-[length:var(--ds-border-width)]
|
|
4491
|
+
"border-[length:var(--ds-border-width)]",
|
|
4492
|
+
control.invalid ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)] hover:border-[var(--ds-input-border-hover)]",
|
|
4295
4493
|
"rounded-[var(--ds-radius-md)]",
|
|
4296
4494
|
"shadow-[var(--ds-input-shadow)]",
|
|
4297
4495
|
"placeholder:text-[var(--ds-text-muted)]",
|
|
4298
|
-
|
|
4299
|
-
FOCUS_RING,
|
|
4496
|
+
control.invalid ? ERROR_FOCUS_RING : FOCUS_RING,
|
|
4300
4497
|
"disabled:cursor-not-allowed disabled:opacity-disabled disabled:hover:border-[var(--ds-input-border)]",
|
|
4301
4498
|
"transition-colors duration-[var(--ds-transition-speed)]"
|
|
4302
4499
|
)
|
|
@@ -4310,59 +4507,19 @@ function MentionInput({
|
|
|
4310
4507
|
className: "fixed top-0 left-0 -z-50 opacity-0 pointer-events-none"
|
|
4311
4508
|
}
|
|
4312
4509
|
),
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
),
|
|
4327
|
-
style: { top: popupPos.top, left: popupPos.left },
|
|
4328
|
-
children: filtered.map((s, i) => /* @__PURE__ */ jsxs(
|
|
4329
|
-
"button",
|
|
4330
|
-
{
|
|
4331
|
-
type: "button",
|
|
4332
|
-
role: "option",
|
|
4333
|
-
"aria-selected": i === activeIndex,
|
|
4334
|
-
className: cn(
|
|
4335
|
-
"flex items-center gap-ds-2.5 w-full px-ds-3 py-ds-1.5 text-left text-sm cursor-pointer",
|
|
4336
|
-
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
4337
|
-
i === activeIndex ? "bg-[var(--ds-bg-muted)] text-[var(--ds-text-primary)]" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-emphasis)] hover:text-[var(--ds-text-primary)]"
|
|
4338
|
-
),
|
|
4339
|
-
onMouseDown: (e) => {
|
|
4340
|
-
e.preventDefault();
|
|
4341
|
-
insertMention(s);
|
|
4342
|
-
},
|
|
4343
|
-
onMouseEnter: () => setActiveIndex(i),
|
|
4344
|
-
children: [
|
|
4345
|
-
/* @__PURE__ */ jsx(
|
|
4346
|
-
Avatar,
|
|
4347
|
-
{
|
|
4348
|
-
src: s.avatar,
|
|
4349
|
-
initials: s.label.charAt(0).toUpperCase(),
|
|
4350
|
-
alt: s.label,
|
|
4351
|
-
size: "sm",
|
|
4352
|
-
className: "!h-6 !w-6 !text-2xs"
|
|
4353
|
-
}
|
|
4354
|
-
),
|
|
4355
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
4356
|
-
/* @__PURE__ */ jsx("div", { className: "font-medium text-[var(--ds-text-primary)] truncate", children: s.label }),
|
|
4357
|
-
s.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-[var(--ds-text-muted)] truncate", children: s.description })
|
|
4358
|
-
] })
|
|
4359
|
-
]
|
|
4360
|
-
},
|
|
4361
|
-
s.id
|
|
4362
|
-
))
|
|
4363
|
-
}
|
|
4364
|
-
),
|
|
4365
|
-
document.body
|
|
4510
|
+
listShown && /* @__PURE__ */ jsx(
|
|
4511
|
+
MentionList,
|
|
4512
|
+
{
|
|
4513
|
+
id: listId,
|
|
4514
|
+
label: "Suggestions",
|
|
4515
|
+
items: filtered,
|
|
4516
|
+
more,
|
|
4517
|
+
activeIndex,
|
|
4518
|
+
onActiveIndexChange: setActiveIndex,
|
|
4519
|
+
onPick: insertMention,
|
|
4520
|
+
anchorRect,
|
|
4521
|
+
listRef: popupRef
|
|
4522
|
+
}
|
|
4366
4523
|
)
|
|
4367
4524
|
] });
|
|
4368
4525
|
}
|
|
@@ -5025,7 +5182,7 @@ function CardGrid({ minWidth, maxColumns = 4, compare = false, gap = "var(--ds-s
|
|
|
5025
5182
|
}
|
|
5026
5183
|
);
|
|
5027
5184
|
}
|
|
5028
|
-
var
|
|
5185
|
+
var sizeStyles2 = {
|
|
5029
5186
|
sm: { gap: "gap-ds-0.5", label: "text-[length:var(--ds-font-size-xs)]", value: "text-[length:var(--ds-font-size-xs)]", iconSize: 12, py: "py-ds-1.5" },
|
|
5030
5187
|
md: { gap: "gap-ds-1", label: "text-[length:var(--ds-font-size-sm)]", value: "text-[length:var(--ds-font-size-sm)]", iconSize: 14, py: "py-ds-2.5" },
|
|
5031
5188
|
lg: { gap: "gap-ds-1.5", label: "text-[length:var(--ds-font-size-base)]", value: "text-[length:var(--ds-font-size-base)]", iconSize: 16, py: "py-ds-3" }
|
|
@@ -5071,7 +5228,7 @@ var DescriptionList = forwardRef(function DescriptionList2({
|
|
|
5071
5228
|
stackBelow: stackBelowProp,
|
|
5072
5229
|
className
|
|
5073
5230
|
}, ref) {
|
|
5074
|
-
const s =
|
|
5231
|
+
const s = sizeStyles2[size];
|
|
5075
5232
|
const stackBelow = stackBelowProp ?? (columns > 1 ? "sm" : void 0);
|
|
5076
5233
|
const templateClass = (layout) => columns > 1 && stackBelow !== "none" ? autoColumnClasses[layout][columns] : columnClasses[columns];
|
|
5077
5234
|
if (orientation === "vertical") {
|
|
@@ -5367,17 +5524,31 @@ function clickIsRows(e) {
|
|
|
5367
5524
|
const control = target.closest(ROW_CONTROL);
|
|
5368
5525
|
return !control || control === e.currentTarget || !e.currentTarget.contains(control);
|
|
5369
5526
|
}
|
|
5527
|
+
var ISO_MOMENT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?$/;
|
|
5370
5528
|
function sortableValue(v) {
|
|
5371
5529
|
if (v === null || v === void 0 || v === "") return void 0;
|
|
5372
5530
|
if (v instanceof Date) return v.getTime();
|
|
5531
|
+
if (typeof v === "string" && ISO_MOMENT.test(v)) {
|
|
5532
|
+
const at = Date.parse(v);
|
|
5533
|
+
if (Number.isFinite(at)) return at;
|
|
5534
|
+
}
|
|
5373
5535
|
if (typeof v === "string" || typeof v === "number") return v;
|
|
5374
5536
|
if (typeof v === "boolean") return v ? 1 : 0;
|
|
5375
5537
|
return isValidElement(v) || typeof v === "object" ? null : String(v);
|
|
5376
5538
|
}
|
|
5377
|
-
var
|
|
5539
|
+
var COLLATORS = /* @__PURE__ */ new Map();
|
|
5540
|
+
function collator() {
|
|
5541
|
+
const locale = formatLocale() ?? "";
|
|
5542
|
+
let c = COLLATORS.get(locale);
|
|
5543
|
+
if (!c) {
|
|
5544
|
+
c = new Intl.Collator(locale || void 0, { numeric: true });
|
|
5545
|
+
COLLATORS.set(locale, c);
|
|
5546
|
+
}
|
|
5547
|
+
return c;
|
|
5548
|
+
}
|
|
5378
5549
|
function compareValues(a, b) {
|
|
5379
5550
|
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
5380
|
-
return
|
|
5551
|
+
return collator().compare(String(a), String(b));
|
|
5381
5552
|
}
|
|
5382
5553
|
var UNIT_SCALE = {
|
|
5383
5554
|
"": 1,
|
|
@@ -5782,7 +5953,7 @@ function Table({
|
|
|
5782
5953
|
if (title) return titledCards(/* @__PURE__ */ jsx("div", { className: "py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", children: emptyState }));
|
|
5783
5954
|
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 });
|
|
5784
5955
|
}
|
|
5785
|
-
const cards = /* @__PURE__ */ jsx(TableCardCtx, { value: true, children: /* @__PURE__ */ jsxs("div", { ref: title ? void 0 : listRoot, "data-ds-list": title ? void 0 : "", "data-gs": title ? void 0 : "table", className: cn("flex flex-col gap-ds-3 overflow-y-auto", title ? "min-h-0" : listClass), onFocus: title ? void 0 : noteFocus, onBlur: title ? void 0 : forgetFocus, children: [
|
|
5956
|
+
const cards = /* @__PURE__ */ jsx(TableCardCtx, { value: true, children: /* @__PURE__ */ jsx(RowsCtx, { value: true, children: /* @__PURE__ */ jsxs("div", { ref: title ? void 0 : listRoot, "data-ds-list": title ? void 0 : "", "data-gs": title ? void 0 : "table", className: cn("flex flex-col gap-ds-3 overflow-y-auto", title ? "min-h-0" : listClass), onFocus: title ? void 0 : noteFocus, onBlur: title ? void 0 : forgetFocus, children: [
|
|
5786
5957
|
selectable && /* @__PURE__ */ jsx("span", { hidden: true, id: `${headingId}-select`, children: "Select" }),
|
|
5787
5958
|
drawn.map(({ row, originalIdx }) => {
|
|
5788
5959
|
const isSelected = selectedSet.has(originalIdx);
|
|
@@ -5865,7 +6036,7 @@ function Table({
|
|
|
5865
6036
|
String(id)
|
|
5866
6037
|
);
|
|
5867
6038
|
})
|
|
5868
|
-
] }) });
|
|
6039
|
+
] }) }) });
|
|
5869
6040
|
return withControl(title ? titledCards(cards) : cards);
|
|
5870
6041
|
}
|
|
5871
6042
|
const cellCount = columns.length + lead;
|
|
@@ -5934,7 +6105,7 @@ function Table({
|
|
|
5934
6105
|
);
|
|
5935
6106
|
})
|
|
5936
6107
|
] }) }),
|
|
5937
|
-
/* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
6108
|
+
/* @__PURE__ */ jsx("tbody", { children: /* @__PURE__ */ jsx(RowsCtx, { value: true, children: loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
5938
6109
|
"td",
|
|
5939
6110
|
{
|
|
5940
6111
|
colSpan: cellCount,
|
|
@@ -6063,7 +6234,7 @@ function Table({
|
|
|
6063
6234
|
}
|
|
6064
6235
|
) })
|
|
6065
6236
|
] }, String(id));
|
|
6066
|
-
}) })
|
|
6237
|
+
}) }) })
|
|
6067
6238
|
] });
|
|
6068
6239
|
const region = scrollable || regionFocused ? { tabIndex: 0, role: "region", ...title ? { "aria-labelledby": titleId } : { "aria-label": ariaLabel ?? "Table" } } : {};
|
|
6069
6240
|
return withControl(
|
|
@@ -6095,7 +6266,7 @@ function Table({
|
|
|
6095
6266
|
},
|
|
6096
6267
|
...fade,
|
|
6097
6268
|
...region,
|
|
6098
|
-
className: cn("min-h-0 overflow-x-auto focus-visible:outline-none", title ? "rounded-b-[inherit]" : "rounded-[inherit]"),
|
|
6269
|
+
className: cn("relative min-h-0 overflow-x-auto focus-visible:outline-none", title ? "rounded-b-[inherit]" : "rounded-[inherit]"),
|
|
6099
6270
|
children: table
|
|
6100
6271
|
}
|
|
6101
6272
|
)
|
|
@@ -6334,593 +6505,755 @@ function SegmentedControl({
|
|
|
6334
6505
|
}
|
|
6335
6506
|
);
|
|
6336
6507
|
}
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
if (
|
|
6346
|
-
const
|
|
6347
|
-
return
|
|
6348
|
-
|
|
6349
|
-
|
|
6508
|
+
|
|
6509
|
+
// ../../showcase/src/components/Calendar/event-colours.ts
|
|
6510
|
+
function eventColours(category) {
|
|
6511
|
+
const colour = category?.color;
|
|
6512
|
+
if (colour === void 0 || colour === "accent" || colour === "var(--ds-accent-primary)") return ACCENT;
|
|
6513
|
+
if (colour === "neutral") return NEUTRAL;
|
|
6514
|
+
if (typeof colour === "number") return Number.isInteger(colour) && colour >= 1 ? supporting(colour) : NEUTRAL;
|
|
6515
|
+
const named = SUPPORTING_TOKEN.exec(colour.trim());
|
|
6516
|
+
if (named) return supporting(Number(named[1]));
|
|
6517
|
+
const chart = CHART_TOKEN.exec(colour.trim());
|
|
6518
|
+
if (chart) return Number(chart[1]) === 1 ? ACCENT : supporting(Number(chart[1]) - 1);
|
|
6519
|
+
return { ...NEUTRAL, edge: colour };
|
|
6520
|
+
}
|
|
6521
|
+
var SUPPORTING_TOKEN = /^var\(\s*--ds-palette-(\d+)-[a-z-]+\s*\)$/;
|
|
6522
|
+
var CHART_TOKEN = /^var\(\s*--ds-chart-(\d+)\s*\)$/;
|
|
6523
|
+
var supporting = (n) => ({
|
|
6524
|
+
fill: `var(--ds-palette-${n}-bg, ${NEUTRAL.fill})`,
|
|
6525
|
+
text: `var(--ds-palette-${n}-text, ${NEUTRAL.text})`,
|
|
6526
|
+
edge: `var(--ds-palette-${n}-chart, ${NEUTRAL.edge})`
|
|
6527
|
+
});
|
|
6528
|
+
var ACCENT = {
|
|
6529
|
+
fill: "var(--ds-accent-bg, var(--ds-accent-subtle))",
|
|
6530
|
+
text: "var(--ds-accent-text, var(--ds-text-primary))",
|
|
6531
|
+
edge: "var(--ds-chart-1)"
|
|
6532
|
+
};
|
|
6533
|
+
var NEUTRAL = {
|
|
6534
|
+
fill: "var(--ds-bg-muted)",
|
|
6535
|
+
text: "var(--ds-text-primary)",
|
|
6536
|
+
edge: "var(--ds-input-border)"
|
|
6537
|
+
};
|
|
6538
|
+
function EventBar({ event, category, compact, onOpen, inert, showTime = true, continuesBefore, continuesAfter, className, style }) {
|
|
6539
|
+
const ref = useRef(null);
|
|
6540
|
+
const colours = eventColours(category);
|
|
6541
|
+
const name = eventName(event, category);
|
|
6542
|
+
const look = cn(
|
|
6543
|
+
"border-[length:var(--ds-border-width)] border-solid rounded-[var(--ds-radius-sm)]",
|
|
6544
|
+
continuesBefore && "rounded-s-none border-s-0",
|
|
6545
|
+
continuesAfter && "rounded-e-none border-e-0"
|
|
6546
|
+
);
|
|
6547
|
+
const paint = { backgroundColor: colours.fill, color: colours.text, borderColor: colours.edge, ...style };
|
|
6548
|
+
if (inert) {
|
|
6549
|
+
return /* @__PURE__ */ jsx(
|
|
6550
|
+
"span",
|
|
6350
6551
|
{
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
"bg-[var(--ds-bg-surface-elevated)]",
|
|
6355
|
-
"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
|
|
6356
|
-
"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
6357
|
-
"rounded-[var(--ds-radius-md)]",
|
|
6358
|
-
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
|
|
6359
|
-
"p-ds-3 space-y-ds-2"
|
|
6360
|
-
),
|
|
6361
|
-
style: { top: pos.top, left: pos.left },
|
|
6362
|
-
role: "tooltip",
|
|
6363
|
-
children: [
|
|
6364
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-ds-2", children: [
|
|
6365
|
-
/* @__PURE__ */ jsx("p", { className: "font-[var(--ds-weight-heading)] text-sm text-[var(--ds-text-primary)] leading-snug", children: event.title }),
|
|
6366
|
-
category && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "sm", className: "shrink-0", children: [
|
|
6367
|
-
/* @__PURE__ */ jsx(
|
|
6368
|
-
"span",
|
|
6369
|
-
{
|
|
6370
|
-
className: "inline-block w-1.5 h-1.5 rounded-[var(--ds-radius-full)] mr-ds-1",
|
|
6371
|
-
style: { backgroundColor: color }
|
|
6372
|
-
}
|
|
6373
|
-
),
|
|
6374
|
-
category.label
|
|
6375
|
-
] })
|
|
6376
|
-
] }),
|
|
6377
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-secondary)]", children: event.allDay ? "All day" : formatTimeRange(event.start, event.end) }),
|
|
6378
|
-
event.location && /* @__PURE__ */ jsxs("p", { className: "text-xs text-[var(--ds-text-muted)] flex items-center gap-ds-1", children: [
|
|
6379
|
-
/* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
6380
|
-
/* @__PURE__ */ jsx("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }),
|
|
6381
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "10", r: "3" })
|
|
6382
|
-
] }),
|
|
6383
|
-
event.location
|
|
6384
|
-
] }),
|
|
6385
|
-
event.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-muted)] line-clamp-2", children: event.description })
|
|
6386
|
-
]
|
|
6552
|
+
className: cn("block w-full text-left text-xs leading-tight px-ds-1.5 py-ds-0.5 truncate", look, className),
|
|
6553
|
+
style: paint,
|
|
6554
|
+
children: event.title
|
|
6387
6555
|
}
|
|
6388
|
-
)
|
|
6389
|
-
|
|
6390
|
-
);
|
|
6391
|
-
}
|
|
6392
|
-
function EventBar({ event, category, compact, onClick, className }) {
|
|
6393
|
-
const [hovered, setHovered] = useState(false);
|
|
6394
|
-
const barRef = useRef(null);
|
|
6395
|
-
const hoverTimeout = useRef(void 0);
|
|
6396
|
-
const color = category?.color ?? "var(--ds-accent-primary)";
|
|
6397
|
-
const handleMouseEnter = () => {
|
|
6398
|
-
hoverTimeout.current = setTimeout(() => setHovered(true), 300);
|
|
6399
|
-
};
|
|
6400
|
-
const handleMouseLeave = () => {
|
|
6401
|
-
clearTimeout(hoverTimeout.current);
|
|
6402
|
-
setHovered(false);
|
|
6403
|
-
};
|
|
6556
|
+
);
|
|
6557
|
+
}
|
|
6404
6558
|
if (compact) {
|
|
6405
6559
|
return /* @__PURE__ */ jsx(
|
|
6406
6560
|
"button",
|
|
6407
6561
|
{
|
|
6408
|
-
ref
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
),
|
|
6413
|
-
style: { backgroundColor: color },
|
|
6414
|
-
onMouseEnter: handleMouseEnter,
|
|
6415
|
-
onMouseLeave: handleMouseLeave,
|
|
6562
|
+
ref,
|
|
6563
|
+
type: "button",
|
|
6564
|
+
className: cn("w-1.5 h-1.5 rounded-[var(--ds-radius-full)] shrink-0 cursor-pointer", className),
|
|
6565
|
+
style: { backgroundColor: colours.edge },
|
|
6416
6566
|
onClick: (e) => {
|
|
6417
6567
|
e.stopPropagation();
|
|
6418
|
-
|
|
6568
|
+
onOpen?.(event, e.currentTarget);
|
|
6419
6569
|
},
|
|
6420
|
-
"aria-label":
|
|
6421
|
-
children: /* @__PURE__ */ jsx(
|
|
6422
|
-
EventPopover,
|
|
6423
|
-
{
|
|
6424
|
-
event,
|
|
6425
|
-
category,
|
|
6426
|
-
open: hovered,
|
|
6427
|
-
anchorRef: barRef
|
|
6428
|
-
}
|
|
6429
|
-
)
|
|
6570
|
+
"aria-label": name
|
|
6430
6571
|
}
|
|
6431
6572
|
);
|
|
6432
6573
|
}
|
|
6433
6574
|
return /* @__PURE__ */ jsxs(
|
|
6434
6575
|
"button",
|
|
6435
6576
|
{
|
|
6436
|
-
ref
|
|
6577
|
+
ref,
|
|
6578
|
+
type: "button",
|
|
6579
|
+
"data-calendar-event": event.id,
|
|
6437
6580
|
className: cn(
|
|
6438
|
-
"w-full text-left text-xs leading-tight px-ds-1.5 py-ds-0.5
|
|
6439
|
-
|
|
6581
|
+
"w-full text-left text-xs leading-tight px-ds-1.5 py-ds-0.5",
|
|
6582
|
+
look,
|
|
6583
|
+
"truncate cursor-pointer transition-[filter] hover:brightness-95",
|
|
6440
6584
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
6441
6585
|
className
|
|
6442
6586
|
),
|
|
6443
|
-
style:
|
|
6444
|
-
backgroundColor: `color-mix(in oklch, ${color} 18%, transparent)`,
|
|
6445
|
-
color,
|
|
6446
|
-
borderLeft: `2px solid ${color}`
|
|
6447
|
-
},
|
|
6448
|
-
onMouseEnter: handleMouseEnter,
|
|
6449
|
-
onMouseLeave: handleMouseLeave,
|
|
6587
|
+
style: paint,
|
|
6450
6588
|
onClick: (e) => {
|
|
6451
6589
|
e.stopPropagation();
|
|
6452
|
-
|
|
6590
|
+
onOpen?.(event, e.currentTarget);
|
|
6453
6591
|
},
|
|
6454
|
-
|
|
6592
|
+
"aria-label": name,
|
|
6455
6593
|
children: [
|
|
6456
|
-
!event.allDay && /* @__PURE__ */ jsx("span", { className: "font-medium mr-ds-1
|
|
6457
|
-
event.title
|
|
6458
|
-
/* @__PURE__ */ jsx(
|
|
6459
|
-
EventPopover,
|
|
6460
|
-
{
|
|
6461
|
-
event,
|
|
6462
|
-
category,
|
|
6463
|
-
open: hovered,
|
|
6464
|
-
anchorRef: barRef
|
|
6465
|
-
}
|
|
6466
|
-
)
|
|
6594
|
+
showTime && !event.allDay && /* @__PURE__ */ jsx("span", { className: "font-medium mr-ds-1", children: formatTime(event.start) }),
|
|
6595
|
+
event.title
|
|
6467
6596
|
]
|
|
6468
6597
|
}
|
|
6469
6598
|
);
|
|
6470
6599
|
}
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
const
|
|
6479
|
-
const
|
|
6480
|
-
const
|
|
6481
|
-
const
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6600
|
+
function eventName(event, category) {
|
|
6601
|
+
return [event.title, formatEventWhen(event, true), category?.label].filter(Boolean).join(", ");
|
|
6602
|
+
}
|
|
6603
|
+
var CALENDAR_LAYER = "data-calendar-layer";
|
|
6604
|
+
function EventCard({ event, category, anchor, actions, onClose, fallbackFocus }) {
|
|
6605
|
+
const anchorRef = useMemo(() => ({ current: anchor }), [anchor]);
|
|
6606
|
+
const panelRef = useRef(null);
|
|
6607
|
+
const titleId = useId();
|
|
6608
|
+
const pos = usePosition(anchorRef, panelRef, true, { side: "bottom", align: "start", offset: 4, flip: true });
|
|
6609
|
+
const { isTop, returnFocus } = usePopupFocus(true, { trigger: anchorRef, panel: panelRef, close: onClose, tabExits: "edges" });
|
|
6610
|
+
const colours = eventColours(category);
|
|
6611
|
+
const [attendeeScroll, setAttendeeScroll] = useState(null);
|
|
6612
|
+
useKeyboardScroll(attendeeScroll, "Attendees");
|
|
6613
|
+
const closeRef = useLatest(onClose);
|
|
6614
|
+
useEffect(() => {
|
|
6615
|
+
const raf = requestAnimationFrame(() => {
|
|
6616
|
+
const panel = panelRef.current;
|
|
6617
|
+
if (!panel) return;
|
|
6618
|
+
const actions2 = Array.from(panel.querySelectorAll("[data-card-action]"));
|
|
6619
|
+
const safe = actions2.find((el) => el.getAttribute("data-variant") !== "destructive");
|
|
6620
|
+
if (safe) safe.focus();
|
|
6621
|
+
else if (actions2.length) panel.focus();
|
|
6622
|
+
else focusInitial(panel);
|
|
6623
|
+
});
|
|
6624
|
+
return () => cancelAnimationFrame(raf);
|
|
6625
|
+
}, [anchor]);
|
|
6488
6626
|
useEffect(() => {
|
|
6489
|
-
if (!open) return;
|
|
6490
|
-
const raf = requestAnimationFrame(() => focusInitial(floatingRef.current));
|
|
6491
6627
|
const onKey = (e) => {
|
|
6492
6628
|
if (e.key !== "Escape" || e.defaultPrevented || !isTop()) return;
|
|
6493
6629
|
e.preventDefault();
|
|
6494
6630
|
returnFocus();
|
|
6495
|
-
|
|
6631
|
+
closeRef.current();
|
|
6496
6632
|
};
|
|
6497
6633
|
const onDown = (e) => {
|
|
6498
|
-
if (!
|
|
6634
|
+
if (!isTop()) return;
|
|
6635
|
+
const t = e.target;
|
|
6636
|
+
if (!(t instanceof Node) || panelRef.current?.contains(t) || anchor.contains(t)) return;
|
|
6637
|
+
if (t instanceof Element && t.closest(`[${CALENDAR_LAYER}]`)) return;
|
|
6638
|
+
closeRef.current();
|
|
6499
6639
|
};
|
|
6500
6640
|
document.addEventListener("keydown", onKey);
|
|
6501
|
-
document.addEventListener("
|
|
6641
|
+
document.addEventListener("pointerdown", onDown, true);
|
|
6502
6642
|
return () => {
|
|
6503
|
-
cancelAnimationFrame(raf);
|
|
6504
6643
|
document.removeEventListener("keydown", onKey);
|
|
6505
|
-
document.removeEventListener("
|
|
6644
|
+
document.removeEventListener("pointerdown", onDown, true);
|
|
6506
6645
|
};
|
|
6507
|
-
}, [
|
|
6508
|
-
|
|
6646
|
+
}, [anchor, isTop, returnFocus, closeRef]);
|
|
6647
|
+
const run = (action) => {
|
|
6648
|
+
const list = anchor.closest(`[${CALENDAR_LAYER}]`);
|
|
6649
|
+
returnFocus();
|
|
6650
|
+
onClose();
|
|
6651
|
+
action.onClick(event);
|
|
6652
|
+
requestAnimationFrame(() => {
|
|
6653
|
+
const now = document.activeElement;
|
|
6654
|
+
if (now && now !== document.body && now.isConnected) return;
|
|
6655
|
+
if (list?.isConnected && focusInitial(list)) return;
|
|
6656
|
+
fallbackFocus?.()?.focus();
|
|
6657
|
+
});
|
|
6658
|
+
};
|
|
6659
|
+
return createPortal(
|
|
6509
6660
|
/* @__PURE__ */ jsxs(
|
|
6510
|
-
"
|
|
6661
|
+
"div",
|
|
6511
6662
|
{
|
|
6512
|
-
ref:
|
|
6513
|
-
|
|
6514
|
-
"aria-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6663
|
+
ref: panelRef,
|
|
6664
|
+
role: "dialog",
|
|
6665
|
+
"aria-labelledby": titleId,
|
|
6666
|
+
...{ [CALENDAR_LAYER]: "" },
|
|
6667
|
+
"data-calendar-card": event.id,
|
|
6668
|
+
tabIndex: -1,
|
|
6669
|
+
className: cn(
|
|
6670
|
+
"fixed z-[var(--ds-z-popover)] w-72 max-w-[calc(100vw-2*var(--ds-space-3))] outline-none",
|
|
6671
|
+
"bg-[var(--ds-bg-surface-elevated)]",
|
|
6672
|
+
"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
|
|
6673
|
+
"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
6674
|
+
"rounded-[var(--ds-radius-md)]",
|
|
6675
|
+
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
|
|
6676
|
+
"p-ds-3 space-y-ds-2"
|
|
6677
|
+
),
|
|
6678
|
+
style: { top: pos.top, left: pos.left },
|
|
6520
6679
|
children: [
|
|
6521
|
-
"
|
|
6522
|
-
|
|
6523
|
-
|
|
6680
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-ds-2", children: [
|
|
6681
|
+
/* @__PURE__ */ jsx("h3", { id: titleId, className: "font-[var(--ds-weight-heading)] text-sm text-[var(--ds-text-primary)] leading-snug min-w-0 break-words", children: event.title }),
|
|
6682
|
+
/* @__PURE__ */ jsx(
|
|
6683
|
+
Button,
|
|
6684
|
+
{
|
|
6685
|
+
variant: "ghost",
|
|
6686
|
+
size: "icon-sm",
|
|
6687
|
+
"aria-label": "Close",
|
|
6688
|
+
...{ [OVERLAY_CLOSE_ATTR]: "" },
|
|
6689
|
+
onClick: () => {
|
|
6690
|
+
returnFocus();
|
|
6691
|
+
onClose();
|
|
6692
|
+
},
|
|
6693
|
+
className: "-mt-ds-1 -mr-ds-1 shrink-0",
|
|
6694
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 14 })
|
|
6695
|
+
}
|
|
6696
|
+
)
|
|
6697
|
+
] }),
|
|
6698
|
+
category && /* @__PURE__ */ jsxs("p", { className: "inline-flex items-center gap-ds-1.5 text-xs text-[var(--ds-text-secondary)]", children: [
|
|
6699
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-block w-2 h-2 rounded-[var(--ds-radius-full)]", style: { backgroundColor: colours.edge } }),
|
|
6700
|
+
category.label
|
|
6701
|
+
] }),
|
|
6702
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-[var(--ds-text-secondary)] tabular-nums", children: [
|
|
6703
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: formatEventWhen(event) }),
|
|
6704
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: formatEventWhen(event, true) })
|
|
6705
|
+
] }),
|
|
6706
|
+
event.location && /* @__PURE__ */ jsxs("p", { className: "text-xs text-[var(--ds-text-secondary)] flex items-start gap-ds-1", children: [
|
|
6707
|
+
/* @__PURE__ */ jsx(Icon, { name: "map-pin", size: 14, className: "shrink-0 mt-px" }),
|
|
6708
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 break-words", children: event.location })
|
|
6709
|
+
] }),
|
|
6710
|
+
event.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-secondary)] whitespace-pre-line break-words", children: event.description }),
|
|
6711
|
+
event.attendees && event.attendees.length > 0 && /* @__PURE__ */ jsx("div", { ref: setAttendeeScroll, className: "max-h-32 overflow-y-auto", children: /* @__PURE__ */ jsx("ul", { "aria-label": "Attendees", className: "space-y-ds-1", children: event.attendees.map((person, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-ds-2 text-xs text-[var(--ds-text-primary)]", children: [
|
|
6712
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "shrink-0", children: /* @__PURE__ */ jsx(Avatar, { size: "sm", initials: person.initials ?? person.name }) }),
|
|
6713
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: person.name })
|
|
6714
|
+
] }, `${person.name}-${i}`)) }) }),
|
|
6715
|
+
actions.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-ds-2 pt-ds-1", children: actions.map((action) => /* @__PURE__ */ jsx(Button, { "data-card-action": "", size: "sm", variant: action.variant ?? "secondary", iconLeft: action.iconLeft, onClick: () => run(action), children: action.label }, action.label)) })
|
|
6524
6716
|
]
|
|
6525
6717
|
}
|
|
6526
6718
|
),
|
|
6527
|
-
|
|
6528
|
-
/* @__PURE__ */ jsxs(
|
|
6529
|
-
"div",
|
|
6530
|
-
{
|
|
6531
|
-
ref: floatingRef,
|
|
6532
|
-
role: "dialog",
|
|
6533
|
-
"aria-label": date.toLocaleDateString(void 0, { weekday: "long", month: "long", day: "numeric" }),
|
|
6534
|
-
className: cn(
|
|
6535
|
-
"fixed z-[var(--ds-z-popover)] w-56 max-h-48 overflow-y-auto",
|
|
6536
|
-
"bg-[var(--ds-bg-surface-elevated)]",
|
|
6537
|
-
"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
|
|
6538
|
-
"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
6539
|
-
"rounded-[var(--ds-radius-md)]",
|
|
6540
|
-
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
|
|
6541
|
-
"p-ds-2 space-y-ds-1"
|
|
6542
|
-
),
|
|
6543
|
-
style: { top: pos.top, left: pos.left },
|
|
6544
|
-
onClick: (e) => e.stopPropagation(),
|
|
6545
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
6546
|
-
children: [
|
|
6547
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-[var(--ds-text-muted)] px-ds-1 mb-ds-1", children: date.toLocaleDateString(void 0, { weekday: "short", month: "short", day: "numeric" }) }),
|
|
6548
|
-
events.map((event) => /* @__PURE__ */ jsx(
|
|
6549
|
-
EventBar,
|
|
6550
|
-
{
|
|
6551
|
-
event,
|
|
6552
|
-
category: categories[event.category ?? ""],
|
|
6553
|
-
onClick: onEventClick
|
|
6554
|
-
},
|
|
6555
|
-
event.id
|
|
6556
|
-
))
|
|
6557
|
-
]
|
|
6558
|
-
}
|
|
6559
|
-
),
|
|
6560
|
-
document.body
|
|
6561
|
-
)
|
|
6562
|
-
] });
|
|
6563
|
-
}
|
|
6564
|
-
function MonthView({
|
|
6565
|
-
date,
|
|
6566
|
-
events,
|
|
6567
|
-
categories,
|
|
6568
|
-
selectedDate,
|
|
6569
|
-
onDayClick,
|
|
6570
|
-
onEventClick,
|
|
6571
|
-
weekStartsOn
|
|
6572
|
-
}) {
|
|
6573
|
-
const weeks = useMemo(
|
|
6574
|
-
() => getMonthGrid(date.getFullYear(), date.getMonth(), weekStartsOn),
|
|
6575
|
-
[date, weekStartsOn]
|
|
6719
|
+
document.body
|
|
6576
6720
|
);
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6721
|
+
}
|
|
6722
|
+
function DayList({ day, events, categories, anchor, onOpenEvent, onNewEvent, onClose }) {
|
|
6723
|
+
const anchorRef = useMemo(() => ({ current: anchor }), [anchor]);
|
|
6724
|
+
const panelRef = useRef(null);
|
|
6725
|
+
const pos = usePosition(anchorRef, panelRef, true, { side: "bottom", align: "start", offset: 4, flip: true });
|
|
6726
|
+
const { isTop, returnFocus } = usePopupFocus(true, { trigger: anchorRef, panel: panelRef, close: onClose, tabExits: "edges" });
|
|
6727
|
+
const closeRef = useLatest(onClose);
|
|
6728
|
+
useEffect(() => {
|
|
6729
|
+
const raf = requestAnimationFrame(() => focusInitial(panelRef.current));
|
|
6730
|
+
return () => cancelAnimationFrame(raf);
|
|
6731
|
+
}, [anchor]);
|
|
6732
|
+
useEffect(() => {
|
|
6733
|
+
const onKey = (e) => {
|
|
6734
|
+
if (e.key !== "Escape" || e.defaultPrevented || !isTop()) return;
|
|
6735
|
+
e.preventDefault();
|
|
6736
|
+
returnFocus();
|
|
6737
|
+
closeRef.current();
|
|
6738
|
+
};
|
|
6739
|
+
const onDown = (e) => {
|
|
6740
|
+
if (!isTop()) return;
|
|
6741
|
+
const t = e.target;
|
|
6742
|
+
if (!(t instanceof Node) || panelRef.current?.contains(t) || anchor.contains(t)) return;
|
|
6743
|
+
if (t instanceof Element && t.closest(`[${CALENDAR_LAYER}]`)) return;
|
|
6744
|
+
closeRef.current();
|
|
6745
|
+
};
|
|
6746
|
+
document.addEventListener("keydown", onKey);
|
|
6747
|
+
document.addEventListener("pointerdown", onDown, true);
|
|
6748
|
+
return () => {
|
|
6749
|
+
document.removeEventListener("keydown", onKey);
|
|
6750
|
+
document.removeEventListener("pointerdown", onDown, true);
|
|
6751
|
+
};
|
|
6752
|
+
}, [anchor, isTop, returnFocus, closeRef]);
|
|
6753
|
+
return createPortal(
|
|
6754
|
+
/* @__PURE__ */ jsxs(
|
|
6581
6755
|
"div",
|
|
6582
6756
|
{
|
|
6583
|
-
|
|
6757
|
+
ref: panelRef,
|
|
6758
|
+
role: "dialog",
|
|
6759
|
+
"aria-label": formatDayLong(day),
|
|
6760
|
+
...{ [CALENDAR_LAYER]: "" },
|
|
6761
|
+
className: cn(
|
|
6762
|
+
"fixed z-[var(--ds-z-popover)] w-60 max-h-72 overflow-y-auto",
|
|
6763
|
+
"bg-[var(--ds-bg-surface-elevated)]",
|
|
6764
|
+
"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
|
|
6765
|
+
"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
6766
|
+
"rounded-[var(--ds-radius-md)]",
|
|
6767
|
+
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]",
|
|
6768
|
+
"p-ds-2 space-y-ds-1"
|
|
6769
|
+
),
|
|
6770
|
+
style: { top: pos.top, left: pos.left },
|
|
6771
|
+
onClick: (e) => e.stopPropagation(),
|
|
6584
6772
|
children: [
|
|
6585
|
-
/* @__PURE__ */ jsx("
|
|
6586
|
-
/* @__PURE__ */ jsx("
|
|
6773
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-[var(--ds-text-muted)] px-ds-1 mb-ds-1", children: formatDayShort(day) }),
|
|
6774
|
+
events.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-secondary)] px-ds-1", children: "No events" }),
|
|
6775
|
+
events.map((event) => /* @__PURE__ */ jsx(EventBar, { event, category: categories[event.category ?? ""], onOpen: onOpenEvent }, event.id)),
|
|
6776
|
+
onNewEvent && /* @__PURE__ */ jsx(
|
|
6777
|
+
Button,
|
|
6778
|
+
{
|
|
6779
|
+
variant: "ghost",
|
|
6780
|
+
size: "sm",
|
|
6781
|
+
iconLeft: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 14 }),
|
|
6782
|
+
className: "w-full justify-start mt-ds-1",
|
|
6783
|
+
onClick: () => {
|
|
6784
|
+
returnFocus();
|
|
6785
|
+
onClose();
|
|
6786
|
+
onNewEvent(day);
|
|
6787
|
+
},
|
|
6788
|
+
children: "New event"
|
|
6789
|
+
}
|
|
6790
|
+
)
|
|
6587
6791
|
]
|
|
6588
|
-
}
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6792
|
+
}
|
|
6793
|
+
),
|
|
6794
|
+
document.body
|
|
6795
|
+
);
|
|
6796
|
+
}
|
|
6797
|
+
|
|
6798
|
+
// ../../showcase/src/components/Calendar/styles.ts
|
|
6799
|
+
var TODAY_CIRCLE = "bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] text-[var(--ds-text-on-primary)] font-bold";
|
|
6800
|
+
var LANES = 3;
|
|
6801
|
+
var LANE_H = 20;
|
|
6802
|
+
var LANE_GAP = 4;
|
|
6803
|
+
var NUMBER_ROW = 30;
|
|
6804
|
+
var INSET = "var(--ds-space-1)";
|
|
6805
|
+
function MonthView({ date, events, categories, selectedDate, onDayClick, canStartEvent, onOpenEvent, onNavigate, weekStartsOn }) {
|
|
6806
|
+
const weeks = useMemo(() => getMonthGrid(date.getFullYear(), date.getMonth(), weekStartsOn), [date, weekStartsOn]);
|
|
6807
|
+
const phone = useBreakpoint("sm");
|
|
6808
|
+
const names = { short: weekdayNames(weekStartsOn, "short"), narrow: weekdayNames(weekStartsOn, "narrow"), long: weekdayNames(weekStartsOn, "long") };
|
|
6809
|
+
const layouts = useMemo(() => weeks.map((week) => layoutWeek(events, week, LANES)), [weeks, events]);
|
|
6810
|
+
const currentMonth = date.getMonth();
|
|
6811
|
+
const gridRef = useRef(null);
|
|
6812
|
+
const [list, setList] = useState(null);
|
|
6813
|
+
const inMonth = (d) => !!d && d.getMonth() === currentMonth && d.getFullYear() === date.getFullYear();
|
|
6814
|
+
const fallback = inMonth(selectedDate) ? selectedDate : inMonth(/* @__PURE__ */ new Date()) ? /* @__PURE__ */ new Date() : new Date(date.getFullYear(), currentMonth, 1);
|
|
6815
|
+
const [activeDay, setActiveDay] = useState(fallback);
|
|
6816
|
+
const active = inMonth(activeDay) ? activeDay : fallback;
|
|
6817
|
+
const openList = (day, anchor) => setList({ day, anchor });
|
|
6818
|
+
const choose = (day, anchor) => phone ? openList(day, anchor) : onDayClick(day);
|
|
6819
|
+
const grid = useGridKeyboard({
|
|
6820
|
+
container: gridRef,
|
|
6821
|
+
active,
|
|
6822
|
+
setActive: (d) => {
|
|
6823
|
+
setActiveDay(d);
|
|
6824
|
+
if (!inMonth(d)) onNavigate(d);
|
|
6825
|
+
},
|
|
6826
|
+
keyOf: dayKey,
|
|
6827
|
+
move: (from, e) => moveDay(from, e.key, e.shiftKey, weekStartsOn),
|
|
6828
|
+
onActivate: (day, e) => choose(day, e.currentTarget.querySelector(`[data-grid-key="${dayKey(day)}"]`) ?? e.target)
|
|
6829
|
+
});
|
|
6830
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
6831
|
+
/* @__PURE__ */ jsxs("div", { ref: gridRef, role: "grid", "aria-label": formatMonthYear(date), onKeyDown: grid.onKeyDown, className: "flex flex-col flex-1 min-h-0", children: [
|
|
6832
|
+
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", children: names.short.map((name, i) => /* @__PURE__ */ jsx("div", { role: "columnheader", "aria-label": names.long[i], className: "text-center text-xs font-medium text-[var(--ds-text-muted)] py-ds-2 px-ds-1", children: phone ? names.narrow[i] : name }, i)) }),
|
|
6833
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col flex-1", children: weeks.map((week, wi) => {
|
|
6834
|
+
const layout = layouts[wi];
|
|
6601
6835
|
const lastRow = wi === weeks.length - 1;
|
|
6602
|
-
return /* @__PURE__ */
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
}
|
|
6645
|
-
)
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6836
|
+
return /* @__PURE__ */ jsx("div", { role: "row", className: "relative grid grid-cols-7 flex-1", children: week.map((day, di) => {
|
|
6837
|
+
const dayEvents = getEventsForDay(events, day);
|
|
6838
|
+
const isCurrentMonth = day.getMonth() === currentMonth;
|
|
6839
|
+
const today = isToday(day);
|
|
6840
|
+
const selected = !!selectedDate && isSameDay(day, selectedDate);
|
|
6841
|
+
const weekend = isWeekend(day);
|
|
6842
|
+
const more = layout.more[di];
|
|
6843
|
+
const label = phone && dayEvents.length > 0 ? `${formatDayLong(day)}, ${dayEvents.length} ${dayEvents.length === 1 ? "event" : "events"}` : formatDayLong(day);
|
|
6844
|
+
return /* @__PURE__ */ jsxs(
|
|
6845
|
+
"div",
|
|
6846
|
+
{
|
|
6847
|
+
role: "gridcell",
|
|
6848
|
+
"data-grid-key": dayKey(day),
|
|
6849
|
+
tabIndex: grid.tabIndexOf(day),
|
|
6850
|
+
"aria-label": label,
|
|
6851
|
+
"aria-selected": selected,
|
|
6852
|
+
"aria-current": today ? "date" : void 0,
|
|
6853
|
+
onFocus: () => {
|
|
6854
|
+
if (!isSameDay(day, active)) setActiveDay(day);
|
|
6855
|
+
},
|
|
6856
|
+
onClick: (e) => choose(day, e.currentTarget),
|
|
6857
|
+
className: cn(
|
|
6858
|
+
"relative min-h-[80px] sm:min-h-[100px] border-[var(--ds-border-subtle)]",
|
|
6859
|
+
!lastRow && "border-b-[length:var(--ds-divider-width)]",
|
|
6860
|
+
di < 6 && "border-r-[length:var(--ds-divider-width)]",
|
|
6861
|
+
"p-ds-1 flex flex-col cursor-pointer transition-colors",
|
|
6862
|
+
FOCUS_INSET,
|
|
6863
|
+
"hover:bg-[var(--ds-bg-muted)]",
|
|
6864
|
+
!isCurrentMonth && "[&>.gs-day-number]:opacity-40",
|
|
6865
|
+
selected && "bg-[var(--ds-accent-whisper)]",
|
|
6866
|
+
weekend && isCurrentMonth && !selected && "bg-[var(--ds-bg-muted)]/30"
|
|
6867
|
+
),
|
|
6868
|
+
children: [
|
|
6869
|
+
/* @__PURE__ */ jsx("span", { className: cn("gs-day-number text-xs w-6 h-6 flex items-center justify-center rounded-[var(--ds-radius-full)] shrink-0", today ? TODAY_CIRCLE : "text-[var(--ds-text-secondary)]"), children: day.getDate() }),
|
|
6870
|
+
phone ? (
|
|
6871
|
+
// dots, a day's presence of events: the day itself is what a tap opens (D46)
|
|
6872
|
+
/* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "flex gap-ds-0.5 flex-wrap mt-ds-0.5", children: [
|
|
6873
|
+
dayEvents.slice(0, 4).map((event) => /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-[var(--ds-radius-full)]", style: { backgroundColor: eventColours(categories[event.category ?? ""]).edge } }, event.id)),
|
|
6874
|
+
dayEvents.length > 4 && /* @__PURE__ */ jsxs("span", { className: "text-2xs text-[var(--ds-text-muted)] leading-none", children: [
|
|
6875
|
+
"+",
|
|
6876
|
+
dayEvents.length - 4
|
|
6877
|
+
] })
|
|
6878
|
+
] })
|
|
6879
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6880
|
+
layout.segments.filter((s) => s.startCol === di).map((s) => /* @__PURE__ */ jsx(
|
|
6881
|
+
EventBar,
|
|
6882
|
+
{
|
|
6883
|
+
event: s.event,
|
|
6884
|
+
category: categories[s.event.category ?? ""],
|
|
6885
|
+
onOpen: onOpenEvent,
|
|
6886
|
+
continuesBefore: s.continuesBefore,
|
|
6887
|
+
continuesAfter: s.continuesAfter,
|
|
6888
|
+
className: "absolute z-[1] flex items-center",
|
|
6889
|
+
style: {
|
|
6890
|
+
top: NUMBER_ROW + s.lane * (LANE_H + LANE_GAP),
|
|
6891
|
+
height: LANE_H,
|
|
6892
|
+
left: s.continuesBefore ? 0 : INSET,
|
|
6893
|
+
width: `calc(${s.span} * (100% + var(--ds-divider-width)) - var(--ds-divider-width) - ${s.continuesBefore ? "0px" : INSET} - ${s.continuesAfter ? "0px" : INSET})`
|
|
6894
|
+
}
|
|
6895
|
+
},
|
|
6896
|
+
`${s.event.id}-${s.startCol}`
|
|
6897
|
+
)),
|
|
6898
|
+
more.length > 0 && /* @__PURE__ */ jsxs(
|
|
6899
|
+
"button",
|
|
6900
|
+
{
|
|
6901
|
+
type: "button",
|
|
6902
|
+
"aria-haspopup": "dialog",
|
|
6903
|
+
"aria-expanded": !!list && isSameDay(list.day, day),
|
|
6904
|
+
className: "absolute z-[1] text-2xs text-[var(--ds-accent-text,var(--ds-accent-primary))] font-medium cursor-pointer hover:underline px-ds-1.5 rounded-[var(--ds-radius-sm)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
6905
|
+
style: { top: NUMBER_ROW + (LANES - 1) * (LANE_H + LANE_GAP), left: INSET, height: LANE_H },
|
|
6906
|
+
onClick: (e) => {
|
|
6907
|
+
e.stopPropagation();
|
|
6908
|
+
openList(day, e.currentTarget);
|
|
6909
|
+
},
|
|
6910
|
+
children: [
|
|
6911
|
+
"+",
|
|
6912
|
+
more.length,
|
|
6913
|
+
" more"
|
|
6914
|
+
]
|
|
6915
|
+
}
|
|
6916
|
+
)
|
|
6661
6917
|
] })
|
|
6662
|
-
]
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
);
|
|
6667
|
-
})
|
|
6668
|
-
|
|
6918
|
+
]
|
|
6919
|
+
},
|
|
6920
|
+
dayKey(day)
|
|
6921
|
+
);
|
|
6922
|
+
}) }, dayKey(week[0]));
|
|
6923
|
+
}) })
|
|
6924
|
+
] }),
|
|
6925
|
+
list && /* @__PURE__ */ jsx(
|
|
6926
|
+
DayList,
|
|
6927
|
+
{
|
|
6928
|
+
day: list.day,
|
|
6929
|
+
events: getEventsForDay(events, list.day),
|
|
6930
|
+
categories,
|
|
6931
|
+
anchor: list.anchor,
|
|
6932
|
+
onOpenEvent,
|
|
6933
|
+
onNewEvent: phone && canStartEvent ? onDayClick : void 0,
|
|
6934
|
+
onClose: () => setList(null)
|
|
6935
|
+
}
|
|
6936
|
+
)
|
|
6669
6937
|
] });
|
|
6670
6938
|
}
|
|
6671
6939
|
var HOUR_HEIGHT = 40;
|
|
6672
6940
|
var HOURS = Array.from({ length: 24 }, (_, i) => i);
|
|
6673
6941
|
var GRID_HEIGHT = HOURS.length * HOUR_HEIGHT;
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6942
|
+
var MIN_EVENT_PX = 24;
|
|
6943
|
+
var MIN_EVENT_MINUTES = MIN_EVENT_PX / HOUR_HEIGHT * 60;
|
|
6944
|
+
var ALL_DAY_LANES = 3;
|
|
6945
|
+
var LANE_H2 = 20;
|
|
6946
|
+
var LANE_GAP2 = 4;
|
|
6947
|
+
var WORKING_DAY = 8;
|
|
6948
|
+
var HOUR_LABEL_ROOM = 8;
|
|
6949
|
+
var FADE = 24;
|
|
6950
|
+
var MIN_DAY_WIDTH = 100;
|
|
6951
|
+
var hh = (hour) => String(hour).padStart(2, "0");
|
|
6952
|
+
var cellKey = (day, hour) => hour === null ? dayKey(day) : `${dayKey(day)}T${hh(hour)}`;
|
|
6953
|
+
function parseKey(key) {
|
|
6954
|
+
const [d, h] = key.split("T");
|
|
6955
|
+
const [y, m, dd] = d.split("-").map(Number);
|
|
6956
|
+
return { day: new Date(y, m - 1, dd), hour: h === void 0 ? null : Number(h) };
|
|
6957
|
+
}
|
|
6958
|
+
function NowLine() {
|
|
6959
|
+
const [now, setNow] = useState(() => /* @__PURE__ */ new Date());
|
|
6682
6960
|
useEffect(() => {
|
|
6683
6961
|
const id = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
|
|
6684
6962
|
return () => clearInterval(id);
|
|
6685
6963
|
}, []);
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
function TimedEvent({
|
|
6700
|
-
event,
|
|
6701
|
-
category,
|
|
6702
|
-
column,
|
|
6703
|
-
totalColumns,
|
|
6704
|
-
onEventClick
|
|
6705
|
-
}) {
|
|
6706
|
-
const start = new Date(event.start);
|
|
6707
|
-
const end = event.end ? new Date(event.end) : new Date(start.getTime() + 60 * 6e4);
|
|
6708
|
-
const top = timeToFraction(start) * GRID_HEIGHT;
|
|
6709
|
-
const bottom = timeToFraction(end) * GRID_HEIGHT;
|
|
6710
|
-
const height = Math.max(bottom - top, 20);
|
|
6711
|
-
const color = category?.color ?? "var(--ds-accent-primary)";
|
|
6712
|
-
const width = `calc(${100 / totalColumns}% - 2px)`;
|
|
6713
|
-
const left = `calc(${column / totalColumns * 100}% + 1px)`;
|
|
6964
|
+
return /* @__PURE__ */ jsx("div", { "data-now-line": "", "aria-hidden": "true", className: "absolute left-0 right-0 z-[2] pointer-events-none", style: { top: timeToFraction(now) * GRID_HEIGHT }, children: /* @__PURE__ */ jsx("div", { className: "relative border-t-2 border-[var(--ds-accent-primary)]", children: /* @__PURE__ */ jsx("span", { className: "absolute -left-1 -top-[5px] box-border w-2 h-2 rounded-[var(--ds-radius-full)] border-4 border-[var(--ds-accent-primary)]" }) }) });
|
|
6965
|
+
}
|
|
6966
|
+
function TimedEvent({ placed, category, onOpen, onFocusEvent }) {
|
|
6967
|
+
const { piece, column, columns } = placed;
|
|
6968
|
+
const { event } = piece;
|
|
6969
|
+
const top = timeToFraction(piece.start) * GRID_HEIGHT;
|
|
6970
|
+
const bottom = piece.end.getHours() === 0 && piece.end.getMinutes() === 0 && piece.end > piece.start ? GRID_HEIGHT : timeToFraction(piece.end) * GRID_HEIGHT;
|
|
6971
|
+
const height = Math.max(bottom - top, MIN_EVENT_PX);
|
|
6972
|
+
const drawnTop = Math.min(top, GRID_HEIGHT - height);
|
|
6973
|
+
const colours = eventColours(category);
|
|
6974
|
+
const end = event.end && event.end > event.start ? event.end : void 0;
|
|
6975
|
+
const cutTop = piece.start > event.start;
|
|
6976
|
+
const cutBottom = !!end && piece.end < end;
|
|
6714
6977
|
return /* @__PURE__ */ jsxs(
|
|
6715
|
-
"
|
|
6978
|
+
"button",
|
|
6716
6979
|
{
|
|
6980
|
+
type: "button",
|
|
6981
|
+
"data-calendar-event": event.id,
|
|
6982
|
+
"aria-label": eventName(event, category),
|
|
6717
6983
|
className: cn(
|
|
6718
|
-
|
|
6719
|
-
"
|
|
6720
|
-
"
|
|
6721
|
-
"
|
|
6984
|
+
// a short event keeps its title whole: no padding above and below it
|
|
6985
|
+
"absolute pointer-events-auto text-left px-ds-1.5 text-xs leading-tight",
|
|
6986
|
+
height > 30 ? "py-ds-1" : "py-0 justify-center",
|
|
6987
|
+
"flex flex-col items-start overflow-hidden cursor-pointer transition-[filter] hover:brightness-95",
|
|
6988
|
+
height > 30 && "justify-start",
|
|
6989
|
+
"border-[length:var(--ds-border-width)] border-solid rounded-[var(--ds-radius-sm)]",
|
|
6990
|
+
cutTop && "rounded-t-none border-t-0",
|
|
6991
|
+
cutBottom && "rounded-b-none border-b-0",
|
|
6992
|
+
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)] focus-visible:z-[3]"
|
|
6722
6993
|
),
|
|
6723
6994
|
style: {
|
|
6724
|
-
top,
|
|
6995
|
+
top: drawnTop,
|
|
6725
6996
|
height,
|
|
6726
|
-
left
|
|
6727
|
-
width
|
|
6728
|
-
backgroundColor:
|
|
6729
|
-
color,
|
|
6730
|
-
|
|
6997
|
+
left: `calc(${column / columns * 100}% + 1px)`,
|
|
6998
|
+
width: `calc(${100 / columns}% - 2px)`,
|
|
6999
|
+
backgroundColor: colours.fill,
|
|
7000
|
+
color: colours.text,
|
|
7001
|
+
borderColor: colours.edge
|
|
6731
7002
|
},
|
|
6732
7003
|
onClick: (e) => {
|
|
6733
7004
|
e.stopPropagation();
|
|
6734
|
-
|
|
7005
|
+
onOpen(event, e.currentTarget);
|
|
6735
7006
|
},
|
|
6736
|
-
|
|
6737
|
-
role: "button",
|
|
6738
|
-
tabIndex: 0,
|
|
7007
|
+
onFocus: onFocusEvent,
|
|
6739
7008
|
children: [
|
|
6740
|
-
/* @__PURE__ */ jsx("
|
|
6741
|
-
height > 30 && /* @__PURE__ */
|
|
6742
|
-
formatTime(start),
|
|
6743
|
-
" \u2013 ",
|
|
6744
|
-
formatTime(end)
|
|
6745
|
-
] })
|
|
7009
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium truncate w-full", children: event.title }),
|
|
7010
|
+
height > 30 && /* @__PURE__ */ jsx("span", { className: "text-2xs truncate w-full tabular-nums", children: formatTimeRange(event.start, end) })
|
|
6746
7011
|
]
|
|
6747
7012
|
}
|
|
6748
7013
|
);
|
|
6749
7014
|
}
|
|
6750
|
-
function WeekView({
|
|
6751
|
-
date,
|
|
6752
|
-
events,
|
|
6753
|
-
categories,
|
|
6754
|
-
selectedDate,
|
|
6755
|
-
onDayClick,
|
|
6756
|
-
onEventClick,
|
|
6757
|
-
weekStartsOn
|
|
6758
|
-
}) {
|
|
7015
|
+
function WeekView({ date, events, categories, selectedDate, onDayClick, onOpenEvent, onNavigate, weekStartsOn }) {
|
|
6759
7016
|
const days = useMemo(() => getWeekDays(date, weekStartsOn), [date, weekStartsOn]);
|
|
6760
|
-
const
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
const
|
|
6766
|
-
const
|
|
7017
|
+
const names = weekdayNames(weekStartsOn, "short");
|
|
7018
|
+
const barEvents = useMemo(() => events.filter(isBarEvent), [events]);
|
|
7019
|
+
const allDay = useMemo(() => layoutWeek(barEvents, days, ALL_DAY_LANES), [barEvents, days]);
|
|
7020
|
+
const pieces = useMemo(() => days.map((day) => layoutPieces(dayPieces(events, day), MIN_EVENT_MINUTES)), [days, events]);
|
|
7021
|
+
const allDayHeight = Math.max(28, 4 + allDay.lanes * (LANE_H2 + LANE_GAP2) + 2);
|
|
7022
|
+
const rootRef = useRef(null);
|
|
7023
|
+
const scrollerRef = useRef(null);
|
|
6767
7024
|
const syncingScroll = useRef(false);
|
|
6768
7025
|
const { ref: edgesRef, measure: measureEdges, fadeProps: edgeFade } = useScrollEdges();
|
|
7026
|
+
const [list, setList] = useState(null);
|
|
6769
7027
|
const handleScroll = useCallback((e) => {
|
|
6770
7028
|
if (syncingScroll.current) return;
|
|
6771
7029
|
syncingScroll.current = true;
|
|
6772
7030
|
const source = e.target;
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
panels?.forEach((panel) => {
|
|
6776
|
-
if (panel !== source) panel.scrollLeft = scrollLeft;
|
|
7031
|
+
rootRef.current?.querySelectorAll("[data-week-scroll]").forEach((panel) => {
|
|
7032
|
+
if (panel !== source) panel.scrollLeft = source.scrollLeft;
|
|
6777
7033
|
});
|
|
6778
7034
|
syncingScroll.current = false;
|
|
6779
7035
|
}, []);
|
|
6780
7036
|
useEffect(() => {
|
|
6781
|
-
const
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
7037
|
+
const panels = rootRef.current?.querySelectorAll("[data-week-scroll]");
|
|
7038
|
+
panels?.forEach((panel) => panel.addEventListener("scroll", handleScroll));
|
|
7039
|
+
return () => panels?.forEach((panel) => panel.removeEventListener("scroll", handleScroll));
|
|
7040
|
+
}, [handleScroll]);
|
|
7041
|
+
const starts = pieces.flat().filter((p) => p.piece.start.getTime() === p.piece.event.start.getTime()).map((p) => p.piece.start.getHours() + p.piece.start.getMinutes() / 60);
|
|
7042
|
+
const earliest = Math.floor(Math.min(WORKING_DAY, ...starts));
|
|
7043
|
+
const topOf = (hour) => Math.max(0, hour * HOUR_HEIGHT - HOUR_LABEL_ROOM);
|
|
7044
|
+
const openingHourRef = useLatest(earliest);
|
|
7045
|
+
const opened = useRef(null);
|
|
7046
|
+
const week = dayKey(days[0]);
|
|
7047
|
+
const weekRef = useLatest(week);
|
|
7048
|
+
const [openingHour] = useState(earliest);
|
|
7049
|
+
useLayoutEffect(() => {
|
|
7050
|
+
const scroller = scrollerRef.current;
|
|
7051
|
+
if (!scroller) return;
|
|
7052
|
+
let done = false;
|
|
7053
|
+
const open = () => {
|
|
7054
|
+
if (done || scroller.scrollHeight <= scroller.clientHeight + 1) return;
|
|
7055
|
+
done = true;
|
|
7056
|
+
scroller.scrollTo({ top: topOf(openingHourRef.current) });
|
|
7057
|
+
opened.current = { top: scroller.scrollTop, week: weekRef.current };
|
|
6787
7058
|
};
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
7059
|
+
open();
|
|
7060
|
+
if (done || typeof ResizeObserver === "undefined") return;
|
|
7061
|
+
const ro = new ResizeObserver(() => {
|
|
7062
|
+
open();
|
|
7063
|
+
if (done) ro.disconnect();
|
|
7064
|
+
});
|
|
7065
|
+
ro.observe(scroller);
|
|
7066
|
+
return () => ro.disconnect();
|
|
7067
|
+
}, [openingHour, openingHourRef, weekRef]);
|
|
7068
|
+
useLayoutEffect(() => {
|
|
7069
|
+
const scroller = scrollerRef.current;
|
|
7070
|
+
const o = opened.current;
|
|
7071
|
+
if (!scroller || !o || o.week !== week) return;
|
|
7072
|
+
if (Math.abs(scroller.scrollTop - o.top) > 1) {
|
|
7073
|
+
opened.current = null;
|
|
7074
|
+
return;
|
|
7075
|
+
}
|
|
7076
|
+
if (topOf(earliest) >= o.top) return;
|
|
7077
|
+
scroller.scrollTo({ top: topOf(earliest) });
|
|
7078
|
+
opened.current = { top: scroller.scrollTop, week };
|
|
7079
|
+
}, [earliest, week]);
|
|
7080
|
+
const inWeek = (d) => days.some((day) => isSameDay(day, d));
|
|
7081
|
+
const anchorDay = selectedDate && inWeek(selectedDate) ? selectedDate : days.find(isToday) ?? days[0];
|
|
7082
|
+
const [activeKey, setActiveKey] = useState(() => cellKey(anchorDay, openingHour));
|
|
7083
|
+
const active = inWeek(parseKey(activeKey).day) ? activeKey : cellKey(anchorDay, parseKey(activeKey).hour);
|
|
7084
|
+
const firstVisibleHour = () => Math.min(23, Math.ceil((scrollerRef.current?.scrollTop ?? 0) / HOUR_HEIGHT));
|
|
7085
|
+
const placeInView = (_key, el) => {
|
|
7086
|
+
const scroller = scrollerRef.current;
|
|
7087
|
+
if (scroller && scroller.contains(el) && scroller.scrollHeight > scroller.clientHeight + 1) {
|
|
7088
|
+
const top = el.offsetTop;
|
|
7089
|
+
if (top < scroller.scrollTop) scroller.scrollTop = top;
|
|
7090
|
+
else if (top + el.offsetHeight > scroller.scrollTop + scroller.clientHeight) scroller.scrollTop = top + el.offsetHeight - scroller.clientHeight;
|
|
7091
|
+
} else {
|
|
7092
|
+
el.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
7093
|
+
}
|
|
7094
|
+
const strip = el.closest("[data-week-scroll]");
|
|
7095
|
+
if (strip) {
|
|
7096
|
+
const cell = el.getBoundingClientRect();
|
|
7097
|
+
const box = strip.getBoundingClientRect();
|
|
7098
|
+
if (cell.left - FADE < box.left) strip.scrollLeft -= box.left - (cell.left - FADE);
|
|
7099
|
+
else if (cell.right + FADE > box.right) strip.scrollLeft += cell.right + FADE - box.right;
|
|
7100
|
+
}
|
|
7101
|
+
};
|
|
7102
|
+
const grid = useGridKeyboard({
|
|
7103
|
+
container: rootRef,
|
|
7104
|
+
active,
|
|
7105
|
+
setActive: (key) => {
|
|
7106
|
+
setActiveKey(key);
|
|
7107
|
+
const { day } = parseKey(key);
|
|
7108
|
+
if (!inWeek(day)) onNavigate(day);
|
|
7109
|
+
},
|
|
7110
|
+
keyOf: (key) => key,
|
|
7111
|
+
move: (from, e) => {
|
|
7112
|
+
const { day, hour } = parseKey(from);
|
|
7113
|
+
const col = days.findIndex((d) => isSameDay(d, day));
|
|
7114
|
+
switch (e.key) {
|
|
7115
|
+
case "ArrowUp":
|
|
7116
|
+
return hour === null ? from : hour === 0 ? cellKey(day, null) : cellKey(day, hour - 1);
|
|
7117
|
+
case "ArrowDown":
|
|
7118
|
+
return hour === null ? cellKey(day, firstVisibleHour()) : cellKey(day, Math.min(23, hour + 1));
|
|
7119
|
+
case "ArrowLeft":
|
|
7120
|
+
return col > 0 ? cellKey(days[col - 1], hour) : from;
|
|
7121
|
+
case "ArrowRight":
|
|
7122
|
+
return col >= 0 && col < days.length - 1 ? cellKey(days[col + 1], hour) : from;
|
|
7123
|
+
case "Home":
|
|
7124
|
+
return cellKey(days[0], hour);
|
|
7125
|
+
case "End":
|
|
7126
|
+
return cellKey(days[days.length - 1], hour);
|
|
7127
|
+
case "PageUp":
|
|
7128
|
+
return cellKey(addDays2(day, -7), hour);
|
|
7129
|
+
case "PageDown":
|
|
7130
|
+
return cellKey(addDays2(day, 7), hour);
|
|
7131
|
+
default:
|
|
7132
|
+
return null;
|
|
7133
|
+
}
|
|
7134
|
+
},
|
|
7135
|
+
onActivate: (key) => {
|
|
7136
|
+
const { day, hour } = parseKey(key);
|
|
7137
|
+
onDayClick(day, hour === null ? void 0 : { time: `${hh(hour)}:00` });
|
|
7138
|
+
},
|
|
7139
|
+
scrollIntoView: placeInView
|
|
7140
|
+
});
|
|
7141
|
+
const dayGridColumns = `repeat(${days.length}, minmax(${MIN_DAY_WIDTH}px, 1fr))`;
|
|
7142
|
+
const stripWidth = MIN_DAY_WIDTH * days.length;
|
|
7143
|
+
const chooseHour = (day, hour) => (e) => {
|
|
7144
|
+
const minutes = e.nativeEvent.offsetY >= HOUR_HEIGHT / 2 ? 30 : 0;
|
|
7145
|
+
onDayClick(day, { time: `${hh(hour)}:${minutes === 30 ? "30" : "00"}` });
|
|
7146
|
+
};
|
|
7147
|
+
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: "flex flex-col h-full overflow-hidden", onKeyDown: grid.onKeyDown, children: [
|
|
7148
|
+
/* @__PURE__ */ jsxs("div", { className: "flex border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", children: [
|
|
7149
|
+
/* @__PURE__ */ jsx("div", { className: "w-14 shrink-0 border-r-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]" }),
|
|
7150
|
+
/* @__PURE__ */ jsx("div", { ref: edgesRef, onScroll: measureEdges, ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx("div", { className: "grid", style: { gridTemplateColumns: dayGridColumns, minWidth: stripWidth }, children: days.map((day, i) => /* @__PURE__ */ jsxs("div", { className: cn("text-center py-ds-2", i > 0 && "border-l-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", selectedDate && isSameDay(day, selectedDate) && "bg-[var(--ds-accent-whisper)]"), children: [
|
|
7151
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-[var(--ds-text-muted)] font-medium", children: names[i] }),
|
|
7152
|
+
/* @__PURE__ */ jsx("div", { className: cn("text-lg font-semibold mt-ds-0.5 mx-auto w-8 h-8 flex items-center justify-center rounded-[var(--ds-radius-full)]", isToday(day) ? TODAY_CIRCLE : "text-[var(--ds-text-primary)]"), children: day.getDate() })
|
|
7153
|
+
] }, i)) }) })
|
|
6831
7154
|
] }),
|
|
6832
|
-
|
|
7155
|
+
/* @__PURE__ */ jsxs("div", { className: "flex border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] bg-[var(--ds-bg-muted)]/30", children: [
|
|
6833
7156
|
/* @__PURE__ */ jsx("div", { className: "w-14 shrink-0 border-r-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] text-2xs text-[var(--ds-text-muted)] px-ds-1 py-ds-1 text-right", children: "all-day" }),
|
|
6834
|
-
/* @__PURE__ */ jsx("div", { ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
"
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
)
|
|
6846
|
-
|
|
7157
|
+
/* @__PURE__ */ jsx("div", { ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx("div", { role: "grid", "aria-label": "All day", "aria-readonly": "true", style: { minWidth: stripWidth }, children: /* @__PURE__ */ jsx("div", { role: "row", className: "grid", style: { gridTemplateColumns: dayGridColumns, height: allDayHeight }, children: days.map((day, i) => {
|
|
7158
|
+
const key = cellKey(day, null);
|
|
7159
|
+
const more = allDay.more[i];
|
|
7160
|
+
return /* @__PURE__ */ jsxs(
|
|
7161
|
+
"div",
|
|
7162
|
+
{
|
|
7163
|
+
role: "gridcell",
|
|
7164
|
+
"data-grid-key": key,
|
|
7165
|
+
tabIndex: grid.tabIndexOf(key),
|
|
7166
|
+
"aria-label": `${formatDayLong(day)}, all day`,
|
|
7167
|
+
onFocus: () => {
|
|
7168
|
+
if (active !== key) setActiveKey(key);
|
|
7169
|
+
},
|
|
7170
|
+
onClick: () => onDayClick(day),
|
|
7171
|
+
className: cn("relative cursor-pointer", FOCUS_INSET, i > 0 && "border-l-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]"),
|
|
7172
|
+
children: [
|
|
7173
|
+
allDay.segments.filter((s) => s.startCol === i).map((s) => /* @__PURE__ */ jsx(
|
|
6847
7174
|
EventBar,
|
|
6848
7175
|
{
|
|
6849
|
-
event,
|
|
6850
|
-
category: categories[event.category ?? ""],
|
|
6851
|
-
|
|
7176
|
+
event: s.event,
|
|
7177
|
+
category: categories[s.event.category ?? ""],
|
|
7178
|
+
onOpen: onOpenEvent,
|
|
7179
|
+
continuesBefore: s.continuesBefore,
|
|
7180
|
+
continuesAfter: s.continuesAfter,
|
|
7181
|
+
className: "absolute z-[1] flex items-center",
|
|
7182
|
+
style: {
|
|
7183
|
+
top: 2 + s.lane * (LANE_H2 + LANE_GAP2),
|
|
7184
|
+
height: LANE_H2,
|
|
7185
|
+
left: s.continuesBefore ? 0 : 2,
|
|
7186
|
+
width: `calc(${s.span} * (100% + var(--ds-divider-width)) - var(--ds-divider-width) - ${s.continuesBefore ? 0 : 2}px - ${s.continuesAfter ? 0 : 2}px)`
|
|
7187
|
+
}
|
|
6852
7188
|
},
|
|
6853
|
-
event.id
|
|
6854
|
-
))
|
|
7189
|
+
`${s.event.id}-${s.startCol}`
|
|
7190
|
+
)),
|
|
7191
|
+
more.length > 0 && /* @__PURE__ */ jsxs(
|
|
7192
|
+
"button",
|
|
7193
|
+
{
|
|
7194
|
+
type: "button",
|
|
7195
|
+
"aria-haspopup": "dialog",
|
|
7196
|
+
"aria-expanded": !!list && isSameDay(list.day, day),
|
|
7197
|
+
className: "absolute z-[1] text-2xs text-[var(--ds-accent-text,var(--ds-accent-primary))] font-medium cursor-pointer hover:underline px-ds-1.5 rounded-[var(--ds-radius-sm)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
7198
|
+
style: { top: 2 + (ALL_DAY_LANES - 1) * (LANE_H2 + LANE_GAP2), left: 2, height: LANE_H2 },
|
|
7199
|
+
onClick: (e) => {
|
|
7200
|
+
e.stopPropagation();
|
|
7201
|
+
setList({ day, anchor: e.currentTarget });
|
|
7202
|
+
},
|
|
7203
|
+
children: [
|
|
7204
|
+
"+",
|
|
7205
|
+
more.length,
|
|
7206
|
+
" more"
|
|
7207
|
+
]
|
|
7208
|
+
}
|
|
7209
|
+
)
|
|
7210
|
+
]
|
|
7211
|
+
},
|
|
7212
|
+
i
|
|
7213
|
+
);
|
|
7214
|
+
}) }) }) })
|
|
7215
|
+
] }),
|
|
7216
|
+
/* @__PURE__ */ jsxs("div", { ref: scrollerRef, className: "flex flex-1 min-h-0 overflow-y-auto", "data-week-hours": "", children: [
|
|
7217
|
+
/* @__PURE__ */ jsx("div", { className: "w-14 shrink-0 relative border-r-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", style: { height: GRID_HEIGHT }, "aria-hidden": "true", children: HOURS.map((h) => /* @__PURE__ */ jsx("div", { className: "absolute right-0 pr-ds-2 text-2xs text-[var(--ds-text-muted)] -translate-y-1/2 tabular-nums", style: { top: h * HOUR_HEIGHT }, children: h > 0 && formatHourLabel(h) }, h)) }),
|
|
7218
|
+
/* @__PURE__ */ jsx("div", { ...edgeFade, className: "flex-1 self-start overflow-x-auto overflow-y-hidden gs-scrollbar-none", style: { height: GRID_HEIGHT }, "data-week-scroll": true, children: /* @__PURE__ */ jsxs("div", { className: "relative", style: { height: GRID_HEIGHT, minWidth: stripWidth }, children: [
|
|
7219
|
+
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": formatWeekRange(date, weekStartsOn), "aria-readonly": "true", className: "absolute inset-0", children: HOURS.map((hour) => /* @__PURE__ */ jsx("div", { role: "row", className: "grid", style: { gridTemplateColumns: dayGridColumns, height: HOUR_HEIGHT }, children: days.map((day, i) => {
|
|
7220
|
+
const key = cellKey(day, hour);
|
|
7221
|
+
return /* @__PURE__ */ jsx(
|
|
7222
|
+
"div",
|
|
7223
|
+
{
|
|
7224
|
+
role: "gridcell",
|
|
7225
|
+
"data-grid-key": key,
|
|
7226
|
+
tabIndex: grid.tabIndexOf(key),
|
|
7227
|
+
"aria-label": `${formatDayLong(day)}, ${formatTime(new Date(day.getFullYear(), day.getMonth(), day.getDate(), hour))}`,
|
|
7228
|
+
onFocus: () => {
|
|
7229
|
+
if (active !== key) setActiveKey(key);
|
|
7230
|
+
},
|
|
7231
|
+
onClick: chooseHour(day, hour),
|
|
7232
|
+
className: cn(
|
|
7233
|
+
"cursor-pointer border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] hover:bg-[var(--ds-bg-muted)]/40",
|
|
7234
|
+
FOCUS_INSET,
|
|
7235
|
+
i > 0 && "border-l-[length:var(--ds-divider-width)]"
|
|
7236
|
+
)
|
|
6855
7237
|
},
|
|
6856
7238
|
i
|
|
7239
|
+
);
|
|
7240
|
+
}) }, hour)) }),
|
|
7241
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 grid pointer-events-none", style: { gridTemplateColumns: dayGridColumns }, children: days.map((day, i) => /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
7242
|
+
isToday(day) && /* @__PURE__ */ jsx(NowLine, {}),
|
|
7243
|
+
pieces[i].map((placed) => /* @__PURE__ */ jsx(
|
|
7244
|
+
TimedEvent,
|
|
7245
|
+
{
|
|
7246
|
+
placed,
|
|
7247
|
+
category: categories[placed.piece.event.category ?? ""],
|
|
7248
|
+
onOpen: onOpenEvent,
|
|
7249
|
+
onFocusEvent: () => setActiveKey(cellKey(day, placed.piece.start.getHours()))
|
|
7250
|
+
},
|
|
7251
|
+
`${placed.piece.event.id}-${i}`
|
|
6857
7252
|
))
|
|
6858
|
-
}
|
|
6859
|
-
) })
|
|
7253
|
+
] }, i)) })
|
|
7254
|
+
] }) })
|
|
6860
7255
|
] }),
|
|
6861
|
-
/* @__PURE__ */
|
|
6862
|
-
/* @__PURE__ */ jsx("div", { className: "w-14 shrink-0 relative border-r-[length:var(--ds-divider-width)] border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", style: { height: GRID_HEIGHT }, children: HOURS.map((h) => /* @__PURE__ */ jsx(
|
|
6863
|
-
"div",
|
|
6864
|
-
{
|
|
6865
|
-
className: "absolute right-0 pr-ds-2 text-2xs text-[var(--ds-text-muted)] -translate-y-1/2",
|
|
6866
|
-
style: { top: h * HOUR_HEIGHT },
|
|
6867
|
-
children: h > 0 && formatHour(h)
|
|
6868
|
-
},
|
|
6869
|
-
h
|
|
6870
|
-
)) }),
|
|
6871
|
-
/* @__PURE__ */ jsx("div", { ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
|
|
6872
|
-
"div",
|
|
6873
|
-
{
|
|
6874
|
-
className: "relative",
|
|
6875
|
-
style: { height: GRID_HEIGHT, minWidth: MIN_DAY_WIDTH * days.length },
|
|
6876
|
-
children: /* @__PURE__ */ jsx(
|
|
6877
|
-
"div",
|
|
6878
|
-
{
|
|
6879
|
-
className: "grid h-full",
|
|
6880
|
-
style: { gridTemplateColumns: dayGridColumns },
|
|
6881
|
-
children: days.map((day, i) => {
|
|
6882
|
-
const dayEvents = getEventsForDay(events, day).filter((e) => !e.allDay);
|
|
6883
|
-
const layout = getOverlappingGroups(dayEvents);
|
|
6884
|
-
const today = isToday(day);
|
|
6885
|
-
return /* @__PURE__ */ jsxs(
|
|
6886
|
-
"div",
|
|
6887
|
-
{
|
|
6888
|
-
className: cn(
|
|
6889
|
-
"relative",
|
|
6890
|
-
i > 0 && "border-l-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]"
|
|
6891
|
-
),
|
|
6892
|
-
onClick: () => onDayClick?.(day),
|
|
6893
|
-
children: [
|
|
6894
|
-
HOURS.map((h) => /* @__PURE__ */ jsx(
|
|
6895
|
-
"div",
|
|
6896
|
-
{
|
|
6897
|
-
className: "absolute left-0 right-0 border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]",
|
|
6898
|
-
style: { top: h * HOUR_HEIGHT }
|
|
6899
|
-
},
|
|
6900
|
-
h
|
|
6901
|
-
)),
|
|
6902
|
-
today && /* @__PURE__ */ jsx(CurrentTimeLine, {}),
|
|
6903
|
-
layout.map(({ event, column, totalColumns }) => /* @__PURE__ */ jsx(
|
|
6904
|
-
TimedEvent,
|
|
6905
|
-
{
|
|
6906
|
-
event,
|
|
6907
|
-
category: categories[event.category ?? ""],
|
|
6908
|
-
column,
|
|
6909
|
-
totalColumns,
|
|
6910
|
-
onEventClick
|
|
6911
|
-
},
|
|
6912
|
-
event.id
|
|
6913
|
-
))
|
|
6914
|
-
]
|
|
6915
|
-
},
|
|
6916
|
-
i
|
|
6917
|
-
);
|
|
6918
|
-
})
|
|
6919
|
-
}
|
|
6920
|
-
)
|
|
6921
|
-
}
|
|
6922
|
-
) })
|
|
6923
|
-
] })
|
|
7256
|
+
list && /* @__PURE__ */ jsx(DayList, { day: list.day, events: getEventsForDay(barEvents, list.day), categories, anchor: list.anchor, onOpenEvent, onClose: () => setList(null) })
|
|
6924
7257
|
] });
|
|
6925
7258
|
}
|
|
6926
7259
|
var WEEKS_SHOWN = 6;
|
|
@@ -6931,7 +7264,6 @@ function DayCellWithPopover({
|
|
|
6931
7264
|
events,
|
|
6932
7265
|
categories,
|
|
6933
7266
|
selectedDate,
|
|
6934
|
-
onEventClick,
|
|
6935
7267
|
isEvenRow
|
|
6936
7268
|
}) {
|
|
6937
7269
|
const [open, setOpen] = useState(false);
|
|
@@ -6947,7 +7279,7 @@ function DayCellWithPopover({
|
|
|
6947
7279
|
const inMonth = day.getMonth() === month;
|
|
6948
7280
|
const dayEvents = inMonth ? getEventsForDay(events, day) : [];
|
|
6949
7281
|
const today = inMonth && isToday(day);
|
|
6950
|
-
const selected = inMonth && selectedDate &&
|
|
7282
|
+
const selected = inMonth && selectedDate && isSameDay(day, selectedDate);
|
|
6951
7283
|
const hasEvents = dayEvents.length > 0;
|
|
6952
7284
|
const handleMouseEnter = () => {
|
|
6953
7285
|
if (!hasEvents) return;
|
|
@@ -6969,7 +7301,6 @@ function DayCellWithPopover({
|
|
|
6969
7301
|
inMonth && "cursor-pointer hover:bg-[var(--ds-bg-muted)]",
|
|
6970
7302
|
!inMonth && "bg-[var(--ds-bg-muted)]/40",
|
|
6971
7303
|
inMonth && isEvenRow && !today && !selected && "bg-[var(--ds-bg-muted)]/20",
|
|
6972
|
-
today && "bg-[var(--ds-accent-subtle)]",
|
|
6973
7304
|
selected && !today && "bg-[var(--ds-accent-whisper)]"
|
|
6974
7305
|
),
|
|
6975
7306
|
children: [
|
|
@@ -6979,7 +7310,7 @@ function DayCellWithPopover({
|
|
|
6979
7310
|
{
|
|
6980
7311
|
className: cn(
|
|
6981
7312
|
"text-2xs leading-none z-[1]",
|
|
6982
|
-
today ? "
|
|
7313
|
+
today ? cn("w-5 h-5 inline-flex items-center justify-center rounded-[var(--ds-radius-full)]", TODAY_CIRCLE) : "text-[var(--ds-text-secondary)]"
|
|
6983
7314
|
),
|
|
6984
7315
|
children: day.getDate()
|
|
6985
7316
|
}
|
|
@@ -7003,16 +7334,8 @@ function DayCellWithPopover({
|
|
|
7003
7334
|
style: { top: pos.top, left: pos.left },
|
|
7004
7335
|
role: "tooltip",
|
|
7005
7336
|
children: [
|
|
7006
|
-
/* @__PURE__ */ jsx("p", { className: "text-2xs font-medium text-[var(--ds-text-muted)] px-ds-1 mb-ds-0.5", children:
|
|
7007
|
-
dayEvents.map((event) => /* @__PURE__ */ jsx(
|
|
7008
|
-
EventBar,
|
|
7009
|
-
{
|
|
7010
|
-
event,
|
|
7011
|
-
category: categories[event.category ?? ""],
|
|
7012
|
-
onClick: onEventClick
|
|
7013
|
-
},
|
|
7014
|
-
event.id
|
|
7015
|
-
))
|
|
7337
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xs font-medium text-[var(--ds-text-muted)] px-ds-1 mb-ds-0.5", children: formatDayShort(day) }),
|
|
7338
|
+
dayEvents.map((event) => /* @__PURE__ */ jsx(EventBar, { event, category: categories[event.category ?? ""], inert: true }, event.id))
|
|
7016
7339
|
]
|
|
7017
7340
|
}
|
|
7018
7341
|
),
|
|
@@ -7029,7 +7352,6 @@ function MonthRow({
|
|
|
7029
7352
|
categories,
|
|
7030
7353
|
selectedDate,
|
|
7031
7354
|
onClick,
|
|
7032
|
-
onEventClick,
|
|
7033
7355
|
weekStartsOn
|
|
7034
7356
|
}) {
|
|
7035
7357
|
const grid = useMemo(
|
|
@@ -7047,7 +7369,7 @@ function MonthRow({
|
|
|
7047
7369
|
"border-r-[length:var(--ds-divider-width)] border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]"
|
|
7048
7370
|
),
|
|
7049
7371
|
onClick,
|
|
7050
|
-
children:
|
|
7372
|
+
children: monthName(month, "short")
|
|
7051
7373
|
}
|
|
7052
7374
|
),
|
|
7053
7375
|
flat.map((day, i) => /* @__PURE__ */ jsx(
|
|
@@ -7058,7 +7380,6 @@ function MonthRow({
|
|
|
7058
7380
|
events,
|
|
7059
7381
|
categories,
|
|
7060
7382
|
selectedDate,
|
|
7061
|
-
onEventClick,
|
|
7062
7383
|
isEvenRow: month % 2 === 0
|
|
7063
7384
|
},
|
|
7064
7385
|
i
|
|
@@ -7071,11 +7392,10 @@ function YearView({
|
|
|
7071
7392
|
categories,
|
|
7072
7393
|
selectedDate,
|
|
7073
7394
|
onMonthClick,
|
|
7074
|
-
onEventClick,
|
|
7075
7395
|
weekStartsOn
|
|
7076
7396
|
}) {
|
|
7077
7397
|
const year = date.getFullYear();
|
|
7078
|
-
const dayNames =
|
|
7398
|
+
const dayNames = weekdayNames(weekStartsOn, "narrow");
|
|
7079
7399
|
const repeatedHeaders = useMemo(() => {
|
|
7080
7400
|
const headers = [];
|
|
7081
7401
|
for (let w = 0; w < WEEKS_SHOWN; w++) {
|
|
@@ -7090,7 +7410,7 @@ function YearView({
|
|
|
7090
7410
|
{
|
|
7091
7411
|
className: "grid min-w-[700px]",
|
|
7092
7412
|
style: {
|
|
7093
|
-
gridTemplateColumns: `48px repeat(${COLS}, minmax(
|
|
7413
|
+
gridTemplateColumns: `48px repeat(${COLS}, minmax(24px, 1fr))`,
|
|
7094
7414
|
gridTemplateRows: `auto repeat(12, 36px)`
|
|
7095
7415
|
},
|
|
7096
7416
|
children: [
|
|
@@ -7103,7 +7423,7 @@ function YearView({
|
|
|
7103
7423
|
"bg-[var(--ds-bg-muted)] border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]",
|
|
7104
7424
|
h.isWeekStart && "border-l-[length:var(--ds-divider-width)]"
|
|
7105
7425
|
),
|
|
7106
|
-
children: h.label
|
|
7426
|
+
children: h.label
|
|
7107
7427
|
},
|
|
7108
7428
|
i
|
|
7109
7429
|
)),
|
|
@@ -7116,7 +7436,6 @@ function YearView({
|
|
|
7116
7436
|
categories,
|
|
7117
7437
|
selectedDate,
|
|
7118
7438
|
onClick: () => onMonthClick(month),
|
|
7119
|
-
onEventClick,
|
|
7120
7439
|
weekStartsOn
|
|
7121
7440
|
},
|
|
7122
7441
|
month
|
|
@@ -7125,191 +7444,83 @@ function YearView({
|
|
|
7125
7444
|
}
|
|
7126
7445
|
) });
|
|
7127
7446
|
}
|
|
7128
|
-
function
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
const
|
|
7138
|
-
const
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7447
|
+
function CompactMonthView({ date, events, categories, selectedDate, onDayClick, onOpenEvent, onNavigate, weekStartsOn }) {
|
|
7448
|
+
const weeks = useMemo(() => getMonthGrid(date.getFullYear(), date.getMonth(), weekStartsOn), [date, weekStartsOn]);
|
|
7449
|
+
const names = { narrow: weekdayNames(weekStartsOn, "narrow"), long: weekdayNames(weekStartsOn, "long") };
|
|
7450
|
+
const currentMonth = date.getMonth();
|
|
7451
|
+
const gridRef = useRef(null);
|
|
7452
|
+
const [list, setList] = useState(null);
|
|
7453
|
+
const inMonth = (d) => !!d && d.getMonth() === currentMonth && d.getFullYear() === date.getFullYear();
|
|
7454
|
+
const fallback = inMonth(selectedDate) ? selectedDate : inMonth(/* @__PURE__ */ new Date()) ? /* @__PURE__ */ new Date() : new Date(date.getFullYear(), currentMonth, 1);
|
|
7455
|
+
const [activeDay, setActiveDay] = useState(fallback);
|
|
7456
|
+
const active = inMonth(activeDay) ? activeDay : fallback;
|
|
7457
|
+
const grid = useGridKeyboard({
|
|
7458
|
+
container: gridRef,
|
|
7459
|
+
active,
|
|
7460
|
+
setActive: (d) => {
|
|
7461
|
+
setActiveDay(d);
|
|
7462
|
+
if (!inMonth(d)) onNavigate(d);
|
|
7463
|
+
},
|
|
7464
|
+
keyOf: dayKey,
|
|
7465
|
+
move: (from, e) => moveDay(from, e.key, e.shiftKey, weekStartsOn)
|
|
7145
7466
|
});
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
setOpen((prev) => !prev);
|
|
7167
|
-
}
|
|
7168
|
-
};
|
|
7169
|
-
useEffect(() => {
|
|
7170
|
-
if (!open) return;
|
|
7171
|
-
const onKey = (e) => {
|
|
7172
|
-
if (e.key !== "Escape" || e.defaultPrevented || !isTop()) return;
|
|
7173
|
-
e.preventDefault();
|
|
7174
|
-
setOpen(false);
|
|
7175
|
-
};
|
|
7176
|
-
const onClick = (e) => {
|
|
7177
|
-
const t = e.target;
|
|
7178
|
-
if (cellRef.current?.contains(t) || floatingRef.current?.contains(t)) return;
|
|
7179
|
-
setOpen(false);
|
|
7180
|
-
};
|
|
7181
|
-
document.addEventListener("keydown", onKey);
|
|
7182
|
-
document.addEventListener("mousedown", onClick);
|
|
7183
|
-
return () => {
|
|
7184
|
-
document.removeEventListener("keydown", onKey);
|
|
7185
|
-
document.removeEventListener("mousedown", onClick);
|
|
7186
|
-
};
|
|
7187
|
-
}, [open, isTop]);
|
|
7188
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7189
|
-
/* @__PURE__ */ jsxs(
|
|
7190
|
-
"button",
|
|
7191
|
-
{
|
|
7192
|
-
ref: cellRef,
|
|
7193
|
-
type: "button",
|
|
7194
|
-
onClick: handleClick,
|
|
7195
|
-
onMouseEnter: handleMouseEnter,
|
|
7196
|
-
onMouseLeave: handleMouseLeave,
|
|
7197
|
-
className: cn(
|
|
7198
|
-
"flex flex-col items-center justify-center py-ds-1.5 rounded-[var(--ds-radius-sm)] cursor-pointer transition-colors",
|
|
7199
|
-
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
7200
|
-
!isCurrentMonth && "opacity-30",
|
|
7201
|
-
selected && "bg-[var(--ds-accent-subtle)]",
|
|
7202
|
-
!selected && "hover:bg-[var(--ds-bg-muted)]"
|
|
7203
|
-
),
|
|
7204
|
-
children: [
|
|
7205
|
-
/* @__PURE__ */ jsx(
|
|
7206
|
-
"span",
|
|
7207
|
-
{
|
|
7208
|
-
className: cn(
|
|
7209
|
-
"text-sm w-7 h-7 flex items-center justify-center rounded-[var(--ds-radius-full)]",
|
|
7210
|
-
today ? "bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] text-[var(--ds-text-on-primary)] font-bold" : "text-[var(--ds-text-primary)]"
|
|
7211
|
-
),
|
|
7212
|
-
children: day.getDate()
|
|
7213
|
-
}
|
|
7214
|
-
),
|
|
7215
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-ds-0.5 mt-ds-0.5 h-[6px] items-center", children: eventColors.map((color, i) => /* @__PURE__ */ jsx(
|
|
7216
|
-
"span",
|
|
7217
|
-
{
|
|
7218
|
-
className: "w-1.5 h-1.5 rounded-[var(--ds-radius-full)]",
|
|
7219
|
-
style: { backgroundColor: color }
|
|
7467
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "var(--ds-space-3) var(--ds-space-2.5)" }, children: [
|
|
7468
|
+
/* @__PURE__ */ jsxs("div", { ref: gridRef, role: "grid", "aria-label": formatMonthYear(date), onKeyDown: grid.onKeyDown, className: "flex flex-col gap-y-ds-0.5", children: [
|
|
7469
|
+
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 mb-ds-1", children: names.narrow.map((name, i) => /* @__PURE__ */ jsx("div", { role: "columnheader", "aria-label": names.long[i], className: "text-center text-xs font-medium text-[var(--ds-text-muted)] py-ds-1.5", children: name }, i)) }),
|
|
7470
|
+
weeks.map((week) => /* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7", children: week.map((day) => {
|
|
7471
|
+
const isCurrentMonth = day.getMonth() === currentMonth;
|
|
7472
|
+
const dayEvents = isCurrentMonth ? getEventsForDay(events, day) : [];
|
|
7473
|
+
const today = isCurrentMonth && isToday(day);
|
|
7474
|
+
const selected = isCurrentMonth && !!selectedDate && isSameDay(day, selectedDate);
|
|
7475
|
+
return /* @__PURE__ */ jsxs(
|
|
7476
|
+
"button",
|
|
7477
|
+
{
|
|
7478
|
+
type: "button",
|
|
7479
|
+
role: "gridcell",
|
|
7480
|
+
"data-grid-key": dayKey(day),
|
|
7481
|
+
tabIndex: grid.tabIndexOf(day),
|
|
7482
|
+
"aria-label": dayEvents.length ? `${formatDayLong(day)}, ${dayEvents.length} ${dayEvents.length === 1 ? "event" : "events"}` : formatDayLong(day),
|
|
7483
|
+
"aria-selected": selected,
|
|
7484
|
+
"aria-current": today ? "date" : void 0,
|
|
7485
|
+
onFocus: () => {
|
|
7486
|
+
if (!isSameDay(day, active)) setActiveDay(day);
|
|
7220
7487
|
},
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
role: "tooltip",
|
|
7244
|
-
children: [
|
|
7245
|
-
/* @__PURE__ */ jsx("p", { className: "text-2xs font-medium text-[var(--ds-text-muted)] px-ds-1 mb-ds-0.5", children: day.toLocaleDateString(void 0, { weekday: "short", month: "short", day: "numeric" }) }),
|
|
7246
|
-
dayEvents.map((event) => /* @__PURE__ */ jsx(
|
|
7247
|
-
EventBar,
|
|
7248
|
-
{
|
|
7249
|
-
event,
|
|
7250
|
-
category: categories[event.category ?? ""],
|
|
7251
|
-
onClick: onEventClick
|
|
7252
|
-
},
|
|
7253
|
-
event.id
|
|
7254
|
-
))
|
|
7255
|
-
]
|
|
7256
|
-
}
|
|
7257
|
-
),
|
|
7258
|
-
document.body
|
|
7259
|
-
)
|
|
7260
|
-
] });
|
|
7261
|
-
}
|
|
7262
|
-
function CompactMonthView({
|
|
7263
|
-
date,
|
|
7264
|
-
events,
|
|
7265
|
-
categories,
|
|
7266
|
-
selectedDate,
|
|
7267
|
-
onDayClick,
|
|
7268
|
-
onEventClick,
|
|
7269
|
-
weekStartsOn
|
|
7270
|
-
}) {
|
|
7271
|
-
const weeks = useMemo(
|
|
7272
|
-
() => getMonthGrid(date.getFullYear(), date.getMonth(), weekStartsOn),
|
|
7273
|
-
[date, weekStartsOn]
|
|
7274
|
-
);
|
|
7275
|
-
const dayNames = useMemo(() => getOrderedDayNames(weekStartsOn), [weekStartsOn]);
|
|
7276
|
-
const currentMonth = date.getMonth();
|
|
7277
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", style: { padding: "var(--ds-space-3) var(--ds-space-2.5)" }, children: [
|
|
7278
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 mb-ds-1.5", children: dayNames.map((name) => /* @__PURE__ */ jsx(
|
|
7279
|
-
"div",
|
|
7280
|
-
{
|
|
7281
|
-
className: "text-center text-xs font-medium text-[var(--ds-text-muted)] py-ds-1.5",
|
|
7282
|
-
children: name[0]
|
|
7283
|
-
},
|
|
7284
|
-
name
|
|
7285
|
-
)) }),
|
|
7286
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-y-ds-0.5", children: weeks.map(
|
|
7287
|
-
(week, wi) => week.map((day, di) => /* @__PURE__ */ jsx(
|
|
7288
|
-
CompactDayCell,
|
|
7289
|
-
{
|
|
7290
|
-
day,
|
|
7291
|
-
isCurrentMonth: day.getMonth() === currentMonth,
|
|
7292
|
-
events,
|
|
7293
|
-
categories,
|
|
7294
|
-
selectedDate,
|
|
7295
|
-
onDayClick,
|
|
7296
|
-
onEventClick
|
|
7297
|
-
},
|
|
7298
|
-
`${wi}-${di}`
|
|
7299
|
-
))
|
|
7300
|
-
) })
|
|
7488
|
+
onClick: (e) => {
|
|
7489
|
+
onDayClick(day);
|
|
7490
|
+
const anchor = e.currentTarget;
|
|
7491
|
+
if (dayEvents.length) setList((cur) => cur && isSameDay(cur.day, day) ? null : { day, anchor });
|
|
7492
|
+
},
|
|
7493
|
+
className: cn(
|
|
7494
|
+
"flex flex-col items-center justify-center py-ds-1.5 rounded-[var(--ds-radius-sm)] cursor-pointer transition-colors",
|
|
7495
|
+
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
7496
|
+
!isCurrentMonth && "opacity-30",
|
|
7497
|
+
selected && "bg-[var(--ds-accent-subtle)]",
|
|
7498
|
+
!selected && "hover:bg-[var(--ds-bg-muted)]"
|
|
7499
|
+
),
|
|
7500
|
+
children: [
|
|
7501
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-sm w-7 h-7 flex items-center justify-center rounded-[var(--ds-radius-full)]", today ? TODAY_CIRCLE : "text-[var(--ds-text-primary)]"), children: day.getDate() }),
|
|
7502
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "flex gap-ds-0.5 mt-ds-0.5 h-[6px] items-center", children: dayEvents.slice(0, 3).map((event) => /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-[var(--ds-radius-full)]", style: { backgroundColor: eventColours(categories[event.category ?? ""]).edge } }, event.id)) })
|
|
7503
|
+
]
|
|
7504
|
+
},
|
|
7505
|
+
dayKey(day)
|
|
7506
|
+
);
|
|
7507
|
+
}) }, dayKey(week[0])))
|
|
7508
|
+
] }),
|
|
7509
|
+
list && /* @__PURE__ */ jsx(DayList, { day: list.day, events: getEventsForDay(events, list.day), categories, anchor: list.anchor, onOpenEvent, onClose: () => setList(null) })
|
|
7301
7510
|
] });
|
|
7302
7511
|
}
|
|
7303
7512
|
|
|
7304
7513
|
// ../../showcase/src/components/Calendar/types.ts
|
|
7305
7514
|
var DEFAULT_CATEGORIES = {
|
|
7306
|
-
work: { color: "
|
|
7307
|
-
personal: { color:
|
|
7308
|
-
meeting: { color:
|
|
7309
|
-
deadline: { color:
|
|
7310
|
-
travel: { color:
|
|
7311
|
-
social: { color:
|
|
7515
|
+
work: { color: "accent", label: "Work" },
|
|
7516
|
+
personal: { color: 1, label: "Personal" },
|
|
7517
|
+
meeting: { color: 2, label: "Meeting" },
|
|
7518
|
+
deadline: { color: 3, label: "Deadline" },
|
|
7519
|
+
travel: { color: 4, label: "Travel" },
|
|
7520
|
+
social: { color: 5, label: "Social" }
|
|
7312
7521
|
};
|
|
7522
|
+
var notADate = (d) => d !== void 0 && Number.isNaN(new Date(d).getTime());
|
|
7523
|
+
var WEEK_FLOOR = 160 + 4 * HOUR_HEIGHT;
|
|
7313
7524
|
function useControllableState(controlled, defaultValue, onChange) {
|
|
7314
7525
|
const [internal, setInternal] = useState(defaultValue);
|
|
7315
7526
|
const value = controlled !== void 0 ? controlled : internal;
|
|
@@ -7389,9 +7600,7 @@ function MonthDropdown({
|
|
|
7389
7600
|
"pl-ds-3 pr-ds-2 py-ds-1"
|
|
7390
7601
|
),
|
|
7391
7602
|
children: [
|
|
7392
|
-
|
|
7393
|
-
" ",
|
|
7394
|
-
currentYear,
|
|
7603
|
+
formatMonthYear(currentDate),
|
|
7395
7604
|
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: 12, className: cn("transition-transform", open && "rotate-180") })
|
|
7396
7605
|
]
|
|
7397
7606
|
}
|
|
@@ -7433,7 +7642,7 @@ function MonthDropdown({
|
|
|
7433
7642
|
}
|
|
7434
7643
|
)
|
|
7435
7644
|
] }),
|
|
7436
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-ds-1", children:
|
|
7645
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-ds-1", children: Array.from({ length: 12 }, (_, i) => monthName(i, "short")).map((name, i) => {
|
|
7437
7646
|
const isActive2 = i === currentMonth && browseYear === currentYear;
|
|
7438
7647
|
return /* @__PURE__ */ jsx(
|
|
7439
7648
|
"button",
|
|
@@ -7451,7 +7660,7 @@ function MonthDropdown({
|
|
|
7451
7660
|
},
|
|
7452
7661
|
children: name
|
|
7453
7662
|
},
|
|
7454
|
-
|
|
7663
|
+
i
|
|
7455
7664
|
);
|
|
7456
7665
|
}) })
|
|
7457
7666
|
]
|
|
@@ -7604,6 +7813,7 @@ function Calendar({
|
|
|
7604
7813
|
onDateRangeChange,
|
|
7605
7814
|
onEventClick,
|
|
7606
7815
|
onDayClick,
|
|
7816
|
+
eventActions,
|
|
7607
7817
|
categories = DEFAULT_CATEGORIES,
|
|
7608
7818
|
weekStartsOn = 1,
|
|
7609
7819
|
size = "default",
|
|
@@ -7614,14 +7824,21 @@ function Calendar({
|
|
|
7614
7824
|
defaultView,
|
|
7615
7825
|
onViewChange
|
|
7616
7826
|
);
|
|
7827
|
+
const today = useMemo(() => /* @__PURE__ */ new Date(), []);
|
|
7617
7828
|
const [currentDate, setCurrentDate] = useControllableState(
|
|
7618
|
-
controlledDate,
|
|
7619
|
-
defaultDate
|
|
7829
|
+
notADate(controlledDate) ? today : controlledDate,
|
|
7830
|
+
defaultDate !== void 0 && !notADate(defaultDate) ? defaultDate : today,
|
|
7620
7831
|
onDateChange
|
|
7621
7832
|
);
|
|
7833
|
+
const dateUnreadable = notADate(controlledDate) || notADate(defaultDate);
|
|
7834
|
+
useEffect(() => {
|
|
7835
|
+
if (dateUnreadable) warnOnce("Calendar", "its date (or defaultDate) isn't a date, so it shows today: pass a Date, or a date string Date reads.");
|
|
7836
|
+
}, [dateUnreadable]);
|
|
7622
7837
|
const [selectedDate, setSelectedDate] = useState(null);
|
|
7623
7838
|
const [isNarrow, setIsNarrow] = useState(false);
|
|
7839
|
+
const rootRef = useRef(null);
|
|
7624
7840
|
const containerRef = useCallback((node) => {
|
|
7841
|
+
rootRef.current = node;
|
|
7625
7842
|
if (!node) return;
|
|
7626
7843
|
const ro = new ResizeObserver((entries) => {
|
|
7627
7844
|
const width = entries[0]?.contentRect.width ?? 0;
|
|
@@ -7630,10 +7847,44 @@ function Calendar({
|
|
|
7630
7847
|
ro.observe(node);
|
|
7631
7848
|
return () => ro.disconnect();
|
|
7632
7849
|
}, []);
|
|
7633
|
-
const
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
);
|
|
7850
|
+
const fillRaw = useFillHeight(rootRef, size !== "compact" && currentView === "week");
|
|
7851
|
+
const fill2 = fillRaw !== null && fillRaw >= WEEK_FLOOR ? fillRaw : null;
|
|
7852
|
+
const inPane = useContext(FillContext) && currentView === "week";
|
|
7853
|
+
const [openEvent, setOpenEvent] = useState(null);
|
|
7854
|
+
const openCard = useCallback((event, from) => {
|
|
7855
|
+
if (onEventClick) {
|
|
7856
|
+
onEventClick(event);
|
|
7857
|
+
return;
|
|
7858
|
+
}
|
|
7859
|
+
setOpenEvent((cur) => cur && cur.event.id === event.id && cur.anchor === from ? null : { event, anchor: from });
|
|
7860
|
+
}, [onEventClick]);
|
|
7861
|
+
const actionsHidden = !!onEventClick && !!eventActions;
|
|
7862
|
+
useEffect(() => {
|
|
7863
|
+
if (actionsHidden) warnOnce("Calendar", "eventActions are never shown while onEventClick is set: the page opens a surface of its own for an event, so no card shows. Pass eventActions for the Calendar's card, or onEventClick for your own (Sprint 25.18).");
|
|
7864
|
+
}, [actionsHidden]);
|
|
7865
|
+
const shownKey = `${currentView}|${currentDate.toDateString()}`;
|
|
7866
|
+
const [cardShownKey, setCardShownKey] = useState(shownKey);
|
|
7867
|
+
if (cardShownKey !== shownKey) {
|
|
7868
|
+
setCardShownKey(shownKey);
|
|
7869
|
+
if (openEvent) setOpenEvent(null);
|
|
7870
|
+
}
|
|
7871
|
+
const { stableEvents, unreadable } = useMemo(() => {
|
|
7872
|
+
const read = [];
|
|
7873
|
+
const left = [];
|
|
7874
|
+
for (const e of events) {
|
|
7875
|
+
const start = new Date(e.start);
|
|
7876
|
+
if (Number.isNaN(start.getTime())) {
|
|
7877
|
+
left.push(String(e.id));
|
|
7878
|
+
continue;
|
|
7879
|
+
}
|
|
7880
|
+
const end = e.end ? new Date(e.end) : void 0;
|
|
7881
|
+
read.push({ ...e, start, end: end && !Number.isNaN(end.getTime()) ? end : void 0 });
|
|
7882
|
+
}
|
|
7883
|
+
return { stableEvents: read, unreadable: left.join(", ") };
|
|
7884
|
+
}, [events]);
|
|
7885
|
+
useEffect(() => {
|
|
7886
|
+
if (unreadable) warnOnce("Calendar", `events with a start that isn't a date aren't drawn (${unreadable}): give each a Date, or a date string Date reads.`);
|
|
7887
|
+
}, [unreadable]);
|
|
7637
7888
|
useEffect(() => {
|
|
7638
7889
|
if (!onDateRangeChange) return;
|
|
7639
7890
|
let start, end;
|
|
@@ -7666,9 +7917,10 @@ function Calendar({
|
|
|
7666
7917
|
setSelectedDate(/* @__PURE__ */ new Date());
|
|
7667
7918
|
}, [setCurrentDate]);
|
|
7668
7919
|
const handleDayClick = useCallback(
|
|
7669
|
-
(date) => {
|
|
7920
|
+
(date, detail) => {
|
|
7670
7921
|
setSelectedDate(date);
|
|
7671
|
-
onDayClick?.(date);
|
|
7922
|
+
if (detail) onDayClick?.(date, detail);
|
|
7923
|
+
else onDayClick?.(date);
|
|
7672
7924
|
},
|
|
7673
7925
|
[onDayClick]
|
|
7674
7926
|
);
|
|
@@ -7683,10 +7935,24 @@ function Calendar({
|
|
|
7683
7935
|
if (currentView === "week") return formatWeekRange(currentDate, weekStartsOn);
|
|
7684
7936
|
return void 0;
|
|
7685
7937
|
}, [currentView, currentDate, weekStartsOn]);
|
|
7938
|
+
const live = openEvent && stableEvents.find((e) => e.id === openEvent.event.id);
|
|
7939
|
+
const card = openEvent && live ? /* @__PURE__ */ jsx(
|
|
7940
|
+
EventCard,
|
|
7941
|
+
{
|
|
7942
|
+
event: live,
|
|
7943
|
+
category: categories[live.category ?? ""],
|
|
7944
|
+
anchor: openEvent.anchor,
|
|
7945
|
+
actions: typeof eventActions === "function" ? eventActions(live) : eventActions ?? [],
|
|
7946
|
+
onClose: () => setOpenEvent(null),
|
|
7947
|
+
fallbackFocus: () => rootRef.current?.querySelector('[role="gridcell"][tabindex="0"]')
|
|
7948
|
+
},
|
|
7949
|
+
openEvent.event.id
|
|
7950
|
+
) : null;
|
|
7686
7951
|
if (size === "compact") {
|
|
7687
7952
|
return /* @__PURE__ */ jsxs(
|
|
7688
7953
|
"div",
|
|
7689
7954
|
{
|
|
7955
|
+
ref: containerRef,
|
|
7690
7956
|
className: cn(
|
|
7691
7957
|
"flex flex-col",
|
|
7692
7958
|
"bg-[var(--ds-bg-surface)]",
|
|
@@ -7716,16 +7982,12 @@ function Calendar({
|
|
|
7716
7982
|
children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", size: 16 })
|
|
7717
7983
|
}
|
|
7718
7984
|
),
|
|
7719
|
-
/* @__PURE__ */
|
|
7985
|
+
/* @__PURE__ */ jsx(
|
|
7720
7986
|
"button",
|
|
7721
7987
|
{
|
|
7722
7988
|
onClick: goToToday,
|
|
7723
7989
|
className: "text-sm font-medium text-[var(--ds-text-primary)] hover:text-[var(--ds-accent-primary)] transition-colors cursor-pointer px-ds-2",
|
|
7724
|
-
children:
|
|
7725
|
-
MONTH_NAMES[currentDate.getMonth()],
|
|
7726
|
-
" ",
|
|
7727
|
-
currentDate.getFullYear()
|
|
7728
|
-
]
|
|
7990
|
+
children: formatMonthYear(currentDate)
|
|
7729
7991
|
}
|
|
7730
7992
|
),
|
|
7731
7993
|
/* @__PURE__ */ jsx(
|
|
@@ -7748,10 +8010,12 @@ function Calendar({
|
|
|
7748
8010
|
categories,
|
|
7749
8011
|
selectedDate,
|
|
7750
8012
|
onDayClick: handleDayClick,
|
|
7751
|
-
|
|
8013
|
+
onOpenEvent: openCard,
|
|
8014
|
+
onNavigate: setCurrentDate,
|
|
7752
8015
|
weekStartsOn
|
|
7753
8016
|
}
|
|
7754
|
-
)
|
|
8017
|
+
),
|
|
8018
|
+
card
|
|
7755
8019
|
]
|
|
7756
8020
|
}
|
|
7757
8021
|
);
|
|
@@ -7760,6 +8024,7 @@ function Calendar({
|
|
|
7760
8024
|
"div",
|
|
7761
8025
|
{
|
|
7762
8026
|
ref: containerRef,
|
|
8027
|
+
"data-fill": fill2 != null ? "" : void 0,
|
|
7763
8028
|
className: cn(
|
|
7764
8029
|
"flex flex-col",
|
|
7765
8030
|
"bg-[var(--ds-bg-surface)]",
|
|
@@ -7767,8 +8032,10 @@ function Calendar({
|
|
|
7767
8032
|
"rounded-[var(--ds-radius-lg)]",
|
|
7768
8033
|
"shadow-[var(--ds-shadow-sm)]",
|
|
7769
8034
|
"overflow-hidden",
|
|
8035
|
+
inPane && "h-full min-h-0",
|
|
7770
8036
|
className
|
|
7771
8037
|
),
|
|
8038
|
+
style: fill2 != null ? { height: fill2 } : void 0,
|
|
7772
8039
|
children: [
|
|
7773
8040
|
isNarrow ? /* @__PURE__ */ jsxs(
|
|
7774
8041
|
"div",
|
|
@@ -7827,7 +8094,7 @@ function Calendar({
|
|
|
7827
8094
|
]
|
|
7828
8095
|
}
|
|
7829
8096
|
),
|
|
7830
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-h-0", style: { minHeight: currentView === "week" ? 420 : currentView === "month" ? isNarrow ? 360 : 500 : void 0 }, children: [
|
|
8097
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-h-0", style: { minHeight: currentView === "week" ? fill2 != null || inPane ? void 0 : 420 : currentView === "month" ? isNarrow ? 360 : 500 : void 0 }, children: [
|
|
7831
8098
|
currentView === "month" && /* @__PURE__ */ jsx(
|
|
7832
8099
|
MonthView,
|
|
7833
8100
|
{
|
|
@@ -7836,7 +8103,9 @@ function Calendar({
|
|
|
7836
8103
|
categories,
|
|
7837
8104
|
selectedDate,
|
|
7838
8105
|
onDayClick: handleDayClick,
|
|
7839
|
-
|
|
8106
|
+
canStartEvent: !!onDayClick,
|
|
8107
|
+
onOpenEvent: openCard,
|
|
8108
|
+
onNavigate: setCurrentDate,
|
|
7840
8109
|
weekStartsOn
|
|
7841
8110
|
}
|
|
7842
8111
|
),
|
|
@@ -7848,7 +8117,8 @@ function Calendar({
|
|
|
7848
8117
|
categories,
|
|
7849
8118
|
selectedDate,
|
|
7850
8119
|
onDayClick: handleDayClick,
|
|
7851
|
-
|
|
8120
|
+
onOpenEvent: openCard,
|
|
8121
|
+
onNavigate: setCurrentDate,
|
|
7852
8122
|
weekStartsOn
|
|
7853
8123
|
}
|
|
7854
8124
|
),
|
|
@@ -7860,11 +8130,11 @@ function Calendar({
|
|
|
7860
8130
|
categories,
|
|
7861
8131
|
selectedDate,
|
|
7862
8132
|
onMonthClick: handleMonthClick,
|
|
7863
|
-
weekStartsOn
|
|
7864
|
-
onEventClick
|
|
8133
|
+
weekStartsOn
|
|
7865
8134
|
}
|
|
7866
8135
|
)
|
|
7867
|
-
] })
|
|
8136
|
+
] }),
|
|
8137
|
+
card
|
|
7868
8138
|
]
|
|
7869
8139
|
}
|
|
7870
8140
|
);
|
|
@@ -7930,7 +8200,7 @@ var defaultIcons = {
|
|
|
7930
8200
|
};
|
|
7931
8201
|
var FRAME_ICON_SIZE = 28;
|
|
7932
8202
|
function renderIcon(icon) {
|
|
7933
|
-
if (typeof icon === "string") return /* @__PURE__ */ jsx(Icon, { name: icon, size: FRAME_ICON_SIZE, className: "text-[var(--ds-text-muted)]" });
|
|
8203
|
+
if (typeof icon === "string") return /* @__PURE__ */ jsx(Icon, { name: icon, size: FRAME_ICON_SIZE, className: "text-[var(--ds-text-muted)]", from: "EmptyState's icon" });
|
|
7934
8204
|
if (isValidElement(icon) && icon.type === Icon) return cloneElement(icon, { size: FRAME_ICON_SIZE });
|
|
7935
8205
|
return icon;
|
|
7936
8206
|
}
|
|
@@ -8109,7 +8379,7 @@ function TableToolbar({
|
|
|
8109
8379
|
var ICON_TEXT_OFFSET = "calc((2rem - 1.25rem) / 2)";
|
|
8110
8380
|
function Marker({ item, vertical }) {
|
|
8111
8381
|
if (item.icon) {
|
|
8112
|
-
return /* @__PURE__ */ jsx("div", { "data-timeline-icon": "", className: "shrink-0 w-8 h-8 flex items-center justify-center *:max-w-8 *:max-h-8", children: item.icon });
|
|
8382
|
+
return /* @__PURE__ */ jsx("div", { "data-timeline-icon": "", className: "shrink-0 w-8 h-8 flex items-center justify-center *:max-w-8 *:max-h-8", children: slotIcon(item.icon, 16, "a Timeline item's icon") });
|
|
8113
8383
|
}
|
|
8114
8384
|
return /* @__PURE__ */ jsx(
|
|
8115
8385
|
"div",
|
|
@@ -8156,7 +8426,7 @@ function ExpandableDescription({ children, className }) {
|
|
|
8156
8426
|
);
|
|
8157
8427
|
}
|
|
8158
8428
|
function HorizontalLayout({ items, minItemWidth, className }) {
|
|
8159
|
-
return /* @__PURE__ */ jsx("div", { "data-timeline-row": "", className: cn("flex items-start overflow-x-auto snap-x", className), children: items.map((item, i) => {
|
|
8429
|
+
return /* @__PURE__ */ jsx("div", { "data-timeline-row": "", className: cn("relative flex items-start overflow-x-auto snap-x", className), children: items.map((item, i) => {
|
|
8160
8430
|
const isFirst = i === 0;
|
|
8161
8431
|
const isLast = i === items.length - 1;
|
|
8162
8432
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 shrink-0 flex-col items-center snap-start", style: { minWidth: minItemWidth }, children: [
|
|
@@ -8189,8 +8459,8 @@ function HorizontalLayout({ items, minItemWidth, className }) {
|
|
|
8189
8459
|
] }, i);
|
|
8190
8460
|
}) });
|
|
8191
8461
|
}
|
|
8192
|
-
var EXACT = new Intl.DateTimeFormat(
|
|
8193
|
-
var EXACT_DAY = new Intl.DateTimeFormat(
|
|
8462
|
+
var EXACT = { format: (d) => new Intl.DateTimeFormat(formatLocale(), { dateStyle: "medium", timeStyle: "short" }).format(d) };
|
|
8463
|
+
var EXACT_DAY = { format: (d) => new Intl.DateTimeFormat(formatLocale(), { dateStyle: "medium" }).format(d) };
|
|
8194
8464
|
var DATE_ONLY = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
8195
8465
|
function exactTime(value) {
|
|
8196
8466
|
if (typeof value === "string") {
|
|
@@ -8205,6 +8475,9 @@ function exactTime(value) {
|
|
|
8205
8475
|
return Number.isNaN(date.getTime()) ? null : { iso: date.toISOString(), text: EXACT.format(date) };
|
|
8206
8476
|
}
|
|
8207
8477
|
function ItemTime({ item }) {
|
|
8478
|
+
if (item.time !== void 0) {
|
|
8479
|
+
return /* @__PURE__ */ jsx("p", { className: "text-2xs text-[var(--ds-text-muted)] mt-ds-0.5 tabular-nums", children: /* @__PURE__ */ jsx(RelativeTime, { time: item.time }) });
|
|
8480
|
+
}
|
|
8208
8481
|
const exact = item.dateTime ? exactTime(item.dateTime) : null;
|
|
8209
8482
|
if (!item.timestamp && !exact) return null;
|
|
8210
8483
|
return /* @__PURE__ */ jsx("p", { className: "text-2xs text-[var(--ds-text-muted)] mt-ds-0.5 tabular-nums", children: exact ? /* @__PURE__ */ jsxs("time", { dateTime: exact.iso, title: exact.text, children: [
|
|
@@ -8242,7 +8515,7 @@ function Timeline({ items: allItems, orientation = "vertical", minItemWidth = 20
|
|
|
8242
8515
|
}, [ref]);
|
|
8243
8516
|
const fits = width === 0 || width >= items.length * minItemWidth;
|
|
8244
8517
|
const horizontal = orientation === "horizontal" || orientation === "responsive" && fits;
|
|
8245
|
-
const list = /* @__PURE__ */ jsx("div", { ref: setRefs, "data-ds-list": "", "data-timeline-orientation": horizontal ? "horizontal" : "vertical", className: pager ? void 0 : className, children: horizontal ? /* @__PURE__ */ jsx(HorizontalLayout, { items, minItemWidth }) : /* @__PURE__ */ jsx(VerticalLayout, { items }) });
|
|
8518
|
+
const list = /* @__PURE__ */ jsx("div", { ref: setRefs, "data-ds-list": "", "data-timeline-orientation": horizontal ? "horizontal" : "vertical", className: pager ? void 0 : className, children: /* @__PURE__ */ jsx(RowsCtx, { value: true, children: horizontal ? /* @__PURE__ */ jsx(HorizontalLayout, { items, minItemWidth }) : /* @__PURE__ */ jsx(VerticalLayout, { items }) }) });
|
|
8246
8519
|
if (!pager) return list;
|
|
8247
8520
|
return /* @__PURE__ */ jsxs("div", { "data-gs-paged": "", className: cn("flex flex-col min-w-0", className), children: [
|
|
8248
8521
|
list,
|
|
@@ -8811,7 +9084,7 @@ function Carousel({
|
|
|
8811
9084
|
);
|
|
8812
9085
|
}
|
|
8813
9086
|
function formatTime2(d) {
|
|
8814
|
-
return d.toLocaleTimeString(
|
|
9087
|
+
return d.toLocaleTimeString(formatLocale(), { hour: "2-digit", minute: "2-digit" });
|
|
8815
9088
|
}
|
|
8816
9089
|
function isSameMinute(a, b) {
|
|
8817
9090
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate() && a.getHours() === b.getHours() && a.getMinutes() === b.getMinutes();
|
|
@@ -9602,7 +9875,7 @@ var StackedList = forwardRef(function StackedList2({
|
|
|
9602
9875
|
!pager && className
|
|
9603
9876
|
),
|
|
9604
9877
|
role: "list",
|
|
9605
|
-
children: shown.map((item) => {
|
|
9878
|
+
children: /* @__PURE__ */ jsx(RowsCtx, { value: true, children: shown.map((item) => {
|
|
9606
9879
|
const isSelected = item.selected ?? (selectedId !== void 0 && item.id === selectedId);
|
|
9607
9880
|
const interactive = !!item.onClick;
|
|
9608
9881
|
const hasEmphasis = item.unread !== void 0;
|
|
@@ -9691,7 +9964,7 @@ var StackedList = forwardRef(function StackedList2({
|
|
|
9691
9964
|
]
|
|
9692
9965
|
}
|
|
9693
9966
|
) }, item.id);
|
|
9694
|
-
})
|
|
9967
|
+
}) })
|
|
9695
9968
|
}
|
|
9696
9969
|
);
|
|
9697
9970
|
if (!pager) return list;
|
|
@@ -9701,9 +9974,9 @@ var StackedList = forwardRef(function StackedList2({
|
|
|
9701
9974
|
] });
|
|
9702
9975
|
});
|
|
9703
9976
|
var TIME_ZOOMS = ["day", "week", "month", "quarter"];
|
|
9704
|
-
var
|
|
9977
|
+
var DAY_MS2 = 864e5;
|
|
9705
9978
|
var DATE_ONLY2 = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
9706
|
-
var utcDay = (y, m, d) => Math.round(Date.UTC(y, m, d) /
|
|
9979
|
+
var utcDay = (y, m, d) => Math.round(Date.UTC(y, m, d) / DAY_MS2);
|
|
9707
9980
|
function dayOfDate(d) {
|
|
9708
9981
|
const t = d.getTime();
|
|
9709
9982
|
if (Number.isNaN(t)) return NaN;
|
|
@@ -9712,7 +9985,7 @@ function dayOfDate(d) {
|
|
|
9712
9985
|
first.setHours(0, 0, 0, 0);
|
|
9713
9986
|
if (first.getTime() === t) return day;
|
|
9714
9987
|
const ms = ((d.getHours() * 60 + d.getMinutes()) * 60 + d.getSeconds()) * 1e3 + d.getMilliseconds();
|
|
9715
|
-
return day + ms /
|
|
9988
|
+
return day + ms / DAY_MS2;
|
|
9716
9989
|
}
|
|
9717
9990
|
function dayOf(value) {
|
|
9718
9991
|
if (typeof value === "number") return Number.isFinite(value) ? value : NaN;
|
|
@@ -9722,13 +9995,13 @@ function dayOf(value) {
|
|
|
9722
9995
|
if (!m) return dayOfDate(new Date(value));
|
|
9723
9996
|
const [y, mo, d] = [Number(m[1]), Number(m[2]) - 1, Number(m[3])];
|
|
9724
9997
|
const day = utcDay(y, mo, d);
|
|
9725
|
-
const back = new Date(day *
|
|
9998
|
+
const back = new Date(day * DAY_MS2);
|
|
9726
9999
|
return back.getUTCFullYear() === y && back.getUTCMonth() === mo && back.getUTCDate() === d ? day : NaN;
|
|
9727
10000
|
}
|
|
9728
10001
|
function dateOfDay(day) {
|
|
9729
10002
|
const whole = Math.floor(day);
|
|
9730
|
-
const u = new Date(whole *
|
|
9731
|
-
return new Date(u.getUTCFullYear(), u.getUTCMonth(), u.getUTCDate(), 0, 0, 0, Math.round((day - whole) *
|
|
10003
|
+
const u = new Date(whole * DAY_MS2);
|
|
10004
|
+
return new Date(u.getUTCFullYear(), u.getUTCMonth(), u.getUTCDate(), 0, 0, 0, Math.round((day - whole) * DAY_MS2));
|
|
9732
10005
|
}
|
|
9733
10006
|
function isWholeDay(value) {
|
|
9734
10007
|
return typeof value === "string" ? DATE_ONLY2.test(value.trim()) : Number.isInteger(dayOf(value));
|
|
@@ -9747,7 +10020,7 @@ function periodStart(unit, day, weekStartsOn) {
|
|
|
9747
10020
|
const d = Math.floor(day);
|
|
9748
10021
|
if (unit === "day") return d;
|
|
9749
10022
|
if (unit === "week") return d - (weekday(d) - weekStartsOn + 7) % 7;
|
|
9750
|
-
const u = new Date(d *
|
|
10023
|
+
const u = new Date(d * DAY_MS2);
|
|
9751
10024
|
const y = u.getUTCFullYear();
|
|
9752
10025
|
const m = u.getUTCMonth();
|
|
9753
10026
|
if (unit === "month") return utcDay(y, m, 1);
|
|
@@ -9757,7 +10030,7 @@ function periodStart(unit, day, weekStartsOn) {
|
|
|
9757
10030
|
function periodAfter(unit, start) {
|
|
9758
10031
|
if (unit === "day") return start + 1;
|
|
9759
10032
|
if (unit === "week") return start + 7;
|
|
9760
|
-
const u = new Date(start *
|
|
10033
|
+
const u = new Date(start * DAY_MS2);
|
|
9761
10034
|
const y = u.getUTCFullYear();
|
|
9762
10035
|
const m = u.getUTCMonth();
|
|
9763
10036
|
if (unit === "month") return utcDay(y, m + 1, 1);
|
|
@@ -9765,7 +10038,8 @@ function periodAfter(unit, start) {
|
|
|
9765
10038
|
return utcDay(y + 1, 0, 1);
|
|
9766
10039
|
}
|
|
9767
10040
|
var formats = /* @__PURE__ */ new Map();
|
|
9768
|
-
function formatter(
|
|
10041
|
+
function formatter(given, options) {
|
|
10042
|
+
const locale = given ?? formatLocale();
|
|
9769
10043
|
const key = `${locale ?? ""}|${JSON.stringify(options)}`;
|
|
9770
10044
|
let f = formats.get(key);
|
|
9771
10045
|
if (!f) {
|
|
@@ -9775,11 +10049,11 @@ function formatter(locale, options) {
|
|
|
9775
10049
|
return f;
|
|
9776
10050
|
}
|
|
9777
10051
|
function format(day, locale, options) {
|
|
9778
|
-
return formatter(locale, options).format(new Date(day *
|
|
10052
|
+
return formatter(locale, options).format(new Date(day * DAY_MS2));
|
|
9779
10053
|
}
|
|
9780
10054
|
var pad22 = (n) => String(n).padStart(2, "0");
|
|
9781
10055
|
function keyOf(unit, day) {
|
|
9782
|
-
const u = new Date(day *
|
|
10056
|
+
const u = new Date(day * DAY_MS2);
|
|
9783
10057
|
const y = u.getUTCFullYear();
|
|
9784
10058
|
const m = u.getUTCMonth();
|
|
9785
10059
|
if (unit === "year") return String(y);
|
|
@@ -9794,7 +10068,7 @@ function labelsOf(unit, role, day, locale) {
|
|
|
9794
10068
|
else if (unit === "week") forms = [f({ day: "numeric", month: "short" }), f({ day: "numeric" })];
|
|
9795
10069
|
else if (unit === "month") {
|
|
9796
10070
|
forms = role === "major" ? [f({ month: "long", year: "numeric" }), f({ month: "short", year: "numeric" }), f({ month: "short" }), f({ month: "narrow" })] : [f({ month: "long" }), f({ month: "short" }), f({ month: "narrow" })];
|
|
9797
|
-
} else if (unit === "quarter") forms = [`Q${Math.floor(new Date(day *
|
|
10071
|
+
} else if (unit === "quarter") forms = [`Q${Math.floor(new Date(day * DAY_MS2).getUTCMonth() / 3) + 1}`];
|
|
9798
10072
|
else forms = [f({ year: "numeric" }), f({ year: "2-digit" })];
|
|
9799
10073
|
return forms;
|
|
9800
10074
|
}
|
|
@@ -9878,10 +10152,10 @@ function extendTimeScaleTo(scale, endDay) {
|
|
|
9878
10152
|
}
|
|
9879
10153
|
var noSubscription = () => () => {
|
|
9880
10154
|
};
|
|
9881
|
-
var
|
|
9882
|
-
var
|
|
10155
|
+
var inBrowser2 = () => true;
|
|
10156
|
+
var onServer2 = () => false;
|
|
9883
10157
|
function useTimeScale({ start, end, zoom, today, weekStartsOn = 1, locale, pxPerDay, pad: pad3 = 0 }) {
|
|
9884
|
-
const readable = useSyncExternalStore(noSubscription,
|
|
10158
|
+
const readable = useSyncExternalStore(noSubscription, inBrowser2, onServer2);
|
|
9885
10159
|
const [mounted] = useState(() => toMinute(dayOf(/* @__PURE__ */ new Date())));
|
|
9886
10160
|
const pending = today === void 0 && !readable;
|
|
9887
10161
|
const from = dayOf(start);
|
|
@@ -9935,8 +10209,8 @@ function formatDateRange(start, end, words) {
|
|
|
9935
10209
|
const timed = !isWholeDay(start) || !isWholeDay(until);
|
|
9936
10210
|
const first = timed ? from : Math.floor(from);
|
|
9937
10211
|
const last = timed ? Math.max(from, stop) : Math.max(first, Math.ceil(stop) - 1);
|
|
9938
|
-
const a = new Date(first *
|
|
9939
|
-
const b = new Date(last *
|
|
10212
|
+
const a = new Date(first * DAY_MS2);
|
|
10213
|
+
const b = new Date(last * DAY_MS2);
|
|
9940
10214
|
const years = a.getUTCFullYear() !== b.getUTCFullYear() && day.year === void 0;
|
|
9941
10215
|
const f = formatter(locale, { ...day, ...years ? { year: "numeric" } : {}, ...timed ? time : {} });
|
|
9942
10216
|
return first === last ? f.format(a) : range(f, a, b, to ?? (english(f) ? " to " : void 0));
|
|
@@ -10213,9 +10487,9 @@ function TimeScaleHeader({ todayLabel = "Today", className }) {
|
|
|
10213
10487
|
}
|
|
10214
10488
|
var ZOOM_NAMES = { day: "Days", week: "Weeks", month: "Months", quarter: "Quarters" };
|
|
10215
10489
|
var SHADE_MIN = 4;
|
|
10216
|
-
var
|
|
10490
|
+
var INSET2 = 8;
|
|
10217
10491
|
var MIN_INSET = 2;
|
|
10218
|
-
var MIN_TITLE = 2 *
|
|
10492
|
+
var MIN_TITLE = 2 * INSET2 + 12;
|
|
10219
10493
|
var PHONE_BELOW = 640;
|
|
10220
10494
|
var MIN_LABEL = 112;
|
|
10221
10495
|
var ROW_HEIGHT = 40;
|
|
@@ -10569,7 +10843,7 @@ function TimeBar({ start, end, minWidth = 0, labels, children, className, style,
|
|
|
10569
10843
|
let label = null;
|
|
10570
10844
|
if (labels && hasLabels) {
|
|
10571
10845
|
const widths = labels.map(measure);
|
|
10572
|
-
const inset = Math.min(
|
|
10846
|
+
const inset = Math.min(INSET2, Math.max(MIN_INSET, (drawnWidth - borders.start - borders.end - Math.min(...widths)) / 2 - 0.5));
|
|
10573
10847
|
const fits = (i) => `clamp(0, calc((${inView} - ${widths[i] + 2 * inset} + 0.25) * 1000), 1)`;
|
|
10574
10848
|
const shows = (i) => i === 0 ? fits(0) : `calc(${[fits(i), ...labels.slice(0, i).map((_, j) => `(1 - ${fits(j)})`)].join(" * ")})`;
|
|
10575
10849
|
const named = props["aria-label"] !== void 0 || props["aria-labelledby"] !== void 0;
|
|
@@ -10584,7 +10858,7 @@ function TimeBar({ start, end, minWidth = 0, labels, children, className, style,
|
|
|
10584
10858
|
"data-time-bar-label": "",
|
|
10585
10859
|
"data-gs-clip": "",
|
|
10586
10860
|
className: "sticky flex min-w-0 items-center gap-ds-1 overflow-hidden whitespace-nowrap",
|
|
10587
|
-
style: { ...sticky, paddingInline:
|
|
10861
|
+
style: { ...sticky, paddingInline: INSET2, opacity: `clamp(0, calc((${inView} - ${MIN_TITLE}) * 1000), 1)` },
|
|
10588
10862
|
children: typeof children === "string" ? /* @__PURE__ */ jsx("span", { className: "truncate", children }) : children
|
|
10589
10863
|
}
|
|
10590
10864
|
);
|
|
@@ -10856,7 +11130,7 @@ function Gantt({
|
|
|
10856
11130
|
const byKey = useMemo(() => new Map(rows.map((r) => [r.key, r])), [rows]);
|
|
10857
11131
|
const names = useMemo(() => {
|
|
10858
11132
|
const byId = new Map(tasks.map((i) => [i.id, i]));
|
|
10859
|
-
const list = new Intl.ListFormat(locale, { type: "conjunction" });
|
|
11133
|
+
const list = new Intl.ListFormat(locale ?? formatLocale(), { type: "conjunction" });
|
|
10860
11134
|
const out = /* @__PURE__ */ new Map();
|
|
10861
11135
|
for (const item of tasks) {
|
|
10862
11136
|
const dates = datesOf(item);
|
|
@@ -15986,7 +16260,7 @@ function HoverCard({
|
|
|
15986
16260
|
className
|
|
15987
16261
|
),
|
|
15988
16262
|
style: { top: pos.top, left: pos.left },
|
|
15989
|
-
children: content
|
|
16263
|
+
children: /* @__PURE__ */ jsx(RowsCtx, { value: false, children: content })
|
|
15990
16264
|
}
|
|
15991
16265
|
),
|
|
15992
16266
|
container ?? document.body
|
|
@@ -17115,6 +17389,7 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
17115
17389
|
title,
|
|
17116
17390
|
onTitleChange,
|
|
17117
17391
|
titleLabel = "Title",
|
|
17392
|
+
titleId,
|
|
17118
17393
|
description,
|
|
17119
17394
|
actions,
|
|
17120
17395
|
badge,
|
|
@@ -17150,7 +17425,7 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
17150
17425
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
|
|
17151
17426
|
editable ? (
|
|
17152
17427
|
// the field is the title: the heading holds it, so the page's headings still name the view by its title
|
|
17153
|
-
/* @__PURE__ */ jsx("h2", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
17428
|
+
/* @__PURE__ */ jsx("h2", { id: titleId, className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
17154
17429
|
Input,
|
|
17155
17430
|
{
|
|
17156
17431
|
size: "md",
|
|
@@ -17160,7 +17435,7 @@ var SectionHeading = forwardRef(function SectionHeading2({
|
|
|
17160
17435
|
className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]"
|
|
17161
17436
|
}
|
|
17162
17437
|
) })
|
|
17163
|
-
) : /* @__PURE__ */ jsx("h2", { className: cn("font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", pane ? "truncate" : "min-w-0 break-words"), children: title }),
|
|
17438
|
+
) : /* @__PURE__ */ jsx("h2", { id: titleId, className: cn("font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", pane ? "truncate" : "min-w-0 break-words"), children: title }),
|
|
17164
17439
|
badge,
|
|
17165
17440
|
count !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "neutral", size: "sm", children: count })
|
|
17166
17441
|
] }),
|
|
@@ -17216,6 +17491,23 @@ var ActionPanelGroup = forwardRef(function ActionPanelGroup2({
|
|
|
17216
17491
|
}
|
|
17217
17492
|
);
|
|
17218
17493
|
});
|
|
17494
|
+
function DangerZone({ title = "Danger zone", description, children, className }) {
|
|
17495
|
+
const titleId = useId();
|
|
17496
|
+
return /* @__PURE__ */ jsxs("section", { "aria-labelledby": titleId, "data-gs": "danger-zone", className, children: [
|
|
17497
|
+
/* @__PURE__ */ jsx(SectionHeading, { title, titleId, description }),
|
|
17498
|
+
/* @__PURE__ */ jsx(
|
|
17499
|
+
"div",
|
|
17500
|
+
{
|
|
17501
|
+
"data-danger-frame": "",
|
|
17502
|
+
className: cn(
|
|
17503
|
+
"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-status-error)] px-ds-5",
|
|
17504
|
+
GLASS_SURFACE
|
|
17505
|
+
),
|
|
17506
|
+
children: /* @__PURE__ */ jsx(ActionPanelGroup, { children })
|
|
17507
|
+
}
|
|
17508
|
+
)
|
|
17509
|
+
] });
|
|
17510
|
+
}
|
|
17219
17511
|
var lineClampClasses = {
|
|
17220
17512
|
1: "truncate",
|
|
17221
17513
|
2: "line-clamp-2",
|
|
@@ -17267,6 +17559,6 @@ var TextOverflow = forwardRef(function TextOverflow2({
|
|
|
17267
17559
|
return /* @__PURE__ */ jsx(Tooltip, { content: resolvedTooltipContent, children: content });
|
|
17268
17560
|
});
|
|
17269
17561
|
|
|
17270
|
-
export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel,
|
|
17562
|
+
export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, AvatarGroup, BottomNav, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DangerZone, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, DropdownMenu, EmptyState, EntityCell, FileUpload, FlowSaved, FormWrapper, Gantt, HoverCard, Kbd, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, PageActions, PageContainer, PageHeader, PinInput, Progress, RadioGroup, Rating, RelativeTime, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sheet, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, TimezoneSelect, Toast, ToastProvider, Tour, TransferList, TreeView, browserTimeZone, canonicalTimeZone, dateOfDay, dayOf, endDayOf, fitLabel, fitLabels, formatDateRange, formatFullTime, formatRelativeTime, readFlowProgress, timeExtent, timeZoneOffset, useContentWidth, useDestructiveAction, useFittedLabels, useFlowSteps, useRelativeTimeFormat, useSidebar, useTextMeasure, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
|
|
17271
17563
|
//# sourceMappingURL=index.js.map
|
|
17272
17564
|
//# sourceMappingURL=index.js.map
|