@geomak/ui 6.24.1 → 6.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +852 -513
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.js +626 -288
- package/dist/index.js.map +1 -1
- package/dist/styles.css +31 -0
- package/package.json +1 -1
package/dist/index.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,7 +6440,7 @@ function SecureLayout({
|
|
|
6006
6440
|
className = ""
|
|
6007
6441
|
}) {
|
|
6008
6442
|
const reduced = framerMotion.useReducedMotion();
|
|
6009
|
-
const cbs =
|
|
6443
|
+
const cbs = React29.useRef({ canAccess, onGranted, onDeny });
|
|
6010
6444
|
cbs.current = { canAccess, onGranted, onDeny };
|
|
6011
6445
|
const rolesKey = JSON.stringify(roles);
|
|
6012
6446
|
const requiredRolesKey = JSON.stringify(requiredRoles);
|
|
@@ -6021,10 +6455,10 @@ function SecureLayout({
|
|
|
6021
6455
|
if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
|
|
6022
6456
|
return true;
|
|
6023
6457
|
};
|
|
6024
|
-
const [state, setState] =
|
|
6458
|
+
const [state, setState] = React29.useState(
|
|
6025
6459
|
() => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
|
|
6026
6460
|
);
|
|
6027
|
-
|
|
6461
|
+
React29.useEffect(() => {
|
|
6028
6462
|
let cancelled = false;
|
|
6029
6463
|
const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
|
|
6030
6464
|
const finish = (ok) => {
|
|
@@ -6062,7 +6496,7 @@ function SecureLayout({
|
|
|
6062
6496
|
]);
|
|
6063
6497
|
if (state === "checking") {
|
|
6064
6498
|
if (loadingFallback === null) return null;
|
|
6065
|
-
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, {}) });
|
|
6066
6500
|
}
|
|
6067
6501
|
if (state === "denied") {
|
|
6068
6502
|
if (fallback === null) return null;
|
|
@@ -6185,10 +6619,10 @@ function ThemeProvider({
|
|
|
6185
6619
|
className = "",
|
|
6186
6620
|
style
|
|
6187
6621
|
}) {
|
|
6188
|
-
const id =
|
|
6622
|
+
const id = React29__default.default.useId().replace(/:/g, "");
|
|
6189
6623
|
const scopeClass = `geo-th-${id}`;
|
|
6190
|
-
const divRef =
|
|
6191
|
-
|
|
6624
|
+
const divRef = React29.useRef(null);
|
|
6625
|
+
React29.useEffect(() => {
|
|
6192
6626
|
const el = divRef.current;
|
|
6193
6627
|
if (!el) return;
|
|
6194
6628
|
if (colorScheme === "auto") return;
|
|
@@ -6203,8 +6637,8 @@ function ThemeProvider({
|
|
|
6203
6637
|
}
|
|
6204
6638
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
6205
6639
|
}, [colorScheme]);
|
|
6206
|
-
const lightVars =
|
|
6207
|
-
const darkVarStr =
|
|
6640
|
+
const lightVars = React29.useMemo(() => toCssVars(theme), [theme]);
|
|
6641
|
+
const darkVarStr = React29.useMemo(() => {
|
|
6208
6642
|
if (!darkTheme) return "";
|
|
6209
6643
|
const dvars = toCssVars(darkTheme);
|
|
6210
6644
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -6246,7 +6680,7 @@ function NumberInput({
|
|
|
6246
6680
|
readOnly = false,
|
|
6247
6681
|
precision
|
|
6248
6682
|
}) {
|
|
6249
|
-
const errorId =
|
|
6683
|
+
const errorId = React29.useId();
|
|
6250
6684
|
const hasError = errorMessage != null;
|
|
6251
6685
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
6252
6686
|
const round = (n) => {
|
|
@@ -6377,8 +6811,8 @@ function Password({
|
|
|
6377
6811
|
showIcon,
|
|
6378
6812
|
hideIcon
|
|
6379
6813
|
}) {
|
|
6380
|
-
const [visible, setVisible] =
|
|
6381
|
-
const errorId =
|
|
6814
|
+
const [visible, setVisible] = React29.useState(false);
|
|
6815
|
+
const errorId = React29.useId();
|
|
6382
6816
|
const hasError = errorMessage != null;
|
|
6383
6817
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6384
6818
|
Field,
|
|
@@ -6451,7 +6885,7 @@ function Checkbox({
|
|
|
6451
6885
|
}) {
|
|
6452
6886
|
const isChecked = checked ?? value ?? false;
|
|
6453
6887
|
const labelFirst = labelPosition === "left";
|
|
6454
|
-
const errorId =
|
|
6888
|
+
const errorId = React29.useId();
|
|
6455
6889
|
const hasError = errorMessage != null;
|
|
6456
6890
|
const box = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6457
6891
|
CheckboxPrimitive__namespace.Root,
|
|
@@ -6559,8 +6993,8 @@ function RadioGroup({
|
|
|
6559
6993
|
className,
|
|
6560
6994
|
errorMessage
|
|
6561
6995
|
}) {
|
|
6562
|
-
const errorId =
|
|
6563
|
-
const groupId =
|
|
6996
|
+
const errorId = React29.useId();
|
|
6997
|
+
const groupId = React29.useId();
|
|
6564
6998
|
const hasError = errorMessage != null;
|
|
6565
6999
|
const labelFirst = labelPosition === "left";
|
|
6566
7000
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6660,11 +7094,11 @@ function Switch({
|
|
|
6660
7094
|
disabled,
|
|
6661
7095
|
errorMessage
|
|
6662
7096
|
}) {
|
|
6663
|
-
const id =
|
|
6664
|
-
const errorId =
|
|
7097
|
+
const id = React29.useId();
|
|
7098
|
+
const errorId = React29.useId();
|
|
6665
7099
|
const hasError = errorMessage != null;
|
|
6666
7100
|
const isControlled = checked !== void 0;
|
|
6667
|
-
const [internal, setInternal] =
|
|
7101
|
+
const [internal, setInternal] = React29.useState(defaultChecked);
|
|
6668
7102
|
const isOn = isControlled ? checked : internal;
|
|
6669
7103
|
const handle = (c) => {
|
|
6670
7104
|
if (!isControlled) setInternal(c);
|
|
@@ -6737,19 +7171,19 @@ function AutoComplete({
|
|
|
6737
7171
|
required,
|
|
6738
7172
|
htmlFor
|
|
6739
7173
|
}) {
|
|
6740
|
-
const errorId =
|
|
7174
|
+
const errorId = React29.useId();
|
|
6741
7175
|
const hasError = errorMessage != null;
|
|
6742
|
-
const [term, setTerm] =
|
|
6743
|
-
const [open, setOpen] =
|
|
6744
|
-
const [asyncItems, setAsyncItems] =
|
|
6745
|
-
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);
|
|
6746
7180
|
const isAsync = typeof onSearch === "function";
|
|
6747
|
-
const debounceRef =
|
|
6748
|
-
const requestIdRef =
|
|
7181
|
+
const debounceRef = React29.useRef(null);
|
|
7182
|
+
const requestIdRef = React29.useRef(0);
|
|
6749
7183
|
const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
|
|
6750
7184
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
6751
7185
|
) : [];
|
|
6752
|
-
|
|
7186
|
+
React29.useEffect(() => {
|
|
6753
7187
|
if (!isAsync) return;
|
|
6754
7188
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
6755
7189
|
if (!term.trim()) {
|
|
@@ -6905,15 +7339,15 @@ function TreeSelect({
|
|
|
6905
7339
|
defaultExpandedKeys = [],
|
|
6906
7340
|
size = "md"
|
|
6907
7341
|
}) {
|
|
6908
|
-
const errorId =
|
|
7342
|
+
const errorId = React29.useId();
|
|
6909
7343
|
const hasError = errorMessage != null;
|
|
6910
|
-
const [open, setOpen] =
|
|
6911
|
-
const [expanded, setExpanded] =
|
|
6912
|
-
const [activeIndex, setActiveIndex] =
|
|
6913
|
-
const listRef =
|
|
6914
|
-
const visible =
|
|
6915
|
-
const didSyncOnOpenRef =
|
|
6916
|
-
|
|
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(() => {
|
|
6917
7351
|
if (!open) {
|
|
6918
7352
|
didSyncOnOpenRef.current = false;
|
|
6919
7353
|
return;
|
|
@@ -6923,7 +7357,7 @@ function TreeSelect({
|
|
|
6923
7357
|
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
6924
7358
|
didSyncOnOpenRef.current = true;
|
|
6925
7359
|
}, [open, value]);
|
|
6926
|
-
const selectedNode =
|
|
7360
|
+
const selectedNode = React29.useMemo(
|
|
6927
7361
|
() => value != null ? findNodeByKey(items, value) : null,
|
|
6928
7362
|
[items, value]
|
|
6929
7363
|
);
|
|
@@ -7154,11 +7588,11 @@ function FileInput({
|
|
|
7154
7588
|
required,
|
|
7155
7589
|
icon
|
|
7156
7590
|
}) {
|
|
7157
|
-
const inputRef =
|
|
7158
|
-
const errorId =
|
|
7159
|
-
const [files, setFiles] =
|
|
7160
|
-
const [dragging, setDragging] =
|
|
7161
|
-
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);
|
|
7162
7596
|
const effectiveError = errorMessage ?? sizeError ?? void 0;
|
|
7163
7597
|
const openPicker = () => {
|
|
7164
7598
|
if (!disabled) inputRef.current?.click();
|
|
@@ -7296,15 +7730,15 @@ var WEEKDAY_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
|
7296
7730
|
function isSameDay(a, b) {
|
|
7297
7731
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
7298
7732
|
}
|
|
7299
|
-
function
|
|
7733
|
+
function startOfMonth2(d) {
|
|
7300
7734
|
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
7301
7735
|
}
|
|
7302
|
-
function
|
|
7736
|
+
function addDays2(d, n) {
|
|
7303
7737
|
const c = new Date(d);
|
|
7304
7738
|
c.setDate(c.getDate() + n);
|
|
7305
7739
|
return c;
|
|
7306
7740
|
}
|
|
7307
|
-
function
|
|
7741
|
+
function addMonths3(d, n) {
|
|
7308
7742
|
const c = new Date(d);
|
|
7309
7743
|
c.setMonth(c.getMonth() + n);
|
|
7310
7744
|
return c;
|
|
@@ -7316,12 +7750,12 @@ function defaultFormat3(d) {
|
|
|
7316
7750
|
return `${y}-${m}-${day}`;
|
|
7317
7751
|
}
|
|
7318
7752
|
function buildGrid2(viewMonth, weekStartsOn) {
|
|
7319
|
-
const first =
|
|
7753
|
+
const first = startOfMonth2(viewMonth);
|
|
7320
7754
|
const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
7321
|
-
const gridStart =
|
|
7755
|
+
const gridStart = addDays2(first, -startOffset);
|
|
7322
7756
|
const cells = [];
|
|
7323
7757
|
for (let i = 0; i < 42; i++) {
|
|
7324
|
-
const d =
|
|
7758
|
+
const d = addDays2(gridStart, i);
|
|
7325
7759
|
cells.push({ date: d, outside: d.getMonth() !== viewMonth.getMonth() });
|
|
7326
7760
|
}
|
|
7327
7761
|
const rows = [];
|
|
@@ -7349,30 +7783,30 @@ function DatePicker({
|
|
|
7349
7783
|
size = "md",
|
|
7350
7784
|
className = ""
|
|
7351
7785
|
}) {
|
|
7352
|
-
const errorId =
|
|
7786
|
+
const errorId = React29.useId();
|
|
7353
7787
|
const hasError = errorMessage != null;
|
|
7354
|
-
const [open, setOpen] =
|
|
7355
|
-
const [viewMonth, setViewMonth] =
|
|
7356
|
-
const [focusDate, setFocusDate] =
|
|
7357
|
-
const [view, setView] =
|
|
7358
|
-
const gridRef =
|
|
7359
|
-
|
|
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(() => {
|
|
7360
7794
|
if (!open) return;
|
|
7361
7795
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7362
|
-
setViewMonth(
|
|
7796
|
+
setViewMonth(startOfMonth2(target));
|
|
7363
7797
|
setFocusDate(target);
|
|
7364
7798
|
setView("days");
|
|
7365
7799
|
}, [open, value]);
|
|
7366
|
-
|
|
7800
|
+
React29.useEffect(() => {
|
|
7367
7801
|
if (!open) return;
|
|
7368
7802
|
const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
|
|
7369
7803
|
cell?.focus();
|
|
7370
7804
|
}, [open, focusDate]);
|
|
7371
|
-
const weekdays =
|
|
7805
|
+
const weekdays = React29.useMemo(() => {
|
|
7372
7806
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
7373
7807
|
return ordered;
|
|
7374
7808
|
}, [weekStartsOn]);
|
|
7375
|
-
const grid =
|
|
7809
|
+
const grid = React29.useMemo(() => buildGrid2(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
7376
7810
|
const isDisabled = (d) => {
|
|
7377
7811
|
if (min && d < min) return true;
|
|
7378
7812
|
if (max && d > max) return true;
|
|
@@ -7385,9 +7819,9 @@ function DatePicker({
|
|
|
7385
7819
|
};
|
|
7386
7820
|
const onKey = (e) => {
|
|
7387
7821
|
const next = (delta) => {
|
|
7388
|
-
const nd =
|
|
7822
|
+
const nd = addDays2(focusDate, delta);
|
|
7389
7823
|
setFocusDate(nd);
|
|
7390
|
-
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(
|
|
7824
|
+
if (nd.getMonth() !== viewMonth.getMonth()) setViewMonth(startOfMonth2(nd));
|
|
7391
7825
|
};
|
|
7392
7826
|
if (e.key === "ArrowLeft") {
|
|
7393
7827
|
e.preventDefault();
|
|
@@ -7403,22 +7837,22 @@ function DatePicker({
|
|
|
7403
7837
|
next(7);
|
|
7404
7838
|
} else if (e.key === "PageUp") {
|
|
7405
7839
|
e.preventDefault();
|
|
7406
|
-
const nm =
|
|
7840
|
+
const nm = addMonths3(viewMonth, -1);
|
|
7407
7841
|
setViewMonth(nm);
|
|
7408
|
-
setFocusDate((d) =>
|
|
7842
|
+
setFocusDate((d) => addMonths3(d, -1));
|
|
7409
7843
|
} else if (e.key === "PageDown") {
|
|
7410
7844
|
e.preventDefault();
|
|
7411
|
-
const nm =
|
|
7845
|
+
const nm = addMonths3(viewMonth, 1);
|
|
7412
7846
|
setViewMonth(nm);
|
|
7413
|
-
setFocusDate((d) =>
|
|
7847
|
+
setFocusDate((d) => addMonths3(d, 1));
|
|
7414
7848
|
} else if (e.key === "Home") {
|
|
7415
7849
|
e.preventDefault();
|
|
7416
7850
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7417
|
-
setFocusDate(
|
|
7851
|
+
setFocusDate(addDays2(focusDate, -dow));
|
|
7418
7852
|
} else if (e.key === "End") {
|
|
7419
7853
|
e.preventDefault();
|
|
7420
7854
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
7421
|
-
setFocusDate(
|
|
7855
|
+
setFocusDate(addDays2(focusDate, 6 - dow));
|
|
7422
7856
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
7423
7857
|
e.preventDefault();
|
|
7424
7858
|
selectDate(focusDate);
|
|
@@ -7475,7 +7909,7 @@ function DatePicker({
|
|
|
7475
7909
|
{
|
|
7476
7910
|
type: "button",
|
|
7477
7911
|
onClick: () => {
|
|
7478
|
-
if (view === "days") setViewMonth(
|
|
7912
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, -1));
|
|
7479
7913
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() - 1, viewMonth.getMonth(), 1));
|
|
7480
7914
|
else setViewMonth(new Date(viewMonth.getFullYear() - 10, viewMonth.getMonth(), 1));
|
|
7481
7915
|
},
|
|
@@ -7510,7 +7944,7 @@ function DatePicker({
|
|
|
7510
7944
|
{
|
|
7511
7945
|
type: "button",
|
|
7512
7946
|
onClick: () => {
|
|
7513
|
-
if (view === "days") setViewMonth(
|
|
7947
|
+
if (view === "days") setViewMonth(addMonths3(viewMonth, 1));
|
|
7514
7948
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() + 1, viewMonth.getMonth(), 1));
|
|
7515
7949
|
else setViewMonth(new Date(viewMonth.getFullYear() + 10, viewMonth.getMonth(), 1));
|
|
7516
7950
|
},
|
|
@@ -7662,10 +8096,10 @@ function TextArea({
|
|
|
7662
8096
|
style,
|
|
7663
8097
|
inputStyle
|
|
7664
8098
|
}) {
|
|
7665
|
-
const errorId =
|
|
8099
|
+
const errorId = React29.useId();
|
|
7666
8100
|
const hasError = errorMessage != null;
|
|
7667
|
-
const ref =
|
|
7668
|
-
|
|
8101
|
+
const ref = React29.useRef(null);
|
|
8102
|
+
React29.useLayoutEffect(() => {
|
|
7669
8103
|
if (!autoGrow) return;
|
|
7670
8104
|
const el = ref.current;
|
|
7671
8105
|
if (!el) return;
|
|
@@ -7712,102 +8146,6 @@ function TextArea({
|
|
|
7712
8146
|
}
|
|
7713
8147
|
);
|
|
7714
8148
|
}
|
|
7715
|
-
var SIZE5 = {
|
|
7716
|
-
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
7717
|
-
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
7718
|
-
lg: { h: "h-control-lg", text: "text-sm", pad: "px-4" }
|
|
7719
|
-
};
|
|
7720
|
-
function SegmentedControl({
|
|
7721
|
-
options,
|
|
7722
|
-
value,
|
|
7723
|
-
defaultValue,
|
|
7724
|
-
onChange,
|
|
7725
|
-
size = "md",
|
|
7726
|
-
fullWidth = false,
|
|
7727
|
-
disabled,
|
|
7728
|
-
label,
|
|
7729
|
-
layout = "vertical",
|
|
7730
|
-
helperText,
|
|
7731
|
-
className,
|
|
7732
|
-
name,
|
|
7733
|
-
required,
|
|
7734
|
-
errorMessage,
|
|
7735
|
-
"aria-label": ariaLabel
|
|
7736
|
-
}) {
|
|
7737
|
-
const sz = SIZE5[size];
|
|
7738
|
-
const groupId = React27.useId();
|
|
7739
|
-
const errorId = React27.useId();
|
|
7740
|
-
const hasError = errorMessage != null;
|
|
7741
|
-
const isControlled = value !== void 0;
|
|
7742
|
-
const [internal, setInternal] = React27.useState(defaultValue);
|
|
7743
|
-
const current = isControlled ? value : internal;
|
|
7744
|
-
const handle = (v) => {
|
|
7745
|
-
if (!v) return;
|
|
7746
|
-
if (!isControlled) setInternal(v);
|
|
7747
|
-
onChange?.(v);
|
|
7748
|
-
};
|
|
7749
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7750
|
-
Field,
|
|
7751
|
-
{
|
|
7752
|
-
className,
|
|
7753
|
-
label,
|
|
7754
|
-
htmlFor: groupId,
|
|
7755
|
-
errorId,
|
|
7756
|
-
errorMessage,
|
|
7757
|
-
layout,
|
|
7758
|
-
required,
|
|
7759
|
-
helperText,
|
|
7760
|
-
children: [
|
|
7761
|
-
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: current ?? "" }),
|
|
7762
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7763
|
-
ToggleGroup__namespace.Root,
|
|
7764
|
-
{
|
|
7765
|
-
id: groupId,
|
|
7766
|
-
type: "single",
|
|
7767
|
-
value: current,
|
|
7768
|
-
onValueChange: handle,
|
|
7769
|
-
disabled,
|
|
7770
|
-
"aria-label": ariaLabel ?? (typeof label === "string" ? label : void 0),
|
|
7771
|
-
"aria-invalid": hasError || void 0,
|
|
7772
|
-
"aria-describedby": hasError ? errorId : void 0,
|
|
7773
|
-
className: [
|
|
7774
|
-
"inline-flex items-center gap-1 rounded-lg border bg-surface-raised p-1",
|
|
7775
|
-
hasError ? "border-status-error" : "border-border",
|
|
7776
|
-
sz.h,
|
|
7777
|
-
fullWidth ? "flex w-full" : "w-fit",
|
|
7778
|
-
disabled ? "opacity-60 cursor-not-allowed" : ""
|
|
7779
|
-
].filter(Boolean).join(" "),
|
|
7780
|
-
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7781
|
-
ToggleGroup__namespace.Item,
|
|
7782
|
-
{
|
|
7783
|
-
value: opt.value,
|
|
7784
|
-
disabled: opt.disabled,
|
|
7785
|
-
className: [
|
|
7786
|
-
"inline-flex items-center justify-center gap-1.5 rounded-md select-none whitespace-nowrap",
|
|
7787
|
-
"transition-colors duration-150 h-full",
|
|
7788
|
-
sz.text,
|
|
7789
|
-
sz.pad,
|
|
7790
|
-
fullWidth ? "flex-1" : "",
|
|
7791
|
-
// Resting: muted text, transparent. Hover lifts the text.
|
|
7792
|
-
"text-foreground-secondary hover:text-foreground",
|
|
7793
|
-
// Active: surface-white pill + accent text + subtle shadow.
|
|
7794
|
-
"data-[state=on]:bg-surface data-[state=on]:text-accent data-[state=on]:shadow-sm",
|
|
7795
|
-
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
7796
|
-
"disabled:opacity-40 disabled:cursor-not-allowed"
|
|
7797
|
-
].filter(Boolean).join(" "),
|
|
7798
|
-
children: [
|
|
7799
|
-
opt.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: opt.icon }),
|
|
7800
|
-
opt.label
|
|
7801
|
-
]
|
|
7802
|
-
},
|
|
7803
|
-
opt.value
|
|
7804
|
-
))
|
|
7805
|
-
}
|
|
7806
|
-
)
|
|
7807
|
-
]
|
|
7808
|
-
}
|
|
7809
|
-
);
|
|
7810
|
-
}
|
|
7811
8149
|
var TRACK_H = { sm: "h-1", md: "h-1.5", lg: "h-2" };
|
|
7812
8150
|
var THUMB = { sm: "h-3.5 w-3.5", md: "h-4 w-4", lg: "h-5 w-5" };
|
|
7813
8151
|
var toArray = (v) => v == null ? void 0 : Array.isArray(v) ? v : [v];
|
|
@@ -7833,14 +8171,14 @@ function Slider({
|
|
|
7833
8171
|
name,
|
|
7834
8172
|
htmlFor
|
|
7835
8173
|
}) {
|
|
7836
|
-
const errorId =
|
|
8174
|
+
const errorId = React29.useId();
|
|
7837
8175
|
const hasError = errorMessage != null;
|
|
7838
8176
|
const isRange = Array.isArray(value ?? defaultValue);
|
|
7839
|
-
const [internal, setInternal] =
|
|
8177
|
+
const [internal, setInternal] = React29.useState(
|
|
7840
8178
|
() => toArray(value) ?? toArray(defaultValue) ?? [min]
|
|
7841
8179
|
);
|
|
7842
8180
|
const current = toArray(value) ?? internal;
|
|
7843
|
-
const [dragging, setDragging] =
|
|
8181
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
7844
8182
|
const emit = (arr) => {
|
|
7845
8183
|
setInternal(arr);
|
|
7846
8184
|
const next = isRange ? [arr[0], arr[1]] : arr[0];
|
|
@@ -7935,11 +8273,11 @@ function TagsInput({
|
|
|
7935
8273
|
validate,
|
|
7936
8274
|
separators = ["Enter", ","]
|
|
7937
8275
|
}) {
|
|
7938
|
-
const errorId =
|
|
7939
|
-
const inputRef =
|
|
7940
|
-
const [internal, setInternal] =
|
|
7941
|
-
const [draft, setDraft] =
|
|
7942
|
-
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);
|
|
7943
8281
|
const tags = value ?? internal;
|
|
7944
8282
|
const hasError = errorMessage != null || localError != null;
|
|
7945
8283
|
const errorText = errorMessage ?? localError ?? void 0;
|
|
@@ -8070,9 +8408,9 @@ function OtpInput({
|
|
|
8070
8408
|
className,
|
|
8071
8409
|
groupAfter
|
|
8072
8410
|
}) {
|
|
8073
|
-
const errorId =
|
|
8411
|
+
const errorId = React29.useId();
|
|
8074
8412
|
const hasError = errorMessage != null;
|
|
8075
|
-
const refs =
|
|
8413
|
+
const refs = React29.useRef([]);
|
|
8076
8414
|
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
8077
8415
|
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
8078
8416
|
const emit = (next) => {
|
|
@@ -8121,7 +8459,7 @@ function OtpInput({
|
|
|
8121
8459
|
emit(valid.join(""));
|
|
8122
8460
|
focusBox(valid.length);
|
|
8123
8461
|
};
|
|
8124
|
-
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: [
|
|
8125
8463
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8126
8464
|
"input",
|
|
8127
8465
|
{
|
|
@@ -8179,9 +8517,9 @@ function Rating({
|
|
|
8179
8517
|
className,
|
|
8180
8518
|
required
|
|
8181
8519
|
}) {
|
|
8182
|
-
const errorId =
|
|
8183
|
-
const [internal, setInternal] =
|
|
8184
|
-
const [hover, setHover] =
|
|
8520
|
+
const errorId = React29.useId();
|
|
8521
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
8522
|
+
const [hover, setHover] = React29.useState(null);
|
|
8185
8523
|
const current = value ?? internal;
|
|
8186
8524
|
const display2 = hover ?? current;
|
|
8187
8525
|
const interactive = !readOnly && !disabled;
|
|
@@ -8304,9 +8642,9 @@ function TimePicker({
|
|
|
8304
8642
|
required,
|
|
8305
8643
|
style
|
|
8306
8644
|
}) {
|
|
8307
|
-
const errorId =
|
|
8645
|
+
const errorId = React29.useId();
|
|
8308
8646
|
const hasError = errorMessage != null;
|
|
8309
|
-
const [open, setOpen] =
|
|
8647
|
+
const [open, setOpen] = React29.useState(false);
|
|
8310
8648
|
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
8311
8649
|
const update = (next) => {
|
|
8312
8650
|
const merged = { ...parsed, ...next };
|
|
@@ -8391,22 +8729,22 @@ function TimePicker({
|
|
|
8391
8729
|
}
|
|
8392
8730
|
var MONTH_NAMES2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
8393
8731
|
var WEEKDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
8394
|
-
var
|
|
8395
|
-
var
|
|
8396
|
-
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) => {
|
|
8397
8735
|
const c = new Date(d);
|
|
8398
8736
|
c.setDate(c.getDate() + n);
|
|
8399
8737
|
return c;
|
|
8400
8738
|
};
|
|
8401
8739
|
var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
8402
|
-
var
|
|
8740
|
+
var startOfDay3 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8403
8741
|
var defaultFmt = (d) => `${d.getFullYear()}-${`${d.getMonth() + 1}`.padStart(2, "0")}-${`${d.getDate()}`.padStart(2, "0")}`;
|
|
8404
8742
|
function buildGrid3(viewMonth, weekStartsOn) {
|
|
8405
|
-
const first =
|
|
8743
|
+
const first = startOfMonth3(viewMonth);
|
|
8406
8744
|
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
8407
|
-
const gridStart =
|
|
8745
|
+
const gridStart = addDays3(first, -offset);
|
|
8408
8746
|
return Array.from({ length: 42 }, (_, i) => {
|
|
8409
|
-
const d =
|
|
8747
|
+
const d = addDays3(gridStart, i);
|
|
8410
8748
|
return { date: d, outside: d.getMonth() !== viewMonth.getMonth() };
|
|
8411
8749
|
});
|
|
8412
8750
|
}
|
|
@@ -8430,23 +8768,23 @@ function DateRangePicker({
|
|
|
8430
8768
|
required,
|
|
8431
8769
|
style
|
|
8432
8770
|
}) {
|
|
8433
|
-
const errorId =
|
|
8771
|
+
const errorId = React29.useId();
|
|
8434
8772
|
const hasError = errorMessage != null;
|
|
8435
|
-
const [open, setOpen] =
|
|
8436
|
-
const [leftMonth, setLeftMonth] =
|
|
8437
|
-
const [pendingStart, setPendingStart] =
|
|
8438
|
-
const [hoverDate, setHoverDate] =
|
|
8439
|
-
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(
|
|
8440
8778
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8441
8779
|
[weekStartsOn]
|
|
8442
8780
|
);
|
|
8443
|
-
const isDisabled = (d) => min && d <
|
|
8781
|
+
const isDisabled = (d) => min && d < startOfDay3(min) || max && d > startOfDay3(max);
|
|
8444
8782
|
const effective = pendingStart ? { start: pendingStart, end: hoverDate } : value;
|
|
8445
8783
|
const inRange = (d) => {
|
|
8446
8784
|
const { start, end } = effective;
|
|
8447
8785
|
if (!start || !end) return false;
|
|
8448
8786
|
const [a, b] = start <= end ? [start, end] : [end, start];
|
|
8449
|
-
return d >=
|
|
8787
|
+
return d >= startOfDay3(a) && d <= startOfDay3(b);
|
|
8450
8788
|
};
|
|
8451
8789
|
const onDayClick = (d) => {
|
|
8452
8790
|
if (isDisabled(d)) return;
|
|
@@ -8553,7 +8891,7 @@ function DateRangePicker({
|
|
|
8553
8891
|
"button",
|
|
8554
8892
|
{
|
|
8555
8893
|
type: "button",
|
|
8556
|
-
onClick: () => setLeftMonth(
|
|
8894
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, -1)),
|
|
8557
8895
|
"aria-label": "Previous month",
|
|
8558
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",
|
|
8559
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" }) })
|
|
@@ -8566,13 +8904,13 @@ function DateRangePicker({
|
|
|
8566
8904
|
"button",
|
|
8567
8905
|
{
|
|
8568
8906
|
type: "button",
|
|
8569
|
-
onClick: () => setLeftMonth(
|
|
8907
|
+
onClick: () => setLeftMonth(addMonths4(leftMonth, 1)),
|
|
8570
8908
|
"aria-label": "Next month",
|
|
8571
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",
|
|
8572
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" }) })
|
|
8573
8911
|
}
|
|
8574
8912
|
),
|
|
8575
|
-
renderMonth(
|
|
8913
|
+
renderMonth(addMonths4(leftMonth, 1))
|
|
8576
8914
|
] })
|
|
8577
8915
|
] })
|
|
8578
8916
|
]
|
|
@@ -8612,10 +8950,10 @@ function ColorPicker({
|
|
|
8612
8950
|
required,
|
|
8613
8951
|
placeholder = "Pick a colour\u2026"
|
|
8614
8952
|
}) {
|
|
8615
|
-
const errorId =
|
|
8953
|
+
const errorId = React29.useId();
|
|
8616
8954
|
const hasError = errorMessage != null;
|
|
8617
|
-
const [open, setOpen] =
|
|
8618
|
-
const [draft, setDraft] =
|
|
8955
|
+
const [open, setOpen] = React29.useState(false);
|
|
8956
|
+
const [draft, setDraft] = React29.useState(value);
|
|
8619
8957
|
const valid = HEX_RE.test(value);
|
|
8620
8958
|
const pick = (hex) => {
|
|
8621
8959
|
onChange?.(hex);
|
|
@@ -8776,6 +9114,7 @@ exports.Portal = Portal;
|
|
|
8776
9114
|
exports.RadioGroup = RadioGroup;
|
|
8777
9115
|
exports.Rating = Rating;
|
|
8778
9116
|
exports.ScalableContainer = ScalableContainer;
|
|
9117
|
+
exports.Scheduler = Scheduler;
|
|
8779
9118
|
exports.SearchInput = SearchInput_default;
|
|
8780
9119
|
exports.SecureLayout = SecureLayout;
|
|
8781
9120
|
exports.SegmentedControl = SegmentedControl;
|