@geomak/ui 6.24.1 → 6.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/dist/index.cjs +928 -513
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.js +702 -288
- package/dist/index.js.map +1 -1
- package/dist/styles.css +24 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { colors_default } from './chunk-I2P4JJDB.js';
|
|
2
2
|
export { colors_default as COLORS, PALETTE as palette, semanticTokens, vars } from './chunk-I2P4JJDB.js';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
-
import
|
|
4
|
+
import React29, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useContext, useSyncExternalStore, useLayoutEffect } from 'react';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
6
6
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
7
7
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
|
@@ -11,12 +11,12 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
|
11
11
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
12
12
|
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
13
13
|
import * as Popover from '@radix-ui/react-popover';
|
|
14
|
+
import * as ToggleGroup from '@radix-ui/react-toggle-group';
|
|
14
15
|
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
15
16
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
16
17
|
import * as NavigationMenu from '@radix-ui/react-navigation-menu';
|
|
17
18
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
18
19
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
19
|
-
import * as ToggleGroup from '@radix-ui/react-toggle-group';
|
|
20
20
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
21
21
|
|
|
22
22
|
var Moon = ({ color = "gray" }) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: color, viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: color, className: "w-8 h-8", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" }) });
|
|
@@ -693,7 +693,7 @@ var SIZE_CLASSES = {
|
|
|
693
693
|
md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
|
|
694
694
|
lg: "h-11 px-5 text-sm gap-2 rounded-xl"
|
|
695
695
|
};
|
|
696
|
-
var Button =
|
|
696
|
+
var Button = React29.forwardRef(function Button2({
|
|
697
697
|
content,
|
|
698
698
|
variant = "primary",
|
|
699
699
|
size = "md",
|
|
@@ -801,7 +801,7 @@ function MenuButton({
|
|
|
801
801
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
802
802
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
803
803
|
].join(" "),
|
|
804
|
-
children: items.map((item) => /* @__PURE__ */ jsxs(
|
|
804
|
+
children: items.map((item) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
805
805
|
item.separatorBefore && /* @__PURE__ */ jsx(DropdownMenu.Separator, { className: "my-1 h-px bg-border" }),
|
|
806
806
|
/* @__PURE__ */ jsxs(
|
|
807
807
|
DropdownMenu.Item,
|
|
@@ -1900,7 +1900,7 @@ function Kbd({
|
|
|
1900
1900
|
style
|
|
1901
1901
|
}) {
|
|
1902
1902
|
if (keys && keys.length > 0) {
|
|
1903
|
-
return /* @__PURE__ */ jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxs(
|
|
1903
|
+
return /* @__PURE__ */ jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
1904
1904
|
i > 0 && /* @__PURE__ */ jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
|
|
1905
1905
|
/* @__PURE__ */ jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
|
|
1906
1906
|
] }, `${k}-${i}`)) });
|
|
@@ -1992,7 +1992,7 @@ function FlatCarousel({
|
|
|
1992
1992
|
style
|
|
1993
1993
|
}) {
|
|
1994
1994
|
const scrollerRef = useRef(null);
|
|
1995
|
-
const slides =
|
|
1995
|
+
const slides = React29.Children.toArray(children);
|
|
1996
1996
|
const [active, setActive] = useState(0);
|
|
1997
1997
|
const [atStart, setAtStart] = useState(true);
|
|
1998
1998
|
const [atEnd, setAtEnd] = useState(false);
|
|
@@ -2047,7 +2047,7 @@ function RotatingCarousel({
|
|
|
2047
2047
|
className = "",
|
|
2048
2048
|
style
|
|
2049
2049
|
}) {
|
|
2050
|
-
const slides =
|
|
2050
|
+
const slides = React29.Children.toArray(children);
|
|
2051
2051
|
const count = slides.length;
|
|
2052
2052
|
const [active, setActive] = useState(0);
|
|
2053
2053
|
const reduced = useReducedMotion();
|
|
@@ -2563,7 +2563,7 @@ function Calendar2({
|
|
|
2563
2563
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-0.5", role: "grid", children: grid.map((d, i) => {
|
|
2564
2564
|
const inMonth = d.getMonth() === visible.getMonth();
|
|
2565
2565
|
const isSelected = value != null && sameDay(d, value);
|
|
2566
|
-
const
|
|
2566
|
+
const isToday2 = sameDay(d, today);
|
|
2567
2567
|
const isDisabled = disabled(d);
|
|
2568
2568
|
const dayEvents = eventsByDay.get(d.toDateString()) ?? [];
|
|
2569
2569
|
return /* @__PURE__ */ jsxs(
|
|
@@ -2572,7 +2572,7 @@ function Calendar2({
|
|
|
2572
2572
|
type: "button",
|
|
2573
2573
|
role: "gridcell",
|
|
2574
2574
|
"aria-selected": isSelected,
|
|
2575
|
-
"aria-current":
|
|
2575
|
+
"aria-current": isToday2 ? "date" : void 0,
|
|
2576
2576
|
disabled: isDisabled,
|
|
2577
2577
|
onClick: () => onChange?.(startOfDay(d)),
|
|
2578
2578
|
className: [
|
|
@@ -2580,24 +2580,662 @@ function Calendar2({
|
|
|
2580
2580
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
2581
2581
|
isSelected ? "bg-accent text-accent-fg font-semibold" : inMonth ? "text-foreground hover:bg-surface-raised" : "text-foreground-muted hover:bg-surface-raised",
|
|
2582
2582
|
isDisabled ? "opacity-40 cursor-not-allowed hover:bg-transparent" : "",
|
|
2583
|
-
!isSelected &&
|
|
2583
|
+
!isSelected && isToday2 ? "ring-1 ring-inset ring-accent/60" : ""
|
|
2584
2584
|
].filter(Boolean).join(" "),
|
|
2585
2585
|
children: [
|
|
2586
2586
|
/* @__PURE__ */ jsx("span", { className: "leading-none", children: d.getDate() }),
|
|
2587
2587
|
dayEvents.length > 0 && /* @__PURE__ */ jsx("span", { className: "absolute bottom-1 flex gap-0.5", children: dayEvents.slice(0, 3).map((ev, j) => /* @__PURE__ */ jsx(
|
|
2588
2588
|
"span",
|
|
2589
2589
|
{
|
|
2590
|
-
title: ev.label,
|
|
2591
|
-
className: "h-1 w-1 rounded-full",
|
|
2592
|
-
style: { backgroundColor: ev.color ?? (isSelected ? "var(--color-accent-fg)" : "var(--color-accent)") }
|
|
2590
|
+
title: ev.label,
|
|
2591
|
+
className: "h-1 w-1 rounded-full",
|
|
2592
|
+
style: { backgroundColor: ev.color ?? (isSelected ? "var(--color-accent-fg)" : "var(--color-accent)") }
|
|
2593
|
+
},
|
|
2594
|
+
j
|
|
2595
|
+
)) })
|
|
2596
|
+
]
|
|
2597
|
+
},
|
|
2598
|
+
i
|
|
2599
|
+
);
|
|
2600
|
+
}) })
|
|
2601
|
+
] });
|
|
2602
|
+
}
|
|
2603
|
+
var FIELD_SIZE = {
|
|
2604
|
+
sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
|
|
2605
|
+
md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
|
|
2606
|
+
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
2607
|
+
};
|
|
2608
|
+
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
|
|
2609
|
+
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
|
|
2610
|
+
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
|
|
2611
|
+
var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
|
|
2612
|
+
function fieldShell({
|
|
2613
|
+
size = "md",
|
|
2614
|
+
hasError = false,
|
|
2615
|
+
disabled = false,
|
|
2616
|
+
focusWithin = false,
|
|
2617
|
+
sized = true
|
|
2618
|
+
} = {}) {
|
|
2619
|
+
const s = FIELD_SIZE[size];
|
|
2620
|
+
return [
|
|
2621
|
+
"w-full rounded-lg border bg-surface text-foreground",
|
|
2622
|
+
"transition-[color,box-shadow,border-color] duration-150",
|
|
2623
|
+
s.text,
|
|
2624
|
+
sized ? `${s.control} ${s.padX}` : "",
|
|
2625
|
+
// resting border
|
|
2626
|
+
hasError ? "border-status-error" : "border-border",
|
|
2627
|
+
// hover (only when interactive + no error)
|
|
2628
|
+
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
2629
|
+
// focus
|
|
2630
|
+
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
2631
|
+
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
2632
|
+
// placeholder colour for native inputs
|
|
2633
|
+
"placeholder:text-foreground-muted"
|
|
2634
|
+
].filter(Boolean).join(" ");
|
|
2635
|
+
}
|
|
2636
|
+
function FieldHelpIcon({ text }) {
|
|
2637
|
+
return /* @__PURE__ */ jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsx(
|
|
2638
|
+
"button",
|
|
2639
|
+
{
|
|
2640
|
+
type: "button",
|
|
2641
|
+
"aria-label": "More information",
|
|
2642
|
+
className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
|
|
2643
|
+
children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
|
|
2644
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
|
|
2645
|
+
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
|
|
2646
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
|
|
2647
|
+
] })
|
|
2648
|
+
}
|
|
2649
|
+
) });
|
|
2650
|
+
}
|
|
2651
|
+
function FieldLabel({
|
|
2652
|
+
label,
|
|
2653
|
+
htmlFor,
|
|
2654
|
+
required,
|
|
2655
|
+
helperText,
|
|
2656
|
+
horizontal = false,
|
|
2657
|
+
align = "start",
|
|
2658
|
+
style,
|
|
2659
|
+
width,
|
|
2660
|
+
className = ""
|
|
2661
|
+
}) {
|
|
2662
|
+
if (label == null && helperText == null) return null;
|
|
2663
|
+
return /* @__PURE__ */ jsxs(
|
|
2664
|
+
"div",
|
|
2665
|
+
{
|
|
2666
|
+
style: { width: horizontal ? width : void 0, ...style },
|
|
2667
|
+
className: [
|
|
2668
|
+
"flex items-center gap-1",
|
|
2669
|
+
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
2670
|
+
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
2671
|
+
// on the row's items-center to line up with a short control.
|
|
2672
|
+
horizontal && align === "start" ? "mt-2" : "",
|
|
2673
|
+
className
|
|
2674
|
+
].filter(Boolean).join(" "),
|
|
2675
|
+
children: [
|
|
2676
|
+
label != null && /* @__PURE__ */ jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
|
|
2677
|
+
label,
|
|
2678
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
2679
|
+
] }),
|
|
2680
|
+
helperText != null && /* @__PURE__ */ jsx(FieldHelpIcon, { text: helperText })
|
|
2681
|
+
]
|
|
2682
|
+
}
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
function Field({
|
|
2686
|
+
label,
|
|
2687
|
+
htmlFor,
|
|
2688
|
+
errorId,
|
|
2689
|
+
errorMessage,
|
|
2690
|
+
layout = "vertical",
|
|
2691
|
+
required,
|
|
2692
|
+
helperText,
|
|
2693
|
+
labelAlign = "start",
|
|
2694
|
+
labelStyle,
|
|
2695
|
+
labelWidth,
|
|
2696
|
+
className = "",
|
|
2697
|
+
children
|
|
2698
|
+
}) {
|
|
2699
|
+
const hasError = errorMessage != null;
|
|
2700
|
+
const horizontal = layout === "horizontal";
|
|
2701
|
+
return /* @__PURE__ */ jsxs(
|
|
2702
|
+
"div",
|
|
2703
|
+
{
|
|
2704
|
+
className: [
|
|
2705
|
+
"flex",
|
|
2706
|
+
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
2707
|
+
className
|
|
2708
|
+
].filter(Boolean).join(" "),
|
|
2709
|
+
children: [
|
|
2710
|
+
/* @__PURE__ */ jsx(
|
|
2711
|
+
FieldLabel,
|
|
2712
|
+
{
|
|
2713
|
+
label,
|
|
2714
|
+
htmlFor,
|
|
2715
|
+
required,
|
|
2716
|
+
helperText,
|
|
2717
|
+
horizontal,
|
|
2718
|
+
align: labelAlign,
|
|
2719
|
+
style: labelStyle,
|
|
2720
|
+
width: labelWidth
|
|
2721
|
+
}
|
|
2722
|
+
),
|
|
2723
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
2724
|
+
children,
|
|
2725
|
+
hasError && /* @__PURE__ */ jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
2726
|
+
] })
|
|
2727
|
+
]
|
|
2728
|
+
}
|
|
2729
|
+
);
|
|
2730
|
+
}
|
|
2731
|
+
var SIZE5 = {
|
|
2732
|
+
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
2733
|
+
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
2734
|
+
lg: { h: "h-control-lg", text: "text-sm", pad: "px-4" }
|
|
2735
|
+
};
|
|
2736
|
+
function SegmentedControl({
|
|
2737
|
+
options,
|
|
2738
|
+
value,
|
|
2739
|
+
defaultValue,
|
|
2740
|
+
onChange,
|
|
2741
|
+
size = "md",
|
|
2742
|
+
fullWidth = false,
|
|
2743
|
+
disabled,
|
|
2744
|
+
label,
|
|
2745
|
+
layout = "vertical",
|
|
2746
|
+
helperText,
|
|
2747
|
+
className,
|
|
2748
|
+
name,
|
|
2749
|
+
required,
|
|
2750
|
+
errorMessage,
|
|
2751
|
+
"aria-label": ariaLabel
|
|
2752
|
+
}) {
|
|
2753
|
+
const sz = SIZE5[size];
|
|
2754
|
+
const groupId = useId();
|
|
2755
|
+
const errorId = useId();
|
|
2756
|
+
const hasError = errorMessage != null;
|
|
2757
|
+
const isControlled = value !== void 0;
|
|
2758
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
2759
|
+
const current = isControlled ? value : internal;
|
|
2760
|
+
const handle = (v) => {
|
|
2761
|
+
if (!v) return;
|
|
2762
|
+
if (!isControlled) setInternal(v);
|
|
2763
|
+
onChange?.(v);
|
|
2764
|
+
};
|
|
2765
|
+
return /* @__PURE__ */ jsxs(
|
|
2766
|
+
Field,
|
|
2767
|
+
{
|
|
2768
|
+
className,
|
|
2769
|
+
label,
|
|
2770
|
+
htmlFor: groupId,
|
|
2771
|
+
errorId,
|
|
2772
|
+
errorMessage,
|
|
2773
|
+
layout,
|
|
2774
|
+
required,
|
|
2775
|
+
helperText,
|
|
2776
|
+
children: [
|
|
2777
|
+
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: current ?? "" }),
|
|
2778
|
+
/* @__PURE__ */ jsx(
|
|
2779
|
+
ToggleGroup.Root,
|
|
2780
|
+
{
|
|
2781
|
+
id: groupId,
|
|
2782
|
+
type: "single",
|
|
2783
|
+
value: current,
|
|
2784
|
+
onValueChange: handle,
|
|
2785
|
+
disabled,
|
|
2786
|
+
"aria-label": ariaLabel ?? (typeof label === "string" ? label : void 0),
|
|
2787
|
+
"aria-invalid": hasError || void 0,
|
|
2788
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
2789
|
+
className: [
|
|
2790
|
+
"inline-flex items-center gap-1 rounded-lg border bg-surface-raised p-1",
|
|
2791
|
+
hasError ? "border-status-error" : "border-border",
|
|
2792
|
+
sz.h,
|
|
2793
|
+
fullWidth ? "flex w-full" : "w-fit",
|
|
2794
|
+
disabled ? "opacity-60 cursor-not-allowed" : ""
|
|
2795
|
+
].filter(Boolean).join(" "),
|
|
2796
|
+
children: options.map((opt) => /* @__PURE__ */ jsxs(
|
|
2797
|
+
ToggleGroup.Item,
|
|
2798
|
+
{
|
|
2799
|
+
value: opt.value,
|
|
2800
|
+
disabled: opt.disabled,
|
|
2801
|
+
className: [
|
|
2802
|
+
"inline-flex items-center justify-center gap-1.5 rounded-md select-none whitespace-nowrap",
|
|
2803
|
+
"transition-colors duration-150 h-full",
|
|
2804
|
+
sz.text,
|
|
2805
|
+
sz.pad,
|
|
2806
|
+
fullWidth ? "flex-1" : "",
|
|
2807
|
+
// Resting: muted text, transparent. Hover lifts the text.
|
|
2808
|
+
"text-foreground-secondary hover:text-foreground",
|
|
2809
|
+
// Active: surface-white pill + accent text + subtle shadow.
|
|
2810
|
+
"data-[state=on]:bg-surface data-[state=on]:text-accent data-[state=on]:shadow-sm",
|
|
2811
|
+
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
2812
|
+
"disabled:opacity-40 disabled:cursor-not-allowed"
|
|
2813
|
+
].filter(Boolean).join(" "),
|
|
2814
|
+
children: [
|
|
2815
|
+
opt.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: opt.icon }),
|
|
2816
|
+
opt.label
|
|
2817
|
+
]
|
|
2818
|
+
},
|
|
2819
|
+
opt.value
|
|
2820
|
+
))
|
|
2821
|
+
}
|
|
2822
|
+
)
|
|
2823
|
+
]
|
|
2824
|
+
}
|
|
2825
|
+
);
|
|
2826
|
+
}
|
|
2827
|
+
|
|
2828
|
+
// src/components/core/scheduler.utils.ts
|
|
2829
|
+
var MONTHS2 = [
|
|
2830
|
+
"January",
|
|
2831
|
+
"February",
|
|
2832
|
+
"March",
|
|
2833
|
+
"April",
|
|
2834
|
+
"May",
|
|
2835
|
+
"June",
|
|
2836
|
+
"July",
|
|
2837
|
+
"August",
|
|
2838
|
+
"September",
|
|
2839
|
+
"October",
|
|
2840
|
+
"November",
|
|
2841
|
+
"December"
|
|
2842
|
+
];
|
|
2843
|
+
var MONTHS_SHORT = MONTHS2.map((m) => m.slice(0, 3));
|
|
2844
|
+
var WEEKDAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2845
|
+
var toDate = (d) => d instanceof Date ? d : new Date(d);
|
|
2846
|
+
var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2847
|
+
var addDays = (d, n) => {
|
|
2848
|
+
const x = new Date(d);
|
|
2849
|
+
x.setDate(x.getDate() + n);
|
|
2850
|
+
return x;
|
|
2851
|
+
};
|
|
2852
|
+
var addMonths2 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
2853
|
+
var sameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2854
|
+
var isToday = (d) => sameDay2(d, /* @__PURE__ */ new Date());
|
|
2855
|
+
var isSameMonth = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
2856
|
+
var startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
2857
|
+
var endOfMonth = (d) => new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
2858
|
+
var startOfWeek = (d, weekStartsOn) => {
|
|
2859
|
+
const x = startOfDay2(d);
|
|
2860
|
+
const diff = (x.getDay() - weekStartsOn + 7) % 7;
|
|
2861
|
+
return addDays(x, -diff);
|
|
2862
|
+
};
|
|
2863
|
+
var buildMonthGrid = (cursor, weekStartsOn) => {
|
|
2864
|
+
const start = startOfWeek(startOfMonth(cursor), weekStartsOn);
|
|
2865
|
+
return Array.from({ length: 42 }, (_, i) => addDays(start, i));
|
|
2866
|
+
};
|
|
2867
|
+
var getWeekDays = (cursor, weekStartsOn) => {
|
|
2868
|
+
const start = startOfWeek(cursor, weekStartsOn);
|
|
2869
|
+
return Array.from({ length: 7 }, (_, i) => addDays(start, i));
|
|
2870
|
+
};
|
|
2871
|
+
var monthRange = (cursor) => ({
|
|
2872
|
+
from: startOfMonth(cursor),
|
|
2873
|
+
to: endOfMonth(cursor)
|
|
2874
|
+
});
|
|
2875
|
+
var weekRange = (cursor, weekStartsOn) => {
|
|
2876
|
+
const from = startOfWeek(cursor, weekStartsOn);
|
|
2877
|
+
return { from, to: addDays(from, 6) };
|
|
2878
|
+
};
|
|
2879
|
+
var weekdayLabels = (weekStartsOn) => Array.from({ length: 7 }, (_, i) => WEEKDAYS2[(i + weekStartsOn) % 7]);
|
|
2880
|
+
var monthYearLabel = (d) => `${MONTHS2[d.getMonth()]} ${d.getFullYear()}`;
|
|
2881
|
+
var weekLabel = (cursor, weekStartsOn) => {
|
|
2882
|
+
const from = startOfWeek(cursor, weekStartsOn);
|
|
2883
|
+
const to = addDays(from, 6);
|
|
2884
|
+
const m = (d) => MONTHS2[d.getMonth()].slice(0, 3);
|
|
2885
|
+
if (from.getMonth() === to.getMonth()) {
|
|
2886
|
+
return `${m(from)} ${from.getDate()} \u2013 ${to.getDate()}, ${to.getFullYear()}`;
|
|
2887
|
+
}
|
|
2888
|
+
const yearPart = from.getFullYear() === to.getFullYear() ? `${to.getFullYear()}` : "";
|
|
2889
|
+
return `${m(from)} ${from.getDate()} \u2013 ${m(to)} ${to.getDate()}${yearPart ? `, ${yearPart}` : `, ${from.getFullYear()}/${to.getFullYear()}`}`;
|
|
2890
|
+
};
|
|
2891
|
+
var minutesIntoDay = (d) => d.getHours() * 60 + d.getMinutes();
|
|
2892
|
+
var hourLabel = (hour) => `${String(hour).padStart(2, "0")}:00`;
|
|
2893
|
+
var timeLabel = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
2894
|
+
var normalize = (e) => {
|
|
2895
|
+
const start = toDate(e.start);
|
|
2896
|
+
const end = e.end ? toDate(e.end) : new Date(start.getTime() + 36e5);
|
|
2897
|
+
return { ...e, start, end };
|
|
2898
|
+
};
|
|
2899
|
+
var Spinner2 = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-5 w-5 animate-spin text-accent", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.755 10.059a7.5 7.5 0 0112.548-3.364l1.903 1.903h-3.183a.75.75 0 100 1.5h4.992a.75.75 0 00.75-.75V4.356a.75.75 0 00-1.5 0v3.18l-1.9-1.9A9 9 0 003.306 9.67a.75.75 0 101.45.388zm15.408 3.352a.75.75 0 00-.919.53 7.5 7.5 0 01-12.548 3.364l-1.902-1.903h3.183a.75.75 0 000-1.5H2.984a.75.75 0 00-.75.75v4.992a.75.75 0 001.5 0v-3.18l1.9 1.9a9 9 0 0015.059-4.035.75.75 0 00-.53-.918z" }) });
|
|
2900
|
+
var Plus = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12h14" }) });
|
|
2901
|
+
var Chevron4 = ({ dir }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: dir === "left" ? "M15 19l-7-7 7-7" : "M9 5l7 7-7 7" }) });
|
|
2902
|
+
function Scheduler({
|
|
2903
|
+
events: controlledEvents,
|
|
2904
|
+
loadEvents,
|
|
2905
|
+
defaultView = "month",
|
|
2906
|
+
defaultDate,
|
|
2907
|
+
weekStartsOn = 0,
|
|
2908
|
+
dayHours = [0, 24],
|
|
2909
|
+
hourHeight = 48,
|
|
2910
|
+
onSelectSlot,
|
|
2911
|
+
onSelectEvent,
|
|
2912
|
+
onNewEvent,
|
|
2913
|
+
className = "",
|
|
2914
|
+
style
|
|
2915
|
+
}) {
|
|
2916
|
+
const reduced = useReducedMotion();
|
|
2917
|
+
const [view, setView] = useState(defaultView);
|
|
2918
|
+
const [cursor, setCursor] = useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2919
|
+
const [loaded, setLoaded] = useState([]);
|
|
2920
|
+
const [loading, setLoading] = useState(false);
|
|
2921
|
+
const [dir, setDir] = useState(0);
|
|
2922
|
+
const loaderRef = useRef(loadEvents);
|
|
2923
|
+
loaderRef.current = loadEvents;
|
|
2924
|
+
const range = useMemo(
|
|
2925
|
+
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2926
|
+
[view, cursor, weekStartsOn]
|
|
2927
|
+
);
|
|
2928
|
+
const fromKey = range.from.getTime();
|
|
2929
|
+
const toKey = range.to.getTime();
|
|
2930
|
+
useEffect(() => {
|
|
2931
|
+
const loader = loaderRef.current;
|
|
2932
|
+
if (!loader) return;
|
|
2933
|
+
let cancelled = false;
|
|
2934
|
+
setLoading(true);
|
|
2935
|
+
Promise.resolve(loader({ from: new Date(fromKey), to: new Date(toKey) }, view)).then((evts) => {
|
|
2936
|
+
if (!cancelled) setLoaded(evts);
|
|
2937
|
+
}).catch(() => {
|
|
2938
|
+
if (!cancelled) setLoaded([]);
|
|
2939
|
+
}).finally(() => {
|
|
2940
|
+
if (!cancelled) setLoading(false);
|
|
2941
|
+
});
|
|
2942
|
+
return () => {
|
|
2943
|
+
cancelled = true;
|
|
2944
|
+
};
|
|
2945
|
+
}, [fromKey, toKey, view]);
|
|
2946
|
+
const events = useMemo(
|
|
2947
|
+
() => (controlledEvents ?? loaded).map(normalize),
|
|
2948
|
+
[controlledEvents, loaded]
|
|
2949
|
+
);
|
|
2950
|
+
const go = useCallback((delta) => {
|
|
2951
|
+
setDir(delta);
|
|
2952
|
+
setCursor((c) => view === "month" ? addMonths2(c, delta) : addDays(c, delta * 7));
|
|
2953
|
+
}, [view]);
|
|
2954
|
+
const goToday = useCallback(() => {
|
|
2955
|
+
setDir(0);
|
|
2956
|
+
setCursor(/* @__PURE__ */ new Date());
|
|
2957
|
+
}, []);
|
|
2958
|
+
const title = view === "month" ? monthYearLabel(cursor) : weekLabel(cursor, weekStartsOn);
|
|
2959
|
+
const slide = reduced ? { duration: 0 } : { duration: 0.22, ease: [0.16, 1, 0.3, 1] };
|
|
2960
|
+
return /* @__PURE__ */ jsxs(
|
|
2961
|
+
"div",
|
|
2962
|
+
{
|
|
2963
|
+
className: ["flex flex-col overflow-hidden rounded-xl border border-border bg-surface", className].filter(Boolean).join(" "),
|
|
2964
|
+
style,
|
|
2965
|
+
children: [
|
|
2966
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3", children: [
|
|
2967
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2968
|
+
/* @__PURE__ */ jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "left" }), title: "Previous", onClick: () => go(-1) }),
|
|
2969
|
+
/* @__PURE__ */ jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "right" }), title: "Next", onClick: () => go(1) }),
|
|
2970
|
+
/* @__PURE__ */ jsx(Button_default, { variant: "ghost", size: "sm", content: "Today", onClick: goToday }),
|
|
2971
|
+
/* @__PURE__ */ jsx(
|
|
2972
|
+
MonthYearPicker,
|
|
2973
|
+
{
|
|
2974
|
+
label: title,
|
|
2975
|
+
cursor,
|
|
2976
|
+
onPick: (d) => {
|
|
2977
|
+
setDir(0);
|
|
2978
|
+
setCursor(d);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
),
|
|
2982
|
+
loading && /* @__PURE__ */ jsx(Spinner2, {})
|
|
2983
|
+
] }),
|
|
2984
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2985
|
+
/* @__PURE__ */ jsx(
|
|
2986
|
+
SegmentedControl,
|
|
2987
|
+
{
|
|
2988
|
+
size: "sm",
|
|
2989
|
+
"aria-label": "Calendar view",
|
|
2990
|
+
value: view,
|
|
2991
|
+
onChange: (v) => setView(v),
|
|
2992
|
+
options: [{ value: "month", label: "Month" }, { value: "week", label: "Week" }]
|
|
2993
|
+
}
|
|
2994
|
+
),
|
|
2995
|
+
onNewEvent && /* @__PURE__ */ jsx(Button_default, { size: "sm", icon: /* @__PURE__ */ jsx(Plus, {}), content: "New event", onClick: onNewEvent })
|
|
2996
|
+
] })
|
|
2997
|
+
] }),
|
|
2998
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
2999
|
+
motion.div,
|
|
3000
|
+
{
|
|
3001
|
+
initial: { opacity: 0, x: reduced ? 0 : dir * 24 },
|
|
3002
|
+
animate: { opacity: 1, x: 0 },
|
|
3003
|
+
transition: slide,
|
|
3004
|
+
className: "h-full",
|
|
3005
|
+
children: view === "month" ? /* @__PURE__ */ jsx(
|
|
3006
|
+
MonthView,
|
|
3007
|
+
{
|
|
3008
|
+
cursor,
|
|
3009
|
+
weekStartsOn,
|
|
3010
|
+
events,
|
|
3011
|
+
onSelectSlot,
|
|
3012
|
+
onSelectEvent
|
|
3013
|
+
}
|
|
3014
|
+
) : /* @__PURE__ */ jsx(
|
|
3015
|
+
WeekView,
|
|
3016
|
+
{
|
|
3017
|
+
cursor,
|
|
3018
|
+
weekStartsOn,
|
|
3019
|
+
events,
|
|
3020
|
+
dayHours,
|
|
3021
|
+
hourHeight,
|
|
3022
|
+
onSelectSlot,
|
|
3023
|
+
onSelectEvent
|
|
3024
|
+
}
|
|
3025
|
+
)
|
|
3026
|
+
},
|
|
3027
|
+
`${view}-${range.from.getTime()}`
|
|
3028
|
+
) })
|
|
3029
|
+
]
|
|
3030
|
+
}
|
|
3031
|
+
);
|
|
3032
|
+
}
|
|
3033
|
+
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3034
|
+
const [open, setOpen] = useState(false);
|
|
3035
|
+
const [viewYear, setViewYear] = useState(cursor.getFullYear());
|
|
3036
|
+
useEffect(() => {
|
|
3037
|
+
if (open) setViewYear(cursor.getFullYear());
|
|
3038
|
+
}, [open, cursor]);
|
|
3039
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
|
|
3040
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
3041
|
+
"button",
|
|
3042
|
+
{
|
|
3043
|
+
type: "button",
|
|
3044
|
+
className: "group ml-1 inline-flex items-center gap-1.5 rounded-md px-1.5 py-0.5 text-lg font-semibold tracking-tight text-foreground transition-colors hover:bg-background focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3045
|
+
children: [
|
|
3046
|
+
label,
|
|
3047
|
+
/* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4 text-foreground-muted transition-transform duration-150 group-data-[state=open]:rotate-180", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9l6 6 6-6" }) })
|
|
3048
|
+
]
|
|
3049
|
+
}
|
|
3050
|
+
) }),
|
|
3051
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
|
|
3052
|
+
Popover.Content,
|
|
3053
|
+
{
|
|
3054
|
+
align: "start",
|
|
3055
|
+
sideOffset: 8,
|
|
3056
|
+
className: [
|
|
3057
|
+
"z-[400] w-64 rounded-lg border border-border bg-surface p-3 shadow-lg",
|
|
3058
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
3059
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
3060
|
+
].join(" "),
|
|
3061
|
+
children: [
|
|
3062
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
|
|
3063
|
+
/* @__PURE__ */ jsx(IconButton, { size: "sm", type: "bordered", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "left" }), title: "Previous year", onClick: () => setViewYear((y) => y - 1) }),
|
|
3064
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-foreground", children: viewYear }),
|
|
3065
|
+
/* @__PURE__ */ jsx(IconButton, { size: "sm", type: "bordered", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "right" }), title: "Next year", onClick: () => setViewYear((y) => y + 1) })
|
|
3066
|
+
] }),
|
|
3067
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1", children: MONTHS_SHORT.map((m, i) => {
|
|
3068
|
+
const current = i === cursor.getMonth() && viewYear === cursor.getFullYear();
|
|
3069
|
+
return /* @__PURE__ */ jsx(
|
|
3070
|
+
"button",
|
|
3071
|
+
{
|
|
3072
|
+
type: "button",
|
|
3073
|
+
onClick: () => {
|
|
3074
|
+
onPick(new Date(viewYear, i, 1));
|
|
3075
|
+
setOpen(false);
|
|
3076
|
+
},
|
|
3077
|
+
className: [
|
|
3078
|
+
"rounded-md px-2 py-1.5 text-sm transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3079
|
+
current ? "bg-accent font-semibold text-accent-fg" : "text-foreground hover:bg-background"
|
|
3080
|
+
].join(" "),
|
|
3081
|
+
children: m
|
|
3082
|
+
},
|
|
3083
|
+
m
|
|
3084
|
+
);
|
|
3085
|
+
}) })
|
|
3086
|
+
]
|
|
3087
|
+
}
|
|
3088
|
+
) })
|
|
3089
|
+
] });
|
|
3090
|
+
}
|
|
3091
|
+
var MAX_CHIPS = 3;
|
|
3092
|
+
function MonthView({
|
|
3093
|
+
cursor,
|
|
3094
|
+
weekStartsOn,
|
|
3095
|
+
events,
|
|
3096
|
+
onSelectSlot,
|
|
3097
|
+
onSelectEvent
|
|
3098
|
+
}) {
|
|
3099
|
+
const grid = useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3100
|
+
const labels = weekdayLabels(weekStartsOn);
|
|
3101
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3102
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 border-b border-border", children: labels.map((l) => /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-center text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: l }, l)) }),
|
|
3103
|
+
/* @__PURE__ */ jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-6", children: grid.map((day, i) => {
|
|
3104
|
+
const inMonth = isSameMonth(day, cursor);
|
|
3105
|
+
const dayEvents = events.filter((e) => sameDay2(e.start, day));
|
|
3106
|
+
const today = isToday(day);
|
|
3107
|
+
return /* @__PURE__ */ jsxs(
|
|
3108
|
+
"button",
|
|
3109
|
+
{
|
|
3110
|
+
type: "button",
|
|
3111
|
+
onClick: () => onSelectSlot?.(day),
|
|
3112
|
+
className: [
|
|
3113
|
+
"group flex min-h-[5rem] flex-col gap-1 border-b border-r border-border p-1.5 text-left transition-colors",
|
|
3114
|
+
"[&:nth-child(7n)]:border-r-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
|
|
3115
|
+
// surface===surface-raised in light mode, so hover lifts toward the
|
|
3116
|
+
// cool chart-mist background instead (a visible, on-brand tint).
|
|
3117
|
+
inMonth ? "bg-surface hover:bg-background" : "bg-background hover:bg-surface"
|
|
3118
|
+
].join(" "),
|
|
3119
|
+
children: [
|
|
3120
|
+
/* @__PURE__ */ jsx(
|
|
3121
|
+
"span",
|
|
3122
|
+
{
|
|
3123
|
+
className: [
|
|
3124
|
+
"flex h-6 w-6 items-center justify-center self-start rounded-full text-xs tabular-nums",
|
|
3125
|
+
today ? "bg-accent font-semibold text-accent-fg" : inMonth ? "text-foreground" : "text-foreground-muted"
|
|
3126
|
+
].join(" "),
|
|
3127
|
+
children: day.getDate()
|
|
3128
|
+
}
|
|
3129
|
+
),
|
|
3130
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3131
|
+
dayEvents.slice(0, MAX_CHIPS).map((e) => /* @__PURE__ */ jsx(EventChip, { event: e, onSelect: onSelectEvent }, e.id)),
|
|
3132
|
+
dayEvents.length > MAX_CHIPS && /* @__PURE__ */ jsxs("span", { className: "px-1 text-[11px] font-medium text-foreground-muted", children: [
|
|
3133
|
+
"+",
|
|
3134
|
+
dayEvents.length - MAX_CHIPS,
|
|
3135
|
+
" more"
|
|
3136
|
+
] })
|
|
3137
|
+
] })
|
|
3138
|
+
]
|
|
3139
|
+
},
|
|
3140
|
+
i
|
|
3141
|
+
);
|
|
3142
|
+
}) })
|
|
3143
|
+
] });
|
|
3144
|
+
}
|
|
3145
|
+
function EventChip({ event, onSelect }) {
|
|
3146
|
+
const color = event.color ?? "var(--color-accent)";
|
|
3147
|
+
return /* @__PURE__ */ jsxs(
|
|
3148
|
+
"button",
|
|
3149
|
+
{
|
|
3150
|
+
type: "button",
|
|
3151
|
+
onClick: (e) => {
|
|
3152
|
+
e.stopPropagation();
|
|
3153
|
+
onSelect?.(event);
|
|
3154
|
+
},
|
|
3155
|
+
title: `${event.title} \xB7 ${timeLabel(event.start)}`,
|
|
3156
|
+
className: "flex items-center gap-1.5 truncate rounded px-1 py-0.5 text-left text-[11px] font-medium text-foreground hover:opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3157
|
+
children: [
|
|
3158
|
+
/* @__PURE__ */ jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
3159
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: event.title })
|
|
3160
|
+
]
|
|
3161
|
+
}
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
function WeekView({
|
|
3165
|
+
cursor,
|
|
3166
|
+
weekStartsOn,
|
|
3167
|
+
events,
|
|
3168
|
+
dayHours,
|
|
3169
|
+
hourHeight,
|
|
3170
|
+
onSelectSlot,
|
|
3171
|
+
onSelectEvent
|
|
3172
|
+
}) {
|
|
3173
|
+
const days = useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3174
|
+
const labels = useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
|
|
3175
|
+
const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
|
|
3176
|
+
const [startHour, endHour] = dayHours;
|
|
3177
|
+
const hours = useMemo(
|
|
3178
|
+
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3179
|
+
[startHour, endHour]
|
|
3180
|
+
);
|
|
3181
|
+
const spanMinutes = (endHour - startHour) * 60;
|
|
3182
|
+
const gridHeight = hours.length * hourHeight;
|
|
3183
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
|
|
3184
|
+
/* @__PURE__ */ jsxs("div", { className: "grid border-b border-border", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)` }, children: [
|
|
3185
|
+
/* @__PURE__ */ jsx("div", { className: "border-r border-border" }),
|
|
3186
|
+
days.map((d) => /* @__PURE__ */ jsxs("div", { className: "border-r border-border px-1 py-1.5 text-center last:border-r-0", children: [
|
|
3187
|
+
/* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: dow(d) }),
|
|
3188
|
+
/* @__PURE__ */ jsx("div", { className: ["mx-auto mt-0.5 flex h-6 w-6 items-center justify-center rounded-full text-xs tabular-nums", isToday(d) ? "bg-accent font-semibold text-accent-fg" : "text-foreground"].join(" "), children: d.getDate() })
|
|
3189
|
+
] }, d.getTime()))
|
|
3190
|
+
] }),
|
|
3191
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "grid", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)`, height: gridHeight }, children: [
|
|
3192
|
+
/* @__PURE__ */ jsx("div", { className: "relative border-r border-border", children: hours.map((h, i) => /* @__PURE__ */ jsx("div", { className: "absolute right-1 -translate-y-1/2 text-[10px] tabular-nums text-foreground-muted", style: { top: i * hourHeight }, children: i === 0 ? "" : hourLabel(h) }, h)) }),
|
|
3193
|
+
days.map((day) => {
|
|
3194
|
+
const dayEvents = events.filter((e) => sameDay2(e.start, day) && !e.allDay);
|
|
3195
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative border-r border-border last:border-r-0", children: [
|
|
3196
|
+
hours.map((h, i) => /* @__PURE__ */ jsx(
|
|
3197
|
+
"button",
|
|
3198
|
+
{
|
|
3199
|
+
type: "button",
|
|
3200
|
+
"aria-label": `${dow(day)} ${day.getDate()} ${hourLabel(h)}`,
|
|
3201
|
+
onClick: () => onSelectSlot?.(new Date(day.getFullYear(), day.getMonth(), day.getDate(), h)),
|
|
3202
|
+
className: "absolute left-0 right-0 border-b border-border hover:bg-background focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
|
|
3203
|
+
style: { top: i * hourHeight, height: hourHeight }
|
|
3204
|
+
},
|
|
3205
|
+
h
|
|
3206
|
+
)),
|
|
3207
|
+
dayEvents.map((e) => {
|
|
3208
|
+
const top = (minutesIntoDay(e.start) - startHour * 60) / spanMinutes * gridHeight;
|
|
3209
|
+
const durMin = Math.max(20, (e.end.getTime() - e.start.getTime()) / 6e4);
|
|
3210
|
+
const height = durMin / spanMinutes * gridHeight;
|
|
3211
|
+
const color = e.color ?? "var(--color-accent)";
|
|
3212
|
+
return /* @__PURE__ */ jsxs(
|
|
3213
|
+
"button",
|
|
3214
|
+
{
|
|
3215
|
+
type: "button",
|
|
3216
|
+
onClick: (ev) => {
|
|
3217
|
+
ev.stopPropagation();
|
|
3218
|
+
onSelectEvent?.(e);
|
|
3219
|
+
},
|
|
3220
|
+
title: `${e.title} \xB7 ${timeLabel(e.start)}\u2013${timeLabel(e.end)}`,
|
|
3221
|
+
className: "absolute left-0.5 right-0.5 overflow-hidden rounded-md border px-1.5 py-0.5 text-left text-[11px] leading-tight text-foreground shadow-sm transition-shadow hover:shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3222
|
+
style: {
|
|
3223
|
+
top: Math.max(0, top),
|
|
3224
|
+
height,
|
|
3225
|
+
backgroundColor: `color-mix(in oklab, ${color} 14%, var(--color-surface))`,
|
|
3226
|
+
borderColor: `color-mix(in oklab, ${color} 40%, var(--color-surface))`
|
|
3227
|
+
},
|
|
3228
|
+
children: [
|
|
3229
|
+
/* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: e.title }),
|
|
3230
|
+
/* @__PURE__ */ jsx("div", { className: "truncate", style: { color }, children: timeLabel(e.start) })
|
|
3231
|
+
]
|
|
2593
3232
|
},
|
|
2594
|
-
|
|
2595
|
-
)
|
|
2596
|
-
|
|
2597
|
-
},
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
}) })
|
|
3233
|
+
e.id
|
|
3234
|
+
);
|
|
3235
|
+
})
|
|
3236
|
+
] }, day.getTime());
|
|
3237
|
+
})
|
|
3238
|
+
] }) })
|
|
2601
3239
|
] });
|
|
2602
3240
|
}
|
|
2603
3241
|
function DefaultIllustration() {
|
|
@@ -3236,134 +3874,6 @@ function useFieldArray(name) {
|
|
|
3236
3874
|
replace: (items) => store.setValue(name, items, { validate: false })
|
|
3237
3875
|
};
|
|
3238
3876
|
}
|
|
3239
|
-
var FIELD_SIZE = {
|
|
3240
|
-
sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
|
|
3241
|
-
md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
|
|
3242
|
-
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
3243
|
-
};
|
|
3244
|
-
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
|
|
3245
|
-
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
|
|
3246
|
-
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
|
|
3247
|
-
var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
|
|
3248
|
-
function fieldShell({
|
|
3249
|
-
size = "md",
|
|
3250
|
-
hasError = false,
|
|
3251
|
-
disabled = false,
|
|
3252
|
-
focusWithin = false,
|
|
3253
|
-
sized = true
|
|
3254
|
-
} = {}) {
|
|
3255
|
-
const s = FIELD_SIZE[size];
|
|
3256
|
-
return [
|
|
3257
|
-
"w-full rounded-lg border bg-surface text-foreground",
|
|
3258
|
-
"transition-[color,box-shadow,border-color] duration-150",
|
|
3259
|
-
s.text,
|
|
3260
|
-
sized ? `${s.control} ${s.padX}` : "",
|
|
3261
|
-
// resting border
|
|
3262
|
-
hasError ? "border-status-error" : "border-border",
|
|
3263
|
-
// hover (only when interactive + no error)
|
|
3264
|
-
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
3265
|
-
// focus
|
|
3266
|
-
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
3267
|
-
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
3268
|
-
// placeholder colour for native inputs
|
|
3269
|
-
"placeholder:text-foreground-muted"
|
|
3270
|
-
].filter(Boolean).join(" ");
|
|
3271
|
-
}
|
|
3272
|
-
function FieldHelpIcon({ text }) {
|
|
3273
|
-
return /* @__PURE__ */ jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsx(
|
|
3274
|
-
"button",
|
|
3275
|
-
{
|
|
3276
|
-
type: "button",
|
|
3277
|
-
"aria-label": "More information",
|
|
3278
|
-
className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
|
|
3279
|
-
children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
|
|
3280
|
-
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
|
|
3281
|
-
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
|
|
3282
|
-
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
|
|
3283
|
-
] })
|
|
3284
|
-
}
|
|
3285
|
-
) });
|
|
3286
|
-
}
|
|
3287
|
-
function FieldLabel({
|
|
3288
|
-
label,
|
|
3289
|
-
htmlFor,
|
|
3290
|
-
required,
|
|
3291
|
-
helperText,
|
|
3292
|
-
horizontal = false,
|
|
3293
|
-
align = "start",
|
|
3294
|
-
style,
|
|
3295
|
-
width,
|
|
3296
|
-
className = ""
|
|
3297
|
-
}) {
|
|
3298
|
-
if (label == null && helperText == null) return null;
|
|
3299
|
-
return /* @__PURE__ */ jsxs(
|
|
3300
|
-
"div",
|
|
3301
|
-
{
|
|
3302
|
-
style: { width: horizontal ? width : void 0, ...style },
|
|
3303
|
-
className: [
|
|
3304
|
-
"flex items-center gap-1",
|
|
3305
|
-
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
3306
|
-
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
3307
|
-
// on the row's items-center to line up with a short control.
|
|
3308
|
-
horizontal && align === "start" ? "mt-2" : "",
|
|
3309
|
-
className
|
|
3310
|
-
].filter(Boolean).join(" "),
|
|
3311
|
-
children: [
|
|
3312
|
-
label != null && /* @__PURE__ */ jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
|
|
3313
|
-
label,
|
|
3314
|
-
required && /* @__PURE__ */ jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
3315
|
-
] }),
|
|
3316
|
-
helperText != null && /* @__PURE__ */ jsx(FieldHelpIcon, { text: helperText })
|
|
3317
|
-
]
|
|
3318
|
-
}
|
|
3319
|
-
);
|
|
3320
|
-
}
|
|
3321
|
-
function Field({
|
|
3322
|
-
label,
|
|
3323
|
-
htmlFor,
|
|
3324
|
-
errorId,
|
|
3325
|
-
errorMessage,
|
|
3326
|
-
layout = "vertical",
|
|
3327
|
-
required,
|
|
3328
|
-
helperText,
|
|
3329
|
-
labelAlign = "start",
|
|
3330
|
-
labelStyle,
|
|
3331
|
-
labelWidth,
|
|
3332
|
-
className = "",
|
|
3333
|
-
children
|
|
3334
|
-
}) {
|
|
3335
|
-
const hasError = errorMessage != null;
|
|
3336
|
-
const horizontal = layout === "horizontal";
|
|
3337
|
-
return /* @__PURE__ */ jsxs(
|
|
3338
|
-
"div",
|
|
3339
|
-
{
|
|
3340
|
-
className: [
|
|
3341
|
-
"flex",
|
|
3342
|
-
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
3343
|
-
className
|
|
3344
|
-
].filter(Boolean).join(" "),
|
|
3345
|
-
children: [
|
|
3346
|
-
/* @__PURE__ */ jsx(
|
|
3347
|
-
FieldLabel,
|
|
3348
|
-
{
|
|
3349
|
-
label,
|
|
3350
|
-
htmlFor,
|
|
3351
|
-
required,
|
|
3352
|
-
helperText,
|
|
3353
|
-
horizontal,
|
|
3354
|
-
align: labelAlign,
|
|
3355
|
-
style: labelStyle,
|
|
3356
|
-
width: labelWidth
|
|
3357
|
-
}
|
|
3358
|
-
),
|
|
3359
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
3360
|
-
children,
|
|
3361
|
-
hasError && /* @__PURE__ */ jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
3362
|
-
] })
|
|
3363
|
-
]
|
|
3364
|
-
}
|
|
3365
|
-
);
|
|
3366
|
-
}
|
|
3367
3877
|
function TextInput({
|
|
3368
3878
|
value,
|
|
3369
3879
|
onChange,
|
|
@@ -3503,8 +4013,8 @@ function expiryError(value, now = /* @__PURE__ */ new Date()) {
|
|
|
3503
4013
|
const mm = Number(m[1]);
|
|
3504
4014
|
const yy = Number(m[2]);
|
|
3505
4015
|
if (mm < 1 || mm > 12) return "Invalid month";
|
|
3506
|
-
const
|
|
3507
|
-
if (
|
|
4016
|
+
const endOfMonth2 = new Date(2e3 + yy, mm, 0, 23, 59, 59, 999);
|
|
4017
|
+
if (endOfMonth2 < now) return "Card has expired";
|
|
3508
4018
|
return void 0;
|
|
3509
4019
|
}
|
|
3510
4020
|
function cvvError(value, cardNumber) {
|
|
@@ -4654,7 +5164,7 @@ function Wizard({
|
|
|
4654
5164
|
] });
|
|
4655
5165
|
}
|
|
4656
5166
|
var SearchIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) });
|
|
4657
|
-
var SearchInput =
|
|
5167
|
+
var SearchInput = React29.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
|
|
4658
5168
|
return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxs(
|
|
4659
5169
|
"div",
|
|
4660
5170
|
{
|
|
@@ -5155,7 +5665,7 @@ function TableBody({
|
|
|
5155
5665
|
return /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => {
|
|
5156
5666
|
const rowKey = getRowKey(row, i);
|
|
5157
5667
|
const isExpanded = expanded.has(rowKey);
|
|
5158
|
-
return /* @__PURE__ */ jsxs(
|
|
5668
|
+
return /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
5159
5669
|
/* @__PURE__ */ jsxs(
|
|
5160
5670
|
"tr",
|
|
5161
5671
|
{
|
|
@@ -5699,8 +6209,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
5699
6209
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
5700
6210
|
return /* @__PURE__ */ jsx("div", { className: ["min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
|
|
5701
6211
|
}
|
|
5702
|
-
var elementsOfType = (children, type) =>
|
|
5703
|
-
(c) =>
|
|
6212
|
+
var elementsOfType = (children, type) => React29.Children.toArray(children).filter(
|
|
6213
|
+
(c) => React29.isValidElement(c) && c.type === type
|
|
5704
6214
|
);
|
|
5705
6215
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsx(
|
|
5706
6216
|
"svg",
|
|
@@ -5737,9 +6247,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
5737
6247
|
);
|
|
5738
6248
|
}
|
|
5739
6249
|
function MobilePanel({ panel, onNavigate }) {
|
|
5740
|
-
const nodes =
|
|
6250
|
+
const nodes = React29.Children.toArray(panel.props.children);
|
|
5741
6251
|
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
5742
|
-
if (!
|
|
6252
|
+
if (!React29.isValidElement(node)) return null;
|
|
5743
6253
|
const el = node;
|
|
5744
6254
|
if (el.type === MegaMenuSection) {
|
|
5745
6255
|
const { title, children } = el.props;
|
|
@@ -5949,7 +6459,7 @@ function tokenValid(token) {
|
|
|
5949
6459
|
return exp * 1e3 > Date.now();
|
|
5950
6460
|
}
|
|
5951
6461
|
var has = (have, need, all) => all ? need.every((n) => have?.includes(n)) : need.some((n) => have?.includes(n));
|
|
5952
|
-
var
|
|
6462
|
+
var Spinner3 = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-6 w-6 animate-spin text-accent", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.755 10.059a7.5 7.5 0 0112.548-3.364l1.903 1.903h-3.183a.75.75 0 100 1.5h4.992a.75.75 0 00.75-.75V4.356a.75.75 0 00-1.5 0v3.18l-1.9-1.9A9 9 0 003.306 9.67a.75.75 0 101.45.388zm15.408 3.352a.75.75 0 00-.919.53 7.5 7.5 0 01-12.548 3.364l-1.902-1.903h3.183a.75.75 0 000-1.5H2.984a.75.75 0 00-.75.75v4.992a.75.75 0 001.5 0v-3.18l1.9 1.9a9 9 0 0015.059-4.035.75.75 0 00-.53-.918z" }) });
|
|
5953
6463
|
function SecureLayout({
|
|
5954
6464
|
children,
|
|
5955
6465
|
isAuthenticated,
|
|
@@ -6025,7 +6535,7 @@ function SecureLayout({
|
|
|
6025
6535
|
]);
|
|
6026
6536
|
if (state === "checking") {
|
|
6027
6537
|
if (loadingFallback === null) return null;
|
|
6028
|
-
return /* @__PURE__ */ jsx("div", { className: ["flex min-h-[8rem] items-center justify-center", className].filter(Boolean).join(" "), children: loadingFallback !== void 0 ? loadingFallback : /* @__PURE__ */ jsx(
|
|
6538
|
+
return /* @__PURE__ */ jsx("div", { className: ["flex min-h-[8rem] items-center justify-center", className].filter(Boolean).join(" "), children: loadingFallback !== void 0 ? loadingFallback : /* @__PURE__ */ jsx(Spinner3, {}) });
|
|
6029
6539
|
}
|
|
6030
6540
|
if (state === "denied") {
|
|
6031
6541
|
if (fallback === null) return null;
|
|
@@ -6148,7 +6658,7 @@ function ThemeProvider({
|
|
|
6148
6658
|
className = "",
|
|
6149
6659
|
style
|
|
6150
6660
|
}) {
|
|
6151
|
-
const id =
|
|
6661
|
+
const id = React29.useId().replace(/:/g, "");
|
|
6152
6662
|
const scopeClass = `geo-th-${id}`;
|
|
6153
6663
|
const divRef = useRef(null);
|
|
6154
6664
|
useEffect(() => {
|
|
@@ -7259,15 +7769,15 @@ var WEEKDAY_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
|
7259
7769
|
function isSameDay(a, b) {
|
|
7260
7770
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
7261
7771
|
}
|
|
7262
|
-
function
|
|
7772
|
+
function startOfMonth2(d) {
|
|
7263
7773
|
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
7264
7774
|
}
|
|
7265
|
-
function
|
|
7775
|
+
function addDays2(d, n) {
|
|
7266
7776
|
const c = new Date(d);
|
|
7267
7777
|
c.setDate(c.getDate() + n);
|
|
7268
7778
|
return c;
|
|
7269
7779
|
}
|
|
7270
|
-
function
|
|
7780
|
+
function addMonths3(d, n) {
|
|
7271
7781
|
const c = new Date(d);
|
|
7272
7782
|
c.setMonth(c.getMonth() + n);
|
|
7273
7783
|
return c;
|
|
@@ -7279,12 +7789,12 @@ function defaultFormat3(d) {
|
|
|
7279
7789
|
return `${y}-${m}-${day}`;
|
|
7280
7790
|
}
|
|
7281
7791
|
function buildGrid2(viewMonth, weekStartsOn) {
|
|
7282
|
-
const first =
|
|
7792
|
+
const first = startOfMonth2(viewMonth);
|
|
7283
7793
|
const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
7284
|
-
const gridStart =
|
|
7794
|
+
const gridStart = addDays2(first, -startOffset);
|
|
7285
7795
|
const cells = [];
|
|
7286
7796
|
for (let i = 0; i < 42; i++) {
|
|
7287
|
-
const d =
|
|
7797
|
+
const d = addDays2(gridStart, i);
|
|
7288
7798
|
cells.push({ date: d, outside: d.getMonth() !== viewMonth.getMonth() });
|
|
7289
7799
|
}
|
|
7290
7800
|
const rows = [];
|
|
@@ -7315,14 +7825,14 @@ function DatePicker({
|
|
|
7315
7825
|
const errorId = useId();
|
|
7316
7826
|
const hasError = errorMessage != null;
|
|
7317
7827
|
const [open, setOpen] = useState(false);
|
|
7318
|
-
const [viewMonth, setViewMonth] = useState(() =>
|
|
7828
|
+
const [viewMonth, setViewMonth] = useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
7319
7829
|
const [focusDate, setFocusDate] = useState(() => value ?? /* @__PURE__ */ new Date());
|
|
7320
7830
|
const [view, setView] = useState("days");
|
|
7321
7831
|
const gridRef = useRef(null);
|
|
7322
7832
|
useEffect(() => {
|
|
7323
7833
|
if (!open) return;
|
|
7324
7834
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7325
|
-
setViewMonth(
|
|
7835
|
+
setViewMonth(startOfMonth2(target));
|
|
7326
7836
|
setFocusDate(target);
|
|
7327
7837
|
setView("days");
|
|
7328
7838
|
}, [open, value]);
|
|
@@ -7348,9 +7858,9 @@ function DatePicker({
|
|
|
7348
7858
|
};
|
|
7349
7859
|
const onKey = (e) => {
|
|
7350
7860
|
const next = (delta) => {
|
|
7351
|
-
const nd =
|
|
7861
|
+
const nd = addDays2(focusDate, delta);
|
|
7352
7862
|
setFocusDate(nd);
|
|
7353
|
-
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(
|
|
7863
|
+
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(startOfMonth2(nd));
|
|
7354
7864
|
};
|
|
7355
7865
|
if (e.key === "ArrowLeft") {
|
|
7356
7866
|
e.preventDefault();
|
|
@@ -7366,22 +7876,22 @@ function DatePicker({
|
|
|
7366
7876
|
next(7);
|
|
7367
7877
|
} else if (e.key === "PageUp") {
|
|
7368
7878
|
e.preventDefault();
|
|
7369
|
-
const nm =
|
|
7879
|
+
const nm = addMonths3(viewMonth, -1);
|
|
7370
7880
|
setViewMonth(nm);
|
|
7371
|
-
setFocusDate((d) =>
|
|
7881
|
+
setFocusDate((d) => addMonths3(d, -1));
|
|
7372
7882
|
} else if (e.key === "PageDown") {
|
|
7373
7883
|
e.preventDefault();
|
|
7374
|
-
const nm =
|
|
7884
|
+
const nm = addMonths3(viewMonth, 1);
|
|
7375
7885
|
setViewMonth(nm);
|
|
7376
|
-
setFocusDate((d) =>
|
|
7886
|
+
setFocusDate((d) => addMonths3(d, 1));
|
|
7377
7887
|
} else if (e.key === "Home") {
|
|
7378
7888
|
e.preventDefault();
|
|
7379
7889
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7380
|
-
setFocusDate(
|
|
7890
|
+
setFocusDate(addDays2(focusDate, -dow));
|
|
7381
7891
|
} else if (e.key === "End") {
|
|
7382
7892
|
e.preventDefault();
|
|
7383
7893
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7384
|
-
setFocusDate(
|
|
7894
|
+
setFocusDate(addDays2(focusDate, 6 - dow));
|
|
7385
7895
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
7386
7896
|
e.preventDefault();
|
|
7387
7897
|
selectDate(focusDate);
|
|
@@ -7438,7 +7948,7 @@ function DatePicker({
|
|
|
7438
7948
|
{
|
|
7439
7949
|
type: "button",
|
|
7440
7950
|
onClick: () => {
|
|
7441
|
-
if (view === "days") setViewMonth(
|
|
7951
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, -1));
|
|
7442
7952
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() - 1, viewMonth.getMonth(), 1));
|
|
7443
7953
|
else setViewMonth(new Date(viewMonth.getFullYear() - 10, viewMonth.getMonth(), 1));
|
|
7444
7954
|
},
|
|
@@ -7473,7 +7983,7 @@ function DatePicker({
|
|
|
7473
7983
|
{
|
|
7474
7984
|
type: "button",
|
|
7475
7985
|
onClick: () => {
|
|
7476
|
-
if (view === "days") setViewMonth(
|
|
7986
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, 1));
|
|
7477
7987
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() + 1, viewMonth.getMonth(), 1));
|
|
7478
7988
|
else setViewMonth(new Date(viewMonth.getFullYear() + 10, viewMonth.getMonth(), 1));
|
|
7479
7989
|
},
|
|
@@ -7675,102 +8185,6 @@ function TextArea({
|
|
|
7675
8185
|
}
|
|
7676
8186
|
);
|
|
7677
8187
|
}
|
|
7678
|
-
var SIZE5 = {
|
|
7679
|
-
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
7680
|
-
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
7681
|
-
lg: { h: "h-control-lg", text: "text-sm", pad: "px-4" }
|
|
7682
|
-
};
|
|
7683
|
-
function SegmentedControl({
|
|
7684
|
-
options,
|
|
7685
|
-
value,
|
|
7686
|
-
defaultValue,
|
|
7687
|
-
onChange,
|
|
7688
|
-
size = "md",
|
|
7689
|
-
fullWidth = false,
|
|
7690
|
-
disabled,
|
|
7691
|
-
label,
|
|
7692
|
-
layout = "vertical",
|
|
7693
|
-
helperText,
|
|
7694
|
-
className,
|
|
7695
|
-
name,
|
|
7696
|
-
required,
|
|
7697
|
-
errorMessage,
|
|
7698
|
-
"aria-label": ariaLabel
|
|
7699
|
-
}) {
|
|
7700
|
-
const sz = SIZE5[size];
|
|
7701
|
-
const groupId = useId();
|
|
7702
|
-
const errorId = useId();
|
|
7703
|
-
const hasError = errorMessage != null;
|
|
7704
|
-
const isControlled = value !== void 0;
|
|
7705
|
-
const [internal, setInternal] = useState(defaultValue);
|
|
7706
|
-
const current = isControlled ? value : internal;
|
|
7707
|
-
const handle = (v) => {
|
|
7708
|
-
if (!v) return;
|
|
7709
|
-
if (!isControlled) setInternal(v);
|
|
7710
|
-
onChange?.(v);
|
|
7711
|
-
};
|
|
7712
|
-
return /* @__PURE__ */ jsxs(
|
|
7713
|
-
Field,
|
|
7714
|
-
{
|
|
7715
|
-
className,
|
|
7716
|
-
label,
|
|
7717
|
-
htmlFor: groupId,
|
|
7718
|
-
errorId,
|
|
7719
|
-
errorMessage,
|
|
7720
|
-
layout,
|
|
7721
|
-
required,
|
|
7722
|
-
helperText,
|
|
7723
|
-
children: [
|
|
7724
|
-
name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: current ?? "" }),
|
|
7725
|
-
/* @__PURE__ */ jsx(
|
|
7726
|
-
ToggleGroup.Root,
|
|
7727
|
-
{
|
|
7728
|
-
id: groupId,
|
|
7729
|
-
type: "single",
|
|
7730
|
-
value: current,
|
|
7731
|
-
onValueChange: handle,
|
|
7732
|
-
disabled,
|
|
7733
|
-
"aria-label": ariaLabel ?? (typeof label === "string" ? label : void 0),
|
|
7734
|
-
"aria-invalid": hasError || void 0,
|
|
7735
|
-
"aria-describedby": hasError ? errorId : void 0,
|
|
7736
|
-
className: [
|
|
7737
|
-
"inline-flex items-center gap-1 rounded-lg border bg-surface-raised p-1",
|
|
7738
|
-
hasError ? "border-status-error" : "border-border",
|
|
7739
|
-
sz.h,
|
|
7740
|
-
fullWidth ? "flex w-full" : "w-fit",
|
|
7741
|
-
disabled ? "opacity-60 cursor-not-allowed" : ""
|
|
7742
|
-
].filter(Boolean).join(" "),
|
|
7743
|
-
children: options.map((opt) => /* @__PURE__ */ jsxs(
|
|
7744
|
-
ToggleGroup.Item,
|
|
7745
|
-
{
|
|
7746
|
-
value: opt.value,
|
|
7747
|
-
disabled: opt.disabled,
|
|
7748
|
-
className: [
|
|
7749
|
-
"inline-flex items-center justify-center gap-1.5 rounded-md select-none whitespace-nowrap",
|
|
7750
|
-
"transition-colors duration-150 h-full",
|
|
7751
|
-
sz.text,
|
|
7752
|
-
sz.pad,
|
|
7753
|
-
fullWidth ? "flex-1" : "",
|
|
7754
|
-
// Resting: muted text, transparent. Hover lifts the text.
|
|
7755
|
-
"text-foreground-secondary hover:text-foreground",
|
|
7756
|
-
// Active: surface-white pill + accent text + subtle shadow.
|
|
7757
|
-
"data-[state=on]:bg-surface data-[state=on]:text-accent data-[state=on]:shadow-sm",
|
|
7758
|
-
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
7759
|
-
"disabled:opacity-40 disabled:cursor-not-allowed"
|
|
7760
|
-
].filter(Boolean).join(" "),
|
|
7761
|
-
children: [
|
|
7762
|
-
opt.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: opt.icon }),
|
|
7763
|
-
opt.label
|
|
7764
|
-
]
|
|
7765
|
-
},
|
|
7766
|
-
opt.value
|
|
7767
|
-
))
|
|
7768
|
-
}
|
|
7769
|
-
)
|
|
7770
|
-
]
|
|
7771
|
-
}
|
|
7772
|
-
);
|
|
7773
|
-
}
|
|
7774
8188
|
var TRACK_H = { sm: "h-1", md: "h-1.5", lg: "h-2" };
|
|
7775
8189
|
var THUMB = { sm: "h-3.5 w-3.5", md: "h-4 w-4", lg: "h-5 w-5" };
|
|
7776
8190
|
var toArray = (v) => v == null ? void 0 : Array.isArray(v) ? v : [v];
|
|
@@ -8084,7 +8498,7 @@ function OtpInput({
|
|
|
8084
8498
|
emit(valid.join(""));
|
|
8085
8499
|
focusBox(valid.length);
|
|
8086
8500
|
};
|
|
8087
|
-
return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(
|
|
8501
|
+
return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
8088
8502
|
/* @__PURE__ */ jsx(
|
|
8089
8503
|
"input",
|
|
8090
8504
|
{
|
|
@@ -8354,22 +8768,22 @@ function TimePicker({
|
|
|
8354
8768
|
}
|
|
8355
8769
|
var MONTH_NAMES2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
8356
8770
|
var WEEKDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
8357
|
-
var
|
|
8358
|
-
var
|
|
8359
|
-
var
|
|
8771
|
+
var startOfMonth3 = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
8772
|
+
var addMonths4 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
8773
|
+
var addDays3 = (d, n) => {
|
|
8360
8774
|
const c = new Date(d);
|
|
8361
8775
|
c.setDate(c.getDate() + n);
|
|
8362
8776
|
return c;
|
|
8363
8777
|
};
|
|
8364
8778
|
var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
8365
|
-
var
|
|
8779
|
+
var startOfDay3 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8366
8780
|
var defaultFmt = (d) => `${d.getFullYear()}-${`${d.getMonth() + 1}`.padStart(2, "0")}-${`${d.getDate()}`.padStart(2, "0")}`;
|
|
8367
8781
|
function buildGrid3(viewMonth, weekStartsOn) {
|
|
8368
|
-
const first =
|
|
8782
|
+
const first = startOfMonth3(viewMonth);
|
|
8369
8783
|
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
8370
|
-
const gridStart =
|
|
8784
|
+
const gridStart = addDays3(first, -offset);
|
|
8371
8785
|
return Array.from({ length: 42 }, (_, i) => {
|
|
8372
|
-
const d =
|
|
8786
|
+
const d = addDays3(gridStart, i);
|
|
8373
8787
|
return { date: d, outside: d.getMonth() !== viewMonth.getMonth() };
|
|
8374
8788
|
});
|
|
8375
8789
|
}
|
|
@@ -8396,20 +8810,20 @@ function DateRangePicker({
|
|
|
8396
8810
|
const errorId = useId();
|
|
8397
8811
|
const hasError = errorMessage != null;
|
|
8398
8812
|
const [open, setOpen] = useState(false);
|
|
8399
|
-
const [leftMonth, setLeftMonth] = useState(() =>
|
|
8813
|
+
const [leftMonth, setLeftMonth] = useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
8400
8814
|
const [pendingStart, setPendingStart] = useState(null);
|
|
8401
8815
|
const [hoverDate, setHoverDate] = useState(null);
|
|
8402
8816
|
const weekdays = useMemo(
|
|
8403
8817
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8404
8818
|
[weekStartsOn]
|
|
8405
8819
|
);
|
|
8406
|
-
const isDisabled = (d) => min && d <
|
|
8820
|
+
const isDisabled = (d) => min && d < startOfDay3(min) || max && d > startOfDay3(max);
|
|
8407
8821
|
const effective = pendingStart ? { start: pendingStart, end: hoverDate } : value;
|
|
8408
8822
|
const inRange = (d) => {
|
|
8409
8823
|
const { start, end } = effective;
|
|
8410
8824
|
if (!start || !end) return false;
|
|
8411
8825
|
const [a, b] = start <= end ? [start, end] : [end, start];
|
|
8412
|
-
return d >=
|
|
8826
|
+
return d >= startOfDay3(a) && d <= startOfDay3(b);
|
|
8413
8827
|
};
|
|
8414
8828
|
const onDayClick = (d) => {
|
|
8415
8829
|
if (isDisabled(d)) return;
|
|
@@ -8516,7 +8930,7 @@ function DateRangePicker({
|
|
|
8516
8930
|
"button",
|
|
8517
8931
|
{
|
|
8518
8932
|
type: "button",
|
|
8519
|
-
onClick: () => setLeftMonth(
|
|
8933
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, -1)),
|
|
8520
8934
|
"aria-label": "Previous month",
|
|
8521
8935
|
className: "absolute -top-1 left-0 w-7 h-7 inline-flex items-center justify-center rounded-md hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
8522
8936
|
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
|
|
@@ -8529,13 +8943,13 @@ function DateRangePicker({
|
|
|
8529
8943
|
"button",
|
|
8530
8944
|
{
|
|
8531
8945
|
type: "button",
|
|
8532
|
-
onClick: () => setLeftMonth(
|
|
8946
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, 1)),
|
|
8533
8947
|
"aria-label": "Next month",
|
|
8534
8948
|
className: "absolute -top-1 right-0 w-7 h-7 inline-flex items-center justify-center rounded-md hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
8535
8949
|
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
8536
8950
|
}
|
|
8537
8951
|
),
|
|
8538
|
-
renderMonth(
|
|
8952
|
+
renderMonth(addMonths4(leftMonth, 1))
|
|
8539
8953
|
] })
|
|
8540
8954
|
] })
|
|
8541
8955
|
]
|
|
@@ -8664,6 +9078,6 @@ function ColorPicker({
|
|
|
8664
9078
|
] });
|
|
8665
9079
|
}
|
|
8666
9080
|
|
|
8667
|
-
export { Accordion_default as Accordion, AppShell, AutoComplete, Avatar, Badge, Box, Breadcrumbs, Button_default as Button, CARD_BRANDS, Calendar2 as Calendar, Card_default as Card, CardCarousel, Cart, CartButton, CartProvider, Catalog, CatalogCarousel, CatalogGrid, Checkbox, Checkout, ColorPicker, ContextMenu, CreditCardForm, DateRangePicker, Drawer, Dropdown, EmptyCart, FAB, FadingBase, Field, FieldHelpIcon, FieldLabel, FileInput, Flex, Form, FormContext, FormField, FormStore, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, Kbd, List2 as List, LoadingSpinner, LogoutTimer, MegaMenu_default as MegaMenu, MenuButton, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Password, PopConfirm, Portal, RadioGroup, Rating, ScalableContainer, SearchInput_default as SearchInput, SecureLayout, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Statistic, Stepper, Switch, Table, Tabs_default as Tabs, TagsInput, DatePicker as Temporal, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, Timeline, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, cardNumberError, cvvError, detectBrand, expiryError, fieldShell, formatCardNumber, formatExpiry, isRequired, luhnValid, onlyDigits, patterns, runFieldRules, useCart, useFieldArray, useForm, useFormField, useFormStore, useNotification };
|
|
9081
|
+
export { Accordion_default as Accordion, AppShell, AutoComplete, Avatar, Badge, Box, Breadcrumbs, Button_default as Button, CARD_BRANDS, Calendar2 as Calendar, Card_default as Card, CardCarousel, Cart, CartButton, CartProvider, Catalog, CatalogCarousel, CatalogGrid, Checkbox, Checkout, ColorPicker, ContextMenu, CreditCardForm, DateRangePicker, Drawer, Dropdown, EmptyCart, FAB, FadingBase, Field, FieldHelpIcon, FieldLabel, FileInput, Flex, Form, FormContext, FormField, FormStore, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, Kbd, List2 as List, LoadingSpinner, LogoutTimer, MegaMenu_default as MegaMenu, MenuButton, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Password, PopConfirm, Portal, RadioGroup, Rating, ScalableContainer, Scheduler, SearchInput_default as SearchInput, SecureLayout, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Statistic, Stepper, Switch, Table, Tabs_default as Tabs, TagsInput, DatePicker as Temporal, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, Timeline, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, cardNumberError, cvvError, detectBrand, expiryError, fieldShell, formatCardNumber, formatExpiry, isRequired, luhnValid, onlyDigits, patterns, runFieldRules, useCart, useFieldArray, useForm, useFormField, useFormStore, useNotification };
|
|
8668
9082
|
//# sourceMappingURL=index.js.map
|
|
8669
9083
|
//# sourceMappingURL=index.js.map
|