@geomak/ui 6.24.0 → 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 +858 -517
- 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 +633 -293
- package/dist/index.js.map +1 -1
- package/dist/styles.css +31 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkOAV4TA4B_cjs = require('./chunk-OAV4TA4B.cjs');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var
|
|
5
|
+
var React29 = require('react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var AvatarPrimitive = require('@radix-ui/react-avatar');
|
|
8
8
|
var DropdownMenu = require('@radix-ui/react-dropdown-menu');
|
|
@@ -12,12 +12,12 @@ var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
|
12
12
|
var TabsPrimitive = require('@radix-ui/react-tabs');
|
|
13
13
|
var AccordionPrimitive = require('@radix-ui/react-accordion');
|
|
14
14
|
var Popover = require('@radix-ui/react-popover');
|
|
15
|
+
var ToggleGroup = require('@radix-ui/react-toggle-group');
|
|
15
16
|
var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
|
|
16
17
|
var SwitchPrimitive = require('@radix-ui/react-switch');
|
|
17
18
|
var NavigationMenu = require('@radix-ui/react-navigation-menu');
|
|
18
19
|
var CheckboxPrimitive = require('@radix-ui/react-checkbox');
|
|
19
20
|
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
20
|
-
var ToggleGroup = require('@radix-ui/react-toggle-group');
|
|
21
21
|
var SliderPrimitive = require('@radix-ui/react-slider');
|
|
22
22
|
|
|
23
23
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -40,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
40
40
|
return Object.freeze(n);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var React29__default = /*#__PURE__*/_interopDefault(React29);
|
|
44
44
|
var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
|
|
45
45
|
var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
|
|
46
46
|
var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
|
|
@@ -48,12 +48,12 @@ var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitiv
|
|
|
48
48
|
var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
|
|
49
49
|
var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
|
|
50
50
|
var Popover__namespace = /*#__PURE__*/_interopNamespace(Popover);
|
|
51
|
+
var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
|
|
51
52
|
var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
|
|
52
53
|
var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
|
|
53
54
|
var NavigationMenu__namespace = /*#__PURE__*/_interopNamespace(NavigationMenu);
|
|
54
55
|
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
55
56
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
56
|
-
var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
|
|
57
57
|
var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
|
|
58
58
|
|
|
59
59
|
var Moon = ({ color = "gray" }) => /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.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" }) });
|
|
@@ -216,8 +216,8 @@ Icon.Copy = Copy;
|
|
|
216
216
|
Icon.CircleStack = CircleStack;
|
|
217
217
|
var icons_default = Icon;
|
|
218
218
|
function Portal({ children, target }) {
|
|
219
|
-
const [resolved, setResolved] =
|
|
220
|
-
|
|
219
|
+
const [resolved, setResolved] = React29.useState(null);
|
|
220
|
+
React29.useEffect(() => {
|
|
221
221
|
if (target === null) {
|
|
222
222
|
setResolved(null);
|
|
223
223
|
return;
|
|
@@ -651,7 +651,7 @@ function IconButton({
|
|
|
651
651
|
className = "",
|
|
652
652
|
style
|
|
653
653
|
}) {
|
|
654
|
-
const colorScheme =
|
|
654
|
+
const colorScheme = React29.useMemo(() => {
|
|
655
655
|
if (type === "primary") {
|
|
656
656
|
return "bg-accent text-accent-fg hover:bg-accent-hover";
|
|
657
657
|
}
|
|
@@ -730,7 +730,7 @@ var SIZE_CLASSES = {
|
|
|
730
730
|
md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
|
|
731
731
|
lg: "h-11 px-5 text-sm gap-2 rounded-xl"
|
|
732
732
|
};
|
|
733
|
-
var Button =
|
|
733
|
+
var Button = React29__default.default.forwardRef(function Button2({
|
|
734
734
|
content,
|
|
735
735
|
variant = "primary",
|
|
736
736
|
size = "md",
|
|
@@ -838,7 +838,7 @@ function MenuButton({
|
|
|
838
838
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
839
839
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
840
840
|
].join(" "),
|
|
841
|
-
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
841
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
842
842
|
item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border" }),
|
|
843
843
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
844
844
|
DropdownMenu__namespace.Item,
|
|
@@ -1081,9 +1081,9 @@ function Tooltip({
|
|
|
1081
1081
|
] }) });
|
|
1082
1082
|
}
|
|
1083
1083
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
1084
|
-
var TabsContext =
|
|
1084
|
+
var TabsContext = React29.createContext(null);
|
|
1085
1085
|
function useTabsContext() {
|
|
1086
|
-
const ctx =
|
|
1086
|
+
const ctx = React29.useContext(TabsContext);
|
|
1087
1087
|
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
|
|
1088
1088
|
return ctx;
|
|
1089
1089
|
}
|
|
@@ -1105,26 +1105,26 @@ function Tabs({
|
|
|
1105
1105
|
children
|
|
1106
1106
|
}) {
|
|
1107
1107
|
const isControlled = value !== void 0;
|
|
1108
|
-
const [internal, setInternal] =
|
|
1108
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
1109
1109
|
const current = isControlled ? value : internal;
|
|
1110
1110
|
const reduced = !!framerMotion.useReducedMotion();
|
|
1111
|
-
const indicatorId =
|
|
1112
|
-
const select =
|
|
1111
|
+
const indicatorId = React29.useId();
|
|
1112
|
+
const select = React29.useCallback((next) => {
|
|
1113
1113
|
if (!isControlled) setInternal(next);
|
|
1114
1114
|
onValueChange?.(next);
|
|
1115
1115
|
}, [isControlled, onValueChange]);
|
|
1116
|
-
const registry =
|
|
1117
|
-
const orderRef =
|
|
1118
|
-
const [, bump] =
|
|
1119
|
-
const registerTab =
|
|
1116
|
+
const registry = React29.useRef(/* @__PURE__ */ new Map());
|
|
1117
|
+
const orderRef = React29.useRef(0);
|
|
1118
|
+
const [, bump] = React29.useState(0);
|
|
1119
|
+
const registerTab = React29.useCallback((val, meta) => {
|
|
1120
1120
|
const existing = registry.current.get(val);
|
|
1121
1121
|
registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
|
|
1122
1122
|
if (!existing) bump((v) => v + 1);
|
|
1123
1123
|
}, []);
|
|
1124
|
-
const unregisterTab =
|
|
1124
|
+
const unregisterTab = React29.useCallback((val) => {
|
|
1125
1125
|
if (registry.current.delete(val)) bump((v) => v + 1);
|
|
1126
1126
|
}, []);
|
|
1127
|
-
const getTabs =
|
|
1127
|
+
const getTabs = React29.useCallback(() => [...registry.current.entries()].sort((a, b) => a[1].order - b[1].order).map(([val, m]) => ({ value: val, label: m.label, icon: m.icon, disabled: m.disabled })), []);
|
|
1128
1128
|
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1129
1129
|
TabsPrimitive__namespace.Root,
|
|
1130
1130
|
{
|
|
@@ -1144,10 +1144,10 @@ function Tabs({
|
|
|
1144
1144
|
function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
1145
1145
|
const { variant, orientation, reduced, value } = useTabsContext();
|
|
1146
1146
|
const horizontal = orientation === "horizontal";
|
|
1147
|
-
const scrollRef =
|
|
1148
|
-
const [edges, setEdges] =
|
|
1147
|
+
const scrollRef = React29.useRef(null);
|
|
1148
|
+
const [edges, setEdges] = React29.useState({ start: false, end: false });
|
|
1149
1149
|
const scrollable = variant !== "segmented";
|
|
1150
|
-
|
|
1150
|
+
React29.useLayoutEffect(() => {
|
|
1151
1151
|
const el = scrollRef.current;
|
|
1152
1152
|
if (!el || !scrollable) return;
|
|
1153
1153
|
const update = () => {
|
|
@@ -1172,13 +1172,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
|
1172
1172
|
ro.disconnect();
|
|
1173
1173
|
};
|
|
1174
1174
|
}, [horizontal, scrollable, children]);
|
|
1175
|
-
const nudge =
|
|
1175
|
+
const nudge = React29.useCallback((dir) => {
|
|
1176
1176
|
const el = scrollRef.current;
|
|
1177
1177
|
if (!el) return;
|
|
1178
1178
|
const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
|
|
1179
1179
|
el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
|
|
1180
1180
|
}, [horizontal, reduced]);
|
|
1181
|
-
|
|
1181
|
+
React29.useLayoutEffect(() => {
|
|
1182
1182
|
const el = scrollRef.current;
|
|
1183
1183
|
if (!el || !scrollable) return;
|
|
1184
1184
|
const active = el.querySelector("[role=tab][data-state=active]");
|
|
@@ -1236,9 +1236,9 @@ function Chevron2({ side, orientation, onClick }) {
|
|
|
1236
1236
|
function OverflowMenu() {
|
|
1237
1237
|
const { getTabs, value, select, orientation } = useTabsContext();
|
|
1238
1238
|
const horizontal = orientation === "horizontal";
|
|
1239
|
-
const [open, setOpen] =
|
|
1240
|
-
const wrapRef =
|
|
1241
|
-
const timer =
|
|
1239
|
+
const [open, setOpen] = React29.useState(false);
|
|
1240
|
+
const wrapRef = React29.useRef(null);
|
|
1241
|
+
const timer = React29.useRef(null);
|
|
1242
1242
|
const openNow = () => {
|
|
1243
1243
|
if (timer.current) clearTimeout(timer.current);
|
|
1244
1244
|
setOpen(true);
|
|
@@ -1246,7 +1246,7 @@ function OverflowMenu() {
|
|
|
1246
1246
|
const closeSoon = () => {
|
|
1247
1247
|
timer.current = setTimeout(() => setOpen(false), 160);
|
|
1248
1248
|
};
|
|
1249
|
-
|
|
1249
|
+
React29.useLayoutEffect(() => {
|
|
1250
1250
|
if (!open) return;
|
|
1251
1251
|
const onDoc = (e) => {
|
|
1252
1252
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1327,7 +1327,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
|
|
|
1327
1327
|
const isActive = active === value;
|
|
1328
1328
|
const horizontal = orientation === "horizontal";
|
|
1329
1329
|
const sz = SIZE[size];
|
|
1330
|
-
|
|
1330
|
+
React29.useLayoutEffect(() => {
|
|
1331
1331
|
registerTab(value, { label: children, icon, disabled });
|
|
1332
1332
|
return () => unregisterTab(value);
|
|
1333
1333
|
}, [value, children, icon, disabled, registerTab, unregisterTab]);
|
|
@@ -1525,7 +1525,7 @@ function Tree({
|
|
|
1525
1525
|
item.key
|
|
1526
1526
|
)) });
|
|
1527
1527
|
}
|
|
1528
|
-
var AccordionCtx =
|
|
1528
|
+
var AccordionCtx = React29.createContext({ variant: "separated" });
|
|
1529
1529
|
function Accordion2({
|
|
1530
1530
|
children,
|
|
1531
1531
|
type = "single",
|
|
@@ -1584,7 +1584,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
1584
1584
|
}
|
|
1585
1585
|
);
|
|
1586
1586
|
function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
|
|
1587
|
-
const { variant } =
|
|
1587
|
+
const { variant } = React29.useContext(AccordionCtx);
|
|
1588
1588
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1589
1589
|
AccordionPrimitive__namespace.Item,
|
|
1590
1590
|
{
|
|
@@ -1643,7 +1643,7 @@ function Breadcrumbs({
|
|
|
1643
1643
|
className = "",
|
|
1644
1644
|
style
|
|
1645
1645
|
}) {
|
|
1646
|
-
const [expanded, setExpanded] =
|
|
1646
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
1647
1647
|
const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
|
|
1648
1648
|
const visible = [];
|
|
1649
1649
|
if (shouldCollapse) {
|
|
@@ -1827,8 +1827,8 @@ function Stepper({
|
|
|
1827
1827
|
className = ""
|
|
1828
1828
|
}) {
|
|
1829
1829
|
const reduced = framerMotion.useReducedMotion();
|
|
1830
|
-
const [forcedVertical, setForcedVertical] =
|
|
1831
|
-
|
|
1830
|
+
const [forcedVertical, setForcedVertical] = React29.useState(false);
|
|
1831
|
+
React29.useEffect(() => {
|
|
1832
1832
|
if (!responsive || orientation === "vertical") return;
|
|
1833
1833
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1834
1834
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
@@ -1937,7 +1937,7 @@ function Kbd({
|
|
|
1937
1937
|
style
|
|
1938
1938
|
}) {
|
|
1939
1939
|
if (keys && keys.length > 0) {
|
|
1940
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1940
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
1941
1941
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
|
|
1942
1942
|
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
|
|
1943
1943
|
] }, `${k}-${i}`)) });
|
|
@@ -2028,13 +2028,13 @@ function FlatCarousel({
|
|
|
2028
2028
|
className = "",
|
|
2029
2029
|
style
|
|
2030
2030
|
}) {
|
|
2031
|
-
const scrollerRef =
|
|
2032
|
-
const slides =
|
|
2033
|
-
const [active, setActive] =
|
|
2034
|
-
const [atStart, setAtStart] =
|
|
2035
|
-
const [atEnd, setAtEnd] =
|
|
2031
|
+
const scrollerRef = React29.useRef(null);
|
|
2032
|
+
const slides = React29__default.default.Children.toArray(children);
|
|
2033
|
+
const [active, setActive] = React29.useState(0);
|
|
2034
|
+
const [atStart, setAtStart] = React29.useState(true);
|
|
2035
|
+
const [atEnd, setAtEnd] = React29.useState(false);
|
|
2036
2036
|
const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
|
|
2037
|
-
const update =
|
|
2037
|
+
const update = React29.useCallback(() => {
|
|
2038
2038
|
const el = scrollerRef.current;
|
|
2039
2039
|
if (!el) return;
|
|
2040
2040
|
setAtStart(el.scrollLeft <= 1);
|
|
@@ -2043,7 +2043,7 @@ function FlatCarousel({
|
|
|
2043
2043
|
const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
|
|
2044
2044
|
setActive(Math.round(el.scrollLeft / slideW));
|
|
2045
2045
|
}, [gap]);
|
|
2046
|
-
|
|
2046
|
+
React29.useEffect(() => {
|
|
2047
2047
|
update();
|
|
2048
2048
|
const el = scrollerRef.current;
|
|
2049
2049
|
if (!el) return;
|
|
@@ -2084,9 +2084,9 @@ function RotatingCarousel({
|
|
|
2084
2084
|
className = "",
|
|
2085
2085
|
style
|
|
2086
2086
|
}) {
|
|
2087
|
-
const slides =
|
|
2087
|
+
const slides = React29__default.default.Children.toArray(children);
|
|
2088
2088
|
const count = slides.length;
|
|
2089
|
-
const [active, setActive] =
|
|
2089
|
+
const [active, setActive] = React29.useState(0);
|
|
2090
2090
|
const reduced = framerMotion.useReducedMotion();
|
|
2091
2091
|
const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
|
|
2092
2092
|
const idx = wrap(active);
|
|
@@ -2236,7 +2236,7 @@ function FAB({
|
|
|
2236
2236
|
className = "",
|
|
2237
2237
|
style
|
|
2238
2238
|
}) {
|
|
2239
|
-
const [open, setOpen] =
|
|
2239
|
+
const [open, setOpen] = React29.useState(false);
|
|
2240
2240
|
const reduced = framerMotion.useReducedMotion();
|
|
2241
2241
|
const hasDial = !!actions && actions.length > 0;
|
|
2242
2242
|
const bottom = position.startsWith("bottom");
|
|
@@ -2338,8 +2338,8 @@ function PopConfirm({
|
|
|
2338
2338
|
onOpenChange,
|
|
2339
2339
|
className = ""
|
|
2340
2340
|
}) {
|
|
2341
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
2342
|
-
const [loading, setLoading] =
|
|
2341
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React29.useState(false);
|
|
2342
|
+
const [loading, setLoading] = React29.useState(false);
|
|
2343
2343
|
const isOpen = open ?? uncontrolledOpen;
|
|
2344
2344
|
const setOpen = (next) => {
|
|
2345
2345
|
onOpenChange?.(next);
|
|
@@ -2426,16 +2426,16 @@ function LogoutTimer({
|
|
|
2426
2426
|
logoutLabel = "Sign out now"
|
|
2427
2427
|
}) {
|
|
2428
2428
|
const reduced = framerMotion.useReducedMotion();
|
|
2429
|
-
const [warning, setWarning] =
|
|
2430
|
-
const [remaining, setRemaining] =
|
|
2431
|
-
const idleTimer =
|
|
2432
|
-
const tick =
|
|
2433
|
-
const deadline =
|
|
2434
|
-
const warningRef =
|
|
2435
|
-
const lastReset =
|
|
2436
|
-
const cbs =
|
|
2429
|
+
const [warning, setWarning] = React29.useState(false);
|
|
2430
|
+
const [remaining, setRemaining] = React29.useState(countdown);
|
|
2431
|
+
const idleTimer = React29.useRef(null);
|
|
2432
|
+
const tick = React29.useRef(null);
|
|
2433
|
+
const deadline = React29.useRef(0);
|
|
2434
|
+
const warningRef = React29.useRef(false);
|
|
2435
|
+
const lastReset = React29.useRef(0);
|
|
2436
|
+
const cbs = React29.useRef({ onLogout, onContinue, onWarning });
|
|
2437
2437
|
cbs.current = { onLogout, onContinue, onWarning };
|
|
2438
|
-
const clearTimers =
|
|
2438
|
+
const clearTimers = React29.useCallback(() => {
|
|
2439
2439
|
if (idleTimer.current) {
|
|
2440
2440
|
clearTimeout(idleTimer.current);
|
|
2441
2441
|
idleTimer.current = null;
|
|
@@ -2445,13 +2445,13 @@ function LogoutTimer({
|
|
|
2445
2445
|
tick.current = null;
|
|
2446
2446
|
}
|
|
2447
2447
|
}, []);
|
|
2448
|
-
const logout =
|
|
2448
|
+
const logout = React29.useCallback(() => {
|
|
2449
2449
|
clearTimers();
|
|
2450
2450
|
warningRef.current = false;
|
|
2451
2451
|
setWarning(false);
|
|
2452
2452
|
cbs.current.onLogout();
|
|
2453
2453
|
}, [clearTimers]);
|
|
2454
|
-
const startIdle =
|
|
2454
|
+
const startIdle = React29.useCallback(() => {
|
|
2455
2455
|
if (idleTimer.current) clearTimeout(idleTimer.current);
|
|
2456
2456
|
idleTimer.current = setTimeout(() => {
|
|
2457
2457
|
warningRef.current = true;
|
|
@@ -2466,7 +2466,7 @@ function LogoutTimer({
|
|
|
2466
2466
|
}, 250);
|
|
2467
2467
|
}, timeout);
|
|
2468
2468
|
}, [timeout, countdown, logout]);
|
|
2469
|
-
const stay =
|
|
2469
|
+
const stay = React29.useCallback(() => {
|
|
2470
2470
|
if (tick.current) {
|
|
2471
2471
|
clearInterval(tick.current);
|
|
2472
2472
|
tick.current = null;
|
|
@@ -2476,7 +2476,7 @@ function LogoutTimer({
|
|
|
2476
2476
|
cbs.current.onContinue?.();
|
|
2477
2477
|
startIdle();
|
|
2478
2478
|
}, [startIdle]);
|
|
2479
|
-
|
|
2479
|
+
React29.useEffect(() => {
|
|
2480
2480
|
if (!enabled) {
|
|
2481
2481
|
clearTimers();
|
|
2482
2482
|
warningRef.current = false;
|
|
@@ -2548,16 +2548,16 @@ function Calendar2({
|
|
|
2548
2548
|
className = "",
|
|
2549
2549
|
style
|
|
2550
2550
|
}) {
|
|
2551
|
-
const today =
|
|
2552
|
-
const [internalMonth, setInternalMonth] =
|
|
2551
|
+
const today = React29.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
2552
|
+
const [internalMonth, setInternalMonth] = React29.useState(() => month ?? defaultMonth ?? value ?? today);
|
|
2553
2553
|
const visible = month ?? internalMonth;
|
|
2554
2554
|
const setMonth = (next) => {
|
|
2555
2555
|
onMonthChange?.(next);
|
|
2556
2556
|
if (month === void 0) setInternalMonth(next);
|
|
2557
2557
|
};
|
|
2558
|
-
const grid =
|
|
2559
|
-
const weekdays =
|
|
2560
|
-
const eventsByDay =
|
|
2558
|
+
const grid = React29.useMemo(() => buildGrid(visible, weekStartsOn), [visible, weekStartsOn]);
|
|
2559
|
+
const weekdays = React29.useMemo(() => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]), [weekStartsOn]);
|
|
2560
|
+
const eventsByDay = React29.useMemo(() => {
|
|
2561
2561
|
const map = /* @__PURE__ */ new Map();
|
|
2562
2562
|
for (const ev of events ?? []) {
|
|
2563
2563
|
const key = startOfDay(ev.date).toDateString();
|
|
@@ -2600,7 +2600,7 @@ function Calendar2({
|
|
|
2600
2600
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-0.5", role: "grid", children: grid.map((d, i) => {
|
|
2601
2601
|
const inMonth = d.getMonth() === visible.getMonth();
|
|
2602
2602
|
const isSelected = value != null && sameDay(d, value);
|
|
2603
|
-
const
|
|
2603
|
+
const isToday2 = sameDay(d, today);
|
|
2604
2604
|
const isDisabled = disabled(d);
|
|
2605
2605
|
const dayEvents = eventsByDay.get(d.toDateString()) ?? [];
|
|
2606
2606
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2609,7 +2609,7 @@ function Calendar2({
|
|
|
2609
2609
|
type: "button",
|
|
2610
2610
|
role: "gridcell",
|
|
2611
2611
|
"aria-selected": isSelected,
|
|
2612
|
-
"aria-current":
|
|
2612
|
+
"aria-current": isToday2 ? "date" : void 0,
|
|
2613
2613
|
disabled: isDisabled,
|
|
2614
2614
|
onClick: () => onChange?.(startOfDay(d)),
|
|
2615
2615
|
className: [
|
|
@@ -2617,24 +2617,586 @@ function Calendar2({
|
|
|
2617
2617
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
2618
2618
|
isSelected ? "bg-accent text-accent-fg font-semibold" : inMonth ? "text-foreground hover:bg-surface-raised" : "text-foreground-muted hover:bg-surface-raised",
|
|
2619
2619
|
isDisabled ? "opacity-40 cursor-not-allowed hover:bg-transparent" : "",
|
|
2620
|
-
!isSelected &&
|
|
2620
|
+
!isSelected && isToday2 ? "ring-1 ring-inset ring-accent/60" : ""
|
|
2621
2621
|
].filter(Boolean).join(" "),
|
|
2622
2622
|
children: [
|
|
2623
2623
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "leading-none", children: d.getDate() }),
|
|
2624
2624
|
dayEvents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-1 flex gap-0.5", children: dayEvents.slice(0, 3).map((ev, j) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2625
2625
|
"span",
|
|
2626
2626
|
{
|
|
2627
|
-
title: ev.label,
|
|
2628
|
-
className: "h-1 w-1 rounded-full",
|
|
2629
|
-
style: { backgroundColor: ev.color ?? (isSelected ? "var(--color-accent-fg)" : "var(--color-accent)") }
|
|
2627
|
+
title: ev.label,
|
|
2628
|
+
className: "h-1 w-1 rounded-full",
|
|
2629
|
+
style: { backgroundColor: ev.color ?? (isSelected ? "var(--color-accent-fg)" : "var(--color-accent)") }
|
|
2630
|
+
},
|
|
2631
|
+
j
|
|
2632
|
+
)) })
|
|
2633
|
+
]
|
|
2634
|
+
},
|
|
2635
|
+
i
|
|
2636
|
+
);
|
|
2637
|
+
}) })
|
|
2638
|
+
] });
|
|
2639
|
+
}
|
|
2640
|
+
var FIELD_SIZE = {
|
|
2641
|
+
sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
|
|
2642
|
+
md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
|
|
2643
|
+
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
2644
|
+
};
|
|
2645
|
+
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
|
|
2646
|
+
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
|
|
2647
|
+
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
|
|
2648
|
+
var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
|
|
2649
|
+
function fieldShell({
|
|
2650
|
+
size = "md",
|
|
2651
|
+
hasError = false,
|
|
2652
|
+
disabled = false,
|
|
2653
|
+
focusWithin = false,
|
|
2654
|
+
sized = true
|
|
2655
|
+
} = {}) {
|
|
2656
|
+
const s = FIELD_SIZE[size];
|
|
2657
|
+
return [
|
|
2658
|
+
"w-full rounded-lg border bg-surface text-foreground",
|
|
2659
|
+
"transition-[color,box-shadow,border-color] duration-150",
|
|
2660
|
+
s.text,
|
|
2661
|
+
sized ? `${s.control} ${s.padX}` : "",
|
|
2662
|
+
// resting border
|
|
2663
|
+
hasError ? "border-status-error" : "border-border",
|
|
2664
|
+
// hover (only when interactive + no error)
|
|
2665
|
+
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
2666
|
+
// focus
|
|
2667
|
+
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
2668
|
+
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
2669
|
+
// placeholder colour for native inputs
|
|
2670
|
+
"placeholder:text-foreground-muted"
|
|
2671
|
+
].filter(Boolean).join(" ");
|
|
2672
|
+
}
|
|
2673
|
+
function FieldHelpIcon({ text }) {
|
|
2674
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2675
|
+
"button",
|
|
2676
|
+
{
|
|
2677
|
+
type: "button",
|
|
2678
|
+
"aria-label": "More information",
|
|
2679
|
+
className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
|
|
2680
|
+
children: /* @__PURE__ */ jsxRuntime.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: [
|
|
2681
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
|
|
2682
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
|
|
2683
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
|
|
2684
|
+
] })
|
|
2685
|
+
}
|
|
2686
|
+
) });
|
|
2687
|
+
}
|
|
2688
|
+
function FieldLabel({
|
|
2689
|
+
label,
|
|
2690
|
+
htmlFor,
|
|
2691
|
+
required,
|
|
2692
|
+
helperText,
|
|
2693
|
+
horizontal = false,
|
|
2694
|
+
align = "start",
|
|
2695
|
+
style,
|
|
2696
|
+
width,
|
|
2697
|
+
className = ""
|
|
2698
|
+
}) {
|
|
2699
|
+
if (label == null && helperText == null) return null;
|
|
2700
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2701
|
+
"div",
|
|
2702
|
+
{
|
|
2703
|
+
style: { width: horizontal ? width : void 0, ...style },
|
|
2704
|
+
className: [
|
|
2705
|
+
"flex items-center gap-1",
|
|
2706
|
+
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
2707
|
+
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
2708
|
+
// on the row's items-center to line up with a short control.
|
|
2709
|
+
horizontal && align === "start" ? "mt-2" : "",
|
|
2710
|
+
className
|
|
2711
|
+
].filter(Boolean).join(" "),
|
|
2712
|
+
children: [
|
|
2713
|
+
label != null && /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
|
|
2714
|
+
label,
|
|
2715
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
2716
|
+
] }),
|
|
2717
|
+
helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
|
|
2718
|
+
]
|
|
2719
|
+
}
|
|
2720
|
+
);
|
|
2721
|
+
}
|
|
2722
|
+
function Field({
|
|
2723
|
+
label,
|
|
2724
|
+
htmlFor,
|
|
2725
|
+
errorId,
|
|
2726
|
+
errorMessage,
|
|
2727
|
+
layout = "vertical",
|
|
2728
|
+
required,
|
|
2729
|
+
helperText,
|
|
2730
|
+
labelAlign = "start",
|
|
2731
|
+
labelStyle,
|
|
2732
|
+
labelWidth,
|
|
2733
|
+
className = "",
|
|
2734
|
+
children
|
|
2735
|
+
}) {
|
|
2736
|
+
const hasError = errorMessage != null;
|
|
2737
|
+
const horizontal = layout === "horizontal";
|
|
2738
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2739
|
+
"div",
|
|
2740
|
+
{
|
|
2741
|
+
className: [
|
|
2742
|
+
"flex",
|
|
2743
|
+
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
2744
|
+
className
|
|
2745
|
+
].filter(Boolean).join(" "),
|
|
2746
|
+
children: [
|
|
2747
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2748
|
+
FieldLabel,
|
|
2749
|
+
{
|
|
2750
|
+
label,
|
|
2751
|
+
htmlFor,
|
|
2752
|
+
required,
|
|
2753
|
+
helperText,
|
|
2754
|
+
horizontal,
|
|
2755
|
+
align: labelAlign,
|
|
2756
|
+
style: labelStyle,
|
|
2757
|
+
width: labelWidth
|
|
2758
|
+
}
|
|
2759
|
+
),
|
|
2760
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
2761
|
+
children,
|
|
2762
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
2763
|
+
] })
|
|
2764
|
+
]
|
|
2765
|
+
}
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
var SIZE5 = {
|
|
2769
|
+
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
2770
|
+
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
2771
|
+
lg: { h: "h-control-lg", text: "text-sm", pad: "px-4" }
|
|
2772
|
+
};
|
|
2773
|
+
function SegmentedControl({
|
|
2774
|
+
options,
|
|
2775
|
+
value,
|
|
2776
|
+
defaultValue,
|
|
2777
|
+
onChange,
|
|
2778
|
+
size = "md",
|
|
2779
|
+
fullWidth = false,
|
|
2780
|
+
disabled,
|
|
2781
|
+
label,
|
|
2782
|
+
layout = "vertical",
|
|
2783
|
+
helperText,
|
|
2784
|
+
className,
|
|
2785
|
+
name,
|
|
2786
|
+
required,
|
|
2787
|
+
errorMessage,
|
|
2788
|
+
"aria-label": ariaLabel
|
|
2789
|
+
}) {
|
|
2790
|
+
const sz = SIZE5[size];
|
|
2791
|
+
const groupId = React29.useId();
|
|
2792
|
+
const errorId = React29.useId();
|
|
2793
|
+
const hasError = errorMessage != null;
|
|
2794
|
+
const isControlled = value !== void 0;
|
|
2795
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
2796
|
+
const current = isControlled ? value : internal;
|
|
2797
|
+
const handle = (v) => {
|
|
2798
|
+
if (!v) return;
|
|
2799
|
+
if (!isControlled) setInternal(v);
|
|
2800
|
+
onChange?.(v);
|
|
2801
|
+
};
|
|
2802
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2803
|
+
Field,
|
|
2804
|
+
{
|
|
2805
|
+
className,
|
|
2806
|
+
label,
|
|
2807
|
+
htmlFor: groupId,
|
|
2808
|
+
errorId,
|
|
2809
|
+
errorMessage,
|
|
2810
|
+
layout,
|
|
2811
|
+
required,
|
|
2812
|
+
helperText,
|
|
2813
|
+
children: [
|
|
2814
|
+
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: current ?? "" }),
|
|
2815
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2816
|
+
ToggleGroup__namespace.Root,
|
|
2817
|
+
{
|
|
2818
|
+
id: groupId,
|
|
2819
|
+
type: "single",
|
|
2820
|
+
value: current,
|
|
2821
|
+
onValueChange: handle,
|
|
2822
|
+
disabled,
|
|
2823
|
+
"aria-label": ariaLabel ?? (typeof label === "string" ? label : void 0),
|
|
2824
|
+
"aria-invalid": hasError || void 0,
|
|
2825
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
2826
|
+
className: [
|
|
2827
|
+
"inline-flex items-center gap-1 rounded-lg border bg-surface-raised p-1",
|
|
2828
|
+
hasError ? "border-status-error" : "border-border",
|
|
2829
|
+
sz.h,
|
|
2830
|
+
fullWidth ? "flex w-full" : "w-fit",
|
|
2831
|
+
disabled ? "opacity-60 cursor-not-allowed" : ""
|
|
2832
|
+
].filter(Boolean).join(" "),
|
|
2833
|
+
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2834
|
+
ToggleGroup__namespace.Item,
|
|
2835
|
+
{
|
|
2836
|
+
value: opt.value,
|
|
2837
|
+
disabled: opt.disabled,
|
|
2838
|
+
className: [
|
|
2839
|
+
"inline-flex items-center justify-center gap-1.5 rounded-md select-none whitespace-nowrap",
|
|
2840
|
+
"transition-colors duration-150 h-full",
|
|
2841
|
+
sz.text,
|
|
2842
|
+
sz.pad,
|
|
2843
|
+
fullWidth ? "flex-1" : "",
|
|
2844
|
+
// Resting: muted text, transparent. Hover lifts the text.
|
|
2845
|
+
"text-foreground-secondary hover:text-foreground",
|
|
2846
|
+
// Active: surface-white pill + accent text + subtle shadow.
|
|
2847
|
+
"data-[state=on]:bg-surface data-[state=on]:text-accent data-[state=on]:shadow-sm",
|
|
2848
|
+
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
2849
|
+
"disabled:opacity-40 disabled:cursor-not-allowed"
|
|
2850
|
+
].filter(Boolean).join(" "),
|
|
2851
|
+
children: [
|
|
2852
|
+
opt.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: opt.icon }),
|
|
2853
|
+
opt.label
|
|
2854
|
+
]
|
|
2855
|
+
},
|
|
2856
|
+
opt.value
|
|
2857
|
+
))
|
|
2858
|
+
}
|
|
2859
|
+
)
|
|
2860
|
+
]
|
|
2861
|
+
}
|
|
2862
|
+
);
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
// src/components/core/scheduler.utils.ts
|
|
2866
|
+
var MONTHS2 = [
|
|
2867
|
+
"January",
|
|
2868
|
+
"February",
|
|
2869
|
+
"March",
|
|
2870
|
+
"April",
|
|
2871
|
+
"May",
|
|
2872
|
+
"June",
|
|
2873
|
+
"July",
|
|
2874
|
+
"August",
|
|
2875
|
+
"September",
|
|
2876
|
+
"October",
|
|
2877
|
+
"November",
|
|
2878
|
+
"December"
|
|
2879
|
+
];
|
|
2880
|
+
var WEEKDAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2881
|
+
var toDate = (d) => d instanceof Date ? d : new Date(d);
|
|
2882
|
+
var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2883
|
+
var addDays = (d, n) => {
|
|
2884
|
+
const x = new Date(d);
|
|
2885
|
+
x.setDate(x.getDate() + n);
|
|
2886
|
+
return x;
|
|
2887
|
+
};
|
|
2888
|
+
var addMonths2 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
2889
|
+
var sameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2890
|
+
var isToday = (d) => sameDay2(d, /* @__PURE__ */ new Date());
|
|
2891
|
+
var isSameMonth = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
2892
|
+
var startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
2893
|
+
var endOfMonth = (d) => new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
2894
|
+
var startOfWeek = (d, weekStartsOn) => {
|
|
2895
|
+
const x = startOfDay2(d);
|
|
2896
|
+
const diff = (x.getDay() - weekStartsOn + 7) % 7;
|
|
2897
|
+
return addDays(x, -diff);
|
|
2898
|
+
};
|
|
2899
|
+
var buildMonthGrid = (cursor, weekStartsOn) => {
|
|
2900
|
+
const start = startOfWeek(startOfMonth(cursor), weekStartsOn);
|
|
2901
|
+
return Array.from({ length: 42 }, (_, i) => addDays(start, i));
|
|
2902
|
+
};
|
|
2903
|
+
var getWeekDays = (cursor, weekStartsOn) => {
|
|
2904
|
+
const start = startOfWeek(cursor, weekStartsOn);
|
|
2905
|
+
return Array.from({ length: 7 }, (_, i) => addDays(start, i));
|
|
2906
|
+
};
|
|
2907
|
+
var monthRange = (cursor) => ({
|
|
2908
|
+
from: startOfMonth(cursor),
|
|
2909
|
+
to: endOfMonth(cursor)
|
|
2910
|
+
});
|
|
2911
|
+
var weekRange = (cursor, weekStartsOn) => {
|
|
2912
|
+
const from = startOfWeek(cursor, weekStartsOn);
|
|
2913
|
+
return { from, to: addDays(from, 6) };
|
|
2914
|
+
};
|
|
2915
|
+
var weekdayLabels = (weekStartsOn) => Array.from({ length: 7 }, (_, i) => WEEKDAYS2[(i + weekStartsOn) % 7]);
|
|
2916
|
+
var monthYearLabel = (d) => `${MONTHS2[d.getMonth()]} ${d.getFullYear()}`;
|
|
2917
|
+
var weekLabel = (cursor, weekStartsOn) => {
|
|
2918
|
+
const from = startOfWeek(cursor, weekStartsOn);
|
|
2919
|
+
const to = addDays(from, 6);
|
|
2920
|
+
const m = (d) => MONTHS2[d.getMonth()].slice(0, 3);
|
|
2921
|
+
if (from.getMonth() === to.getMonth()) {
|
|
2922
|
+
return `${m(from)} ${from.getDate()} \u2013 ${to.getDate()}, ${to.getFullYear()}`;
|
|
2923
|
+
}
|
|
2924
|
+
const yearPart = from.getFullYear() === to.getFullYear() ? `${to.getFullYear()}` : "";
|
|
2925
|
+
return `${m(from)} ${from.getDate()} \u2013 ${m(to)} ${to.getDate()}${yearPart ? `, ${yearPart}` : `, ${from.getFullYear()}/${to.getFullYear()}`}`;
|
|
2926
|
+
};
|
|
2927
|
+
var minutesIntoDay = (d) => d.getHours() * 60 + d.getMinutes();
|
|
2928
|
+
var hourLabel = (hour) => `${String(hour).padStart(2, "0")}:00`;
|
|
2929
|
+
var timeLabel = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
2930
|
+
var normalize = (e) => {
|
|
2931
|
+
const start = toDate(e.start);
|
|
2932
|
+
const end = e.end ? toDate(e.end) : new Date(start.getTime() + 36e5);
|
|
2933
|
+
return { ...e, start, end };
|
|
2934
|
+
};
|
|
2935
|
+
var Spinner2 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-5 w-5 animate-spin text-accent", children: /* @__PURE__ */ jsxRuntime.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" }) });
|
|
2936
|
+
var Plus = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12h14" }) });
|
|
2937
|
+
var Chevron4 = ({ dir }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: dir === "left" ? "M15 19l-7-7 7-7" : "M9 5l7 7-7 7" }) });
|
|
2938
|
+
function Scheduler({
|
|
2939
|
+
events: controlledEvents,
|
|
2940
|
+
loadEvents,
|
|
2941
|
+
defaultView = "month",
|
|
2942
|
+
defaultDate,
|
|
2943
|
+
weekStartsOn = 0,
|
|
2944
|
+
dayHours = [0, 24],
|
|
2945
|
+
hourHeight = 48,
|
|
2946
|
+
onSelectSlot,
|
|
2947
|
+
onSelectEvent,
|
|
2948
|
+
onNewEvent,
|
|
2949
|
+
className = "",
|
|
2950
|
+
style
|
|
2951
|
+
}) {
|
|
2952
|
+
const reduced = framerMotion.useReducedMotion();
|
|
2953
|
+
const [view, setView] = React29.useState(defaultView);
|
|
2954
|
+
const [cursor, setCursor] = React29.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2955
|
+
const [loaded, setLoaded] = React29.useState([]);
|
|
2956
|
+
const [loading, setLoading] = React29.useState(false);
|
|
2957
|
+
const [dir, setDir] = React29.useState(0);
|
|
2958
|
+
const loaderRef = React29.useRef(loadEvents);
|
|
2959
|
+
loaderRef.current = loadEvents;
|
|
2960
|
+
const range = React29.useMemo(
|
|
2961
|
+
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2962
|
+
[view, cursor, weekStartsOn]
|
|
2963
|
+
);
|
|
2964
|
+
const fromKey = range.from.getTime();
|
|
2965
|
+
const toKey = range.to.getTime();
|
|
2966
|
+
React29.useEffect(() => {
|
|
2967
|
+
const loader = loaderRef.current;
|
|
2968
|
+
if (!loader) return;
|
|
2969
|
+
let cancelled = false;
|
|
2970
|
+
setLoading(true);
|
|
2971
|
+
Promise.resolve(loader({ from: new Date(fromKey), to: new Date(toKey) }, view)).then((evts) => {
|
|
2972
|
+
if (!cancelled) setLoaded(evts);
|
|
2973
|
+
}).catch(() => {
|
|
2974
|
+
if (!cancelled) setLoaded([]);
|
|
2975
|
+
}).finally(() => {
|
|
2976
|
+
if (!cancelled) setLoading(false);
|
|
2977
|
+
});
|
|
2978
|
+
return () => {
|
|
2979
|
+
cancelled = true;
|
|
2980
|
+
};
|
|
2981
|
+
}, [fromKey, toKey, view]);
|
|
2982
|
+
const events = React29.useMemo(
|
|
2983
|
+
() => (controlledEvents ?? loaded).map(normalize),
|
|
2984
|
+
[controlledEvents, loaded]
|
|
2985
|
+
);
|
|
2986
|
+
const go = React29.useCallback((delta) => {
|
|
2987
|
+
setDir(delta);
|
|
2988
|
+
setCursor((c) => view === "month" ? addMonths2(c, delta) : addDays(c, delta * 7));
|
|
2989
|
+
}, [view]);
|
|
2990
|
+
const goToday = React29.useCallback(() => {
|
|
2991
|
+
setDir(0);
|
|
2992
|
+
setCursor(/* @__PURE__ */ new Date());
|
|
2993
|
+
}, []);
|
|
2994
|
+
const title = view === "month" ? monthYearLabel(cursor) : weekLabel(cursor, weekStartsOn);
|
|
2995
|
+
const slide = reduced ? { duration: 0 } : { duration: 0.22, ease: [0.16, 1, 0.3, 1] };
|
|
2996
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2997
|
+
"div",
|
|
2998
|
+
{
|
|
2999
|
+
className: ["flex flex-col overflow-hidden rounded-xl border border-border bg-surface", className].filter(Boolean).join(" "),
|
|
3000
|
+
style,
|
|
3001
|
+
children: [
|
|
3002
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3", children: [
|
|
3003
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3004
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron4, { dir: "left" }), title: "Previous", onClick: () => go(-1) }),
|
|
3005
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron4, { dir: "right" }), title: "Next", onClick: () => go(1) }),
|
|
3006
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { variant: "ghost", size: "sm", content: "Today", onClick: goToday }),
|
|
3007
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "ml-1 min-w-[9rem] text-base font-semibold tracking-tight text-foreground", children: [
|
|
3008
|
+
title,
|
|
3009
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 inline-flex translate-y-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner2, {}) })
|
|
3010
|
+
] })
|
|
3011
|
+
] }),
|
|
3012
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3013
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3014
|
+
SegmentedControl,
|
|
3015
|
+
{
|
|
3016
|
+
size: "sm",
|
|
3017
|
+
"aria-label": "Calendar view",
|
|
3018
|
+
value: view,
|
|
3019
|
+
onChange: (v) => setView(v),
|
|
3020
|
+
options: [{ value: "month", label: "Month" }, { value: "week", label: "Week" }]
|
|
3021
|
+
}
|
|
3022
|
+
),
|
|
3023
|
+
onNewEvent && /* @__PURE__ */ jsxRuntime.jsx(Button_default, { size: "sm", icon: /* @__PURE__ */ jsxRuntime.jsx(Plus, {}), content: "New event", onClick: onNewEvent })
|
|
3024
|
+
] })
|
|
3025
|
+
] }),
|
|
3026
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3027
|
+
framerMotion.motion.div,
|
|
3028
|
+
{
|
|
3029
|
+
initial: { opacity: 0, x: reduced ? 0 : dir * 24 },
|
|
3030
|
+
animate: { opacity: 1, x: 0 },
|
|
3031
|
+
transition: slide,
|
|
3032
|
+
className: "h-full",
|
|
3033
|
+
children: view === "month" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3034
|
+
MonthView,
|
|
3035
|
+
{
|
|
3036
|
+
cursor,
|
|
3037
|
+
weekStartsOn,
|
|
3038
|
+
events,
|
|
3039
|
+
onSelectSlot,
|
|
3040
|
+
onSelectEvent
|
|
3041
|
+
}
|
|
3042
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3043
|
+
WeekView,
|
|
3044
|
+
{
|
|
3045
|
+
cursor,
|
|
3046
|
+
weekStartsOn,
|
|
3047
|
+
events,
|
|
3048
|
+
dayHours,
|
|
3049
|
+
hourHeight,
|
|
3050
|
+
onSelectSlot,
|
|
3051
|
+
onSelectEvent
|
|
3052
|
+
}
|
|
3053
|
+
)
|
|
3054
|
+
},
|
|
3055
|
+
`${view}-${range.from.getTime()}`
|
|
3056
|
+
) })
|
|
3057
|
+
]
|
|
3058
|
+
}
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
var MAX_CHIPS = 3;
|
|
3062
|
+
function MonthView({
|
|
3063
|
+
cursor,
|
|
3064
|
+
weekStartsOn,
|
|
3065
|
+
events,
|
|
3066
|
+
onSelectSlot,
|
|
3067
|
+
onSelectEvent
|
|
3068
|
+
}) {
|
|
3069
|
+
const grid = React29.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3070
|
+
const labels = weekdayLabels(weekStartsOn);
|
|
3071
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3072
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 border-b border-border", children: labels.map((l) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-center text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: l }, l)) }),
|
|
3073
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-6", children: grid.map((day, i) => {
|
|
3074
|
+
const inMonth = isSameMonth(day, cursor);
|
|
3075
|
+
const dayEvents = events.filter((e) => sameDay2(e.start, day));
|
|
3076
|
+
const today = isToday(day);
|
|
3077
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3078
|
+
"button",
|
|
3079
|
+
{
|
|
3080
|
+
type: "button",
|
|
3081
|
+
onClick: () => onSelectSlot?.(day),
|
|
3082
|
+
className: [
|
|
3083
|
+
"group flex min-h-[5rem] flex-col gap-1 border-b border-r border-border p-1.5 text-left transition-colors",
|
|
3084
|
+
"[&:nth-child(7n)]:border-r-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
|
|
3085
|
+
inMonth ? "bg-surface hover:bg-surface-raised" : "bg-background/40"
|
|
3086
|
+
].join(" "),
|
|
3087
|
+
children: [
|
|
3088
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3089
|
+
"span",
|
|
3090
|
+
{
|
|
3091
|
+
className: [
|
|
3092
|
+
"flex h-6 w-6 items-center justify-center self-start rounded-full text-xs tabular-nums",
|
|
3093
|
+
today ? "bg-accent font-semibold text-accent-fg" : inMonth ? "text-foreground" : "text-foreground-muted"
|
|
3094
|
+
].join(" "),
|
|
3095
|
+
children: day.getDate()
|
|
3096
|
+
}
|
|
3097
|
+
),
|
|
3098
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3099
|
+
dayEvents.slice(0, MAX_CHIPS).map((e) => /* @__PURE__ */ jsxRuntime.jsx(EventChip, { event: e, onSelect: onSelectEvent }, e.id)),
|
|
3100
|
+
dayEvents.length > MAX_CHIPS && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-1 text-[11px] font-medium text-foreground-muted", children: [
|
|
3101
|
+
"+",
|
|
3102
|
+
dayEvents.length - MAX_CHIPS,
|
|
3103
|
+
" more"
|
|
3104
|
+
] })
|
|
3105
|
+
] })
|
|
3106
|
+
]
|
|
3107
|
+
},
|
|
3108
|
+
i
|
|
3109
|
+
);
|
|
3110
|
+
}) })
|
|
3111
|
+
] });
|
|
3112
|
+
}
|
|
3113
|
+
function EventChip({ event, onSelect }) {
|
|
3114
|
+
const color = event.color ?? "var(--color-accent)";
|
|
3115
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3116
|
+
"button",
|
|
3117
|
+
{
|
|
3118
|
+
type: "button",
|
|
3119
|
+
onClick: (e) => {
|
|
3120
|
+
e.stopPropagation();
|
|
3121
|
+
onSelect?.(event);
|
|
3122
|
+
},
|
|
3123
|
+
title: `${event.title} \xB7 ${timeLabel(event.start)}`,
|
|
3124
|
+
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",
|
|
3125
|
+
children: [
|
|
3126
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
3127
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: event.title })
|
|
3128
|
+
]
|
|
3129
|
+
}
|
|
3130
|
+
);
|
|
3131
|
+
}
|
|
3132
|
+
function WeekView({
|
|
3133
|
+
cursor,
|
|
3134
|
+
weekStartsOn,
|
|
3135
|
+
events,
|
|
3136
|
+
dayHours,
|
|
3137
|
+
hourHeight,
|
|
3138
|
+
onSelectSlot,
|
|
3139
|
+
onSelectEvent
|
|
3140
|
+
}) {
|
|
3141
|
+
const days = React29.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3142
|
+
const [startHour, endHour] = dayHours;
|
|
3143
|
+
const hours = React29.useMemo(
|
|
3144
|
+
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3145
|
+
[startHour, endHour]
|
|
3146
|
+
);
|
|
3147
|
+
const spanMinutes = (endHour - startHour) * 60;
|
|
3148
|
+
const gridHeight = hours.length * hourHeight;
|
|
3149
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
|
|
3150
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid border-b border-border", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)` }, children: [
|
|
3151
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-r border-border" }),
|
|
3152
|
+
days.map((d) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-r border-border px-1 py-1.5 text-center last:border-r-0", children: [
|
|
3153
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: weekdayLabels(weekStartsOn)[(d.getDay() - weekStartsOn + 7) % 7] }),
|
|
3154
|
+
/* @__PURE__ */ jsxRuntime.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() })
|
|
3155
|
+
] }, d.getTime()))
|
|
3156
|
+
] }),
|
|
3157
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)`, height: gridHeight }, children: [
|
|
3158
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative border-r border-border", children: hours.map((h, i) => /* @__PURE__ */ jsxRuntime.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)) }),
|
|
3159
|
+
days.map((day) => {
|
|
3160
|
+
const dayEvents = events.filter((e) => sameDay2(e.start, day) && !e.allDay);
|
|
3161
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative border-r border-border last:border-r-0", children: [
|
|
3162
|
+
hours.map((h, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3163
|
+
"button",
|
|
3164
|
+
{
|
|
3165
|
+
type: "button",
|
|
3166
|
+
"aria-label": `${weekdayLabels(weekStartsOn)[(day.getDay() - weekStartsOn + 7) % 7]} ${day.getDate()} ${hourLabel(h)}`,
|
|
3167
|
+
onClick: () => onSelectSlot?.(new Date(day.getFullYear(), day.getMonth(), day.getDate(), h)),
|
|
3168
|
+
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",
|
|
3169
|
+
style: { top: i * hourHeight, height: hourHeight }
|
|
3170
|
+
},
|
|
3171
|
+
h
|
|
3172
|
+
)),
|
|
3173
|
+
dayEvents.map((e) => {
|
|
3174
|
+
const top = (minutesIntoDay(e.start) - startHour * 60) / spanMinutes * gridHeight;
|
|
3175
|
+
const durMin = Math.max(20, (e.end.getTime() - e.start.getTime()) / 6e4);
|
|
3176
|
+
const height = durMin / spanMinutes * gridHeight;
|
|
3177
|
+
const color = e.color ?? "var(--color-accent)";
|
|
3178
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3179
|
+
"button",
|
|
3180
|
+
{
|
|
3181
|
+
type: "button",
|
|
3182
|
+
onClick: (ev) => {
|
|
3183
|
+
ev.stopPropagation();
|
|
3184
|
+
onSelectEvent?.(e);
|
|
3185
|
+
},
|
|
3186
|
+
title: `${e.title} \xB7 ${timeLabel(e.start)}\u2013${timeLabel(e.end)}`,
|
|
3187
|
+
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",
|
|
3188
|
+
style: { top: Math.max(0, top), height, borderLeftColor: color, backgroundColor: `color-mix(in oklab, ${color} 16%, var(--color-surface))` },
|
|
3189
|
+
children: [
|
|
3190
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate font-medium", children: e.title }),
|
|
3191
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-foreground-muted", children: timeLabel(e.start) })
|
|
3192
|
+
]
|
|
2630
3193
|
},
|
|
2631
|
-
|
|
2632
|
-
)
|
|
2633
|
-
|
|
2634
|
-
},
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
}) })
|
|
3194
|
+
e.id
|
|
3195
|
+
);
|
|
3196
|
+
})
|
|
3197
|
+
] }, day.getTime());
|
|
3198
|
+
})
|
|
3199
|
+
] }) })
|
|
2638
3200
|
] });
|
|
2639
3201
|
}
|
|
2640
3202
|
function DefaultIllustration() {
|
|
@@ -2764,17 +3326,17 @@ function Cart({
|
|
|
2764
3326
|
] })
|
|
2765
3327
|
] });
|
|
2766
3328
|
}
|
|
2767
|
-
var CartContext =
|
|
3329
|
+
var CartContext = React29.createContext(null);
|
|
2768
3330
|
var clampQty = (qty, max) => {
|
|
2769
3331
|
const lower = Math.max(1, Math.round(qty));
|
|
2770
3332
|
return max != null ? Math.min(lower, max) : lower;
|
|
2771
3333
|
};
|
|
2772
3334
|
function CartProvider({ children, initialItems = [], onChange }) {
|
|
2773
|
-
const [items, setItems] =
|
|
2774
|
-
|
|
3335
|
+
const [items, setItems] = React29.useState(initialItems);
|
|
3336
|
+
React29.useEffect(() => {
|
|
2775
3337
|
onChange?.(items);
|
|
2776
3338
|
}, [items]);
|
|
2777
|
-
const addToCart =
|
|
3339
|
+
const addToCart = React29.useCallback((item, quantity) => {
|
|
2778
3340
|
const addQty = quantity ?? item.quantity ?? 1;
|
|
2779
3341
|
setItems((prev) => {
|
|
2780
3342
|
const existing = prev.find((it) => it.id === item.id);
|
|
@@ -2787,29 +3349,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
|
|
|
2787
3349
|
return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
|
|
2788
3350
|
});
|
|
2789
3351
|
}, []);
|
|
2790
|
-
const removeFromCart =
|
|
3352
|
+
const removeFromCart = React29.useCallback((id) => {
|
|
2791
3353
|
setItems((prev) => prev.filter((it) => it.id !== id));
|
|
2792
3354
|
}, []);
|
|
2793
|
-
const updateQuantity =
|
|
3355
|
+
const updateQuantity = React29.useCallback((id, quantity) => {
|
|
2794
3356
|
setItems(
|
|
2795
3357
|
(prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
|
|
2796
3358
|
);
|
|
2797
3359
|
}, []);
|
|
2798
|
-
const clearCart =
|
|
2799
|
-
const isInCart =
|
|
2800
|
-
const getItemCount =
|
|
2801
|
-
const getCartTotal =
|
|
3360
|
+
const clearCart = React29.useCallback(() => setItems([]), []);
|
|
3361
|
+
const isInCart = React29.useCallback((id) => items.some((it) => it.id === id), [items]);
|
|
3362
|
+
const getItemCount = React29.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
|
|
3363
|
+
const getCartTotal = React29.useCallback(
|
|
2802
3364
|
() => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
|
|
2803
3365
|
[items]
|
|
2804
3366
|
);
|
|
2805
|
-
const value =
|
|
3367
|
+
const value = React29.useMemo(
|
|
2806
3368
|
() => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
|
|
2807
3369
|
[items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
|
|
2808
3370
|
);
|
|
2809
3371
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
2810
3372
|
}
|
|
2811
3373
|
function useCart() {
|
|
2812
|
-
const ctx =
|
|
3374
|
+
const ctx = React29.useContext(CartContext);
|
|
2813
3375
|
if (!ctx) {
|
|
2814
3376
|
throw new Error("useCart must be used within a <CartProvider>.");
|
|
2815
3377
|
}
|
|
@@ -3143,11 +3705,11 @@ function buildBindings(store, name, kind, snap) {
|
|
|
3143
3705
|
|
|
3144
3706
|
// src/form/useForm.ts
|
|
3145
3707
|
function useForm(options = {}) {
|
|
3146
|
-
const ref =
|
|
3708
|
+
const ref = React29.useRef(null);
|
|
3147
3709
|
if (ref.current === null) ref.current = new FormStore(options);
|
|
3148
3710
|
const store = ref.current;
|
|
3149
|
-
|
|
3150
|
-
const make =
|
|
3711
|
+
React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3712
|
+
const make = React29.useCallback(
|
|
3151
3713
|
(kind) => (name, rules) => {
|
|
3152
3714
|
if (rules !== void 0) store.setRule(name, rules);
|
|
3153
3715
|
return buildBindings(store, name, kind, store.getFieldSnapshot(name));
|
|
@@ -3176,9 +3738,9 @@ function useForm(options = {}) {
|
|
|
3176
3738
|
fieldTarget: make("target")
|
|
3177
3739
|
};
|
|
3178
3740
|
}
|
|
3179
|
-
var FormContext =
|
|
3741
|
+
var FormContext = React29.createContext(null);
|
|
3180
3742
|
function useFormStore() {
|
|
3181
|
-
const store =
|
|
3743
|
+
const store = React29.useContext(FormContext);
|
|
3182
3744
|
if (!store) {
|
|
3183
3745
|
throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
|
|
3184
3746
|
}
|
|
@@ -3192,8 +3754,8 @@ function Form({
|
|
|
3192
3754
|
children,
|
|
3193
3755
|
...rest
|
|
3194
3756
|
}) {
|
|
3195
|
-
const ref =
|
|
3196
|
-
const bypass =
|
|
3757
|
+
const ref = React29.useRef(null);
|
|
3758
|
+
const bypass = React29.useRef(false);
|
|
3197
3759
|
const handleSubmit = async (e) => {
|
|
3198
3760
|
if (bypass.current) {
|
|
3199
3761
|
bypass.current = false;
|
|
@@ -3245,12 +3807,12 @@ function useFormField(name, options = {}) {
|
|
|
3245
3807
|
const store = useFormStore();
|
|
3246
3808
|
const { kind = "value", rules } = options;
|
|
3247
3809
|
if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
|
|
3248
|
-
|
|
3810
|
+
React29.useEffect(() => {
|
|
3249
3811
|
return () => {
|
|
3250
3812
|
if (rules !== void 0) store.removeRule(name);
|
|
3251
3813
|
};
|
|
3252
3814
|
}, [store, name]);
|
|
3253
|
-
const snap =
|
|
3815
|
+
const snap = React29.useSyncExternalStore(
|
|
3254
3816
|
store.subscribe,
|
|
3255
3817
|
() => store.getFieldSnapshot(name)
|
|
3256
3818
|
);
|
|
@@ -3262,7 +3824,7 @@ function FormField({ name, kind, rules, children }) {
|
|
|
3262
3824
|
}
|
|
3263
3825
|
function useFieldArray(name) {
|
|
3264
3826
|
const store = useFormStore();
|
|
3265
|
-
|
|
3827
|
+
React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3266
3828
|
const arr = store.getValue(name) ?? [];
|
|
3267
3829
|
const keys = store.getKeys(name);
|
|
3268
3830
|
return {
|
|
@@ -3273,134 +3835,6 @@ function useFieldArray(name) {
|
|
|
3273
3835
|
replace: (items) => store.setValue(name, items, { validate: false })
|
|
3274
3836
|
};
|
|
3275
3837
|
}
|
|
3276
|
-
var FIELD_SIZE = {
|
|
3277
|
-
sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
|
|
3278
|
-
md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
|
|
3279
|
-
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
3280
|
-
};
|
|
3281
|
-
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
|
|
3282
|
-
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
|
|
3283
|
-
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
|
|
3284
|
-
var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
|
|
3285
|
-
function fieldShell({
|
|
3286
|
-
size = "md",
|
|
3287
|
-
hasError = false,
|
|
3288
|
-
disabled = false,
|
|
3289
|
-
focusWithin = false,
|
|
3290
|
-
sized = true
|
|
3291
|
-
} = {}) {
|
|
3292
|
-
const s = FIELD_SIZE[size];
|
|
3293
|
-
return [
|
|
3294
|
-
"w-full rounded-lg border bg-surface text-foreground",
|
|
3295
|
-
"transition-[color,box-shadow,border-color] duration-150",
|
|
3296
|
-
s.text,
|
|
3297
|
-
sized ? `${s.control} ${s.padX}` : "",
|
|
3298
|
-
// resting border
|
|
3299
|
-
hasError ? "border-status-error" : "border-border",
|
|
3300
|
-
// hover (only when interactive + no error)
|
|
3301
|
-
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
3302
|
-
// focus
|
|
3303
|
-
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
3304
|
-
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
3305
|
-
// placeholder colour for native inputs
|
|
3306
|
-
"placeholder:text-foreground-muted"
|
|
3307
|
-
].filter(Boolean).join(" ");
|
|
3308
|
-
}
|
|
3309
|
-
function FieldHelpIcon({ text }) {
|
|
3310
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3311
|
-
"button",
|
|
3312
|
-
{
|
|
3313
|
-
type: "button",
|
|
3314
|
-
"aria-label": "More information",
|
|
3315
|
-
className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
|
|
3316
|
-
children: /* @__PURE__ */ jsxRuntime.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: [
|
|
3317
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
|
|
3318
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
|
|
3319
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
|
|
3320
|
-
] })
|
|
3321
|
-
}
|
|
3322
|
-
) });
|
|
3323
|
-
}
|
|
3324
|
-
function FieldLabel({
|
|
3325
|
-
label,
|
|
3326
|
-
htmlFor,
|
|
3327
|
-
required,
|
|
3328
|
-
helperText,
|
|
3329
|
-
horizontal = false,
|
|
3330
|
-
align = "start",
|
|
3331
|
-
style,
|
|
3332
|
-
width,
|
|
3333
|
-
className = ""
|
|
3334
|
-
}) {
|
|
3335
|
-
if (label == null && helperText == null) return null;
|
|
3336
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3337
|
-
"div",
|
|
3338
|
-
{
|
|
3339
|
-
style: { width: horizontal ? width : void 0, ...style },
|
|
3340
|
-
className: [
|
|
3341
|
-
"flex items-center gap-1",
|
|
3342
|
-
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
3343
|
-
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
3344
|
-
// on the row's items-center to line up with a short control.
|
|
3345
|
-
horizontal && align === "start" ? "mt-2" : "",
|
|
3346
|
-
className
|
|
3347
|
-
].filter(Boolean).join(" "),
|
|
3348
|
-
children: [
|
|
3349
|
-
label != null && /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
|
|
3350
|
-
label,
|
|
3351
|
-
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
3352
|
-
] }),
|
|
3353
|
-
helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
|
|
3354
|
-
]
|
|
3355
|
-
}
|
|
3356
|
-
);
|
|
3357
|
-
}
|
|
3358
|
-
function Field({
|
|
3359
|
-
label,
|
|
3360
|
-
htmlFor,
|
|
3361
|
-
errorId,
|
|
3362
|
-
errorMessage,
|
|
3363
|
-
layout = "vertical",
|
|
3364
|
-
required,
|
|
3365
|
-
helperText,
|
|
3366
|
-
labelAlign = "start",
|
|
3367
|
-
labelStyle,
|
|
3368
|
-
labelWidth,
|
|
3369
|
-
className = "",
|
|
3370
|
-
children
|
|
3371
|
-
}) {
|
|
3372
|
-
const hasError = errorMessage != null;
|
|
3373
|
-
const horizontal = layout === "horizontal";
|
|
3374
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3375
|
-
"div",
|
|
3376
|
-
{
|
|
3377
|
-
className: [
|
|
3378
|
-
"flex",
|
|
3379
|
-
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
3380
|
-
className
|
|
3381
|
-
].filter(Boolean).join(" "),
|
|
3382
|
-
children: [
|
|
3383
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3384
|
-
FieldLabel,
|
|
3385
|
-
{
|
|
3386
|
-
label,
|
|
3387
|
-
htmlFor,
|
|
3388
|
-
required,
|
|
3389
|
-
helperText,
|
|
3390
|
-
horizontal,
|
|
3391
|
-
align: labelAlign,
|
|
3392
|
-
style: labelStyle,
|
|
3393
|
-
width: labelWidth
|
|
3394
|
-
}
|
|
3395
|
-
),
|
|
3396
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
3397
|
-
children,
|
|
3398
|
-
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
3399
|
-
] })
|
|
3400
|
-
]
|
|
3401
|
-
}
|
|
3402
|
-
);
|
|
3403
|
-
}
|
|
3404
3838
|
function TextInput({
|
|
3405
3839
|
value,
|
|
3406
3840
|
onChange,
|
|
@@ -3423,7 +3857,7 @@ function TextInput({
|
|
|
3423
3857
|
suffix,
|
|
3424
3858
|
id
|
|
3425
3859
|
}) {
|
|
3426
|
-
const errorId =
|
|
3860
|
+
const errorId = React29.useId();
|
|
3427
3861
|
const hasError = errorMessage != null;
|
|
3428
3862
|
const hasAdornment = prefix != null || suffix != null;
|
|
3429
3863
|
const inputId = htmlFor ?? id;
|
|
@@ -3540,8 +3974,8 @@ function expiryError(value, now = /* @__PURE__ */ new Date()) {
|
|
|
3540
3974
|
const mm = Number(m[1]);
|
|
3541
3975
|
const yy = Number(m[2]);
|
|
3542
3976
|
if (mm < 1 || mm > 12) return "Invalid month";
|
|
3543
|
-
const
|
|
3544
|
-
if (
|
|
3977
|
+
const endOfMonth2 = new Date(2e3 + yy, mm, 0, 23, 59, 59, 999);
|
|
3978
|
+
if (endOfMonth2 < now) return "Card has expired";
|
|
3545
3979
|
return void 0;
|
|
3546
3980
|
}
|
|
3547
3981
|
function cvvError(value, cardNumber) {
|
|
@@ -3584,7 +4018,7 @@ function CreditCardForm({
|
|
|
3584
4018
|
className = "",
|
|
3585
4019
|
style
|
|
3586
4020
|
}) {
|
|
3587
|
-
const initial =
|
|
4021
|
+
const initial = React29.useRef({
|
|
3588
4022
|
number: formatCardNumber(defaultValue?.number ?? ""),
|
|
3589
4023
|
name: defaultValue?.name ?? "",
|
|
3590
4024
|
expiry: formatExpiry(defaultValue?.expiry ?? ""),
|
|
@@ -3593,7 +4027,7 @@ function CreditCardForm({
|
|
|
3593
4027
|
const form = useForm({ initialValues: initial });
|
|
3594
4028
|
const numberStr = String(form.values.number ?? "");
|
|
3595
4029
|
const brand = detectBrand(numberStr);
|
|
3596
|
-
|
|
4030
|
+
React29.useEffect(() => {
|
|
3597
4031
|
onChange?.(toCard(form.values));
|
|
3598
4032
|
}, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
|
|
3599
4033
|
const numberBind = form.fieldNative("number", {
|
|
@@ -3716,7 +4150,7 @@ function Checkout({
|
|
|
3716
4150
|
] })
|
|
3717
4151
|
] });
|
|
3718
4152
|
}
|
|
3719
|
-
var NotificationContext =
|
|
4153
|
+
var NotificationContext = React29.createContext({
|
|
3720
4154
|
open: () => void 0,
|
|
3721
4155
|
close: () => void 0
|
|
3722
4156
|
});
|
|
@@ -3774,26 +4208,26 @@ function NotificationItem({
|
|
|
3774
4208
|
onClose,
|
|
3775
4209
|
reduced
|
|
3776
4210
|
}) {
|
|
3777
|
-
const [paused, setPaused] =
|
|
4211
|
+
const [paused, setPaused] = React29.useState(false);
|
|
3778
4212
|
const duration = n.duration ?? 4e3;
|
|
3779
4213
|
const isAutoDismissing = isFinite(duration) && duration > 0;
|
|
3780
4214
|
const showProgress = !reduced && isAutoDismissing;
|
|
3781
|
-
const timerRef =
|
|
3782
|
-
const startTimeRef =
|
|
3783
|
-
const remainingRef =
|
|
3784
|
-
const clearTimer =
|
|
4215
|
+
const timerRef = React29.useRef(null);
|
|
4216
|
+
const startTimeRef = React29.useRef(0);
|
|
4217
|
+
const remainingRef = React29.useRef(duration);
|
|
4218
|
+
const clearTimer = React29.useCallback(() => {
|
|
3785
4219
|
if (timerRef.current !== null) {
|
|
3786
4220
|
clearTimeout(timerRef.current);
|
|
3787
4221
|
timerRef.current = null;
|
|
3788
4222
|
}
|
|
3789
4223
|
}, []);
|
|
3790
|
-
const scheduleDismiss =
|
|
4224
|
+
const scheduleDismiss = React29.useCallback((ms) => {
|
|
3791
4225
|
clearTimer();
|
|
3792
4226
|
if (!isAutoDismissing) return;
|
|
3793
4227
|
startTimeRef.current = Date.now();
|
|
3794
4228
|
timerRef.current = setTimeout(() => onClose(n.id), ms);
|
|
3795
4229
|
}, [clearTimer, isAutoDismissing, n.id, onClose]);
|
|
3796
|
-
|
|
4230
|
+
React29.useEffect(() => {
|
|
3797
4231
|
if (paused || !isAutoDismissing) return;
|
|
3798
4232
|
scheduleDismiss(remainingRef.current);
|
|
3799
4233
|
return clearTimer;
|
|
@@ -3876,15 +4310,15 @@ function NotificationProvider({
|
|
|
3876
4310
|
children,
|
|
3877
4311
|
position = "top-right"
|
|
3878
4312
|
}) {
|
|
3879
|
-
const [notifications, setNotifications] =
|
|
4313
|
+
const [notifications, setNotifications] = React29.useState([]);
|
|
3880
4314
|
const reduced = framerMotion.useReducedMotion();
|
|
3881
|
-
const open =
|
|
4315
|
+
const open = React29.useCallback((payload) => {
|
|
3882
4316
|
setNotifications((prev) => [
|
|
3883
4317
|
...prev,
|
|
3884
4318
|
{ duration: 4e3, ...payload, id: Date.now() + Math.random() }
|
|
3885
4319
|
]);
|
|
3886
4320
|
}, []);
|
|
3887
|
-
const close =
|
|
4321
|
+
const close = React29.useCallback((id) => {
|
|
3888
4322
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
3889
4323
|
}, []);
|
|
3890
4324
|
return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
|
|
@@ -3913,7 +4347,7 @@ function NotificationProvider({
|
|
|
3913
4347
|
] });
|
|
3914
4348
|
}
|
|
3915
4349
|
function useNotification() {
|
|
3916
|
-
const { open } =
|
|
4350
|
+
const { open } = React29.useContext(NotificationContext);
|
|
3917
4351
|
return {
|
|
3918
4352
|
info: (props) => open({ type: "info", ...props }),
|
|
3919
4353
|
success: (props) => open({ type: "success", ...props }),
|
|
@@ -4030,10 +4464,10 @@ function FadingBase({
|
|
|
4030
4464
|
isMounted = false,
|
|
4031
4465
|
children
|
|
4032
4466
|
}) {
|
|
4033
|
-
const [shouldRender, setShouldRender] =
|
|
4034
|
-
const [visible, setVisible] =
|
|
4035
|
-
const timerRef =
|
|
4036
|
-
|
|
4467
|
+
const [shouldRender, setShouldRender] = React29.useState(isMounted);
|
|
4468
|
+
const [visible, setVisible] = React29.useState(false);
|
|
4469
|
+
const timerRef = React29.useRef(null);
|
|
4470
|
+
React29.useEffect(() => {
|
|
4037
4471
|
if (isMounted) {
|
|
4038
4472
|
setShouldRender(true);
|
|
4039
4473
|
const rafId = requestAnimationFrame(() => setVisible(true));
|
|
@@ -4131,8 +4565,8 @@ function ScalableContainer({
|
|
|
4131
4565
|
togglePosition = "top-right",
|
|
4132
4566
|
className = ""
|
|
4133
4567
|
}) {
|
|
4134
|
-
const containerRef =
|
|
4135
|
-
const [internalScaled, setInternalScaled] =
|
|
4568
|
+
const containerRef = React29.useRef(null);
|
|
4569
|
+
const [internalScaled, setInternalScaled] = React29.useState(false);
|
|
4136
4570
|
const isScaled = expanded ?? internalScaled;
|
|
4137
4571
|
const reduced = framerMotion.useReducedMotion();
|
|
4138
4572
|
const onToggle = () => {
|
|
@@ -4270,17 +4704,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
|
|
|
4270
4704
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap gap-2 ${className}`.trim(), children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(GridCard, { item, buttonText, onOpen }, item.key)) });
|
|
4271
4705
|
}
|
|
4272
4706
|
function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
|
|
4273
|
-
const [activeIndex, setActiveIndex] =
|
|
4274
|
-
const [indexPool, setIndexPool] =
|
|
4275
|
-
const cardRefs =
|
|
4276
|
-
const getIndexes =
|
|
4707
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
4708
|
+
const [indexPool, setIndexPool] = React29.useState([]);
|
|
4709
|
+
const cardRefs = React29.useRef([]);
|
|
4710
|
+
const getIndexes = React29.useMemo(() => {
|
|
4277
4711
|
let nextIndex = activeIndex + 1;
|
|
4278
4712
|
let previousIndex = activeIndex - 1;
|
|
4279
4713
|
if (activeIndex === 0) previousIndex = items.length - 1;
|
|
4280
4714
|
if (activeIndex === items.length - 1) nextIndex = 0;
|
|
4281
4715
|
return { previousIndex, nextIndex };
|
|
4282
4716
|
}, [activeIndex, items.length]);
|
|
4283
|
-
|
|
4717
|
+
React29.useEffect(() => {
|
|
4284
4718
|
const { nextIndex, previousIndex } = getIndexes;
|
|
4285
4719
|
let indexes = [previousIndex, activeIndex, nextIndex];
|
|
4286
4720
|
if (activeIndex !== 0 && activeIndex !== items.length - 1) {
|
|
@@ -4453,8 +4887,8 @@ function writeDismissed(key) {
|
|
|
4453
4887
|
}
|
|
4454
4888
|
}
|
|
4455
4889
|
function useTargetBbox(ref) {
|
|
4456
|
-
const [bbox, setBbox] =
|
|
4457
|
-
|
|
4890
|
+
const [bbox, setBbox] = React29.useState(null);
|
|
4891
|
+
React29.useLayoutEffect(() => {
|
|
4458
4892
|
const el = ref?.current;
|
|
4459
4893
|
if (!el) {
|
|
4460
4894
|
setBbox(null);
|
|
@@ -4484,7 +4918,7 @@ function tooltipStyleFor(bbox, placement) {
|
|
|
4484
4918
|
return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
|
|
4485
4919
|
}
|
|
4486
4920
|
function useFocusTrap(containerRef, active) {
|
|
4487
|
-
|
|
4921
|
+
React29.useEffect(() => {
|
|
4488
4922
|
if (!active) return;
|
|
4489
4923
|
const el = containerRef.current;
|
|
4490
4924
|
if (!el) return;
|
|
@@ -4523,16 +4957,16 @@ function Wizard({
|
|
|
4523
4957
|
onComplete,
|
|
4524
4958
|
onSkip
|
|
4525
4959
|
}) {
|
|
4526
|
-
const tooltipRef =
|
|
4527
|
-
const tooltipTitleId =
|
|
4528
|
-
const tooltipBodyId =
|
|
4960
|
+
const tooltipRef = React29.useRef(null);
|
|
4961
|
+
const tooltipTitleId = React29.useId();
|
|
4962
|
+
const tooltipBodyId = React29.useId();
|
|
4529
4963
|
const reduced = framerMotion.useReducedMotion();
|
|
4530
|
-
const [open, setOpen] =
|
|
4531
|
-
const [activeIndex, setActiveIndex] =
|
|
4964
|
+
const [open, setOpen] = React29.useState(() => steps.length > 0 && !readDismissed(storageKey));
|
|
4965
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
4532
4966
|
const step = steps[activeIndex];
|
|
4533
4967
|
const bbox = useTargetBbox(step?.stepRef);
|
|
4534
4968
|
useFocusTrap(tooltipRef, open);
|
|
4535
|
-
|
|
4969
|
+
React29.useEffect(() => {
|
|
4536
4970
|
if (!open || !dismissible) return;
|
|
4537
4971
|
const onKey = (e) => {
|
|
4538
4972
|
if (e.key === "Escape") {
|
|
@@ -4543,12 +4977,12 @@ function Wizard({
|
|
|
4543
4977
|
document.addEventListener("keydown", onKey);
|
|
4544
4978
|
return () => document.removeEventListener("keydown", onKey);
|
|
4545
4979
|
}, [open, dismissible]);
|
|
4546
|
-
const handleSkip =
|
|
4980
|
+
const handleSkip = React29.useCallback(() => {
|
|
4547
4981
|
writeDismissed(storageKey);
|
|
4548
4982
|
setOpen(false);
|
|
4549
4983
|
onSkip?.();
|
|
4550
4984
|
}, [storageKey, onSkip]);
|
|
4551
|
-
const handleComplete =
|
|
4985
|
+
const handleComplete = React29.useCallback(() => {
|
|
4552
4986
|
writeDismissed(storageKey);
|
|
4553
4987
|
setOpen(false);
|
|
4554
4988
|
onComplete?.();
|
|
@@ -4691,7 +5125,7 @@ function Wizard({
|
|
|
4691
5125
|
] });
|
|
4692
5126
|
}
|
|
4693
5127
|
var SearchIcon = /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.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" }) });
|
|
4694
|
-
var SearchInput =
|
|
5128
|
+
var SearchInput = React29__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
|
|
4695
5129
|
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4696
5130
|
"div",
|
|
4697
5131
|
{
|
|
@@ -4745,11 +5179,11 @@ function MultiTagRow({
|
|
|
4745
5179
|
labelFor,
|
|
4746
5180
|
onRemove
|
|
4747
5181
|
}) {
|
|
4748
|
-
const wrapRef =
|
|
4749
|
-
const measureRef =
|
|
4750
|
-
const [visibleCount, setVisibleCount] =
|
|
5182
|
+
const wrapRef = React29.useRef(null);
|
|
5183
|
+
const measureRef = React29.useRef(null);
|
|
5184
|
+
const [visibleCount, setVisibleCount] = React29.useState(values.length);
|
|
4751
5185
|
const key = values.map(String).join("|");
|
|
4752
|
-
|
|
5186
|
+
React29.useLayoutEffect(() => {
|
|
4753
5187
|
const wrap = wrapRef.current;
|
|
4754
5188
|
const measure = measureRef.current;
|
|
4755
5189
|
if (!wrap || !measure) return;
|
|
@@ -4843,16 +5277,16 @@ function Dropdown({
|
|
|
4843
5277
|
size = "md",
|
|
4844
5278
|
className = ""
|
|
4845
5279
|
}) {
|
|
4846
|
-
const [open, setOpen] =
|
|
4847
|
-
const [selectedItems, setSelectedItems] =
|
|
4848
|
-
const [searchTerm, setSearchTerm] =
|
|
4849
|
-
const [innerItems, setInnerItems] =
|
|
4850
|
-
const errorId =
|
|
5280
|
+
const [open, setOpen] = React29.useState(false);
|
|
5281
|
+
const [selectedItems, setSelectedItems] = React29.useState([]);
|
|
5282
|
+
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
5283
|
+
const [innerItems, setInnerItems] = React29.useState([]);
|
|
5284
|
+
const errorId = React29.useId();
|
|
4851
5285
|
const hasError = errorMessage != null;
|
|
4852
|
-
|
|
5286
|
+
React29.useEffect(() => {
|
|
4853
5287
|
setInnerItems(items);
|
|
4854
5288
|
}, [items]);
|
|
4855
|
-
|
|
5289
|
+
React29.useEffect(() => {
|
|
4856
5290
|
if (isMultiselect && Array.isArray(value)) {
|
|
4857
5291
|
setSelectedItems(value);
|
|
4858
5292
|
}
|
|
@@ -5177,7 +5611,7 @@ function TableBody({
|
|
|
5177
5611
|
expandRow,
|
|
5178
5612
|
getRowKey
|
|
5179
5613
|
}) {
|
|
5180
|
-
const [expanded, setExpanded] =
|
|
5614
|
+
const [expanded, setExpanded] = React29.useState(() => /* @__PURE__ */ new Set());
|
|
5181
5615
|
const reduced = framerMotion.useReducedMotion();
|
|
5182
5616
|
const toggleRow = (rowKey) => {
|
|
5183
5617
|
setExpanded((prev) => {
|
|
@@ -5192,7 +5626,7 @@ function TableBody({
|
|
|
5192
5626
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
|
|
5193
5627
|
const rowKey = getRowKey(row, i);
|
|
5194
5628
|
const isExpanded = expanded.has(rowKey);
|
|
5195
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5629
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
5196
5630
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5197
5631
|
"tr",
|
|
5198
5632
|
{
|
|
@@ -5248,9 +5682,9 @@ function Pagination({
|
|
|
5248
5682
|
const matchedOption = picker.find(
|
|
5249
5683
|
(o) => o.label === options.perPage || o.value === options.perPage
|
|
5250
5684
|
);
|
|
5251
|
-
const [perPageKey, setPerPageKey] =
|
|
5685
|
+
const [perPageKey, setPerPageKey] = React29.useState(() => matchedOption?.key ?? picker[0]?.key);
|
|
5252
5686
|
const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
|
|
5253
|
-
|
|
5687
|
+
React29.useEffect(() => {
|
|
5254
5688
|
if (serverSide && options.perPage != null) {
|
|
5255
5689
|
const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
|
|
5256
5690
|
if (next) setPerPageKey(next.key);
|
|
@@ -5314,14 +5748,14 @@ function Table({
|
|
|
5314
5748
|
className = "",
|
|
5315
5749
|
style
|
|
5316
5750
|
}) {
|
|
5317
|
-
const searchRef =
|
|
5318
|
-
const [searchTerm, setSearchTerm] =
|
|
5319
|
-
const [perPage, setPerPage] =
|
|
5751
|
+
const searchRef = React29.useRef(null);
|
|
5752
|
+
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
5753
|
+
const [perPage, setPerPage] = React29.useState(
|
|
5320
5754
|
typeof pagination.perPage === "number" ? pagination.perPage : 15
|
|
5321
5755
|
);
|
|
5322
|
-
const [activePage, setActivePage] =
|
|
5756
|
+
const [activePage, setActivePage] = React29.useState(0);
|
|
5323
5757
|
const isServerSide = !!(pagination.enabled && pagination.serverSide);
|
|
5324
|
-
const filteredRows =
|
|
5758
|
+
const filteredRows = React29.useMemo(() => {
|
|
5325
5759
|
if (isServerSide || !searchTerm) return rows;
|
|
5326
5760
|
const term = searchTerm.toLowerCase();
|
|
5327
5761
|
return rows.filter(
|
|
@@ -5330,29 +5764,29 @@ function Table({
|
|
|
5330
5764
|
)
|
|
5331
5765
|
);
|
|
5332
5766
|
}, [rows, searchTerm, isServerSide]);
|
|
5333
|
-
const datasets =
|
|
5767
|
+
const datasets = React29.useMemo(() => {
|
|
5334
5768
|
if (isServerSide) return [rows];
|
|
5335
5769
|
return createDatasets(filteredRows, pagination.enabled ? perPage : null);
|
|
5336
5770
|
}, [filteredRows, perPage, pagination.enabled, isServerSide, rows]);
|
|
5337
|
-
const MAX_PAGE =
|
|
5771
|
+
const MAX_PAGE = React29.useMemo(() => {
|
|
5338
5772
|
if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
|
|
5339
5773
|
if (isServerSide && typeof pagination.totalCount === "number")
|
|
5340
5774
|
return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
|
|
5341
5775
|
return datasets.length ? datasets.length - 1 : 0;
|
|
5342
5776
|
}, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
|
|
5343
|
-
const currentPageRows =
|
|
5777
|
+
const currentPageRows = React29.useMemo(() => {
|
|
5344
5778
|
if (isServerSide) return rows;
|
|
5345
5779
|
return datasets[activePage] ?? [];
|
|
5346
5780
|
}, [isServerSide, rows, datasets, activePage]);
|
|
5347
|
-
|
|
5781
|
+
React29.useEffect(() => {
|
|
5348
5782
|
if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
|
|
5349
5783
|
setPerPage(pagination.perPage);
|
|
5350
5784
|
}
|
|
5351
5785
|
}, [pagination.enabled, pagination.perPage, isServerSide]);
|
|
5352
|
-
|
|
5786
|
+
React29.useEffect(() => {
|
|
5353
5787
|
if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
|
|
5354
5788
|
}, [isServerSide, pagination.perPage]);
|
|
5355
|
-
|
|
5789
|
+
React29.useEffect(() => {
|
|
5356
5790
|
if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
|
|
5357
5791
|
setActivePage(pagination.page - 1);
|
|
5358
5792
|
}, [isServerSide, pagination.page]);
|
|
@@ -5436,7 +5870,7 @@ function TableSkeletonBody({
|
|
|
5436
5870
|
)) });
|
|
5437
5871
|
}
|
|
5438
5872
|
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
|
|
5439
|
-
const id =
|
|
5873
|
+
const id = React29.useId();
|
|
5440
5874
|
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5441
5875
|
SwitchPrimitive__namespace.Root,
|
|
5442
5876
|
{
|
|
@@ -5620,7 +6054,7 @@ function Sidebar({
|
|
|
5620
6054
|
}
|
|
5621
6055
|
) });
|
|
5622
6056
|
}
|
|
5623
|
-
var MegaMenuContext =
|
|
6057
|
+
var MegaMenuContext = React29.createContext({ align: "start" });
|
|
5624
6058
|
function MegaMenu({
|
|
5625
6059
|
children,
|
|
5626
6060
|
align = "start",
|
|
@@ -5651,7 +6085,7 @@ function MegaMenu({
|
|
|
5651
6085
|
}
|
|
5652
6086
|
var TOP_ITEM = "group/top inline-flex items-center gap-1.5 h-10 px-3 rounded-md text-sm font-medium select-none text-foreground-secondary hover:text-foreground hover:bg-surface-raised data-[state=open]:text-accent data-[active]:text-accent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent";
|
|
5653
6087
|
function MegaMenuItem({ label, icon, href, children, className = "" }) {
|
|
5654
|
-
const { align } =
|
|
6088
|
+
const { align } = React29.useContext(MegaMenuContext);
|
|
5655
6089
|
const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
|
|
5656
6090
|
if (!children) {
|
|
5657
6091
|
return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: [TOP_ITEM, className].filter(Boolean).join(" "), children: [
|
|
@@ -5736,8 +6170,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
5736
6170
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
5737
6171
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
|
|
5738
6172
|
}
|
|
5739
|
-
var elementsOfType = (children, type) =>
|
|
5740
|
-
(c) =>
|
|
6173
|
+
var elementsOfType = (children, type) => React29__default.default.Children.toArray(children).filter(
|
|
6174
|
+
(c) => React29__default.default.isValidElement(c) && c.type === type
|
|
5741
6175
|
);
|
|
5742
6176
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5743
6177
|
"svg",
|
|
@@ -5774,9 +6208,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
5774
6208
|
);
|
|
5775
6209
|
}
|
|
5776
6210
|
function MobilePanel({ panel, onNavigate }) {
|
|
5777
|
-
const nodes =
|
|
6211
|
+
const nodes = React29__default.default.Children.toArray(panel.props.children);
|
|
5778
6212
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
5779
|
-
if (!
|
|
6213
|
+
if (!React29__default.default.isValidElement(node)) return null;
|
|
5780
6214
|
const el = node;
|
|
5781
6215
|
if (el.type === MegaMenuSection) {
|
|
5782
6216
|
const { title, children } = el.props;
|
|
@@ -5795,8 +6229,8 @@ function MegaMenuMobile({
|
|
|
5795
6229
|
children,
|
|
5796
6230
|
label
|
|
5797
6231
|
}) {
|
|
5798
|
-
const [open, setOpen] =
|
|
5799
|
-
const [expanded, setExpanded] =
|
|
6232
|
+
const [open, setOpen] = React29.useState(false);
|
|
6233
|
+
const [expanded, setExpanded] = React29.useState(null);
|
|
5800
6234
|
const items = elementsOfType(children, MegaMenuItem);
|
|
5801
6235
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
|
|
5802
6236
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -5869,17 +6303,17 @@ function AppShell({
|
|
|
5869
6303
|
children,
|
|
5870
6304
|
className = ""
|
|
5871
6305
|
}) {
|
|
5872
|
-
const [expanded, setExpanded] =
|
|
5873
|
-
const [isMobile, setIsMobile] =
|
|
5874
|
-
const [mobileOpen, setMobileOpen] =
|
|
5875
|
-
|
|
6306
|
+
const [expanded, setExpanded] = React29.useState(sidebarDefaultExpanded);
|
|
6307
|
+
const [isMobile, setIsMobile] = React29.useState(false);
|
|
6308
|
+
const [mobileOpen, setMobileOpen] = React29.useState(false);
|
|
6309
|
+
React29.useEffect(() => {
|
|
5876
6310
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
5877
6311
|
const update = (e) => setIsMobile(e.matches);
|
|
5878
6312
|
update(mq);
|
|
5879
6313
|
mq.addEventListener("change", update);
|
|
5880
6314
|
return () => mq.removeEventListener("change", update);
|
|
5881
6315
|
}, []);
|
|
5882
|
-
|
|
6316
|
+
React29.useEffect(() => {
|
|
5883
6317
|
if (!isMobile) setMobileOpen(false);
|
|
5884
6318
|
}, [isMobile]);
|
|
5885
6319
|
const hasSidebar = sidebarSections.length > 0;
|
|
@@ -5986,7 +6420,7 @@ function tokenValid(token) {
|
|
|
5986
6420
|
return exp * 1e3 > Date.now();
|
|
5987
6421
|
}
|
|
5988
6422
|
var has = (have, need, all) => all ? need.every((n) => have?.includes(n)) : need.some((n) => have?.includes(n));
|
|
5989
|
-
var
|
|
6423
|
+
var Spinner3 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-6 w-6 animate-spin text-accent", children: /* @__PURE__ */ jsxRuntime.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" }) });
|
|
5990
6424
|
function SecureLayout({
|
|
5991
6425
|
children,
|
|
5992
6426
|
isAuthenticated,
|
|
@@ -6006,6 +6440,8 @@ function SecureLayout({
|
|
|
6006
6440
|
className = ""
|
|
6007
6441
|
}) {
|
|
6008
6442
|
const reduced = framerMotion.useReducedMotion();
|
|
6443
|
+
const cbs = React29.useRef({ canAccess, onGranted, onDeny });
|
|
6444
|
+
cbs.current = { canAccess, onGranted, onDeny };
|
|
6009
6445
|
const rolesKey = JSON.stringify(roles);
|
|
6010
6446
|
const requiredRolesKey = JSON.stringify(requiredRoles);
|
|
6011
6447
|
const permissionsKey = JSON.stringify(permissions);
|
|
@@ -6019,23 +6455,24 @@ function SecureLayout({
|
|
|
6019
6455
|
if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
|
|
6020
6456
|
return true;
|
|
6021
6457
|
};
|
|
6022
|
-
const [state, setState] =
|
|
6458
|
+
const [state, setState] = React29.useState(
|
|
6023
6459
|
() => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
|
|
6024
6460
|
);
|
|
6025
|
-
|
|
6461
|
+
React29.useEffect(() => {
|
|
6026
6462
|
let cancelled = false;
|
|
6463
|
+
const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
|
|
6027
6464
|
const finish = (ok) => {
|
|
6028
6465
|
if (cancelled) return;
|
|
6029
6466
|
setState(ok ? "granted" : "denied");
|
|
6030
|
-
if (ok)
|
|
6031
|
-
else
|
|
6467
|
+
if (ok) granted?.();
|
|
6468
|
+
else deny?.();
|
|
6032
6469
|
};
|
|
6033
6470
|
if (!passesSync()) {
|
|
6034
6471
|
finish(false);
|
|
6035
|
-
} else if (!
|
|
6472
|
+
} else if (!check) {
|
|
6036
6473
|
finish(true);
|
|
6037
6474
|
} else {
|
|
6038
|
-
const result =
|
|
6475
|
+
const result = check(route);
|
|
6039
6476
|
if (result && typeof result.then === "function") {
|
|
6040
6477
|
setState("checking");
|
|
6041
6478
|
result.then((ok) => finish(Boolean(ok)));
|
|
@@ -6052,7 +6489,6 @@ function SecureLayout({
|
|
|
6052
6489
|
route,
|
|
6053
6490
|
requireAllRoles,
|
|
6054
6491
|
requireAllPermissions,
|
|
6055
|
-
canAccess,
|
|
6056
6492
|
rolesKey,
|
|
6057
6493
|
requiredRolesKey,
|
|
6058
6494
|
permissionsKey,
|
|
@@ -6060,7 +6496,7 @@ function SecureLayout({
|
|
|
6060
6496
|
]);
|
|
6061
6497
|
if (state === "checking") {
|
|
6062
6498
|
if (loadingFallback === null) return null;
|
|
6063
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["flex min-h-[8rem] items-center justify-center", className].filter(Boolean).join(" "), children: loadingFallback !== void 0 ? loadingFallback : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6499
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["flex min-h-[8rem] items-center justify-center", className].filter(Boolean).join(" "), children: loadingFallback !== void 0 ? loadingFallback : /* @__PURE__ */ jsxRuntime.jsx(Spinner3, {}) });
|
|
6064
6500
|
}
|
|
6065
6501
|
if (state === "denied") {
|
|
6066
6502
|
if (fallback === null) return null;
|
|
@@ -6183,10 +6619,10 @@ function ThemeProvider({
|
|
|
6183
6619
|
className = "",
|
|
6184
6620
|
style
|
|
6185
6621
|
}) {
|
|
6186
|
-
const id =
|
|
6622
|
+
const id = React29__default.default.useId().replace(/:/g, "");
|
|
6187
6623
|
const scopeClass = `geo-th-${id}`;
|
|
6188
|
-
const divRef =
|
|
6189
|
-
|
|
6624
|
+
const divRef = React29.useRef(null);
|
|
6625
|
+
React29.useEffect(() => {
|
|
6190
6626
|
const el = divRef.current;
|
|
6191
6627
|
if (!el) return;
|
|
6192
6628
|
if (colorScheme === "auto") return;
|
|
@@ -6201,8 +6637,8 @@ function ThemeProvider({
|
|
|
6201
6637
|
}
|
|
6202
6638
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
6203
6639
|
}, [colorScheme]);
|
|
6204
|
-
const lightVars =
|
|
6205
|
-
const darkVarStr =
|
|
6640
|
+
const lightVars = React29.useMemo(() => toCssVars(theme), [theme]);
|
|
6641
|
+
const darkVarStr = React29.useMemo(() => {
|
|
6206
6642
|
if (!darkTheme) return "";
|
|
6207
6643
|
const dvars = toCssVars(darkTheme);
|
|
6208
6644
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -6244,7 +6680,7 @@ function NumberInput({
|
|
|
6244
6680
|
readOnly = false,
|
|
6245
6681
|
precision
|
|
6246
6682
|
}) {
|
|
6247
|
-
const errorId =
|
|
6683
|
+
const errorId = React29.useId();
|
|
6248
6684
|
const hasError = errorMessage != null;
|
|
6249
6685
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
6250
6686
|
const round = (n) => {
|
|
@@ -6375,8 +6811,8 @@ function Password({
|
|
|
6375
6811
|
showIcon,
|
|
6376
6812
|
hideIcon
|
|
6377
6813
|
}) {
|
|
6378
|
-
const [visible, setVisible] =
|
|
6379
|
-
const errorId =
|
|
6814
|
+
const [visible, setVisible] = React29.useState(false);
|
|
6815
|
+
const errorId = React29.useId();
|
|
6380
6816
|
const hasError = errorMessage != null;
|
|
6381
6817
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6382
6818
|
Field,
|
|
@@ -6449,7 +6885,7 @@ function Checkbox({
|
|
|
6449
6885
|
}) {
|
|
6450
6886
|
const isChecked = checked ?? value ?? false;
|
|
6451
6887
|
const labelFirst = labelPosition === "left";
|
|
6452
|
-
const errorId =
|
|
6888
|
+
const errorId = React29.useId();
|
|
6453
6889
|
const hasError = errorMessage != null;
|
|
6454
6890
|
const box = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6455
6891
|
CheckboxPrimitive__namespace.Root,
|
|
@@ -6557,8 +6993,8 @@ function RadioGroup({
|
|
|
6557
6993
|
className,
|
|
6558
6994
|
errorMessage
|
|
6559
6995
|
}) {
|
|
6560
|
-
const errorId =
|
|
6561
|
-
const groupId =
|
|
6996
|
+
const errorId = React29.useId();
|
|
6997
|
+
const groupId = React29.useId();
|
|
6562
6998
|
const hasError = errorMessage != null;
|
|
6563
6999
|
const labelFirst = labelPosition === "left";
|
|
6564
7000
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6658,11 +7094,11 @@ function Switch({
|
|
|
6658
7094
|
disabled,
|
|
6659
7095
|
errorMessage
|
|
6660
7096
|
}) {
|
|
6661
|
-
const id =
|
|
6662
|
-
const errorId =
|
|
7097
|
+
const id = React29.useId();
|
|
7098
|
+
const errorId = React29.useId();
|
|
6663
7099
|
const hasError = errorMessage != null;
|
|
6664
7100
|
const isControlled = checked !== void 0;
|
|
6665
|
-
const [internal, setInternal] =
|
|
7101
|
+
const [internal, setInternal] = React29.useState(defaultChecked);
|
|
6666
7102
|
const isOn = isControlled ? checked : internal;
|
|
6667
7103
|
const handle = (c) => {
|
|
6668
7104
|
if (!isControlled) setInternal(c);
|
|
@@ -6735,19 +7171,19 @@ function AutoComplete({
|
|
|
6735
7171
|
required,
|
|
6736
7172
|
htmlFor
|
|
6737
7173
|
}) {
|
|
6738
|
-
const errorId =
|
|
7174
|
+
const errorId = React29.useId();
|
|
6739
7175
|
const hasError = errorMessage != null;
|
|
6740
|
-
const [term, setTerm] =
|
|
6741
|
-
const [open, setOpen] =
|
|
6742
|
-
const [asyncItems, setAsyncItems] =
|
|
6743
|
-
const [loading, setLoading] =
|
|
7176
|
+
const [term, setTerm] = React29.useState("");
|
|
7177
|
+
const [open, setOpen] = React29.useState(false);
|
|
7178
|
+
const [asyncItems, setAsyncItems] = React29.useState([]);
|
|
7179
|
+
const [loading, setLoading] = React29.useState(false);
|
|
6744
7180
|
const isAsync = typeof onSearch === "function";
|
|
6745
|
-
const debounceRef =
|
|
6746
|
-
const requestIdRef =
|
|
7181
|
+
const debounceRef = React29.useRef(null);
|
|
7182
|
+
const requestIdRef = React29.useRef(0);
|
|
6747
7183
|
const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
|
|
6748
7184
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
6749
7185
|
) : [];
|
|
6750
|
-
|
|
7186
|
+
React29.useEffect(() => {
|
|
6751
7187
|
if (!isAsync) return;
|
|
6752
7188
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
6753
7189
|
if (!term.trim()) {
|
|
@@ -6903,15 +7339,15 @@ function TreeSelect({
|
|
|
6903
7339
|
defaultExpandedKeys = [],
|
|
6904
7340
|
size = "md"
|
|
6905
7341
|
}) {
|
|
6906
|
-
const errorId =
|
|
7342
|
+
const errorId = React29.useId();
|
|
6907
7343
|
const hasError = errorMessage != null;
|
|
6908
|
-
const [open, setOpen] =
|
|
6909
|
-
const [expanded, setExpanded] =
|
|
6910
|
-
const [activeIndex, setActiveIndex] =
|
|
6911
|
-
const listRef =
|
|
6912
|
-
const visible =
|
|
6913
|
-
const didSyncOnOpenRef =
|
|
6914
|
-
|
|
7344
|
+
const [open, setOpen] = React29.useState(false);
|
|
7345
|
+
const [expanded, setExpanded] = React29.useState(() => new Set(defaultExpandedKeys));
|
|
7346
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
7347
|
+
const listRef = React29.useRef(null);
|
|
7348
|
+
const visible = React29.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
|
|
7349
|
+
const didSyncOnOpenRef = React29.useRef(false);
|
|
7350
|
+
React29.useEffect(() => {
|
|
6915
7351
|
if (!open) {
|
|
6916
7352
|
didSyncOnOpenRef.current = false;
|
|
6917
7353
|
return;
|
|
@@ -6921,7 +7357,7 @@ function TreeSelect({
|
|
|
6921
7357
|
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
6922
7358
|
didSyncOnOpenRef.current = true;
|
|
6923
7359
|
}, [open, value]);
|
|
6924
|
-
const selectedNode =
|
|
7360
|
+
const selectedNode = React29.useMemo(
|
|
6925
7361
|
() => value != null ? findNodeByKey(items, value) : null,
|
|
6926
7362
|
[items, value]
|
|
6927
7363
|
);
|
|
@@ -7152,11 +7588,11 @@ function FileInput({
|
|
|
7152
7588
|
required,
|
|
7153
7589
|
icon
|
|
7154
7590
|
}) {
|
|
7155
|
-
const inputRef =
|
|
7156
|
-
const errorId =
|
|
7157
|
-
const [files, setFiles] =
|
|
7158
|
-
const [dragging, setDragging] =
|
|
7159
|
-
const [sizeError, setSizeError] =
|
|
7591
|
+
const inputRef = React29.useRef(null);
|
|
7592
|
+
const errorId = React29.useId();
|
|
7593
|
+
const [files, setFiles] = React29.useState([]);
|
|
7594
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
7595
|
+
const [sizeError, setSizeError] = React29.useState(null);
|
|
7160
7596
|
const effectiveError = errorMessage ?? sizeError ?? void 0;
|
|
7161
7597
|
const openPicker = () => {
|
|
7162
7598
|
if (!disabled) inputRef.current?.click();
|
|
@@ -7294,15 +7730,15 @@ var WEEKDAY_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
|
7294
7730
|
function isSameDay(a, b) {
|
|
7295
7731
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
7296
7732
|
}
|
|
7297
|
-
function
|
|
7733
|
+
function startOfMonth2(d) {
|
|
7298
7734
|
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
7299
7735
|
}
|
|
7300
|
-
function
|
|
7736
|
+
function addDays2(d, n) {
|
|
7301
7737
|
const c = new Date(d);
|
|
7302
7738
|
c.setDate(c.getDate() + n);
|
|
7303
7739
|
return c;
|
|
7304
7740
|
}
|
|
7305
|
-
function
|
|
7741
|
+
function addMonths3(d, n) {
|
|
7306
7742
|
const c = new Date(d);
|
|
7307
7743
|
c.setMonth(c.getMonth() + n);
|
|
7308
7744
|
return c;
|
|
@@ -7314,12 +7750,12 @@ function defaultFormat3(d) {
|
|
|
7314
7750
|
return `${y}-${m}-${day}`;
|
|
7315
7751
|
}
|
|
7316
7752
|
function buildGrid2(viewMonth, weekStartsOn) {
|
|
7317
|
-
const first =
|
|
7753
|
+
const first = startOfMonth2(viewMonth);
|
|
7318
7754
|
const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
7319
|
-
const gridStart =
|
|
7755
|
+
const gridStart = addDays2(first, -startOffset);
|
|
7320
7756
|
const cells = [];
|
|
7321
7757
|
for (let i = 0; i < 42; i++) {
|
|
7322
|
-
const d =
|
|
7758
|
+
const d = addDays2(gridStart, i);
|
|
7323
7759
|
cells.push({ date: d, outside: d.getMonth() !== viewMonth.getMonth() });
|
|
7324
7760
|
}
|
|
7325
7761
|
const rows = [];
|
|
@@ -7347,30 +7783,30 @@ function DatePicker({
|
|
|
7347
7783
|
size = "md",
|
|
7348
7784
|
className = ""
|
|
7349
7785
|
}) {
|
|
7350
|
-
const errorId =
|
|
7786
|
+
const errorId = React29.useId();
|
|
7351
7787
|
const hasError = errorMessage != null;
|
|
7352
|
-
const [open, setOpen] =
|
|
7353
|
-
const [viewMonth, setViewMonth] =
|
|
7354
|
-
const [focusDate, setFocusDate] =
|
|
7355
|
-
const [view, setView] =
|
|
7356
|
-
const gridRef =
|
|
7357
|
-
|
|
7788
|
+
const [open, setOpen] = React29.useState(false);
|
|
7789
|
+
const [viewMonth, setViewMonth] = React29.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
7790
|
+
const [focusDate, setFocusDate] = React29.useState(() => value ?? /* @__PURE__ */ new Date());
|
|
7791
|
+
const [view, setView] = React29.useState("days");
|
|
7792
|
+
const gridRef = React29.useRef(null);
|
|
7793
|
+
React29.useEffect(() => {
|
|
7358
7794
|
if (!open) return;
|
|
7359
7795
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7360
|
-
setViewMonth(
|
|
7796
|
+
setViewMonth(startOfMonth2(target));
|
|
7361
7797
|
setFocusDate(target);
|
|
7362
7798
|
setView("days");
|
|
7363
7799
|
}, [open, value]);
|
|
7364
|
-
|
|
7800
|
+
React29.useEffect(() => {
|
|
7365
7801
|
if (!open) return;
|
|
7366
7802
|
const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
|
|
7367
7803
|
cell?.focus();
|
|
7368
7804
|
}, [open, focusDate]);
|
|
7369
|
-
const weekdays =
|
|
7805
|
+
const weekdays = React29.useMemo(() => {
|
|
7370
7806
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
7371
7807
|
return ordered;
|
|
7372
7808
|
}, [weekStartsOn]);
|
|
7373
|
-
const grid =
|
|
7809
|
+
const grid = React29.useMemo(() => buildGrid2(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
7374
7810
|
const isDisabled = (d) => {
|
|
7375
7811
|
if (min && d < min) return true;
|
|
7376
7812
|
if (max && d > max) return true;
|
|
@@ -7383,9 +7819,9 @@ function DatePicker({
|
|
|
7383
7819
|
};
|
|
7384
7820
|
const onKey = (e) => {
|
|
7385
7821
|
const next = (delta) => {
|
|
7386
|
-
const nd =
|
|
7822
|
+
const nd = addDays2(focusDate, delta);
|
|
7387
7823
|
setFocusDate(nd);
|
|
7388
|
-
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(
|
|
7824
|
+
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(startOfMonth2(nd));
|
|
7389
7825
|
};
|
|
7390
7826
|
if (e.key === "ArrowLeft") {
|
|
7391
7827
|
e.preventDefault();
|
|
@@ -7401,22 +7837,22 @@ function DatePicker({
|
|
|
7401
7837
|
next(7);
|
|
7402
7838
|
} else if (e.key === "PageUp") {
|
|
7403
7839
|
e.preventDefault();
|
|
7404
|
-
const nm =
|
|
7840
|
+
const nm = addMonths3(viewMonth, -1);
|
|
7405
7841
|
setViewMonth(nm);
|
|
7406
|
-
setFocusDate((d) =>
|
|
7842
|
+
setFocusDate((d) => addMonths3(d, -1));
|
|
7407
7843
|
} else if (e.key === "PageDown") {
|
|
7408
7844
|
e.preventDefault();
|
|
7409
|
-
const nm =
|
|
7845
|
+
const nm = addMonths3(viewMonth, 1);
|
|
7410
7846
|
setViewMonth(nm);
|
|
7411
|
-
setFocusDate((d) =>
|
|
7847
|
+
setFocusDate((d) => addMonths3(d, 1));
|
|
7412
7848
|
} else if (e.key === "Home") {
|
|
7413
7849
|
e.preventDefault();
|
|
7414
7850
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7415
|
-
setFocusDate(
|
|
7851
|
+
setFocusDate(addDays2(focusDate, -dow));
|
|
7416
7852
|
} else if (e.key === "End") {
|
|
7417
7853
|
e.preventDefault();
|
|
7418
7854
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7419
|
-
setFocusDate(
|
|
7855
|
+
setFocusDate(addDays2(focusDate, 6 - dow));
|
|
7420
7856
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
7421
7857
|
e.preventDefault();
|
|
7422
7858
|
selectDate(focusDate);
|
|
@@ -7473,7 +7909,7 @@ function DatePicker({
|
|
|
7473
7909
|
{
|
|
7474
7910
|
type: "button",
|
|
7475
7911
|
onClick: () => {
|
|
7476
|
-
if (view === "days") setViewMonth(
|
|
7912
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, -1));
|
|
7477
7913
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() - 1, viewMonth.getMonth(), 1));
|
|
7478
7914
|
else setViewMonth(new Date(viewMonth.getFullYear() - 10, viewMonth.getMonth(), 1));
|
|
7479
7915
|
},
|
|
@@ -7508,7 +7944,7 @@ function DatePicker({
|
|
|
7508
7944
|
{
|
|
7509
7945
|
type: "button",
|
|
7510
7946
|
onClick: () => {
|
|
7511
|
-
if (view === "days") setViewMonth(
|
|
7947
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, 1));
|
|
7512
7948
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() + 1, viewMonth.getMonth(), 1));
|
|
7513
7949
|
else setViewMonth(new Date(viewMonth.getFullYear() + 10, viewMonth.getMonth(), 1));
|
|
7514
7950
|
},
|
|
@@ -7660,10 +8096,10 @@ function TextArea({
|
|
|
7660
8096
|
style,
|
|
7661
8097
|
inputStyle
|
|
7662
8098
|
}) {
|
|
7663
|
-
const errorId =
|
|
8099
|
+
const errorId = React29.useId();
|
|
7664
8100
|
const hasError = errorMessage != null;
|
|
7665
|
-
const ref =
|
|
7666
|
-
|
|
8101
|
+
const ref = React29.useRef(null);
|
|
8102
|
+
React29.useLayoutEffect(() => {
|
|
7667
8103
|
if (!autoGrow) return;
|
|
7668
8104
|
const el = ref.current;
|
|
7669
8105
|
if (!el) return;
|
|
@@ -7710,102 +8146,6 @@ function TextArea({
|
|
|
7710
8146
|
}
|
|
7711
8147
|
);
|
|
7712
8148
|
}
|
|
7713
|
-
var SIZE5 = {
|
|
7714
|
-
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
7715
|
-
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
7716
|
-
lg: { h: "h-control-lg", text: "text-sm", pad: "px-4" }
|
|
7717
|
-
};
|
|
7718
|
-
function SegmentedControl({
|
|
7719
|
-
options,
|
|
7720
|
-
value,
|
|
7721
|
-
defaultValue,
|
|
7722
|
-
onChange,
|
|
7723
|
-
size = "md",
|
|
7724
|
-
fullWidth = false,
|
|
7725
|
-
disabled,
|
|
7726
|
-
label,
|
|
7727
|
-
layout = "vertical",
|
|
7728
|
-
helperText,
|
|
7729
|
-
className,
|
|
7730
|
-
name,
|
|
7731
|
-
required,
|
|
7732
|
-
errorMessage,
|
|
7733
|
-
"aria-label": ariaLabel
|
|
7734
|
-
}) {
|
|
7735
|
-
const sz = SIZE5[size];
|
|
7736
|
-
const groupId = React27.useId();
|
|
7737
|
-
const errorId = React27.useId();
|
|
7738
|
-
const hasError = errorMessage != null;
|
|
7739
|
-
const isControlled = value !== void 0;
|
|
7740
|
-
const [internal, setInternal] = React27.useState(defaultValue);
|
|
7741
|
-
const current = isControlled ? value : internal;
|
|
7742
|
-
const handle = (v) => {
|
|
7743
|
-
if (!v) return;
|
|
7744
|
-
if (!isControlled) setInternal(v);
|
|
7745
|
-
onChange?.(v);
|
|
7746
|
-
};
|
|
7747
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7748
|
-
Field,
|
|
7749
|
-
{
|
|
7750
|
-
className,
|
|
7751
|
-
label,
|
|
7752
|
-
htmlFor: groupId,
|
|
7753
|
-
errorId,
|
|
7754
|
-
errorMessage,
|
|
7755
|
-
layout,
|
|
7756
|
-
required,
|
|
7757
|
-
helperText,
|
|
7758
|
-
children: [
|
|
7759
|
-
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: current ?? "" }),
|
|
7760
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7761
|
-
ToggleGroup__namespace.Root,
|
|
7762
|
-
{
|
|
7763
|
-
id: groupId,
|
|
7764
|
-
type: "single",
|
|
7765
|
-
value: current,
|
|
7766
|
-
onValueChange: handle,
|
|
7767
|
-
disabled,
|
|
7768
|
-
"aria-label": ariaLabel ?? (typeof label === "string" ? label : void 0),
|
|
7769
|
-
"aria-invalid": hasError || void 0,
|
|
7770
|
-
"aria-describedby": hasError ? errorId : void 0,
|
|
7771
|
-
className: [
|
|
7772
|
-
"inline-flex items-center gap-1 rounded-lg border bg-surface-raised p-1",
|
|
7773
|
-
hasError ? "border-status-error" : "border-border",
|
|
7774
|
-
sz.h,
|
|
7775
|
-
fullWidth ? "flex w-full" : "w-fit",
|
|
7776
|
-
disabled ? "opacity-60 cursor-not-allowed" : ""
|
|
7777
|
-
].filter(Boolean).join(" "),
|
|
7778
|
-
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7779
|
-
ToggleGroup__namespace.Item,
|
|
7780
|
-
{
|
|
7781
|
-
value: opt.value,
|
|
7782
|
-
disabled: opt.disabled,
|
|
7783
|
-
className: [
|
|
7784
|
-
"inline-flex items-center justify-center gap-1.5 rounded-md select-none whitespace-nowrap",
|
|
7785
|
-
"transition-colors duration-150 h-full",
|
|
7786
|
-
sz.text,
|
|
7787
|
-
sz.pad,
|
|
7788
|
-
fullWidth ? "flex-1" : "",
|
|
7789
|
-
// Resting: muted text, transparent. Hover lifts the text.
|
|
7790
|
-
"text-foreground-secondary hover:text-foreground",
|
|
7791
|
-
// Active: surface-white pill + accent text + subtle shadow.
|
|
7792
|
-
"data-[state=on]:bg-surface data-[state=on]:text-accent data-[state=on]:shadow-sm",
|
|
7793
|
-
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
7794
|
-
"disabled:opacity-40 disabled:cursor-not-allowed"
|
|
7795
|
-
].filter(Boolean).join(" "),
|
|
7796
|
-
children: [
|
|
7797
|
-
opt.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: opt.icon }),
|
|
7798
|
-
opt.label
|
|
7799
|
-
]
|
|
7800
|
-
},
|
|
7801
|
-
opt.value
|
|
7802
|
-
))
|
|
7803
|
-
}
|
|
7804
|
-
)
|
|
7805
|
-
]
|
|
7806
|
-
}
|
|
7807
|
-
);
|
|
7808
|
-
}
|
|
7809
8149
|
var TRACK_H = { sm: "h-1", md: "h-1.5", lg: "h-2" };
|
|
7810
8150
|
var THUMB = { sm: "h-3.5 w-3.5", md: "h-4 w-4", lg: "h-5 w-5" };
|
|
7811
8151
|
var toArray = (v) => v == null ? void 0 : Array.isArray(v) ? v : [v];
|
|
@@ -7831,14 +8171,14 @@ function Slider({
|
|
|
7831
8171
|
name,
|
|
7832
8172
|
htmlFor
|
|
7833
8173
|
}) {
|
|
7834
|
-
const errorId =
|
|
8174
|
+
const errorId = React29.useId();
|
|
7835
8175
|
const hasError = errorMessage != null;
|
|
7836
8176
|
const isRange = Array.isArray(value ?? defaultValue);
|
|
7837
|
-
const [internal, setInternal] =
|
|
8177
|
+
const [internal, setInternal] = React29.useState(
|
|
7838
8178
|
() => toArray(value) ?? toArray(defaultValue) ?? [min]
|
|
7839
8179
|
);
|
|
7840
8180
|
const current = toArray(value) ?? internal;
|
|
7841
|
-
const [dragging, setDragging] =
|
|
8181
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
7842
8182
|
const emit = (arr) => {
|
|
7843
8183
|
setInternal(arr);
|
|
7844
8184
|
const next = isRange ? [arr[0], arr[1]] : arr[0];
|
|
@@ -7933,11 +8273,11 @@ function TagsInput({
|
|
|
7933
8273
|
validate,
|
|
7934
8274
|
separators = ["Enter", ","]
|
|
7935
8275
|
}) {
|
|
7936
|
-
const errorId =
|
|
7937
|
-
const inputRef =
|
|
7938
|
-
const [internal, setInternal] =
|
|
7939
|
-
const [draft, setDraft] =
|
|
7940
|
-
const [localError, setLocalError] =
|
|
8276
|
+
const errorId = React29.useId();
|
|
8277
|
+
const inputRef = React29.useRef(null);
|
|
8278
|
+
const [internal, setInternal] = React29.useState(defaultValue ?? []);
|
|
8279
|
+
const [draft, setDraft] = React29.useState("");
|
|
8280
|
+
const [localError, setLocalError] = React29.useState(null);
|
|
7941
8281
|
const tags = value ?? internal;
|
|
7942
8282
|
const hasError = errorMessage != null || localError != null;
|
|
7943
8283
|
const errorText = errorMessage ?? localError ?? void 0;
|
|
@@ -8068,9 +8408,9 @@ function OtpInput({
|
|
|
8068
8408
|
className,
|
|
8069
8409
|
groupAfter
|
|
8070
8410
|
}) {
|
|
8071
|
-
const errorId =
|
|
8411
|
+
const errorId = React29.useId();
|
|
8072
8412
|
const hasError = errorMessage != null;
|
|
8073
|
-
const refs =
|
|
8413
|
+
const refs = React29.useRef([]);
|
|
8074
8414
|
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
8075
8415
|
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
8076
8416
|
const emit = (next) => {
|
|
@@ -8119,7 +8459,7 @@ function OtpInput({
|
|
|
8119
8459
|
emit(valid.join(""));
|
|
8120
8460
|
focusBox(valid.length);
|
|
8121
8461
|
};
|
|
8122
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs(
|
|
8462
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
8123
8463
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8124
8464
|
"input",
|
|
8125
8465
|
{
|
|
@@ -8177,9 +8517,9 @@ function Rating({
|
|
|
8177
8517
|
className,
|
|
8178
8518
|
required
|
|
8179
8519
|
}) {
|
|
8180
|
-
const errorId =
|
|
8181
|
-
const [internal, setInternal] =
|
|
8182
|
-
const [hover, setHover] =
|
|
8520
|
+
const errorId = React29.useId();
|
|
8521
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
8522
|
+
const [hover, setHover] = React29.useState(null);
|
|
8183
8523
|
const current = value ?? internal;
|
|
8184
8524
|
const display2 = hover ?? current;
|
|
8185
8525
|
const interactive = !readOnly && !disabled;
|
|
@@ -8302,9 +8642,9 @@ function TimePicker({
|
|
|
8302
8642
|
required,
|
|
8303
8643
|
style
|
|
8304
8644
|
}) {
|
|
8305
|
-
const errorId =
|
|
8645
|
+
const errorId = React29.useId();
|
|
8306
8646
|
const hasError = errorMessage != null;
|
|
8307
|
-
const [open, setOpen] =
|
|
8647
|
+
const [open, setOpen] = React29.useState(false);
|
|
8308
8648
|
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
8309
8649
|
const update = (next) => {
|
|
8310
8650
|
const merged = { ...parsed, ...next };
|
|
@@ -8389,22 +8729,22 @@ function TimePicker({
|
|
|
8389
8729
|
}
|
|
8390
8730
|
var MONTH_NAMES2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
8391
8731
|
var WEEKDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
8392
|
-
var
|
|
8393
|
-
var
|
|
8394
|
-
var
|
|
8732
|
+
var startOfMonth3 = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
8733
|
+
var addMonths4 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
8734
|
+
var addDays3 = (d, n) => {
|
|
8395
8735
|
const c = new Date(d);
|
|
8396
8736
|
c.setDate(c.getDate() + n);
|
|
8397
8737
|
return c;
|
|
8398
8738
|
};
|
|
8399
8739
|
var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
8400
|
-
var
|
|
8740
|
+
var startOfDay3 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8401
8741
|
var defaultFmt = (d) => `${d.getFullYear()}-${`${d.getMonth() + 1}`.padStart(2, "0")}-${`${d.getDate()}`.padStart(2, "0")}`;
|
|
8402
8742
|
function buildGrid3(viewMonth, weekStartsOn) {
|
|
8403
|
-
const first =
|
|
8743
|
+
const first = startOfMonth3(viewMonth);
|
|
8404
8744
|
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
8405
|
-
const gridStart =
|
|
8745
|
+
const gridStart = addDays3(first, -offset);
|
|
8406
8746
|
return Array.from({ length: 42 }, (_, i) => {
|
|
8407
|
-
const d =
|
|
8747
|
+
const d = addDays3(gridStart, i);
|
|
8408
8748
|
return { date: d, outside: d.getMonth() !== viewMonth.getMonth() };
|
|
8409
8749
|
});
|
|
8410
8750
|
}
|
|
@@ -8428,23 +8768,23 @@ function DateRangePicker({
|
|
|
8428
8768
|
required,
|
|
8429
8769
|
style
|
|
8430
8770
|
}) {
|
|
8431
|
-
const errorId =
|
|
8771
|
+
const errorId = React29.useId();
|
|
8432
8772
|
const hasError = errorMessage != null;
|
|
8433
|
-
const [open, setOpen] =
|
|
8434
|
-
const [leftMonth, setLeftMonth] =
|
|
8435
|
-
const [pendingStart, setPendingStart] =
|
|
8436
|
-
const [hoverDate, setHoverDate] =
|
|
8437
|
-
const weekdays =
|
|
8773
|
+
const [open, setOpen] = React29.useState(false);
|
|
8774
|
+
const [leftMonth, setLeftMonth] = React29.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
8775
|
+
const [pendingStart, setPendingStart] = React29.useState(null);
|
|
8776
|
+
const [hoverDate, setHoverDate] = React29.useState(null);
|
|
8777
|
+
const weekdays = React29.useMemo(
|
|
8438
8778
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8439
8779
|
[weekStartsOn]
|
|
8440
8780
|
);
|
|
8441
|
-
const isDisabled = (d) => min && d <
|
|
8781
|
+
const isDisabled = (d) => min && d < startOfDay3(min) || max && d > startOfDay3(max);
|
|
8442
8782
|
const effective = pendingStart ? { start: pendingStart, end: hoverDate } : value;
|
|
8443
8783
|
const inRange = (d) => {
|
|
8444
8784
|
const { start, end } = effective;
|
|
8445
8785
|
if (!start || !end) return false;
|
|
8446
8786
|
const [a, b] = start <= end ? [start, end] : [end, start];
|
|
8447
|
-
return d >=
|
|
8787
|
+
return d >= startOfDay3(a) && d <= startOfDay3(b);
|
|
8448
8788
|
};
|
|
8449
8789
|
const onDayClick = (d) => {
|
|
8450
8790
|
if (isDisabled(d)) return;
|
|
@@ -8551,7 +8891,7 @@ function DateRangePicker({
|
|
|
8551
8891
|
"button",
|
|
8552
8892
|
{
|
|
8553
8893
|
type: "button",
|
|
8554
|
-
onClick: () => setLeftMonth(
|
|
8894
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, -1)),
|
|
8555
8895
|
"aria-label": "Previous month",
|
|
8556
8896
|
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",
|
|
8557
8897
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
|
|
@@ -8564,13 +8904,13 @@ function DateRangePicker({
|
|
|
8564
8904
|
"button",
|
|
8565
8905
|
{
|
|
8566
8906
|
type: "button",
|
|
8567
|
-
onClick: () => setLeftMonth(
|
|
8907
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, 1)),
|
|
8568
8908
|
"aria-label": "Next month",
|
|
8569
8909
|
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",
|
|
8570
8910
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
8571
8911
|
}
|
|
8572
8912
|
),
|
|
8573
|
-
renderMonth(
|
|
8913
|
+
renderMonth(addMonths4(leftMonth, 1))
|
|
8574
8914
|
] })
|
|
8575
8915
|
] })
|
|
8576
8916
|
]
|
|
@@ -8610,10 +8950,10 @@ function ColorPicker({
|
|
|
8610
8950
|
required,
|
|
8611
8951
|
placeholder = "Pick a colour\u2026"
|
|
8612
8952
|
}) {
|
|
8613
|
-
const errorId =
|
|
8953
|
+
const errorId = React29.useId();
|
|
8614
8954
|
const hasError = errorMessage != null;
|
|
8615
|
-
const [open, setOpen] =
|
|
8616
|
-
const [draft, setDraft] =
|
|
8955
|
+
const [open, setOpen] = React29.useState(false);
|
|
8956
|
+
const [draft, setDraft] = React29.useState(value);
|
|
8617
8957
|
const valid = HEX_RE.test(value);
|
|
8618
8958
|
const pick = (hex) => {
|
|
8619
8959
|
onChange?.(hex);
|
|
@@ -8774,6 +9114,7 @@ exports.Portal = Portal;
|
|
|
8774
9114
|
exports.RadioGroup = RadioGroup;
|
|
8775
9115
|
exports.Rating = Rating;
|
|
8776
9116
|
exports.ScalableContainer = ScalableContainer;
|
|
9117
|
+
exports.Scheduler = Scheduler;
|
|
8777
9118
|
exports.SearchInput = SearchInput_default;
|
|
8778
9119
|
exports.SecureLayout = SecureLayout;
|
|
8779
9120
|
exports.SegmentedControl = SegmentedControl;
|