@geomak/ui 6.24.1 → 6.25.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 +852 -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 +626 -288
- package/dist/index.js.map +1 -1
- package/dist/styles.css +31 -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,586 @@ 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 WEEKDAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2844
|
+
var toDate = (d) => d instanceof Date ? d : new Date(d);
|
|
2845
|
+
var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2846
|
+
var addDays = (d, n) => {
|
|
2847
|
+
const x = new Date(d);
|
|
2848
|
+
x.setDate(x.getDate() + n);
|
|
2849
|
+
return x;
|
|
2850
|
+
};
|
|
2851
|
+
var addMonths2 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
2852
|
+
var sameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2853
|
+
var isToday = (d) => sameDay2(d, /* @__PURE__ */ new Date());
|
|
2854
|
+
var isSameMonth = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
2855
|
+
var startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
2856
|
+
var endOfMonth = (d) => new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
2857
|
+
var startOfWeek = (d, weekStartsOn) => {
|
|
2858
|
+
const x = startOfDay2(d);
|
|
2859
|
+
const diff = (x.getDay() - weekStartsOn + 7) % 7;
|
|
2860
|
+
return addDays(x, -diff);
|
|
2861
|
+
};
|
|
2862
|
+
var buildMonthGrid = (cursor, weekStartsOn) => {
|
|
2863
|
+
const start = startOfWeek(startOfMonth(cursor), weekStartsOn);
|
|
2864
|
+
return Array.from({ length: 42 }, (_, i) => addDays(start, i));
|
|
2865
|
+
};
|
|
2866
|
+
var getWeekDays = (cursor, weekStartsOn) => {
|
|
2867
|
+
const start = startOfWeek(cursor, weekStartsOn);
|
|
2868
|
+
return Array.from({ length: 7 }, (_, i) => addDays(start, i));
|
|
2869
|
+
};
|
|
2870
|
+
var monthRange = (cursor) => ({
|
|
2871
|
+
from: startOfMonth(cursor),
|
|
2872
|
+
to: endOfMonth(cursor)
|
|
2873
|
+
});
|
|
2874
|
+
var weekRange = (cursor, weekStartsOn) => {
|
|
2875
|
+
const from = startOfWeek(cursor, weekStartsOn);
|
|
2876
|
+
return { from, to: addDays(from, 6) };
|
|
2877
|
+
};
|
|
2878
|
+
var weekdayLabels = (weekStartsOn) => Array.from({ length: 7 }, (_, i) => WEEKDAYS2[(i + weekStartsOn) % 7]);
|
|
2879
|
+
var monthYearLabel = (d) => `${MONTHS2[d.getMonth()]} ${d.getFullYear()}`;
|
|
2880
|
+
var weekLabel = (cursor, weekStartsOn) => {
|
|
2881
|
+
const from = startOfWeek(cursor, weekStartsOn);
|
|
2882
|
+
const to = addDays(from, 6);
|
|
2883
|
+
const m = (d) => MONTHS2[d.getMonth()].slice(0, 3);
|
|
2884
|
+
if (from.getMonth() === to.getMonth()) {
|
|
2885
|
+
return `${m(from)} ${from.getDate()} \u2013 ${to.getDate()}, ${to.getFullYear()}`;
|
|
2886
|
+
}
|
|
2887
|
+
const yearPart = from.getFullYear() === to.getFullYear() ? `${to.getFullYear()}` : "";
|
|
2888
|
+
return `${m(from)} ${from.getDate()} \u2013 ${m(to)} ${to.getDate()}${yearPart ? `, ${yearPart}` : `, ${from.getFullYear()}/${to.getFullYear()}`}`;
|
|
2889
|
+
};
|
|
2890
|
+
var minutesIntoDay = (d) => d.getHours() * 60 + d.getMinutes();
|
|
2891
|
+
var hourLabel = (hour) => `${String(hour).padStart(2, "0")}:00`;
|
|
2892
|
+
var timeLabel = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
2893
|
+
var normalize = (e) => {
|
|
2894
|
+
const start = toDate(e.start);
|
|
2895
|
+
const end = e.end ? toDate(e.end) : new Date(start.getTime() + 36e5);
|
|
2896
|
+
return { ...e, start, end };
|
|
2897
|
+
};
|
|
2898
|
+
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" }) });
|
|
2899
|
+
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" }) });
|
|
2900
|
+
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" }) });
|
|
2901
|
+
function Scheduler({
|
|
2902
|
+
events: controlledEvents,
|
|
2903
|
+
loadEvents,
|
|
2904
|
+
defaultView = "month",
|
|
2905
|
+
defaultDate,
|
|
2906
|
+
weekStartsOn = 0,
|
|
2907
|
+
dayHours = [0, 24],
|
|
2908
|
+
hourHeight = 48,
|
|
2909
|
+
onSelectSlot,
|
|
2910
|
+
onSelectEvent,
|
|
2911
|
+
onNewEvent,
|
|
2912
|
+
className = "",
|
|
2913
|
+
style
|
|
2914
|
+
}) {
|
|
2915
|
+
const reduced = useReducedMotion();
|
|
2916
|
+
const [view, setView] = useState(defaultView);
|
|
2917
|
+
const [cursor, setCursor] = useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2918
|
+
const [loaded, setLoaded] = useState([]);
|
|
2919
|
+
const [loading, setLoading] = useState(false);
|
|
2920
|
+
const [dir, setDir] = useState(0);
|
|
2921
|
+
const loaderRef = useRef(loadEvents);
|
|
2922
|
+
loaderRef.current = loadEvents;
|
|
2923
|
+
const range = useMemo(
|
|
2924
|
+
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2925
|
+
[view, cursor, weekStartsOn]
|
|
2926
|
+
);
|
|
2927
|
+
const fromKey = range.from.getTime();
|
|
2928
|
+
const toKey = range.to.getTime();
|
|
2929
|
+
useEffect(() => {
|
|
2930
|
+
const loader = loaderRef.current;
|
|
2931
|
+
if (!loader) return;
|
|
2932
|
+
let cancelled = false;
|
|
2933
|
+
setLoading(true);
|
|
2934
|
+
Promise.resolve(loader({ from: new Date(fromKey), to: new Date(toKey) }, view)).then((evts) => {
|
|
2935
|
+
if (!cancelled) setLoaded(evts);
|
|
2936
|
+
}).catch(() => {
|
|
2937
|
+
if (!cancelled) setLoaded([]);
|
|
2938
|
+
}).finally(() => {
|
|
2939
|
+
if (!cancelled) setLoading(false);
|
|
2940
|
+
});
|
|
2941
|
+
return () => {
|
|
2942
|
+
cancelled = true;
|
|
2943
|
+
};
|
|
2944
|
+
}, [fromKey, toKey, view]);
|
|
2945
|
+
const events = useMemo(
|
|
2946
|
+
() => (controlledEvents ?? loaded).map(normalize),
|
|
2947
|
+
[controlledEvents, loaded]
|
|
2948
|
+
);
|
|
2949
|
+
const go = useCallback((delta) => {
|
|
2950
|
+
setDir(delta);
|
|
2951
|
+
setCursor((c) => view === "month" ? addMonths2(c, delta) : addDays(c, delta * 7));
|
|
2952
|
+
}, [view]);
|
|
2953
|
+
const goToday = useCallback(() => {
|
|
2954
|
+
setDir(0);
|
|
2955
|
+
setCursor(/* @__PURE__ */ new Date());
|
|
2956
|
+
}, []);
|
|
2957
|
+
const title = view === "month" ? monthYearLabel(cursor) : weekLabel(cursor, weekStartsOn);
|
|
2958
|
+
const slide = reduced ? { duration: 0 } : { duration: 0.22, ease: [0.16, 1, 0.3, 1] };
|
|
2959
|
+
return /* @__PURE__ */ jsxs(
|
|
2960
|
+
"div",
|
|
2961
|
+
{
|
|
2962
|
+
className: ["flex flex-col overflow-hidden rounded-xl border border-border bg-surface", className].filter(Boolean).join(" "),
|
|
2963
|
+
style,
|
|
2964
|
+
children: [
|
|
2965
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3", children: [
|
|
2966
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2967
|
+
/* @__PURE__ */ jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "left" }), title: "Previous", onClick: () => go(-1) }),
|
|
2968
|
+
/* @__PURE__ */ jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "right" }), title: "Next", onClick: () => go(1) }),
|
|
2969
|
+
/* @__PURE__ */ jsx(Button_default, { variant: "ghost", size: "sm", content: "Today", onClick: goToday }),
|
|
2970
|
+
/* @__PURE__ */ jsxs("h2", { className: "ml-1 min-w-[9rem] text-base font-semibold tracking-tight text-foreground", children: [
|
|
2971
|
+
title,
|
|
2972
|
+
loading && /* @__PURE__ */ jsx("span", { className: "ml-2 inline-flex translate-y-0.5", children: /* @__PURE__ */ jsx(Spinner2, {}) })
|
|
2973
|
+
] })
|
|
2974
|
+
] }),
|
|
2975
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2976
|
+
/* @__PURE__ */ jsx(
|
|
2977
|
+
SegmentedControl,
|
|
2978
|
+
{
|
|
2979
|
+
size: "sm",
|
|
2980
|
+
"aria-label": "Calendar view",
|
|
2981
|
+
value: view,
|
|
2982
|
+
onChange: (v) => setView(v),
|
|
2983
|
+
options: [{ value: "month", label: "Month" }, { value: "week", label: "Week" }]
|
|
2984
|
+
}
|
|
2985
|
+
),
|
|
2986
|
+
onNewEvent && /* @__PURE__ */ jsx(Button_default, { size: "sm", icon: /* @__PURE__ */ jsx(Plus, {}), content: "New event", onClick: onNewEvent })
|
|
2987
|
+
] })
|
|
2988
|
+
] }),
|
|
2989
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
2990
|
+
motion.div,
|
|
2991
|
+
{
|
|
2992
|
+
initial: { opacity: 0, x: reduced ? 0 : dir * 24 },
|
|
2993
|
+
animate: { opacity: 1, x: 0 },
|
|
2994
|
+
transition: slide,
|
|
2995
|
+
className: "h-full",
|
|
2996
|
+
children: view === "month" ? /* @__PURE__ */ jsx(
|
|
2997
|
+
MonthView,
|
|
2998
|
+
{
|
|
2999
|
+
cursor,
|
|
3000
|
+
weekStartsOn,
|
|
3001
|
+
events,
|
|
3002
|
+
onSelectSlot,
|
|
3003
|
+
onSelectEvent
|
|
3004
|
+
}
|
|
3005
|
+
) : /* @__PURE__ */ jsx(
|
|
3006
|
+
WeekView,
|
|
3007
|
+
{
|
|
3008
|
+
cursor,
|
|
3009
|
+
weekStartsOn,
|
|
3010
|
+
events,
|
|
3011
|
+
dayHours,
|
|
3012
|
+
hourHeight,
|
|
3013
|
+
onSelectSlot,
|
|
3014
|
+
onSelectEvent
|
|
3015
|
+
}
|
|
3016
|
+
)
|
|
3017
|
+
},
|
|
3018
|
+
`${view}-${range.from.getTime()}`
|
|
3019
|
+
) })
|
|
3020
|
+
]
|
|
3021
|
+
}
|
|
3022
|
+
);
|
|
3023
|
+
}
|
|
3024
|
+
var MAX_CHIPS = 3;
|
|
3025
|
+
function MonthView({
|
|
3026
|
+
cursor,
|
|
3027
|
+
weekStartsOn,
|
|
3028
|
+
events,
|
|
3029
|
+
onSelectSlot,
|
|
3030
|
+
onSelectEvent
|
|
3031
|
+
}) {
|
|
3032
|
+
const grid = useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3033
|
+
const labels = weekdayLabels(weekStartsOn);
|
|
3034
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3035
|
+
/* @__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)) }),
|
|
3036
|
+
/* @__PURE__ */ jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-6", children: grid.map((day, i) => {
|
|
3037
|
+
const inMonth = isSameMonth(day, cursor);
|
|
3038
|
+
const dayEvents = events.filter((e) => sameDay2(e.start, day));
|
|
3039
|
+
const today = isToday(day);
|
|
3040
|
+
return /* @__PURE__ */ jsxs(
|
|
3041
|
+
"button",
|
|
3042
|
+
{
|
|
3043
|
+
type: "button",
|
|
3044
|
+
onClick: () => onSelectSlot?.(day),
|
|
3045
|
+
className: [
|
|
3046
|
+
"group flex min-h-[5rem] flex-col gap-1 border-b border-r border-border p-1.5 text-left transition-colors",
|
|
3047
|
+
"[&:nth-child(7n)]:border-r-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
|
|
3048
|
+
inMonth ? "bg-surface hover:bg-surface-raised" : "bg-background/40"
|
|
3049
|
+
].join(" "),
|
|
3050
|
+
children: [
|
|
3051
|
+
/* @__PURE__ */ jsx(
|
|
3052
|
+
"span",
|
|
3053
|
+
{
|
|
3054
|
+
className: [
|
|
3055
|
+
"flex h-6 w-6 items-center justify-center self-start rounded-full text-xs tabular-nums",
|
|
3056
|
+
today ? "bg-accent font-semibold text-accent-fg" : inMonth ? "text-foreground" : "text-foreground-muted"
|
|
3057
|
+
].join(" "),
|
|
3058
|
+
children: day.getDate()
|
|
3059
|
+
}
|
|
3060
|
+
),
|
|
3061
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3062
|
+
dayEvents.slice(0, MAX_CHIPS).map((e) => /* @__PURE__ */ jsx(EventChip, { event: e, onSelect: onSelectEvent }, e.id)),
|
|
3063
|
+
dayEvents.length > MAX_CHIPS && /* @__PURE__ */ jsxs("span", { className: "px-1 text-[11px] font-medium text-foreground-muted", children: [
|
|
3064
|
+
"+",
|
|
3065
|
+
dayEvents.length - MAX_CHIPS,
|
|
3066
|
+
" more"
|
|
3067
|
+
] })
|
|
3068
|
+
] })
|
|
3069
|
+
]
|
|
3070
|
+
},
|
|
3071
|
+
i
|
|
3072
|
+
);
|
|
3073
|
+
}) })
|
|
3074
|
+
] });
|
|
3075
|
+
}
|
|
3076
|
+
function EventChip({ event, onSelect }) {
|
|
3077
|
+
const color = event.color ?? "var(--color-accent)";
|
|
3078
|
+
return /* @__PURE__ */ jsxs(
|
|
3079
|
+
"button",
|
|
3080
|
+
{
|
|
3081
|
+
type: "button",
|
|
3082
|
+
onClick: (e) => {
|
|
3083
|
+
e.stopPropagation();
|
|
3084
|
+
onSelect?.(event);
|
|
3085
|
+
},
|
|
3086
|
+
title: `${event.title} \xB7 ${timeLabel(event.start)}`,
|
|
3087
|
+
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",
|
|
3088
|
+
children: [
|
|
3089
|
+
/* @__PURE__ */ jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
3090
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: event.title })
|
|
3091
|
+
]
|
|
3092
|
+
}
|
|
3093
|
+
);
|
|
3094
|
+
}
|
|
3095
|
+
function WeekView({
|
|
3096
|
+
cursor,
|
|
3097
|
+
weekStartsOn,
|
|
3098
|
+
events,
|
|
3099
|
+
dayHours,
|
|
3100
|
+
hourHeight,
|
|
3101
|
+
onSelectSlot,
|
|
3102
|
+
onSelectEvent
|
|
3103
|
+
}) {
|
|
3104
|
+
const days = useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3105
|
+
const [startHour, endHour] = dayHours;
|
|
3106
|
+
const hours = useMemo(
|
|
3107
|
+
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3108
|
+
[startHour, endHour]
|
|
3109
|
+
);
|
|
3110
|
+
const spanMinutes = (endHour - startHour) * 60;
|
|
3111
|
+
const gridHeight = hours.length * hourHeight;
|
|
3112
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
|
|
3113
|
+
/* @__PURE__ */ jsxs("div", { className: "grid border-b border-border", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)` }, children: [
|
|
3114
|
+
/* @__PURE__ */ jsx("div", { className: "border-r border-border" }),
|
|
3115
|
+
days.map((d) => /* @__PURE__ */ jsxs("div", { className: "border-r border-border px-1 py-1.5 text-center last:border-r-0", children: [
|
|
3116
|
+
/* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: weekdayLabels(weekStartsOn)[(d.getDay() - weekStartsOn + 7) % 7] }),
|
|
3117
|
+
/* @__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() })
|
|
3118
|
+
] }, d.getTime()))
|
|
3119
|
+
] }),
|
|
3120
|
+
/* @__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: [
|
|
3121
|
+
/* @__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)) }),
|
|
3122
|
+
days.map((day) => {
|
|
3123
|
+
const dayEvents = events.filter((e) => sameDay2(e.start, day) && !e.allDay);
|
|
3124
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative border-r border-border last:border-r-0", children: [
|
|
3125
|
+
hours.map((h, i) => /* @__PURE__ */ jsx(
|
|
3126
|
+
"button",
|
|
3127
|
+
{
|
|
3128
|
+
type: "button",
|
|
3129
|
+
"aria-label": `${weekdayLabels(weekStartsOn)[(day.getDay() - weekStartsOn + 7) % 7]} ${day.getDate()} ${hourLabel(h)}`,
|
|
3130
|
+
onClick: () => onSelectSlot?.(new Date(day.getFullYear(), day.getMonth(), day.getDate(), h)),
|
|
3131
|
+
className: "absolute left-0 right-0 border-b border-border/60 hover:bg-surface-raised/60 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
|
|
3132
|
+
style: { top: i * hourHeight, height: hourHeight }
|
|
3133
|
+
},
|
|
3134
|
+
h
|
|
3135
|
+
)),
|
|
3136
|
+
dayEvents.map((e) => {
|
|
3137
|
+
const top = (minutesIntoDay(e.start) - startHour * 60) / spanMinutes * gridHeight;
|
|
3138
|
+
const durMin = Math.max(20, (e.end.getTime() - e.start.getTime()) / 6e4);
|
|
3139
|
+
const height = durMin / spanMinutes * gridHeight;
|
|
3140
|
+
const color = e.color ?? "var(--color-accent)";
|
|
3141
|
+
return /* @__PURE__ */ jsxs(
|
|
3142
|
+
"button",
|
|
3143
|
+
{
|
|
3144
|
+
type: "button",
|
|
3145
|
+
onClick: (ev) => {
|
|
3146
|
+
ev.stopPropagation();
|
|
3147
|
+
onSelectEvent?.(e);
|
|
3148
|
+
},
|
|
3149
|
+
title: `${e.title} \xB7 ${timeLabel(e.start)}\u2013${timeLabel(e.end)}`,
|
|
3150
|
+
className: "absolute left-0.5 right-0.5 overflow-hidden rounded-md border-l-2 px-1.5 py-0.5 text-left text-[11px] leading-tight text-foreground shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3151
|
+
style: { top: Math.max(0, top), height, borderLeftColor: color, backgroundColor: `color-mix(in oklab, ${color} 16%, var(--color-surface))` },
|
|
3152
|
+
children: [
|
|
3153
|
+
/* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: e.title }),
|
|
3154
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-foreground-muted", children: timeLabel(e.start) })
|
|
3155
|
+
]
|
|
2593
3156
|
},
|
|
2594
|
-
|
|
2595
|
-
)
|
|
2596
|
-
|
|
2597
|
-
},
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
}) })
|
|
3157
|
+
e.id
|
|
3158
|
+
);
|
|
3159
|
+
})
|
|
3160
|
+
] }, day.getTime());
|
|
3161
|
+
})
|
|
3162
|
+
] }) })
|
|
2601
3163
|
] });
|
|
2602
3164
|
}
|
|
2603
3165
|
function DefaultIllustration() {
|
|
@@ -3236,134 +3798,6 @@ function useFieldArray(name) {
|
|
|
3236
3798
|
replace: (items) => store.setValue(name, items, { validate: false })
|
|
3237
3799
|
};
|
|
3238
3800
|
}
|
|
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
3801
|
function TextInput({
|
|
3368
3802
|
value,
|
|
3369
3803
|
onChange,
|
|
@@ -3503,8 +3937,8 @@ function expiryError(value, now = /* @__PURE__ */ new Date()) {
|
|
|
3503
3937
|
const mm = Number(m[1]);
|
|
3504
3938
|
const yy = Number(m[2]);
|
|
3505
3939
|
if (mm < 1 || mm > 12) return "Invalid month";
|
|
3506
|
-
const
|
|
3507
|
-
if (
|
|
3940
|
+
const endOfMonth2 = new Date(2e3 + yy, mm, 0, 23, 59, 59, 999);
|
|
3941
|
+
if (endOfMonth2 < now) return "Card has expired";
|
|
3508
3942
|
return void 0;
|
|
3509
3943
|
}
|
|
3510
3944
|
function cvvError(value, cardNumber) {
|
|
@@ -4654,7 +5088,7 @@ function Wizard({
|
|
|
4654
5088
|
] });
|
|
4655
5089
|
}
|
|
4656
5090
|
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 =
|
|
5091
|
+
var SearchInput = React29.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
|
|
4658
5092
|
return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxs(
|
|
4659
5093
|
"div",
|
|
4660
5094
|
{
|
|
@@ -5155,7 +5589,7 @@ function TableBody({
|
|
|
5155
5589
|
return /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => {
|
|
5156
5590
|
const rowKey = getRowKey(row, i);
|
|
5157
5591
|
const isExpanded = expanded.has(rowKey);
|
|
5158
|
-
return /* @__PURE__ */ jsxs(
|
|
5592
|
+
return /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
5159
5593
|
/* @__PURE__ */ jsxs(
|
|
5160
5594
|
"tr",
|
|
5161
5595
|
{
|
|
@@ -5699,8 +6133,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
5699
6133
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
5700
6134
|
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
6135
|
}
|
|
5702
|
-
var elementsOfType = (children, type) =>
|
|
5703
|
-
(c) =>
|
|
6136
|
+
var elementsOfType = (children, type) => React29.Children.toArray(children).filter(
|
|
6137
|
+
(c) => React29.isValidElement(c) && c.type === type
|
|
5704
6138
|
);
|
|
5705
6139
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsx(
|
|
5706
6140
|
"svg",
|
|
@@ -5737,9 +6171,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
5737
6171
|
);
|
|
5738
6172
|
}
|
|
5739
6173
|
function MobilePanel({ panel, onNavigate }) {
|
|
5740
|
-
const nodes =
|
|
6174
|
+
const nodes = React29.Children.toArray(panel.props.children);
|
|
5741
6175
|
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
5742
|
-
if (!
|
|
6176
|
+
if (!React29.isValidElement(node)) return null;
|
|
5743
6177
|
const el = node;
|
|
5744
6178
|
if (el.type === MegaMenuSection) {
|
|
5745
6179
|
const { title, children } = el.props;
|
|
@@ -5949,7 +6383,7 @@ function tokenValid(token) {
|
|
|
5949
6383
|
return exp * 1e3 > Date.now();
|
|
5950
6384
|
}
|
|
5951
6385
|
var has = (have, need, all) => all ? need.every((n) => have?.includes(n)) : need.some((n) => have?.includes(n));
|
|
5952
|
-
var
|
|
6386
|
+
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
6387
|
function SecureLayout({
|
|
5954
6388
|
children,
|
|
5955
6389
|
isAuthenticated,
|
|
@@ -6025,7 +6459,7 @@ function SecureLayout({
|
|
|
6025
6459
|
]);
|
|
6026
6460
|
if (state === "checking") {
|
|
6027
6461
|
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(
|
|
6462
|
+
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
6463
|
}
|
|
6030
6464
|
if (state === "denied") {
|
|
6031
6465
|
if (fallback === null) return null;
|
|
@@ -6148,7 +6582,7 @@ function ThemeProvider({
|
|
|
6148
6582
|
className = "",
|
|
6149
6583
|
style
|
|
6150
6584
|
}) {
|
|
6151
|
-
const id =
|
|
6585
|
+
const id = React29.useId().replace(/:/g, "");
|
|
6152
6586
|
const scopeClass = `geo-th-${id}`;
|
|
6153
6587
|
const divRef = useRef(null);
|
|
6154
6588
|
useEffect(() => {
|
|
@@ -7259,15 +7693,15 @@ var WEEKDAY_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
|
7259
7693
|
function isSameDay(a, b) {
|
|
7260
7694
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
7261
7695
|
}
|
|
7262
|
-
function
|
|
7696
|
+
function startOfMonth2(d) {
|
|
7263
7697
|
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
7264
7698
|
}
|
|
7265
|
-
function
|
|
7699
|
+
function addDays2(d, n) {
|
|
7266
7700
|
const c = new Date(d);
|
|
7267
7701
|
c.setDate(c.getDate() + n);
|
|
7268
7702
|
return c;
|
|
7269
7703
|
}
|
|
7270
|
-
function
|
|
7704
|
+
function addMonths3(d, n) {
|
|
7271
7705
|
const c = new Date(d);
|
|
7272
7706
|
c.setMonth(c.getMonth() + n);
|
|
7273
7707
|
return c;
|
|
@@ -7279,12 +7713,12 @@ function defaultFormat3(d) {
|
|
|
7279
7713
|
return `${y}-${m}-${day}`;
|
|
7280
7714
|
}
|
|
7281
7715
|
function buildGrid2(viewMonth, weekStartsOn) {
|
|
7282
|
-
const first =
|
|
7716
|
+
const first = startOfMonth2(viewMonth);
|
|
7283
7717
|
const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
7284
|
-
const gridStart =
|
|
7718
|
+
const gridStart = addDays2(first, -startOffset);
|
|
7285
7719
|
const cells = [];
|
|
7286
7720
|
for (let i = 0; i < 42; i++) {
|
|
7287
|
-
const d =
|
|
7721
|
+
const d = addDays2(gridStart, i);
|
|
7288
7722
|
cells.push({ date: d, outside: d.getMonth() !== viewMonth.getMonth() });
|
|
7289
7723
|
}
|
|
7290
7724
|
const rows = [];
|
|
@@ -7315,14 +7749,14 @@ function DatePicker({
|
|
|
7315
7749
|
const errorId = useId();
|
|
7316
7750
|
const hasError = errorMessage != null;
|
|
7317
7751
|
const [open, setOpen] = useState(false);
|
|
7318
|
-
const [viewMonth, setViewMonth] = useState(() =>
|
|
7752
|
+
const [viewMonth, setViewMonth] = useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
7319
7753
|
const [focusDate, setFocusDate] = useState(() => value ?? /* @__PURE__ */ new Date());
|
|
7320
7754
|
const [view, setView] = useState("days");
|
|
7321
7755
|
const gridRef = useRef(null);
|
|
7322
7756
|
useEffect(() => {
|
|
7323
7757
|
if (!open) return;
|
|
7324
7758
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7325
|
-
setViewMonth(
|
|
7759
|
+
setViewMonth(startOfMonth2(target));
|
|
7326
7760
|
setFocusDate(target);
|
|
7327
7761
|
setView("days");
|
|
7328
7762
|
}, [open, value]);
|
|
@@ -7348,9 +7782,9 @@ function DatePicker({
|
|
|
7348
7782
|
};
|
|
7349
7783
|
const onKey = (e) => {
|
|
7350
7784
|
const next = (delta) => {
|
|
7351
|
-
const nd =
|
|
7785
|
+
const nd = addDays2(focusDate, delta);
|
|
7352
7786
|
setFocusDate(nd);
|
|
7353
|
-
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(
|
|
7787
|
+
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(startOfMonth2(nd));
|
|
7354
7788
|
};
|
|
7355
7789
|
if (e.key === "ArrowLeft") {
|
|
7356
7790
|
e.preventDefault();
|
|
@@ -7366,22 +7800,22 @@ function DatePicker({
|
|
|
7366
7800
|
next(7);
|
|
7367
7801
|
} else if (e.key === "PageUp") {
|
|
7368
7802
|
e.preventDefault();
|
|
7369
|
-
const nm =
|
|
7803
|
+
const nm = addMonths3(viewMonth, -1);
|
|
7370
7804
|
setViewMonth(nm);
|
|
7371
|
-
setFocusDate((d) =>
|
|
7805
|
+
setFocusDate((d) => addMonths3(d, -1));
|
|
7372
7806
|
} else if (e.key === "PageDown") {
|
|
7373
7807
|
e.preventDefault();
|
|
7374
|
-
const nm =
|
|
7808
|
+
const nm = addMonths3(viewMonth, 1);
|
|
7375
7809
|
setViewMonth(nm);
|
|
7376
|
-
setFocusDate((d) =>
|
|
7810
|
+
setFocusDate((d) => addMonths3(d, 1));
|
|
7377
7811
|
} else if (e.key === "Home") {
|
|
7378
7812
|
e.preventDefault();
|
|
7379
7813
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7380
|
-
setFocusDate(
|
|
7814
|
+
setFocusDate(addDays2(focusDate, -dow));
|
|
7381
7815
|
} else if (e.key === "End") {
|
|
7382
7816
|
e.preventDefault();
|
|
7383
7817
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7384
|
-
setFocusDate(
|
|
7818
|
+
setFocusDate(addDays2(focusDate, 6 - dow));
|
|
7385
7819
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
7386
7820
|
e.preventDefault();
|
|
7387
7821
|
selectDate(focusDate);
|
|
@@ -7438,7 +7872,7 @@ function DatePicker({
|
|
|
7438
7872
|
{
|
|
7439
7873
|
type: "button",
|
|
7440
7874
|
onClick: () => {
|
|
7441
|
-
if (view === "days") setViewMonth(
|
|
7875
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, -1));
|
|
7442
7876
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() - 1, viewMonth.getMonth(), 1));
|
|
7443
7877
|
else setViewMonth(new Date(viewMonth.getFullYear() - 10, viewMonth.getMonth(), 1));
|
|
7444
7878
|
},
|
|
@@ -7473,7 +7907,7 @@ function DatePicker({
|
|
|
7473
7907
|
{
|
|
7474
7908
|
type: "button",
|
|
7475
7909
|
onClick: () => {
|
|
7476
|
-
if (view === "days") setViewMonth(
|
|
7910
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, 1));
|
|
7477
7911
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() + 1, viewMonth.getMonth(), 1));
|
|
7478
7912
|
else setViewMonth(new Date(viewMonth.getFullYear() + 10, viewMonth.getMonth(), 1));
|
|
7479
7913
|
},
|
|
@@ -7675,102 +8109,6 @@ function TextArea({
|
|
|
7675
8109
|
}
|
|
7676
8110
|
);
|
|
7677
8111
|
}
|
|
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
8112
|
var TRACK_H = { sm: "h-1", md: "h-1.5", lg: "h-2" };
|
|
7775
8113
|
var THUMB = { sm: "h-3.5 w-3.5", md: "h-4 w-4", lg: "h-5 w-5" };
|
|
7776
8114
|
var toArray = (v) => v == null ? void 0 : Array.isArray(v) ? v : [v];
|
|
@@ -8084,7 +8422,7 @@ function OtpInput({
|
|
|
8084
8422
|
emit(valid.join(""));
|
|
8085
8423
|
focusBox(valid.length);
|
|
8086
8424
|
};
|
|
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(
|
|
8425
|
+
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
8426
|
/* @__PURE__ */ jsx(
|
|
8089
8427
|
"input",
|
|
8090
8428
|
{
|
|
@@ -8354,22 +8692,22 @@ function TimePicker({
|
|
|
8354
8692
|
}
|
|
8355
8693
|
var MONTH_NAMES2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
8356
8694
|
var WEEKDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
8357
|
-
var
|
|
8358
|
-
var
|
|
8359
|
-
var
|
|
8695
|
+
var startOfMonth3 = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
8696
|
+
var addMonths4 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
8697
|
+
var addDays3 = (d, n) => {
|
|
8360
8698
|
const c = new Date(d);
|
|
8361
8699
|
c.setDate(c.getDate() + n);
|
|
8362
8700
|
return c;
|
|
8363
8701
|
};
|
|
8364
8702
|
var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
8365
|
-
var
|
|
8703
|
+
var startOfDay3 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8366
8704
|
var defaultFmt = (d) => `${d.getFullYear()}-${`${d.getMonth() + 1}`.padStart(2, "0")}-${`${d.getDate()}`.padStart(2, "0")}`;
|
|
8367
8705
|
function buildGrid3(viewMonth, weekStartsOn) {
|
|
8368
|
-
const first =
|
|
8706
|
+
const first = startOfMonth3(viewMonth);
|
|
8369
8707
|
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
8370
|
-
const gridStart =
|
|
8708
|
+
const gridStart = addDays3(first, -offset);
|
|
8371
8709
|
return Array.from({ length: 42 }, (_, i) => {
|
|
8372
|
-
const d =
|
|
8710
|
+
const d = addDays3(gridStart, i);
|
|
8373
8711
|
return { date: d, outside: d.getMonth() !== viewMonth.getMonth() };
|
|
8374
8712
|
});
|
|
8375
8713
|
}
|
|
@@ -8396,20 +8734,20 @@ function DateRangePicker({
|
|
|
8396
8734
|
const errorId = useId();
|
|
8397
8735
|
const hasError = errorMessage != null;
|
|
8398
8736
|
const [open, setOpen] = useState(false);
|
|
8399
|
-
const [leftMonth, setLeftMonth] = useState(() =>
|
|
8737
|
+
const [leftMonth, setLeftMonth] = useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
8400
8738
|
const [pendingStart, setPendingStart] = useState(null);
|
|
8401
8739
|
const [hoverDate, setHoverDate] = useState(null);
|
|
8402
8740
|
const weekdays = useMemo(
|
|
8403
8741
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8404
8742
|
[weekStartsOn]
|
|
8405
8743
|
);
|
|
8406
|
-
const isDisabled = (d) => min && d <
|
|
8744
|
+
const isDisabled = (d) => min && d < startOfDay3(min) || max && d > startOfDay3(max);
|
|
8407
8745
|
const effective = pendingStart ? { start: pendingStart, end: hoverDate } : value;
|
|
8408
8746
|
const inRange = (d) => {
|
|
8409
8747
|
const { start, end } = effective;
|
|
8410
8748
|
if (!start || !end) return false;
|
|
8411
8749
|
const [a, b] = start <= end ? [start, end] : [end, start];
|
|
8412
|
-
return d >=
|
|
8750
|
+
return d >= startOfDay3(a) && d <= startOfDay3(b);
|
|
8413
8751
|
};
|
|
8414
8752
|
const onDayClick = (d) => {
|
|
8415
8753
|
if (isDisabled(d)) return;
|
|
@@ -8516,7 +8854,7 @@ function DateRangePicker({
|
|
|
8516
8854
|
"button",
|
|
8517
8855
|
{
|
|
8518
8856
|
type: "button",
|
|
8519
|
-
onClick: () => setLeftMonth(
|
|
8857
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, -1)),
|
|
8520
8858
|
"aria-label": "Previous month",
|
|
8521
8859
|
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
8860
|
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 +8867,13 @@ function DateRangePicker({
|
|
|
8529
8867
|
"button",
|
|
8530
8868
|
{
|
|
8531
8869
|
type: "button",
|
|
8532
|
-
onClick: () => setLeftMonth(
|
|
8870
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, 1)),
|
|
8533
8871
|
"aria-label": "Next month",
|
|
8534
8872
|
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
8873
|
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
8874
|
}
|
|
8537
8875
|
),
|
|
8538
|
-
renderMonth(
|
|
8876
|
+
renderMonth(addMonths4(leftMonth, 1))
|
|
8539
8877
|
] })
|
|
8540
8878
|
] })
|
|
8541
8879
|
]
|
|
@@ -8664,6 +9002,6 @@ function ColorPicker({
|
|
|
8664
9002
|
] });
|
|
8665
9003
|
}
|
|
8666
9004
|
|
|
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 };
|
|
9005
|
+
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
9006
|
//# sourceMappingURL=index.js.map
|
|
8669
9007
|
//# sourceMappingURL=index.js.map
|