@geomak/ui 7.0.1 → 7.2.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 +729 -349
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +213 -2
- package/dist/index.d.ts +213 -2
- package/dist/index.js +449 -74
- package/dist/index.js.map +1 -1
- package/dist/styles.css +26 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunk4V4U2W7K_cjs = require('./chunk-4V4U2W7K.cjs');
|
|
4
4
|
var chunkOAV4TA4B_cjs = require('./chunk-OAV4TA4B.cjs');
|
|
5
|
-
var
|
|
5
|
+
var React29 = require('react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
var AvatarPrimitive = require('@radix-ui/react-avatar');
|
|
@@ -17,8 +17,8 @@ var ToggleGroup = require('@radix-ui/react-toggle-group');
|
|
|
17
17
|
var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
|
|
18
18
|
var SwitchPrimitive = require('@radix-ui/react-switch');
|
|
19
19
|
var NavigationMenu = require('@radix-ui/react-navigation-menu');
|
|
20
|
-
var CheckboxPrimitive = require('@radix-ui/react-checkbox');
|
|
21
20
|
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
21
|
+
var CheckboxPrimitive = require('@radix-ui/react-checkbox');
|
|
22
22
|
var SliderPrimitive = require('@radix-ui/react-slider');
|
|
23
23
|
|
|
24
24
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -41,7 +41,7 @@ function _interopNamespace(e) {
|
|
|
41
41
|
return Object.freeze(n);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
var
|
|
44
|
+
var React29__default = /*#__PURE__*/_interopDefault(React29);
|
|
45
45
|
var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
|
|
46
46
|
var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
|
|
47
47
|
var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
|
|
@@ -53,8 +53,8 @@ var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
|
|
|
53
53
|
var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
|
|
54
54
|
var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
|
|
55
55
|
var NavigationMenu__namespace = /*#__PURE__*/_interopNamespace(NavigationMenu);
|
|
56
|
-
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
57
56
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
57
|
+
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
58
58
|
var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
|
|
59
59
|
|
|
60
60
|
// src/utils/cx.ts
|
|
@@ -67,8 +67,8 @@ function cx(...values) {
|
|
|
67
67
|
return out;
|
|
68
68
|
}
|
|
69
69
|
function Portal({ children, target }) {
|
|
70
|
-
const [resolved, setResolved] =
|
|
71
|
-
|
|
70
|
+
const [resolved, setResolved] = React29.useState(null);
|
|
71
|
+
React29.useEffect(() => {
|
|
72
72
|
if (target === null) {
|
|
73
73
|
setResolved(null);
|
|
74
74
|
return;
|
|
@@ -502,7 +502,7 @@ function IconButton({
|
|
|
502
502
|
className = "",
|
|
503
503
|
style
|
|
504
504
|
}) {
|
|
505
|
-
const colorScheme =
|
|
505
|
+
const colorScheme = React29.useMemo(() => {
|
|
506
506
|
if (type === "primary") {
|
|
507
507
|
return "bg-accent text-accent-fg hover:bg-accent-hover";
|
|
508
508
|
}
|
|
@@ -592,7 +592,7 @@ var SIZE_CLASSES = {
|
|
|
592
592
|
md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
|
|
593
593
|
lg: "h-11 px-5 text-sm gap-2 rounded-xl"
|
|
594
594
|
};
|
|
595
|
-
var Button =
|
|
595
|
+
var Button = React29__default.default.forwardRef(function Button2({
|
|
596
596
|
content,
|
|
597
597
|
variant = "primary",
|
|
598
598
|
size = "md",
|
|
@@ -700,7 +700,7 @@ function MenuButton({
|
|
|
700
700
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
701
701
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
702
702
|
].join(" "),
|
|
703
|
-
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
703
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
704
704
|
item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border" }),
|
|
705
705
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
706
706
|
DropdownMenu__namespace.Item,
|
|
@@ -943,9 +943,9 @@ function Tooltip({
|
|
|
943
943
|
] }) });
|
|
944
944
|
}
|
|
945
945
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
946
|
-
var TabsContext =
|
|
946
|
+
var TabsContext = React29.createContext(null);
|
|
947
947
|
function useTabsContext() {
|
|
948
|
-
const ctx =
|
|
948
|
+
const ctx = React29.useContext(TabsContext);
|
|
949
949
|
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
|
|
950
950
|
return ctx;
|
|
951
951
|
}
|
|
@@ -967,26 +967,26 @@ function Tabs({
|
|
|
967
967
|
children
|
|
968
968
|
}) {
|
|
969
969
|
const isControlled = value !== void 0;
|
|
970
|
-
const [internal, setInternal] =
|
|
970
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
971
971
|
const current = isControlled ? value : internal;
|
|
972
972
|
const reduced = !!framerMotion.useReducedMotion();
|
|
973
|
-
const indicatorId =
|
|
974
|
-
const select =
|
|
973
|
+
const indicatorId = React29.useId();
|
|
974
|
+
const select = React29.useCallback((next) => {
|
|
975
975
|
if (!isControlled) setInternal(next);
|
|
976
976
|
onChange?.(next);
|
|
977
977
|
}, [isControlled, onChange]);
|
|
978
|
-
const registry =
|
|
979
|
-
const orderRef =
|
|
980
|
-
const [, bump] =
|
|
981
|
-
const registerTab =
|
|
978
|
+
const registry = React29.useRef(/* @__PURE__ */ new Map());
|
|
979
|
+
const orderRef = React29.useRef(0);
|
|
980
|
+
const [, bump] = React29.useState(0);
|
|
981
|
+
const registerTab = React29.useCallback((val, meta) => {
|
|
982
982
|
const existing = registry.current.get(val);
|
|
983
983
|
registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
|
|
984
984
|
if (!existing) bump((v) => v + 1);
|
|
985
985
|
}, []);
|
|
986
|
-
const unregisterTab =
|
|
986
|
+
const unregisterTab = React29.useCallback((val) => {
|
|
987
987
|
if (registry.current.delete(val)) bump((v) => v + 1);
|
|
988
988
|
}, []);
|
|
989
|
-
const getTabs =
|
|
989
|
+
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 })), []);
|
|
990
990
|
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
991
991
|
TabsPrimitive__namespace.Root,
|
|
992
992
|
{
|
|
@@ -1006,10 +1006,10 @@ function Tabs({
|
|
|
1006
1006
|
function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
1007
1007
|
const { variant, orientation, reduced, value } = useTabsContext();
|
|
1008
1008
|
const horizontal = orientation === "horizontal";
|
|
1009
|
-
const scrollRef =
|
|
1010
|
-
const [edges, setEdges] =
|
|
1009
|
+
const scrollRef = React29.useRef(null);
|
|
1010
|
+
const [edges, setEdges] = React29.useState({ start: false, end: false });
|
|
1011
1011
|
const scrollable = variant !== "segmented";
|
|
1012
|
-
|
|
1012
|
+
React29.useLayoutEffect(() => {
|
|
1013
1013
|
const el = scrollRef.current;
|
|
1014
1014
|
if (!el || !scrollable) return;
|
|
1015
1015
|
const update = () => {
|
|
@@ -1034,13 +1034,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
|
1034
1034
|
ro.disconnect();
|
|
1035
1035
|
};
|
|
1036
1036
|
}, [horizontal, scrollable, children]);
|
|
1037
|
-
const nudge =
|
|
1037
|
+
const nudge = React29.useCallback((dir) => {
|
|
1038
1038
|
const el = scrollRef.current;
|
|
1039
1039
|
if (!el) return;
|
|
1040
1040
|
const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
|
|
1041
1041
|
el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
|
|
1042
1042
|
}, [horizontal, reduced]);
|
|
1043
|
-
|
|
1043
|
+
React29.useLayoutEffect(() => {
|
|
1044
1044
|
const el = scrollRef.current;
|
|
1045
1045
|
if (!el || !scrollable) return;
|
|
1046
1046
|
const active = el.querySelector("[role=tab][data-state=active]");
|
|
@@ -1098,9 +1098,9 @@ function Chevron2({ side, orientation, onClick }) {
|
|
|
1098
1098
|
function OverflowMenu() {
|
|
1099
1099
|
const { getTabs, value, select, orientation } = useTabsContext();
|
|
1100
1100
|
const horizontal = orientation === "horizontal";
|
|
1101
|
-
const [open, setOpen] =
|
|
1102
|
-
const wrapRef =
|
|
1103
|
-
const timer =
|
|
1101
|
+
const [open, setOpen] = React29.useState(false);
|
|
1102
|
+
const wrapRef = React29.useRef(null);
|
|
1103
|
+
const timer = React29.useRef(null);
|
|
1104
1104
|
const openNow = () => {
|
|
1105
1105
|
if (timer.current) clearTimeout(timer.current);
|
|
1106
1106
|
setOpen(true);
|
|
@@ -1108,7 +1108,7 @@ function OverflowMenu() {
|
|
|
1108
1108
|
const closeSoon = () => {
|
|
1109
1109
|
timer.current = setTimeout(() => setOpen(false), 160);
|
|
1110
1110
|
};
|
|
1111
|
-
|
|
1111
|
+
React29.useLayoutEffect(() => {
|
|
1112
1112
|
if (!open) return;
|
|
1113
1113
|
const onDoc = (e) => {
|
|
1114
1114
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1189,7 +1189,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
|
|
|
1189
1189
|
const isActive = active === value;
|
|
1190
1190
|
const horizontal = orientation === "horizontal";
|
|
1191
1191
|
const sz = SIZE[size];
|
|
1192
|
-
|
|
1192
|
+
React29.useLayoutEffect(() => {
|
|
1193
1193
|
registerTab(value, { label: children, icon, disabled });
|
|
1194
1194
|
return () => unregisterTab(value);
|
|
1195
1195
|
}, [value, children, icon, disabled, registerTab, unregisterTab]);
|
|
@@ -1387,7 +1387,7 @@ function Tree({
|
|
|
1387
1387
|
item.key
|
|
1388
1388
|
)) });
|
|
1389
1389
|
}
|
|
1390
|
-
var AccordionCtx =
|
|
1390
|
+
var AccordionCtx = React29.createContext({ variant: "separated" });
|
|
1391
1391
|
function Accordion2({
|
|
1392
1392
|
children,
|
|
1393
1393
|
type = "single",
|
|
@@ -1446,7 +1446,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
1446
1446
|
}
|
|
1447
1447
|
);
|
|
1448
1448
|
function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
|
|
1449
|
-
const { variant } =
|
|
1449
|
+
const { variant } = React29.useContext(AccordionCtx);
|
|
1450
1450
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1451
1451
|
AccordionPrimitive__namespace.Item,
|
|
1452
1452
|
{
|
|
@@ -1505,7 +1505,7 @@ function Breadcrumbs({
|
|
|
1505
1505
|
className = "",
|
|
1506
1506
|
style
|
|
1507
1507
|
}) {
|
|
1508
|
-
const [expanded, setExpanded] =
|
|
1508
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
1509
1509
|
const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
|
|
1510
1510
|
const visible = [];
|
|
1511
1511
|
if (shouldCollapse) {
|
|
@@ -1689,8 +1689,8 @@ function Stepper({
|
|
|
1689
1689
|
className = ""
|
|
1690
1690
|
}) {
|
|
1691
1691
|
const reduced = framerMotion.useReducedMotion();
|
|
1692
|
-
const [forcedVertical, setForcedVertical] =
|
|
1693
|
-
|
|
1692
|
+
const [forcedVertical, setForcedVertical] = React29.useState(false);
|
|
1693
|
+
React29.useEffect(() => {
|
|
1694
1694
|
if (!responsive || orientation === "vertical") return;
|
|
1695
1695
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1696
1696
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
@@ -1799,7 +1799,7 @@ function Kbd({
|
|
|
1799
1799
|
style
|
|
1800
1800
|
}) {
|
|
1801
1801
|
if (keys && keys.length > 0) {
|
|
1802
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1802
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
1803
1803
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
|
|
1804
1804
|
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
|
|
1805
1805
|
] }, `${k}-${i}`)) });
|
|
@@ -1890,13 +1890,13 @@ function FlatCarousel({
|
|
|
1890
1890
|
className = "",
|
|
1891
1891
|
style
|
|
1892
1892
|
}) {
|
|
1893
|
-
const scrollerRef =
|
|
1894
|
-
const slides =
|
|
1895
|
-
const [active, setActive] =
|
|
1896
|
-
const [atStart, setAtStart] =
|
|
1897
|
-
const [atEnd, setAtEnd] =
|
|
1893
|
+
const scrollerRef = React29.useRef(null);
|
|
1894
|
+
const slides = React29__default.default.Children.toArray(children);
|
|
1895
|
+
const [active, setActive] = React29.useState(0);
|
|
1896
|
+
const [atStart, setAtStart] = React29.useState(true);
|
|
1897
|
+
const [atEnd, setAtEnd] = React29.useState(false);
|
|
1898
1898
|
const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
|
|
1899
|
-
const update =
|
|
1899
|
+
const update = React29.useCallback(() => {
|
|
1900
1900
|
const el = scrollerRef.current;
|
|
1901
1901
|
if (!el) return;
|
|
1902
1902
|
setAtStart(el.scrollLeft <= 1);
|
|
@@ -1905,7 +1905,7 @@ function FlatCarousel({
|
|
|
1905
1905
|
const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
|
|
1906
1906
|
setActive(Math.round(el.scrollLeft / slideW));
|
|
1907
1907
|
}, [gap]);
|
|
1908
|
-
|
|
1908
|
+
React29.useEffect(() => {
|
|
1909
1909
|
update();
|
|
1910
1910
|
const el = scrollerRef.current;
|
|
1911
1911
|
if (!el) return;
|
|
@@ -1946,9 +1946,9 @@ function RotatingCarousel({
|
|
|
1946
1946
|
className = "",
|
|
1947
1947
|
style
|
|
1948
1948
|
}) {
|
|
1949
|
-
const slides =
|
|
1949
|
+
const slides = React29__default.default.Children.toArray(children);
|
|
1950
1950
|
const count = slides.length;
|
|
1951
|
-
const [active, setActive] =
|
|
1951
|
+
const [active, setActive] = React29.useState(0);
|
|
1952
1952
|
const reduced = framerMotion.useReducedMotion();
|
|
1953
1953
|
const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
|
|
1954
1954
|
const idx = wrap(active);
|
|
@@ -2186,13 +2186,13 @@ function Chat({
|
|
|
2186
2186
|
className = "",
|
|
2187
2187
|
style
|
|
2188
2188
|
}) {
|
|
2189
|
-
const listRef =
|
|
2190
|
-
const atBottomRef =
|
|
2191
|
-
const [showJump, setShowJump] =
|
|
2192
|
-
const [draft, setDraft] =
|
|
2189
|
+
const listRef = React29.useRef(null);
|
|
2190
|
+
const atBottomRef = React29.useRef(true);
|
|
2191
|
+
const [showJump, setShowJump] = React29.useState(false);
|
|
2192
|
+
const [draft, setDraft] = React29.useState("");
|
|
2193
2193
|
const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
|
|
2194
2194
|
const isTyping = typingNames.length > 0;
|
|
2195
|
-
const scrollToBottom =
|
|
2195
|
+
const scrollToBottom = React29.useCallback((smooth = true) => {
|
|
2196
2196
|
const el = listRef.current;
|
|
2197
2197
|
if (!el) return;
|
|
2198
2198
|
if (typeof el.scrollTo === "function") el.scrollTo({ top: el.scrollHeight, behavior: smooth ? "smooth" : "auto" });
|
|
@@ -2205,10 +2205,10 @@ function Chat({
|
|
|
2205
2205
|
atBottomRef.current = near;
|
|
2206
2206
|
setShowJump(!near);
|
|
2207
2207
|
};
|
|
2208
|
-
|
|
2208
|
+
React29.useEffect(() => {
|
|
2209
2209
|
if (atBottomRef.current) scrollToBottom(messages.length > 0);
|
|
2210
2210
|
}, [messages.length, isTyping]);
|
|
2211
|
-
|
|
2211
|
+
React29.useEffect(() => {
|
|
2212
2212
|
scrollToBottom(false);
|
|
2213
2213
|
}, [scrollToBottom]);
|
|
2214
2214
|
const send = () => {
|
|
@@ -2398,7 +2398,7 @@ function FAB({
|
|
|
2398
2398
|
className = "",
|
|
2399
2399
|
style
|
|
2400
2400
|
}) {
|
|
2401
|
-
const [open, setOpen] =
|
|
2401
|
+
const [open, setOpen] = React29.useState(false);
|
|
2402
2402
|
const reduced = framerMotion.useReducedMotion();
|
|
2403
2403
|
const hasDial = !!actions && actions.length > 0;
|
|
2404
2404
|
const bottom = position.startsWith("bottom");
|
|
@@ -2500,8 +2500,8 @@ function PopConfirm({
|
|
|
2500
2500
|
onOpenChange,
|
|
2501
2501
|
className = ""
|
|
2502
2502
|
}) {
|
|
2503
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
2504
|
-
const [loading, setLoading] =
|
|
2503
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React29.useState(false);
|
|
2504
|
+
const [loading, setLoading] = React29.useState(false);
|
|
2505
2505
|
const isOpen = open ?? uncontrolledOpen;
|
|
2506
2506
|
const setOpen = (next) => {
|
|
2507
2507
|
onOpenChange?.(next);
|
|
@@ -2588,16 +2588,16 @@ function LogoutTimer({
|
|
|
2588
2588
|
logoutLabel = "Sign out now"
|
|
2589
2589
|
}) {
|
|
2590
2590
|
const reduced = framerMotion.useReducedMotion();
|
|
2591
|
-
const [warning, setWarning] =
|
|
2592
|
-
const [remaining, setRemaining] =
|
|
2593
|
-
const idleTimer =
|
|
2594
|
-
const tick =
|
|
2595
|
-
const deadline =
|
|
2596
|
-
const warningRef =
|
|
2597
|
-
const lastReset =
|
|
2598
|
-
const cbs =
|
|
2591
|
+
const [warning, setWarning] = React29.useState(false);
|
|
2592
|
+
const [remaining, setRemaining] = React29.useState(countdown);
|
|
2593
|
+
const idleTimer = React29.useRef(null);
|
|
2594
|
+
const tick = React29.useRef(null);
|
|
2595
|
+
const deadline = React29.useRef(0);
|
|
2596
|
+
const warningRef = React29.useRef(false);
|
|
2597
|
+
const lastReset = React29.useRef(0);
|
|
2598
|
+
const cbs = React29.useRef({ onLogout, onContinue, onWarning });
|
|
2599
2599
|
cbs.current = { onLogout, onContinue, onWarning };
|
|
2600
|
-
const clearTimers =
|
|
2600
|
+
const clearTimers = React29.useCallback(() => {
|
|
2601
2601
|
if (idleTimer.current) {
|
|
2602
2602
|
clearTimeout(idleTimer.current);
|
|
2603
2603
|
idleTimer.current = null;
|
|
@@ -2607,13 +2607,13 @@ function LogoutTimer({
|
|
|
2607
2607
|
tick.current = null;
|
|
2608
2608
|
}
|
|
2609
2609
|
}, []);
|
|
2610
|
-
const logout =
|
|
2610
|
+
const logout = React29.useCallback(() => {
|
|
2611
2611
|
clearTimers();
|
|
2612
2612
|
warningRef.current = false;
|
|
2613
2613
|
setWarning(false);
|
|
2614
2614
|
cbs.current.onLogout();
|
|
2615
2615
|
}, [clearTimers]);
|
|
2616
|
-
const startIdle =
|
|
2616
|
+
const startIdle = React29.useCallback(() => {
|
|
2617
2617
|
if (idleTimer.current) clearTimeout(idleTimer.current);
|
|
2618
2618
|
idleTimer.current = setTimeout(() => {
|
|
2619
2619
|
warningRef.current = true;
|
|
@@ -2628,7 +2628,7 @@ function LogoutTimer({
|
|
|
2628
2628
|
}, 250);
|
|
2629
2629
|
}, timeout);
|
|
2630
2630
|
}, [timeout, countdown, logout]);
|
|
2631
|
-
const stay =
|
|
2631
|
+
const stay = React29.useCallback(() => {
|
|
2632
2632
|
if (tick.current) {
|
|
2633
2633
|
clearInterval(tick.current);
|
|
2634
2634
|
tick.current = null;
|
|
@@ -2638,7 +2638,7 @@ function LogoutTimer({
|
|
|
2638
2638
|
cbs.current.onContinue?.();
|
|
2639
2639
|
startIdle();
|
|
2640
2640
|
}, [startIdle]);
|
|
2641
|
-
|
|
2641
|
+
React29.useEffect(() => {
|
|
2642
2642
|
if (!enabled) {
|
|
2643
2643
|
clearTimers();
|
|
2644
2644
|
warningRef.current = false;
|
|
@@ -2703,11 +2703,11 @@ function SegmentedControl({
|
|
|
2703
2703
|
"aria-label": ariaLabel
|
|
2704
2704
|
}) {
|
|
2705
2705
|
const sz = SIZE5[size];
|
|
2706
|
-
const groupId =
|
|
2707
|
-
const errorId =
|
|
2706
|
+
const groupId = React29.useId();
|
|
2707
|
+
const errorId = React29.useId();
|
|
2708
2708
|
const hasError = errorMessage != null;
|
|
2709
2709
|
const isControlled = value !== void 0;
|
|
2710
|
-
const [internal, setInternal] =
|
|
2710
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
2711
2711
|
const current = isControlled ? value : internal;
|
|
2712
2712
|
const handle = (v) => {
|
|
2713
2713
|
if (!v) return;
|
|
@@ -2868,22 +2868,22 @@ function Scheduler({
|
|
|
2868
2868
|
style
|
|
2869
2869
|
}) {
|
|
2870
2870
|
const reduced = framerMotion.useReducedMotion();
|
|
2871
|
-
const [view, setView] =
|
|
2872
|
-
const [cursor, setCursor] =
|
|
2873
|
-
const [loaded, setLoaded] =
|
|
2874
|
-
const [loading, setLoading] =
|
|
2875
|
-
const [error, setError] =
|
|
2876
|
-
const [reloadKey, setReloadKey] =
|
|
2877
|
-
const [dir, setDir] =
|
|
2878
|
-
const cbRef =
|
|
2871
|
+
const [view, setView] = React29.useState(defaultView);
|
|
2872
|
+
const [cursor, setCursor] = React29.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2873
|
+
const [loaded, setLoaded] = React29.useState([]);
|
|
2874
|
+
const [loading, setLoading] = React29.useState(false);
|
|
2875
|
+
const [error, setError] = React29.useState(null);
|
|
2876
|
+
const [reloadKey, setReloadKey] = React29.useState(0);
|
|
2877
|
+
const [dir, setDir] = React29.useState(0);
|
|
2878
|
+
const cbRef = React29.useRef({ loadEvents, onError });
|
|
2879
2879
|
cbRef.current = { loadEvents, onError };
|
|
2880
|
-
const range =
|
|
2880
|
+
const range = React29.useMemo(
|
|
2881
2881
|
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2882
2882
|
[view, cursor, weekStartsOn]
|
|
2883
2883
|
);
|
|
2884
2884
|
const fromKey = range.from.getTime();
|
|
2885
2885
|
const toKey = range.to.getTime();
|
|
2886
|
-
|
|
2886
|
+
React29.useEffect(() => {
|
|
2887
2887
|
const { loadEvents: loader, onError: onErr } = cbRef.current;
|
|
2888
2888
|
if (!loader) return;
|
|
2889
2889
|
let cancelled = false;
|
|
@@ -2903,16 +2903,16 @@ function Scheduler({
|
|
|
2903
2903
|
cancelled = true;
|
|
2904
2904
|
};
|
|
2905
2905
|
}, [fromKey, toKey, view, reloadKey]);
|
|
2906
|
-
const retry =
|
|
2907
|
-
const events =
|
|
2906
|
+
const retry = React29.useCallback(() => setReloadKey((k) => k + 1), []);
|
|
2907
|
+
const events = React29.useMemo(
|
|
2908
2908
|
() => (controlledEvents ?? loaded).map(normalize),
|
|
2909
2909
|
[controlledEvents, loaded]
|
|
2910
2910
|
);
|
|
2911
|
-
const go =
|
|
2911
|
+
const go = React29.useCallback((delta) => {
|
|
2912
2912
|
setDir(delta);
|
|
2913
2913
|
setCursor((c) => view === "month" ? addMonths(c, delta) : addDays(c, delta * 7));
|
|
2914
2914
|
}, [view]);
|
|
2915
|
-
const goToday =
|
|
2915
|
+
const goToday = React29.useCallback(() => {
|
|
2916
2916
|
setDir(0);
|
|
2917
2917
|
setCursor(/* @__PURE__ */ new Date());
|
|
2918
2918
|
}, []);
|
|
@@ -3022,9 +3022,9 @@ function SchedulerError({ onRetry }) {
|
|
|
3022
3022
|
] });
|
|
3023
3023
|
}
|
|
3024
3024
|
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3025
|
-
const [open, setOpen] =
|
|
3026
|
-
const [viewYear, setViewYear] =
|
|
3027
|
-
|
|
3025
|
+
const [open, setOpen] = React29.useState(false);
|
|
3026
|
+
const [viewYear, setViewYear] = React29.useState(cursor.getFullYear());
|
|
3027
|
+
React29.useEffect(() => {
|
|
3028
3028
|
if (open) setViewYear(cursor.getFullYear());
|
|
3029
3029
|
}, [open, cursor]);
|
|
3030
3030
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open, onOpenChange: setOpen, children: [
|
|
@@ -3098,8 +3098,8 @@ function MonthView({
|
|
|
3098
3098
|
onSelectSlot,
|
|
3099
3099
|
onSelectEvent
|
|
3100
3100
|
}) {
|
|
3101
|
-
const grid =
|
|
3102
|
-
const eventsByDay =
|
|
3101
|
+
const grid = React29.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3102
|
+
const eventsByDay = React29.useMemo(() => bucketByDay(events), [events]);
|
|
3103
3103
|
const labels = weekdayLabels(weekStartsOn);
|
|
3104
3104
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3105
3105
|
/* @__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)) }),
|
|
@@ -3173,12 +3173,12 @@ function WeekView({
|
|
|
3173
3173
|
onSelectSlot,
|
|
3174
3174
|
onSelectEvent
|
|
3175
3175
|
}) {
|
|
3176
|
-
const days =
|
|
3177
|
-
const eventsByDay =
|
|
3178
|
-
const labels =
|
|
3176
|
+
const days = React29.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3177
|
+
const eventsByDay = React29.useMemo(() => bucketByDay(events), [events]);
|
|
3178
|
+
const labels = React29.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
|
|
3179
3179
|
const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
|
|
3180
3180
|
const [startHour, endHour] = dayHours;
|
|
3181
|
-
const hours =
|
|
3181
|
+
const hours = React29.useMemo(
|
|
3182
3182
|
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3183
3183
|
[startHour, endHour]
|
|
3184
3184
|
);
|
|
@@ -3369,17 +3369,17 @@ function Cart({
|
|
|
3369
3369
|
] })
|
|
3370
3370
|
] });
|
|
3371
3371
|
}
|
|
3372
|
-
var CartContext =
|
|
3372
|
+
var CartContext = React29.createContext(null);
|
|
3373
3373
|
var clampQty = (qty, max) => {
|
|
3374
3374
|
const lower = Math.max(1, Math.round(qty));
|
|
3375
3375
|
return max != null ? Math.min(lower, max) : lower;
|
|
3376
3376
|
};
|
|
3377
3377
|
function CartProvider({ children, initialItems = [], onChange }) {
|
|
3378
|
-
const [items, setItems] =
|
|
3379
|
-
|
|
3378
|
+
const [items, setItems] = React29.useState(initialItems);
|
|
3379
|
+
React29.useEffect(() => {
|
|
3380
3380
|
onChange?.(items);
|
|
3381
3381
|
}, [items]);
|
|
3382
|
-
const addToCart =
|
|
3382
|
+
const addToCart = React29.useCallback((item, quantity) => {
|
|
3383
3383
|
const addQty = quantity ?? item.quantity ?? 1;
|
|
3384
3384
|
setItems((prev) => {
|
|
3385
3385
|
const existing = prev.find((it) => it.id === item.id);
|
|
@@ -3392,29 +3392,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
|
|
|
3392
3392
|
return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
|
|
3393
3393
|
});
|
|
3394
3394
|
}, []);
|
|
3395
|
-
const removeFromCart =
|
|
3395
|
+
const removeFromCart = React29.useCallback((id) => {
|
|
3396
3396
|
setItems((prev) => prev.filter((it) => it.id !== id));
|
|
3397
3397
|
}, []);
|
|
3398
|
-
const updateQuantity =
|
|
3398
|
+
const updateQuantity = React29.useCallback((id, quantity) => {
|
|
3399
3399
|
setItems(
|
|
3400
3400
|
(prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
|
|
3401
3401
|
);
|
|
3402
3402
|
}, []);
|
|
3403
|
-
const clearCart =
|
|
3404
|
-
const isInCart =
|
|
3405
|
-
const getItemCount =
|
|
3406
|
-
const getCartTotal =
|
|
3403
|
+
const clearCart = React29.useCallback(() => setItems([]), []);
|
|
3404
|
+
const isInCart = React29.useCallback((id) => items.some((it) => it.id === id), [items]);
|
|
3405
|
+
const getItemCount = React29.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
|
|
3406
|
+
const getCartTotal = React29.useCallback(
|
|
3407
3407
|
() => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
|
|
3408
3408
|
[items]
|
|
3409
3409
|
);
|
|
3410
|
-
const value =
|
|
3410
|
+
const value = React29.useMemo(
|
|
3411
3411
|
() => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
|
|
3412
3412
|
[items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
|
|
3413
3413
|
);
|
|
3414
3414
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
3415
3415
|
}
|
|
3416
3416
|
function useCart() {
|
|
3417
|
-
const ctx =
|
|
3417
|
+
const ctx = React29.useContext(CartContext);
|
|
3418
3418
|
if (!ctx) {
|
|
3419
3419
|
throw new Error("useCart must be used within a <CartProvider>.");
|
|
3420
3420
|
}
|
|
@@ -3748,11 +3748,11 @@ function buildBindings(store, name, kind, snap) {
|
|
|
3748
3748
|
|
|
3749
3749
|
// src/form/useForm.ts
|
|
3750
3750
|
function useForm(options = {}) {
|
|
3751
|
-
const ref =
|
|
3751
|
+
const ref = React29.useRef(null);
|
|
3752
3752
|
if (ref.current === null) ref.current = new FormStore(options);
|
|
3753
3753
|
const store = ref.current;
|
|
3754
|
-
|
|
3755
|
-
const make =
|
|
3754
|
+
React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3755
|
+
const make = React29.useCallback(
|
|
3756
3756
|
(kind) => (name, rules) => {
|
|
3757
3757
|
if (rules !== void 0) store.setRule(name, rules);
|
|
3758
3758
|
return buildBindings(store, name, kind, store.getFieldSnapshot(name));
|
|
@@ -3781,9 +3781,9 @@ function useForm(options = {}) {
|
|
|
3781
3781
|
fieldTarget: make("target")
|
|
3782
3782
|
};
|
|
3783
3783
|
}
|
|
3784
|
-
var FormContext =
|
|
3784
|
+
var FormContext = React29.createContext(null);
|
|
3785
3785
|
function useFormStore() {
|
|
3786
|
-
const store =
|
|
3786
|
+
const store = React29.useContext(FormContext);
|
|
3787
3787
|
if (!store) {
|
|
3788
3788
|
throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
|
|
3789
3789
|
}
|
|
@@ -3797,8 +3797,8 @@ function Form({
|
|
|
3797
3797
|
children,
|
|
3798
3798
|
...rest
|
|
3799
3799
|
}) {
|
|
3800
|
-
const ref =
|
|
3801
|
-
const bypass =
|
|
3800
|
+
const ref = React29.useRef(null);
|
|
3801
|
+
const bypass = React29.useRef(false);
|
|
3802
3802
|
const handleSubmit = async (e) => {
|
|
3803
3803
|
if (bypass.current) {
|
|
3804
3804
|
bypass.current = false;
|
|
@@ -3850,12 +3850,12 @@ function useFormField(name, options = {}) {
|
|
|
3850
3850
|
const store = useFormStore();
|
|
3851
3851
|
const { kind = "value", rules } = options;
|
|
3852
3852
|
if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
|
|
3853
|
-
|
|
3853
|
+
React29.useEffect(() => {
|
|
3854
3854
|
return () => {
|
|
3855
3855
|
if (rules !== void 0) store.removeRule(name);
|
|
3856
3856
|
};
|
|
3857
3857
|
}, [store, name]);
|
|
3858
|
-
const snap =
|
|
3858
|
+
const snap = React29.useSyncExternalStore(
|
|
3859
3859
|
store.subscribe,
|
|
3860
3860
|
() => store.getFieldSnapshot(name)
|
|
3861
3861
|
);
|
|
@@ -3867,7 +3867,7 @@ function FormField({ name, kind, rules, children }) {
|
|
|
3867
3867
|
}
|
|
3868
3868
|
function useFieldArray(name) {
|
|
3869
3869
|
const store = useFormStore();
|
|
3870
|
-
|
|
3870
|
+
React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3871
3871
|
const arr = store.getValue(name) ?? [];
|
|
3872
3872
|
const keys = store.getKeys(name);
|
|
3873
3873
|
return {
|
|
@@ -3900,7 +3900,7 @@ function TextInput({
|
|
|
3900
3900
|
suffix,
|
|
3901
3901
|
id
|
|
3902
3902
|
}) {
|
|
3903
|
-
const errorId =
|
|
3903
|
+
const errorId = React29.useId();
|
|
3904
3904
|
const hasError = errorMessage != null;
|
|
3905
3905
|
const hasAdornment = prefix != null || suffix != null;
|
|
3906
3906
|
const inputId = htmlFor ?? id;
|
|
@@ -4061,7 +4061,7 @@ function CreditCardForm({
|
|
|
4061
4061
|
className = "",
|
|
4062
4062
|
style
|
|
4063
4063
|
}) {
|
|
4064
|
-
const initial =
|
|
4064
|
+
const initial = React29.useRef({
|
|
4065
4065
|
number: formatCardNumber(defaultValue?.number ?? ""),
|
|
4066
4066
|
name: defaultValue?.name ?? "",
|
|
4067
4067
|
expiry: formatExpiry(defaultValue?.expiry ?? ""),
|
|
@@ -4070,7 +4070,7 @@ function CreditCardForm({
|
|
|
4070
4070
|
const form = useForm({ initialValues: initial });
|
|
4071
4071
|
const numberStr = String(form.values.number ?? "");
|
|
4072
4072
|
const brand = detectBrand(numberStr);
|
|
4073
|
-
|
|
4073
|
+
React29.useEffect(() => {
|
|
4074
4074
|
onChange?.(toCard(form.values));
|
|
4075
4075
|
}, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
|
|
4076
4076
|
const numberBind = form.fieldNative("number", {
|
|
@@ -4193,7 +4193,7 @@ function Checkout({
|
|
|
4193
4193
|
] })
|
|
4194
4194
|
] });
|
|
4195
4195
|
}
|
|
4196
|
-
var NotificationContext =
|
|
4196
|
+
var NotificationContext = React29.createContext({
|
|
4197
4197
|
open: () => void 0,
|
|
4198
4198
|
close: () => void 0
|
|
4199
4199
|
});
|
|
@@ -4251,26 +4251,26 @@ function NotificationItem({
|
|
|
4251
4251
|
onClose,
|
|
4252
4252
|
reduced
|
|
4253
4253
|
}) {
|
|
4254
|
-
const [paused, setPaused] =
|
|
4254
|
+
const [paused, setPaused] = React29.useState(false);
|
|
4255
4255
|
const duration = n.duration ?? 4e3;
|
|
4256
4256
|
const isAutoDismissing = isFinite(duration) && duration > 0;
|
|
4257
4257
|
const showProgress = !reduced && isAutoDismissing;
|
|
4258
|
-
const timerRef =
|
|
4259
|
-
const startTimeRef =
|
|
4260
|
-
const remainingRef =
|
|
4261
|
-
const clearTimer =
|
|
4258
|
+
const timerRef = React29.useRef(null);
|
|
4259
|
+
const startTimeRef = React29.useRef(0);
|
|
4260
|
+
const remainingRef = React29.useRef(duration);
|
|
4261
|
+
const clearTimer = React29.useCallback(() => {
|
|
4262
4262
|
if (timerRef.current !== null) {
|
|
4263
4263
|
clearTimeout(timerRef.current);
|
|
4264
4264
|
timerRef.current = null;
|
|
4265
4265
|
}
|
|
4266
4266
|
}, []);
|
|
4267
|
-
const scheduleDismiss =
|
|
4267
|
+
const scheduleDismiss = React29.useCallback((ms) => {
|
|
4268
4268
|
clearTimer();
|
|
4269
4269
|
if (!isAutoDismissing) return;
|
|
4270
4270
|
startTimeRef.current = Date.now();
|
|
4271
4271
|
timerRef.current = setTimeout(() => onClose(n.id), ms);
|
|
4272
4272
|
}, [clearTimer, isAutoDismissing, n.id, onClose]);
|
|
4273
|
-
|
|
4273
|
+
React29.useEffect(() => {
|
|
4274
4274
|
if (paused || !isAutoDismissing) return;
|
|
4275
4275
|
scheduleDismiss(remainingRef.current);
|
|
4276
4276
|
return clearTimer;
|
|
@@ -4353,15 +4353,15 @@ function NotificationProvider({
|
|
|
4353
4353
|
children,
|
|
4354
4354
|
position = "top-right"
|
|
4355
4355
|
}) {
|
|
4356
|
-
const [notifications, setNotifications] =
|
|
4356
|
+
const [notifications, setNotifications] = React29.useState([]);
|
|
4357
4357
|
const reduced = framerMotion.useReducedMotion();
|
|
4358
|
-
const open =
|
|
4358
|
+
const open = React29.useCallback((payload) => {
|
|
4359
4359
|
setNotifications((prev) => [
|
|
4360
4360
|
...prev,
|
|
4361
4361
|
{ duration: 4e3, ...payload, id: Date.now() + Math.random() }
|
|
4362
4362
|
]);
|
|
4363
4363
|
}, []);
|
|
4364
|
-
const close =
|
|
4364
|
+
const close = React29.useCallback((id) => {
|
|
4365
4365
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
4366
4366
|
}, []);
|
|
4367
4367
|
return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
|
|
@@ -4390,7 +4390,7 @@ function NotificationProvider({
|
|
|
4390
4390
|
] });
|
|
4391
4391
|
}
|
|
4392
4392
|
function useNotification() {
|
|
4393
|
-
const { open } =
|
|
4393
|
+
const { open } = React29.useContext(NotificationContext);
|
|
4394
4394
|
return {
|
|
4395
4395
|
info: (props) => open({ type: "info", ...props }),
|
|
4396
4396
|
success: (props) => open({ type: "success", ...props }),
|
|
@@ -4507,10 +4507,10 @@ function FadingBase({
|
|
|
4507
4507
|
isMounted = false,
|
|
4508
4508
|
children
|
|
4509
4509
|
}) {
|
|
4510
|
-
const [shouldRender, setShouldRender] =
|
|
4511
|
-
const [visible, setVisible] =
|
|
4512
|
-
const timerRef =
|
|
4513
|
-
|
|
4510
|
+
const [shouldRender, setShouldRender] = React29.useState(isMounted);
|
|
4511
|
+
const [visible, setVisible] = React29.useState(false);
|
|
4512
|
+
const timerRef = React29.useRef(null);
|
|
4513
|
+
React29.useEffect(() => {
|
|
4514
4514
|
if (isMounted) {
|
|
4515
4515
|
setShouldRender(true);
|
|
4516
4516
|
const rafId = requestAnimationFrame(() => setVisible(true));
|
|
@@ -4608,8 +4608,8 @@ function ScalableContainer({
|
|
|
4608
4608
|
togglePosition = "top-right",
|
|
4609
4609
|
className = ""
|
|
4610
4610
|
}) {
|
|
4611
|
-
const containerRef =
|
|
4612
|
-
const [internalScaled, setInternalScaled] =
|
|
4611
|
+
const containerRef = React29.useRef(null);
|
|
4612
|
+
const [internalScaled, setInternalScaled] = React29.useState(false);
|
|
4613
4613
|
const isScaled = expanded ?? internalScaled;
|
|
4614
4614
|
const reduced = framerMotion.useReducedMotion();
|
|
4615
4615
|
const onToggle = () => {
|
|
@@ -4747,17 +4747,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
|
|
|
4747
4747
|
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)) });
|
|
4748
4748
|
}
|
|
4749
4749
|
function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
|
|
4750
|
-
const [activeIndex, setActiveIndex] =
|
|
4751
|
-
const [indexPool, setIndexPool] =
|
|
4752
|
-
const cardRefs =
|
|
4753
|
-
const getIndexes =
|
|
4750
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
4751
|
+
const [indexPool, setIndexPool] = React29.useState([]);
|
|
4752
|
+
const cardRefs = React29.useRef([]);
|
|
4753
|
+
const getIndexes = React29.useMemo(() => {
|
|
4754
4754
|
let nextIndex = activeIndex + 1;
|
|
4755
4755
|
let previousIndex = activeIndex - 1;
|
|
4756
4756
|
if (activeIndex === 0) previousIndex = items.length - 1;
|
|
4757
4757
|
if (activeIndex === items.length - 1) nextIndex = 0;
|
|
4758
4758
|
return { previousIndex, nextIndex };
|
|
4759
4759
|
}, [activeIndex, items.length]);
|
|
4760
|
-
|
|
4760
|
+
React29.useEffect(() => {
|
|
4761
4761
|
const { nextIndex, previousIndex } = getIndexes;
|
|
4762
4762
|
let indexes = [previousIndex, activeIndex, nextIndex];
|
|
4763
4763
|
if (activeIndex !== 0 && activeIndex !== items.length - 1) {
|
|
@@ -4930,8 +4930,8 @@ function writeDismissed(key) {
|
|
|
4930
4930
|
}
|
|
4931
4931
|
}
|
|
4932
4932
|
function useTargetBbox(ref) {
|
|
4933
|
-
const [bbox, setBbox] =
|
|
4934
|
-
|
|
4933
|
+
const [bbox, setBbox] = React29.useState(null);
|
|
4934
|
+
React29.useLayoutEffect(() => {
|
|
4935
4935
|
const el = ref?.current;
|
|
4936
4936
|
if (!el) {
|
|
4937
4937
|
setBbox(null);
|
|
@@ -4961,7 +4961,7 @@ function tooltipStyleFor(bbox, placement) {
|
|
|
4961
4961
|
return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
|
|
4962
4962
|
}
|
|
4963
4963
|
function useFocusTrap(containerRef, active) {
|
|
4964
|
-
|
|
4964
|
+
React29.useEffect(() => {
|
|
4965
4965
|
if (!active) return;
|
|
4966
4966
|
const el = containerRef.current;
|
|
4967
4967
|
if (!el) return;
|
|
@@ -5000,16 +5000,16 @@ function Wizard({
|
|
|
5000
5000
|
onComplete,
|
|
5001
5001
|
onSkip
|
|
5002
5002
|
}) {
|
|
5003
|
-
const tooltipRef =
|
|
5004
|
-
const tooltipTitleId =
|
|
5005
|
-
const tooltipBodyId =
|
|
5003
|
+
const tooltipRef = React29.useRef(null);
|
|
5004
|
+
const tooltipTitleId = React29.useId();
|
|
5005
|
+
const tooltipBodyId = React29.useId();
|
|
5006
5006
|
const reduced = framerMotion.useReducedMotion();
|
|
5007
|
-
const [open, setOpen] =
|
|
5008
|
-
const [activeIndex, setActiveIndex] =
|
|
5007
|
+
const [open, setOpen] = React29.useState(() => steps.length > 0 && !readDismissed(storageKey));
|
|
5008
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
5009
5009
|
const step = steps[activeIndex];
|
|
5010
5010
|
const bbox = useTargetBbox(step?.stepRef);
|
|
5011
5011
|
useFocusTrap(tooltipRef, open);
|
|
5012
|
-
|
|
5012
|
+
React29.useEffect(() => {
|
|
5013
5013
|
if (!open || !dismissible) return;
|
|
5014
5014
|
const onKey = (e) => {
|
|
5015
5015
|
if (e.key === "Escape") {
|
|
@@ -5020,12 +5020,12 @@ function Wizard({
|
|
|
5020
5020
|
document.addEventListener("keydown", onKey);
|
|
5021
5021
|
return () => document.removeEventListener("keydown", onKey);
|
|
5022
5022
|
}, [open, dismissible]);
|
|
5023
|
-
const handleSkip =
|
|
5023
|
+
const handleSkip = React29.useCallback(() => {
|
|
5024
5024
|
writeDismissed(storageKey);
|
|
5025
5025
|
setOpen(false);
|
|
5026
5026
|
onSkip?.();
|
|
5027
5027
|
}, [storageKey, onSkip]);
|
|
5028
|
-
const handleComplete =
|
|
5028
|
+
const handleComplete = React29.useCallback(() => {
|
|
5029
5029
|
writeDismissed(storageKey);
|
|
5030
5030
|
setOpen(false);
|
|
5031
5031
|
onComplete?.();
|
|
@@ -5168,7 +5168,7 @@ function Wizard({
|
|
|
5168
5168
|
] });
|
|
5169
5169
|
}
|
|
5170
5170
|
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" }) });
|
|
5171
|
-
var SearchInput =
|
|
5171
|
+
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) {
|
|
5172
5172
|
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5173
5173
|
"div",
|
|
5174
5174
|
{
|
|
@@ -5310,22 +5310,78 @@ function createDatasets(rows, perPage) {
|
|
|
5310
5310
|
}
|
|
5311
5311
|
var defaultGetRowKey = (_row, index) => index;
|
|
5312
5312
|
var cellAlign = (align) => align === "left" ? "text-left" : align === "right" ? "text-right" : "text-center";
|
|
5313
|
+
function compareValues(a, b) {
|
|
5314
|
+
if (a == null && b == null) return 0;
|
|
5315
|
+
if (a == null) return -1;
|
|
5316
|
+
if (b == null) return 1;
|
|
5317
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
5318
|
+
if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
|
|
5319
|
+
if (typeof a === "boolean" && typeof b === "boolean") return a === b ? 0 : a ? 1 : -1;
|
|
5320
|
+
return String(a).localeCompare(String(b), void 0, { numeric: true, sensitivity: "base" });
|
|
5321
|
+
}
|
|
5322
|
+
function SortGlyph({ direction }) {
|
|
5323
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", "aria-hidden": "true", className: "shrink-0", children: [
|
|
5324
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5325
|
+
"path",
|
|
5326
|
+
{
|
|
5327
|
+
d: "M8 11l4-4 4 4",
|
|
5328
|
+
stroke: "currentColor",
|
|
5329
|
+
strokeWidth: 2,
|
|
5330
|
+
strokeLinecap: "round",
|
|
5331
|
+
strokeLinejoin: "round",
|
|
5332
|
+
className: direction === "asc" ? "text-accent" : "text-foreground-muted",
|
|
5333
|
+
opacity: direction === "asc" ? 1 : 0.45
|
|
5334
|
+
}
|
|
5335
|
+
),
|
|
5336
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5337
|
+
"path",
|
|
5338
|
+
{
|
|
5339
|
+
d: "M8 13l4 4 4-4",
|
|
5340
|
+
stroke: "currentColor",
|
|
5341
|
+
strokeWidth: 2,
|
|
5342
|
+
strokeLinecap: "round",
|
|
5343
|
+
strokeLinejoin: "round",
|
|
5344
|
+
className: direction === "desc" ? "text-accent" : "text-foreground-muted",
|
|
5345
|
+
opacity: direction === "desc" ? 1 : 0.45
|
|
5346
|
+
}
|
|
5347
|
+
)
|
|
5348
|
+
] });
|
|
5349
|
+
}
|
|
5313
5350
|
function TableHeader({
|
|
5314
5351
|
columns,
|
|
5315
|
-
hasExpand
|
|
5352
|
+
hasExpand,
|
|
5353
|
+
sort,
|
|
5354
|
+
onSort
|
|
5316
5355
|
}) {
|
|
5317
5356
|
return /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-surface-raised border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
5318
5357
|
hasExpand && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", className: "w-9" }),
|
|
5319
|
-
columns.map((col) =>
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5358
|
+
columns.map((col) => {
|
|
5359
|
+
const active = sort?.key === col.keyBind;
|
|
5360
|
+
const dir = active ? sort.direction : void 0;
|
|
5361
|
+
const justify = col.align === "left" ? "justify-start" : col.align === "right" ? "justify-end" : "justify-center";
|
|
5362
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5363
|
+
"th",
|
|
5364
|
+
{
|
|
5365
|
+
scope: "col",
|
|
5366
|
+
"aria-sort": col.sortable ? active ? dir === "asc" ? "ascending" : "descending" : "none" : void 0,
|
|
5367
|
+
className: `${cellAlign(col.align)} text-sm font-semibold text-foreground py-3 px-3`,
|
|
5368
|
+
style: col.width != null ? { width: col.width } : void 0,
|
|
5369
|
+
children: col.sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5370
|
+
"button",
|
|
5371
|
+
{
|
|
5372
|
+
type: "button",
|
|
5373
|
+
onClick: () => onSort(col),
|
|
5374
|
+
className: `inline-flex items-center gap-1.5 ${justify} w-full select-none rounded transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${active ? "text-accent" : "hover:text-accent"}`,
|
|
5375
|
+
children: [
|
|
5376
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: col.label }),
|
|
5377
|
+
/* @__PURE__ */ jsxRuntime.jsx(SortGlyph, { direction: dir })
|
|
5378
|
+
]
|
|
5379
|
+
}
|
|
5380
|
+
) : col.label
|
|
5381
|
+
},
|
|
5382
|
+
col.key
|
|
5383
|
+
);
|
|
5384
|
+
})
|
|
5329
5385
|
] }) });
|
|
5330
5386
|
}
|
|
5331
5387
|
var DefaultExpandIcon = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5333,26 +5389,68 @@ var DefaultExpandIcon = /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
5333
5389
|
{
|
|
5334
5390
|
xmlns: "http://www.w3.org/2000/svg",
|
|
5335
5391
|
viewBox: "0 0 24 24",
|
|
5336
|
-
fill: "
|
|
5337
|
-
|
|
5392
|
+
fill: "none",
|
|
5393
|
+
stroke: "currentColor",
|
|
5394
|
+
strokeWidth: 2,
|
|
5395
|
+
className: "w-4 h-4 text-foreground-muted",
|
|
5338
5396
|
"aria-hidden": "true",
|
|
5339
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5340
|
-
|
|
5397
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19.5 8.25l-7.5 7.5-7.5-7.5" })
|
|
5398
|
+
}
|
|
5399
|
+
);
|
|
5400
|
+
function EditableCell({
|
|
5401
|
+
col,
|
|
5402
|
+
row,
|
|
5403
|
+
rowIndex,
|
|
5404
|
+
onCellEdit
|
|
5405
|
+
}) {
|
|
5406
|
+
const [editing, setEditing] = React29.useState(false);
|
|
5407
|
+
const value = row[col.keyBind];
|
|
5408
|
+
const commit = (next) => {
|
|
5409
|
+
setEditing(false);
|
|
5410
|
+
onCellEdit?.({ row, key: col.keyBind, value: next, rowIndex });
|
|
5411
|
+
};
|
|
5412
|
+
const cancel = () => setEditing(false);
|
|
5413
|
+
if (editing) {
|
|
5414
|
+
if (col.editor) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: col.editor({ value, row, commit, cancel }) });
|
|
5415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5416
|
+
"input",
|
|
5341
5417
|
{
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5418
|
+
autoFocus: true,
|
|
5419
|
+
defaultValue: value == null ? "" : String(value),
|
|
5420
|
+
onBlur: (e) => commit(e.target.value),
|
|
5421
|
+
onKeyDown: (e) => {
|
|
5422
|
+
if (e.key === "Enter") {
|
|
5423
|
+
e.preventDefault();
|
|
5424
|
+
commit(e.target.value);
|
|
5425
|
+
} else if (e.key === "Escape") {
|
|
5426
|
+
e.preventDefault();
|
|
5427
|
+
cancel();
|
|
5428
|
+
}
|
|
5429
|
+
},
|
|
5430
|
+
"aria-label": `Edit ${typeof col.label === "string" ? col.label : col.keyBind}`,
|
|
5431
|
+
className: "w-full rounded border border-accent bg-surface px-2 py-1 text-sm text-foreground outline-none"
|
|
5345
5432
|
}
|
|
5346
|
-
)
|
|
5433
|
+
);
|
|
5347
5434
|
}
|
|
5348
|
-
|
|
5435
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5436
|
+
"button",
|
|
5437
|
+
{
|
|
5438
|
+
type: "button",
|
|
5439
|
+
onClick: () => setEditing(true),
|
|
5440
|
+
title: "Click to edit",
|
|
5441
|
+
className: `${cellAlign(col.align)} w-full cursor-text rounded px-1 py-0.5 hover:bg-background focus:outline-none focus-visible:ring-2 focus-visible:ring-accent`,
|
|
5442
|
+
children: col.component ? col.component(value, row) : value
|
|
5443
|
+
}
|
|
5444
|
+
);
|
|
5445
|
+
}
|
|
5349
5446
|
function TableBody({
|
|
5350
5447
|
columns,
|
|
5351
5448
|
rows,
|
|
5352
5449
|
expandRow,
|
|
5353
|
-
getRowKey
|
|
5450
|
+
getRowKey,
|
|
5451
|
+
onCellEdit
|
|
5354
5452
|
}) {
|
|
5355
|
-
const [expanded, setExpanded] =
|
|
5453
|
+
const [expanded, setExpanded] = React29.useState(() => /* @__PURE__ */ new Set());
|
|
5356
5454
|
const reduced = framerMotion.useReducedMotion();
|
|
5357
5455
|
const toggleRow = (rowKey) => {
|
|
5358
5456
|
setExpanded((prev) => {
|
|
@@ -5367,7 +5465,7 @@ function TableBody({
|
|
|
5367
5465
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
|
|
5368
5466
|
const rowKey = getRowKey(row, i);
|
|
5369
5467
|
const isExpanded = expanded.has(rowKey);
|
|
5370
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5468
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
5371
5469
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5372
5470
|
"tr",
|
|
5373
5471
|
{
|
|
@@ -5380,15 +5478,15 @@ function TableBody({
|
|
|
5380
5478
|
onClick: () => toggleRow(rowKey),
|
|
5381
5479
|
"aria-expanded": isExpanded,
|
|
5382
5480
|
"aria-label": isExpanded ? "Collapse row" : "Expand row",
|
|
5383
|
-
className: `w-9 h-9 inline-flex items-center justify-center rounded-md hover:bg-
|
|
5384
|
-
children: expandRow.expandIcon ?? DefaultExpandIcon
|
|
5481
|
+
className: `w-9 h-9 inline-flex items-center justify-center rounded-md hover:bg-background transition-transform duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${isExpanded && !expandRow.collapseIcon ? "rotate-180" : ""}`,
|
|
5482
|
+
children: isExpanded ? expandRow.collapseIcon ?? expandRow.expandIcon ?? DefaultExpandIcon : expandRow.expandIcon ?? DefaultExpandIcon
|
|
5385
5483
|
}
|
|
5386
5484
|
) }),
|
|
5387
5485
|
columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5388
5486
|
"td",
|
|
5389
5487
|
{
|
|
5390
5488
|
className: `${cellAlign(col.align)} text-sm text-foreground py-2 px-3 align-middle`,
|
|
5391
|
-
children: col.component ? col.component(row[col.keyBind], row) : row[col.keyBind]
|
|
5489
|
+
children: col.editable ? /* @__PURE__ */ jsxRuntime.jsx(EditableCell, { col, row, rowIndex: i, onCellEdit }) : col.component ? col.component(row[col.keyBind], row) : row[col.keyBind]
|
|
5392
5490
|
},
|
|
5393
5491
|
col.key
|
|
5394
5492
|
))
|
|
@@ -5423,9 +5521,9 @@ function Pagination({
|
|
|
5423
5521
|
const matchedOption = picker.find(
|
|
5424
5522
|
(o) => o.label === options.perPage || o.value === options.perPage
|
|
5425
5523
|
);
|
|
5426
|
-
const [perPageKey, setPerPageKey] =
|
|
5524
|
+
const [perPageKey, setPerPageKey] = React29.useState(() => matchedOption?.key ?? picker[0]?.key);
|
|
5427
5525
|
const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
|
|
5428
|
-
|
|
5526
|
+
React29.useEffect(() => {
|
|
5429
5527
|
if (serverSide && options.perPage != null) {
|
|
5430
5528
|
const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
|
|
5431
5529
|
if (next) setPerPageKey(next.key);
|
|
@@ -5482,6 +5580,10 @@ function Table({
|
|
|
5482
5580
|
pagination = DEFAULT_PAGINATION,
|
|
5483
5581
|
expandRow = DEFAULT_EXPAND,
|
|
5484
5582
|
hasSearch = true,
|
|
5583
|
+
search,
|
|
5584
|
+
defaultSort = null,
|
|
5585
|
+
onSortChange,
|
|
5586
|
+
onCellEdit,
|
|
5485
5587
|
footer = null,
|
|
5486
5588
|
header = null,
|
|
5487
5589
|
loading = false,
|
|
@@ -5489,45 +5591,79 @@ function Table({
|
|
|
5489
5591
|
className = "",
|
|
5490
5592
|
style
|
|
5491
5593
|
}) {
|
|
5492
|
-
const searchRef =
|
|
5493
|
-
const [searchTerm, setSearchTerm] =
|
|
5494
|
-
const [perPage, setPerPage] =
|
|
5594
|
+
const searchRef = React29.useRef(null);
|
|
5595
|
+
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
5596
|
+
const [perPage, setPerPage] = React29.useState(
|
|
5495
5597
|
typeof pagination.perPage === "number" ? pagination.perPage : 15
|
|
5496
5598
|
);
|
|
5497
|
-
const [activePage, setActivePage] =
|
|
5599
|
+
const [activePage, setActivePage] = React29.useState(0);
|
|
5600
|
+
const [sortState, setSortState] = React29.useState(defaultSort);
|
|
5498
5601
|
const isServerSide = !!(pagination.enabled && pagination.serverSide);
|
|
5499
|
-
const
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
);
|
|
5507
|
-
}
|
|
5508
|
-
const
|
|
5602
|
+
const handleSort = (col) => {
|
|
5603
|
+
const key = col.keyBind;
|
|
5604
|
+
let next;
|
|
5605
|
+
if (!sortState || sortState.key !== key) next = { key, direction: "asc" };
|
|
5606
|
+
else if (sortState.direction === "asc") next = { key, direction: "desc" };
|
|
5607
|
+
else next = null;
|
|
5608
|
+
setSortState(next);
|
|
5609
|
+
onSortChange?.(next);
|
|
5610
|
+
};
|
|
5611
|
+
const debounceMs = search?.debounceMs ?? 0;
|
|
5612
|
+
const [debouncedTerm, setDebouncedTerm] = React29.useState("");
|
|
5613
|
+
React29.useEffect(() => {
|
|
5614
|
+
if (debounceMs <= 0) {
|
|
5615
|
+
setDebouncedTerm(searchTerm);
|
|
5616
|
+
return;
|
|
5617
|
+
}
|
|
5618
|
+
const t = setTimeout(() => setDebouncedTerm(searchTerm), debounceMs);
|
|
5619
|
+
return () => clearTimeout(t);
|
|
5620
|
+
}, [searchTerm, debounceMs]);
|
|
5621
|
+
const term = debounceMs > 0 ? debouncedTerm : searchTerm;
|
|
5622
|
+
const filteredRows = React29.useMemo(() => {
|
|
5623
|
+
if (isServerSide || !term) return rows;
|
|
5624
|
+
if (search?.predicate) return rows.filter((row) => search.predicate(row, term));
|
|
5625
|
+
const cs = !!search?.caseSensitive;
|
|
5626
|
+
const needle = cs ? term : term.toLowerCase();
|
|
5627
|
+
const mode = search?.matchMode ?? "contains";
|
|
5628
|
+
const keys = search?.keys;
|
|
5629
|
+
const test = (raw) => {
|
|
5630
|
+
if (raw == null) return false;
|
|
5631
|
+
const s = cs ? String(raw) : String(raw).toLowerCase();
|
|
5632
|
+
return mode === "startsWith" ? s.startsWith(needle) : mode === "equals" ? s === needle : s.includes(needle);
|
|
5633
|
+
};
|
|
5634
|
+
return rows.filter((row) => keys ? keys.some((k) => test(row[k])) : Object.values(row).some(test));
|
|
5635
|
+
}, [rows, term, isServerSide, search?.predicate, search?.caseSensitive, search?.matchMode, search?.keys]);
|
|
5636
|
+
const sortedRows = React29.useMemo(() => {
|
|
5637
|
+
if (isServerSide || !sortState) return filteredRows;
|
|
5638
|
+
const col = columns.find((c) => c.keyBind === sortState.key);
|
|
5639
|
+
const accessor = col?.sortAccessor ?? ((r) => r[sortState.key]);
|
|
5640
|
+
const out = [...filteredRows].sort((a, b) => compareValues(accessor(a), accessor(b)));
|
|
5641
|
+
if (sortState.direction === "desc") out.reverse();
|
|
5642
|
+
return out;
|
|
5643
|
+
}, [filteredRows, sortState, isServerSide, columns]);
|
|
5644
|
+
const datasets = React29.useMemo(() => {
|
|
5509
5645
|
if (isServerSide) return [rows];
|
|
5510
|
-
return createDatasets(
|
|
5511
|
-
}, [
|
|
5512
|
-
const MAX_PAGE =
|
|
5646
|
+
return createDatasets(sortedRows, pagination.enabled ? perPage : null);
|
|
5647
|
+
}, [sortedRows, perPage, pagination.enabled, isServerSide, rows]);
|
|
5648
|
+
const MAX_PAGE = React29.useMemo(() => {
|
|
5513
5649
|
if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
|
|
5514
5650
|
if (isServerSide && typeof pagination.totalCount === "number")
|
|
5515
5651
|
return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
|
|
5516
5652
|
return datasets.length ? datasets.length - 1 : 0;
|
|
5517
5653
|
}, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
|
|
5518
|
-
const currentPageRows =
|
|
5654
|
+
const currentPageRows = React29.useMemo(() => {
|
|
5519
5655
|
if (isServerSide) return rows;
|
|
5520
5656
|
return datasets[activePage] ?? [];
|
|
5521
5657
|
}, [isServerSide, rows, datasets, activePage]);
|
|
5522
|
-
|
|
5658
|
+
React29.useEffect(() => {
|
|
5523
5659
|
if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
|
|
5524
5660
|
setPerPage(pagination.perPage);
|
|
5525
5661
|
}
|
|
5526
5662
|
}, [pagination.enabled, pagination.perPage, isServerSide]);
|
|
5527
|
-
|
|
5663
|
+
React29.useEffect(() => {
|
|
5528
5664
|
if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
|
|
5529
5665
|
}, [isServerSide, pagination.perPage]);
|
|
5530
|
-
|
|
5666
|
+
React29.useEffect(() => {
|
|
5531
5667
|
if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
|
|
5532
5668
|
setActivePage(pagination.page - 1);
|
|
5533
5669
|
}, [isServerSide, pagination.page]);
|
|
@@ -5547,32 +5683,36 @@ function Table({
|
|
|
5547
5683
|
}
|
|
5548
5684
|
setActivePage(newPage);
|
|
5549
5685
|
};
|
|
5686
|
+
const pagPos = pagination.position ?? "top";
|
|
5687
|
+
const showTopPager = !!pagination.enabled && (pagPos === "top" || pagPos === "both");
|
|
5688
|
+
const showBottomPager = !!pagination.enabled && (pagPos === "bottom" || pagPos === "both");
|
|
5689
|
+
const pager = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5690
|
+
Pagination,
|
|
5691
|
+
{
|
|
5692
|
+
activePage,
|
|
5693
|
+
onPageChange: handlePageChange,
|
|
5694
|
+
maxPage: MAX_PAGE,
|
|
5695
|
+
onPerPageChange: onPaginationChange,
|
|
5696
|
+
options: pagination,
|
|
5697
|
+
serverSide: isServerSide
|
|
5698
|
+
}
|
|
5699
|
+
);
|
|
5550
5700
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full h-max rounded-lg ${className}`.trim(), style, children: [
|
|
5551
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
|
|
5552
|
-
hasSearch
|
|
5701
|
+
(hasSearch || showTopPager) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 mb-2", children: [
|
|
5702
|
+
hasSearch ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5553
5703
|
SearchInput_default,
|
|
5554
5704
|
{
|
|
5555
5705
|
ref: searchRef,
|
|
5556
5706
|
value: searchTerm,
|
|
5557
5707
|
onChange: onSearchChange,
|
|
5558
|
-
placeholder: "Search term..."
|
|
5708
|
+
placeholder: search?.placeholder ?? "Search term..."
|
|
5559
5709
|
}
|
|
5560
|
-
),
|
|
5561
|
-
|
|
5562
|
-
Pagination,
|
|
5563
|
-
{
|
|
5564
|
-
activePage,
|
|
5565
|
-
onPageChange: handlePageChange,
|
|
5566
|
-
maxPage: MAX_PAGE,
|
|
5567
|
-
onPerPageChange: onPaginationChange,
|
|
5568
|
-
options: pagination,
|
|
5569
|
-
serverSide: isServerSide
|
|
5570
|
-
}
|
|
5571
|
-
)
|
|
5710
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
5711
|
+
showTopPager && pager
|
|
5572
5712
|
] }),
|
|
5573
5713
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: header }),
|
|
5574
5714
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", "aria-busy": loading || void 0, children: [
|
|
5575
|
-
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { columns, hasExpand: !!expandRow.enabled }),
|
|
5715
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { columns, hasExpand: !!expandRow.enabled, sort: sortState, onSort: handleSort }),
|
|
5576
5716
|
loading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5577
5717
|
TableSkeletonBody,
|
|
5578
5718
|
{
|
|
@@ -5586,10 +5726,12 @@ function Table({
|
|
|
5586
5726
|
columns,
|
|
5587
5727
|
rows: currentPageRows,
|
|
5588
5728
|
expandRow,
|
|
5589
|
-
getRowKey
|
|
5729
|
+
getRowKey,
|
|
5730
|
+
onCellEdit
|
|
5590
5731
|
}
|
|
5591
5732
|
)
|
|
5592
5733
|
] }) }),
|
|
5734
|
+
showBottomPager && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex justify-end", children: pager }),
|
|
5593
5735
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: footer })
|
|
5594
5736
|
] });
|
|
5595
5737
|
}
|
|
@@ -5610,8 +5752,86 @@ function TableSkeletonBody({
|
|
|
5610
5752
|
i
|
|
5611
5753
|
)) });
|
|
5612
5754
|
}
|
|
5755
|
+
var useIsoLayoutEffect = typeof window !== "undefined" ? React29.useLayoutEffect : React29.useEffect;
|
|
5756
|
+
function VirtualList({
|
|
5757
|
+
items,
|
|
5758
|
+
rowHeight,
|
|
5759
|
+
renderItem: renderItem2,
|
|
5760
|
+
height = 400,
|
|
5761
|
+
getKey,
|
|
5762
|
+
overscan = 6,
|
|
5763
|
+
searchable = false,
|
|
5764
|
+
searchKeys,
|
|
5765
|
+
filter,
|
|
5766
|
+
searchPlaceholder = "Search\u2026",
|
|
5767
|
+
emptyState = "No results",
|
|
5768
|
+
"aria-label": ariaLabel = "List",
|
|
5769
|
+
className = "",
|
|
5770
|
+
style
|
|
5771
|
+
}) {
|
|
5772
|
+
const scrollRef = React29.useRef(null);
|
|
5773
|
+
const [scrollTop, setScrollTop] = React29.useState(0);
|
|
5774
|
+
const [viewport, setViewport] = React29.useState(typeof height === "number" ? height : 400);
|
|
5775
|
+
const [term, setTerm] = React29.useState("");
|
|
5776
|
+
useIsoLayoutEffect(() => {
|
|
5777
|
+
const el = scrollRef.current;
|
|
5778
|
+
if (!el) return;
|
|
5779
|
+
const measure = () => setViewport(el.clientHeight);
|
|
5780
|
+
measure();
|
|
5781
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
5782
|
+
const ro = new ResizeObserver(measure);
|
|
5783
|
+
ro.observe(el);
|
|
5784
|
+
return () => ro.disconnect();
|
|
5785
|
+
}, []);
|
|
5786
|
+
const filtered = React29.useMemo(() => {
|
|
5787
|
+
if (!searchable || !term) return items;
|
|
5788
|
+
if (filter) return items.filter((it) => filter(it, term));
|
|
5789
|
+
const needle = term.toLowerCase();
|
|
5790
|
+
return items.filter((it) => {
|
|
5791
|
+
if (searchKeys) return searchKeys.some((k) => String(it[k] ?? "").toLowerCase().includes(needle));
|
|
5792
|
+
return String(it).toLowerCase().includes(needle);
|
|
5793
|
+
});
|
|
5794
|
+
}, [items, searchable, term, filter, searchKeys]);
|
|
5795
|
+
const total = filtered.length * rowHeight;
|
|
5796
|
+
const startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
|
|
5797
|
+
const endIndex = Math.min(filtered.length, Math.ceil((scrollTop + viewport) / rowHeight) + overscan);
|
|
5798
|
+
const offsetY = startIndex * rowHeight;
|
|
5799
|
+
const visible = filtered.slice(startIndex, endIndex);
|
|
5800
|
+
const onSearch = (e) => {
|
|
5801
|
+
setTerm(e.target.value);
|
|
5802
|
+
setScrollTop(0);
|
|
5803
|
+
if (scrollRef.current) scrollRef.current.scrollTop = 0;
|
|
5804
|
+
};
|
|
5805
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex w-full flex-col gap-2", className), style, children: [
|
|
5806
|
+
searchable && /* @__PURE__ */ jsxRuntime.jsx(SearchInput_default, { value: term, onChange: onSearch, placeholder: searchPlaceholder }),
|
|
5807
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5808
|
+
"div",
|
|
5809
|
+
{
|
|
5810
|
+
ref: scrollRef,
|
|
5811
|
+
onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
|
|
5812
|
+
role: "list",
|
|
5813
|
+
"aria-label": ariaLabel,
|
|
5814
|
+
className: "relative overflow-y-auto rounded-lg border border-border bg-surface",
|
|
5815
|
+
style: { height },
|
|
5816
|
+
children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center p-6 text-sm text-foreground-muted", children: emptyState }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: total, position: "relative" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { transform: `translateY(${offsetY}px)` }, children: visible.map((item, i) => {
|
|
5817
|
+
const index = startIndex + i;
|
|
5818
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5819
|
+
"div",
|
|
5820
|
+
{
|
|
5821
|
+
role: "listitem",
|
|
5822
|
+
style: { height: rowHeight },
|
|
5823
|
+
className: "box-border",
|
|
5824
|
+
children: renderItem2(item, index)
|
|
5825
|
+
},
|
|
5826
|
+
getKey ? getKey(item, index) : index
|
|
5827
|
+
);
|
|
5828
|
+
}) }) })
|
|
5829
|
+
}
|
|
5830
|
+
)
|
|
5831
|
+
] });
|
|
5832
|
+
}
|
|
5613
5833
|
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
|
|
5614
|
-
const id =
|
|
5834
|
+
const id = React29.useId();
|
|
5615
5835
|
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5616
5836
|
SwitchPrimitive__namespace.Root,
|
|
5617
5837
|
{
|
|
@@ -5795,7 +6015,7 @@ function Sidebar({
|
|
|
5795
6015
|
}
|
|
5796
6016
|
) });
|
|
5797
6017
|
}
|
|
5798
|
-
var MegaMenuContext =
|
|
6018
|
+
var MegaMenuContext = React29.createContext({ align: "start" });
|
|
5799
6019
|
function MegaMenu({
|
|
5800
6020
|
children,
|
|
5801
6021
|
align = "start",
|
|
@@ -5826,7 +6046,7 @@ function MegaMenu({
|
|
|
5826
6046
|
}
|
|
5827
6047
|
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";
|
|
5828
6048
|
function MegaMenuItem({ label, icon, href, children, className = "" }) {
|
|
5829
|
-
const { align } =
|
|
6049
|
+
const { align } = React29.useContext(MegaMenuContext);
|
|
5830
6050
|
const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
|
|
5831
6051
|
if (!children) {
|
|
5832
6052
|
return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: cx(TOP_ITEM, className), children: [
|
|
@@ -5911,8 +6131,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
5911
6131
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
5912
6132
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className), children });
|
|
5913
6133
|
}
|
|
5914
|
-
var elementsOfType = (children, type) =>
|
|
5915
|
-
(c) =>
|
|
6134
|
+
var elementsOfType = (children, type) => React29__default.default.Children.toArray(children).filter(
|
|
6135
|
+
(c) => React29__default.default.isValidElement(c) && c.type === type
|
|
5916
6136
|
);
|
|
5917
6137
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5918
6138
|
"svg",
|
|
@@ -5949,9 +6169,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
5949
6169
|
);
|
|
5950
6170
|
}
|
|
5951
6171
|
function MobilePanel({ panel, onNavigate }) {
|
|
5952
|
-
const nodes =
|
|
6172
|
+
const nodes = React29__default.default.Children.toArray(panel.props.children);
|
|
5953
6173
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
5954
|
-
if (!
|
|
6174
|
+
if (!React29__default.default.isValidElement(node)) return null;
|
|
5955
6175
|
const el = node;
|
|
5956
6176
|
if (el.type === MegaMenuSection) {
|
|
5957
6177
|
const { title, children } = el.props;
|
|
@@ -5970,8 +6190,8 @@ function MegaMenuMobile({
|
|
|
5970
6190
|
children,
|
|
5971
6191
|
label
|
|
5972
6192
|
}) {
|
|
5973
|
-
const [open, setOpen] =
|
|
5974
|
-
const [expanded, setExpanded] =
|
|
6193
|
+
const [open, setOpen] = React29.useState(false);
|
|
6194
|
+
const [expanded, setExpanded] = React29.useState(null);
|
|
5975
6195
|
const items = elementsOfType(children, MegaMenuItem);
|
|
5976
6196
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
|
|
5977
6197
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6044,17 +6264,17 @@ function AppShell({
|
|
|
6044
6264
|
children,
|
|
6045
6265
|
className = ""
|
|
6046
6266
|
}) {
|
|
6047
|
-
const [expanded, setExpanded] =
|
|
6048
|
-
const [isMobile, setIsMobile] =
|
|
6049
|
-
const [mobileOpen, setMobileOpen] =
|
|
6050
|
-
|
|
6267
|
+
const [expanded, setExpanded] = React29.useState(sidebarDefaultExpanded);
|
|
6268
|
+
const [isMobile, setIsMobile] = React29.useState(false);
|
|
6269
|
+
const [mobileOpen, setMobileOpen] = React29.useState(false);
|
|
6270
|
+
React29.useEffect(() => {
|
|
6051
6271
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
6052
6272
|
const update = (e) => setIsMobile(e.matches);
|
|
6053
6273
|
update(mq);
|
|
6054
6274
|
mq.addEventListener("change", update);
|
|
6055
6275
|
return () => mq.removeEventListener("change", update);
|
|
6056
6276
|
}, []);
|
|
6057
|
-
|
|
6277
|
+
React29.useEffect(() => {
|
|
6058
6278
|
if (!isMobile) setMobileOpen(false);
|
|
6059
6279
|
}, [isMobile]);
|
|
6060
6280
|
const hasSidebar = sidebarSections.length > 0;
|
|
@@ -6181,7 +6401,7 @@ function SecureLayout({
|
|
|
6181
6401
|
className = ""
|
|
6182
6402
|
}) {
|
|
6183
6403
|
const reduced = framerMotion.useReducedMotion();
|
|
6184
|
-
const cbs =
|
|
6404
|
+
const cbs = React29.useRef({ canAccess, onGranted, onDeny });
|
|
6185
6405
|
cbs.current = { canAccess, onGranted, onDeny };
|
|
6186
6406
|
const rolesKey = JSON.stringify(roles);
|
|
6187
6407
|
const requiredRolesKey = JSON.stringify(requiredRoles);
|
|
@@ -6196,10 +6416,10 @@ function SecureLayout({
|
|
|
6196
6416
|
if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
|
|
6197
6417
|
return true;
|
|
6198
6418
|
};
|
|
6199
|
-
const [state, setState] =
|
|
6419
|
+
const [state, setState] = React29.useState(
|
|
6200
6420
|
() => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
|
|
6201
6421
|
);
|
|
6202
|
-
|
|
6422
|
+
React29.useEffect(() => {
|
|
6203
6423
|
let cancelled = false;
|
|
6204
6424
|
const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
|
|
6205
6425
|
const finish = (ok) => {
|
|
@@ -6360,10 +6580,10 @@ function ThemeProvider({
|
|
|
6360
6580
|
className = "",
|
|
6361
6581
|
style
|
|
6362
6582
|
}) {
|
|
6363
|
-
const id =
|
|
6583
|
+
const id = React29__default.default.useId().replace(/:/g, "");
|
|
6364
6584
|
const scopeClass = `geo-th-${id}`;
|
|
6365
|
-
const divRef =
|
|
6366
|
-
|
|
6585
|
+
const divRef = React29.useRef(null);
|
|
6586
|
+
React29.useEffect(() => {
|
|
6367
6587
|
const el = divRef.current;
|
|
6368
6588
|
if (!el) return;
|
|
6369
6589
|
if (colorScheme === "auto") return;
|
|
@@ -6378,8 +6598,8 @@ function ThemeProvider({
|
|
|
6378
6598
|
}
|
|
6379
6599
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
6380
6600
|
}, [colorScheme]);
|
|
6381
|
-
const lightVars =
|
|
6382
|
-
const darkVarStr =
|
|
6601
|
+
const lightVars = React29.useMemo(() => toCssVars(theme), [theme]);
|
|
6602
|
+
const darkVarStr = React29.useMemo(() => {
|
|
6383
6603
|
if (!darkTheme) return "";
|
|
6384
6604
|
const dvars = toCssVars(darkTheme);
|
|
6385
6605
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -6421,7 +6641,7 @@ function NumberInput({
|
|
|
6421
6641
|
readOnly = false,
|
|
6422
6642
|
precision
|
|
6423
6643
|
}) {
|
|
6424
|
-
const errorId =
|
|
6644
|
+
const errorId = React29.useId();
|
|
6425
6645
|
const hasError = errorMessage != null;
|
|
6426
6646
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
6427
6647
|
const round = (n) => {
|
|
@@ -6552,8 +6772,8 @@ function Password({
|
|
|
6552
6772
|
showIcon,
|
|
6553
6773
|
hideIcon
|
|
6554
6774
|
}) {
|
|
6555
|
-
const [visible, setVisible] =
|
|
6556
|
-
const errorId =
|
|
6775
|
+
const [visible, setVisible] = React29.useState(false);
|
|
6776
|
+
const errorId = React29.useId();
|
|
6557
6777
|
const hasError = errorMessage != null;
|
|
6558
6778
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6559
6779
|
Field,
|
|
@@ -6607,6 +6827,161 @@ function Password({
|
|
|
6607
6827
|
}
|
|
6608
6828
|
);
|
|
6609
6829
|
}
|
|
6830
|
+
var defaultPasswordRules = [
|
|
6831
|
+
{ label: "At least 8 characters", test: (p) => p.length >= 8 },
|
|
6832
|
+
{ label: "A lowercase letter", test: (p) => /[a-z]/.test(p) },
|
|
6833
|
+
{ label: "An uppercase letter", test: (p) => /[A-Z]/.test(p) },
|
|
6834
|
+
{ label: "A number", test: (p) => /\d/.test(p) },
|
|
6835
|
+
{ label: "A symbol", test: (p) => /[^A-Za-z0-9]/.test(p) }
|
|
6836
|
+
];
|
|
6837
|
+
var LABELS = ["", "Weak", "Fair", "Good", "Strong"];
|
|
6838
|
+
function scorePassword(password) {
|
|
6839
|
+
if (!password) return { score: 0, label: "" };
|
|
6840
|
+
let s = 0;
|
|
6841
|
+
if (password.length >= 8) s++;
|
|
6842
|
+
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) s++;
|
|
6843
|
+
if (/\d/.test(password)) s++;
|
|
6844
|
+
if (/[^A-Za-z0-9]/.test(password)) s++;
|
|
6845
|
+
if (password.length >= 12) s++;
|
|
6846
|
+
const lowEntropy = /^(.)\1+$/.test(password) || /^(?:0123456789|abcdefghijklmnopqrstuvwxyz|qwertyuiop)/i.test(password);
|
|
6847
|
+
if (lowEntropy) s = Math.min(s, 1);
|
|
6848
|
+
const score = Math.max(1, Math.min(4, s));
|
|
6849
|
+
return { score, label: LABELS[score] };
|
|
6850
|
+
}
|
|
6851
|
+
var BAR_COLOR = {
|
|
6852
|
+
0: "bg-border",
|
|
6853
|
+
1: "bg-status-error",
|
|
6854
|
+
2: "bg-status-warning",
|
|
6855
|
+
3: "bg-accent",
|
|
6856
|
+
4: "bg-status-success"
|
|
6857
|
+
};
|
|
6858
|
+
var TEXT_COLOR = {
|
|
6859
|
+
0: "text-foreground-muted",
|
|
6860
|
+
1: "text-status-error",
|
|
6861
|
+
2: "text-status-warning",
|
|
6862
|
+
3: "text-accent",
|
|
6863
|
+
4: "text-status-success"
|
|
6864
|
+
};
|
|
6865
|
+
var Tick = ({ ok }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", className: cx("h-3.5 w-3.5 shrink-0", ok ? "text-status-success" : "text-foreground-muted"), children: ok ? /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd", d: "M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm3.7 6.3a1 1 0 0 0-1.4-1.4L9 10.18 7.7 8.88a1 1 0 0 0-1.4 1.42l2 2a1 1 0 0 0 1.4 0l4-4Z" }) : /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "2.5", fill: "currentColor" }) });
|
|
6866
|
+
function PasswordStrength({
|
|
6867
|
+
value,
|
|
6868
|
+
scorer = scorePassword,
|
|
6869
|
+
showRequirements = false,
|
|
6870
|
+
rules = defaultPasswordRules,
|
|
6871
|
+
confirmValue,
|
|
6872
|
+
hideMeter = false,
|
|
6873
|
+
className = "",
|
|
6874
|
+
style
|
|
6875
|
+
}) {
|
|
6876
|
+
const { score, label } = React29.useMemo(() => scorer(value), [scorer, value]);
|
|
6877
|
+
const showMatch = confirmValue != null && (value.length > 0 || confirmValue.length > 0);
|
|
6878
|
+
const matches = value.length > 0 && value === confirmValue;
|
|
6879
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col gap-2", className), style, "aria-live": "polite", children: [
|
|
6880
|
+
!hideMeter && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6881
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", role: "meter", "aria-valuemin": 0, "aria-valuemax": 4, "aria-valuenow": score, "aria-label": "Password strength", children: [1, 2, 3, 4].map((seg) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6882
|
+
"span",
|
|
6883
|
+
{
|
|
6884
|
+
className: cx("h-1.5 flex-1 rounded-full transition-colors duration-200", seg <= score ? BAR_COLOR[score] : "bg-border")
|
|
6885
|
+
},
|
|
6886
|
+
seg
|
|
6887
|
+
)) }),
|
|
6888
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs", children: [
|
|
6889
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted", children: "Strength: " }),
|
|
6890
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("font-medium", TEXT_COLOR[score]), children: label })
|
|
6891
|
+
] })
|
|
6892
|
+
] }),
|
|
6893
|
+
showRequirements && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-0.5 flex flex-col gap-1", children: rules.map((rule, i) => {
|
|
6894
|
+
const ok = rule.test(value);
|
|
6895
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cx("flex items-center gap-1.5 text-xs", ok ? "text-foreground-secondary" : "text-foreground-muted"), children: [
|
|
6896
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tick, { ok }),
|
|
6897
|
+
rule.label
|
|
6898
|
+
] }, i);
|
|
6899
|
+
}) }),
|
|
6900
|
+
showMatch && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: cx("flex items-center gap-1.5 text-xs font-medium", matches ? "text-status-success" : "text-status-error"), children: [
|
|
6901
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tick, { ok: matches }),
|
|
6902
|
+
matches ? "Passwords match" : "Passwords don\u2019t match"
|
|
6903
|
+
] })
|
|
6904
|
+
] });
|
|
6905
|
+
}
|
|
6906
|
+
var COLS = {
|
|
6907
|
+
1: "grid-cols-1",
|
|
6908
|
+
2: "grid-cols-1 sm:grid-cols-2",
|
|
6909
|
+
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
|
|
6910
|
+
};
|
|
6911
|
+
var PAD2 = { sm: "p-3", md: "p-4", lg: "p-5" };
|
|
6912
|
+
var TITLE = { sm: "text-sm", md: "text-sm", lg: "text-base" };
|
|
6913
|
+
var CheckMark = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-5 w-5 text-accent", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M12 2.25a9.75 9.75 0 1 0 0 19.5 9.75 9.75 0 0 0 0-19.5Zm4.28 7.53a.75.75 0 0 0-1.06-1.06l-4.97 4.97-1.97-1.97a.75.75 0 1 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5.5-5.5Z" }) });
|
|
6914
|
+
function RadioTile({
|
|
6915
|
+
options,
|
|
6916
|
+
value,
|
|
6917
|
+
defaultValue,
|
|
6918
|
+
onChange,
|
|
6919
|
+
name,
|
|
6920
|
+
label,
|
|
6921
|
+
columns = 2,
|
|
6922
|
+
size = "md",
|
|
6923
|
+
disabled,
|
|
6924
|
+
required,
|
|
6925
|
+
helperText,
|
|
6926
|
+
errorMessage,
|
|
6927
|
+
className
|
|
6928
|
+
}) {
|
|
6929
|
+
const groupId = React29.useId();
|
|
6930
|
+
const errorId = React29.useId();
|
|
6931
|
+
const hasError = errorMessage != null;
|
|
6932
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6933
|
+
Field,
|
|
6934
|
+
{
|
|
6935
|
+
className,
|
|
6936
|
+
label,
|
|
6937
|
+
htmlFor: groupId,
|
|
6938
|
+
errorId,
|
|
6939
|
+
errorMessage,
|
|
6940
|
+
required,
|
|
6941
|
+
helperText,
|
|
6942
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6943
|
+
RadioGroupPrimitive__namespace.Root,
|
|
6944
|
+
{
|
|
6945
|
+
id: groupId,
|
|
6946
|
+
name,
|
|
6947
|
+
value,
|
|
6948
|
+
defaultValue,
|
|
6949
|
+
onValueChange: onChange,
|
|
6950
|
+
disabled,
|
|
6951
|
+
required,
|
|
6952
|
+
"aria-invalid": hasError || void 0,
|
|
6953
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
6954
|
+
className: cx("grid gap-3", COLS[columns]),
|
|
6955
|
+
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6956
|
+
RadioGroupPrimitive__namespace.Item,
|
|
6957
|
+
{
|
|
6958
|
+
value: opt.value,
|
|
6959
|
+
disabled: opt.disabled,
|
|
6960
|
+
className: cx(
|
|
6961
|
+
"group relative flex flex-col gap-1 rounded-xl border bg-surface text-left transition-all duration-150",
|
|
6962
|
+
PAD2[size],
|
|
6963
|
+
"border-border hover:border-border-strong",
|
|
6964
|
+
"data-[state=checked]:border-accent data-[state=checked]:ring-1 data-[state=checked]:ring-accent",
|
|
6965
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
6966
|
+
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
6967
|
+
),
|
|
6968
|
+
children: [
|
|
6969
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "absolute right-3 top-3", children: CheckMark }),
|
|
6970
|
+
opt.icon != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 text-accent [&>svg]:h-6 [&>svg]:w-6", children: opt.icon }),
|
|
6971
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2 pr-6", children: [
|
|
6972
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("font-semibold text-foreground", TITLE[size]), children: opt.label }),
|
|
6973
|
+
opt.badge != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-border bg-surface-raised px-2 py-0.5 text-[11px] font-medium text-foreground-secondary", children: opt.badge })
|
|
6974
|
+
] }),
|
|
6975
|
+
opt.description != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs leading-relaxed text-foreground-secondary", children: opt.description })
|
|
6976
|
+
]
|
|
6977
|
+
},
|
|
6978
|
+
opt.value
|
|
6979
|
+
))
|
|
6980
|
+
}
|
|
6981
|
+
)
|
|
6982
|
+
}
|
|
6983
|
+
);
|
|
6984
|
+
}
|
|
6610
6985
|
function Checkbox({
|
|
6611
6986
|
checked,
|
|
6612
6987
|
value,
|
|
@@ -6626,7 +7001,7 @@ function Checkbox({
|
|
|
6626
7001
|
}) {
|
|
6627
7002
|
const isChecked = checked ?? value ?? false;
|
|
6628
7003
|
const labelFirst = labelPosition === "left";
|
|
6629
|
-
const errorId =
|
|
7004
|
+
const errorId = React29.useId();
|
|
6630
7005
|
const hasError = errorMessage != null;
|
|
6631
7006
|
const box = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6632
7007
|
CheckboxPrimitive__namespace.Root,
|
|
@@ -6734,8 +7109,8 @@ function RadioGroup({
|
|
|
6734
7109
|
className,
|
|
6735
7110
|
errorMessage
|
|
6736
7111
|
}) {
|
|
6737
|
-
const errorId =
|
|
6738
|
-
const groupId =
|
|
7112
|
+
const errorId = React29.useId();
|
|
7113
|
+
const groupId = React29.useId();
|
|
6739
7114
|
const hasError = errorMessage != null;
|
|
6740
7115
|
const labelFirst = labelPosition === "left";
|
|
6741
7116
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6835,11 +7210,11 @@ function Switch({
|
|
|
6835
7210
|
disabled,
|
|
6836
7211
|
errorMessage
|
|
6837
7212
|
}) {
|
|
6838
|
-
const id =
|
|
6839
|
-
const errorId =
|
|
7213
|
+
const id = React29.useId();
|
|
7214
|
+
const errorId = React29.useId();
|
|
6840
7215
|
const hasError = errorMessage != null;
|
|
6841
7216
|
const isControlled = checked !== void 0;
|
|
6842
|
-
const [internal, setInternal] =
|
|
7217
|
+
const [internal, setInternal] = React29.useState(defaultChecked);
|
|
6843
7218
|
const isOn = isControlled ? checked : internal;
|
|
6844
7219
|
const handle = (c) => {
|
|
6845
7220
|
if (!isControlled) setInternal(c);
|
|
@@ -6915,11 +7290,11 @@ function MultiTagRow({
|
|
|
6915
7290
|
labelFor,
|
|
6916
7291
|
onRemove
|
|
6917
7292
|
}) {
|
|
6918
|
-
const wrapRef =
|
|
6919
|
-
const measureRef =
|
|
6920
|
-
const [visibleCount, setVisibleCount] =
|
|
7293
|
+
const wrapRef = React29.useRef(null);
|
|
7294
|
+
const measureRef = React29.useRef(null);
|
|
7295
|
+
const [visibleCount, setVisibleCount] = React29.useState(values.length);
|
|
6921
7296
|
const key = values.map(String).join("|");
|
|
6922
|
-
|
|
7297
|
+
React29.useLayoutEffect(() => {
|
|
6923
7298
|
const wrap = wrapRef.current;
|
|
6924
7299
|
const measure = measureRef.current;
|
|
6925
7300
|
if (!wrap || !measure) return;
|
|
@@ -7013,16 +7388,16 @@ function Dropdown({
|
|
|
7013
7388
|
size = "md",
|
|
7014
7389
|
className = ""
|
|
7015
7390
|
}) {
|
|
7016
|
-
const [open, setOpen] =
|
|
7017
|
-
const [selectedItems, setSelectedItems] =
|
|
7018
|
-
const [searchTerm, setSearchTerm] =
|
|
7019
|
-
const [innerItems, setInnerItems] =
|
|
7020
|
-
const errorId =
|
|
7391
|
+
const [open, setOpen] = React29.useState(false);
|
|
7392
|
+
const [selectedItems, setSelectedItems] = React29.useState([]);
|
|
7393
|
+
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
7394
|
+
const [innerItems, setInnerItems] = React29.useState([]);
|
|
7395
|
+
const errorId = React29.useId();
|
|
7021
7396
|
const hasError = errorMessage != null;
|
|
7022
|
-
|
|
7397
|
+
React29.useEffect(() => {
|
|
7023
7398
|
setInnerItems(items);
|
|
7024
7399
|
}, [items]);
|
|
7025
|
-
|
|
7400
|
+
React29.useEffect(() => {
|
|
7026
7401
|
if (isMultiselect && Array.isArray(value)) {
|
|
7027
7402
|
setSelectedItems(value);
|
|
7028
7403
|
}
|
|
@@ -7214,19 +7589,19 @@ function AutoComplete({
|
|
|
7214
7589
|
required,
|
|
7215
7590
|
htmlFor
|
|
7216
7591
|
}) {
|
|
7217
|
-
const errorId =
|
|
7592
|
+
const errorId = React29.useId();
|
|
7218
7593
|
const hasError = errorMessage != null;
|
|
7219
|
-
const [term, setTerm] =
|
|
7220
|
-
const [open, setOpen] =
|
|
7221
|
-
const [asyncItems, setAsyncItems] =
|
|
7222
|
-
const [loading, setLoading] =
|
|
7594
|
+
const [term, setTerm] = React29.useState("");
|
|
7595
|
+
const [open, setOpen] = React29.useState(false);
|
|
7596
|
+
const [asyncItems, setAsyncItems] = React29.useState([]);
|
|
7597
|
+
const [loading, setLoading] = React29.useState(false);
|
|
7223
7598
|
const isAsync = typeof onSearch === "function";
|
|
7224
|
-
const debounceRef =
|
|
7225
|
-
const requestIdRef =
|
|
7599
|
+
const debounceRef = React29.useRef(null);
|
|
7600
|
+
const requestIdRef = React29.useRef(0);
|
|
7226
7601
|
const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
|
|
7227
7602
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
7228
7603
|
) : [];
|
|
7229
|
-
|
|
7604
|
+
React29.useEffect(() => {
|
|
7230
7605
|
if (!isAsync) return;
|
|
7231
7606
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
7232
7607
|
if (!term.trim()) {
|
|
@@ -7382,15 +7757,15 @@ function TreeSelect({
|
|
|
7382
7757
|
defaultExpandedKeys = [],
|
|
7383
7758
|
size = "md"
|
|
7384
7759
|
}) {
|
|
7385
|
-
const errorId =
|
|
7760
|
+
const errorId = React29.useId();
|
|
7386
7761
|
const hasError = errorMessage != null;
|
|
7387
|
-
const [open, setOpen] =
|
|
7388
|
-
const [expanded, setExpanded] =
|
|
7389
|
-
const [activeIndex, setActiveIndex] =
|
|
7390
|
-
const listRef =
|
|
7391
|
-
const visible =
|
|
7392
|
-
const didSyncOnOpenRef =
|
|
7393
|
-
|
|
7762
|
+
const [open, setOpen] = React29.useState(false);
|
|
7763
|
+
const [expanded, setExpanded] = React29.useState(() => new Set(defaultExpandedKeys));
|
|
7764
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
7765
|
+
const listRef = React29.useRef(null);
|
|
7766
|
+
const visible = React29.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
|
|
7767
|
+
const didSyncOnOpenRef = React29.useRef(false);
|
|
7768
|
+
React29.useEffect(() => {
|
|
7394
7769
|
if (!open) {
|
|
7395
7770
|
didSyncOnOpenRef.current = false;
|
|
7396
7771
|
return;
|
|
@@ -7400,7 +7775,7 @@ function TreeSelect({
|
|
|
7400
7775
|
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
7401
7776
|
didSyncOnOpenRef.current = true;
|
|
7402
7777
|
}, [open, value]);
|
|
7403
|
-
const selectedNode =
|
|
7778
|
+
const selectedNode = React29.useMemo(
|
|
7404
7779
|
() => value != null ? findNodeByKey(items, value) : null,
|
|
7405
7780
|
[items, value]
|
|
7406
7781
|
);
|
|
@@ -7631,11 +8006,11 @@ function FileInput({
|
|
|
7631
8006
|
required,
|
|
7632
8007
|
icon
|
|
7633
8008
|
}) {
|
|
7634
|
-
const inputRef =
|
|
7635
|
-
const errorId =
|
|
7636
|
-
const [files, setFiles] =
|
|
7637
|
-
const [dragging, setDragging] =
|
|
7638
|
-
const [sizeError, setSizeError] =
|
|
8009
|
+
const inputRef = React29.useRef(null);
|
|
8010
|
+
const errorId = React29.useId();
|
|
8011
|
+
const [files, setFiles] = React29.useState([]);
|
|
8012
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
8013
|
+
const [sizeError, setSizeError] = React29.useState(null);
|
|
7639
8014
|
const effectiveError = errorMessage ?? sizeError ?? void 0;
|
|
7640
8015
|
const openPicker = () => {
|
|
7641
8016
|
if (!disabled) inputRef.current?.click();
|
|
@@ -7826,30 +8201,30 @@ function DatePicker({
|
|
|
7826
8201
|
size = "md",
|
|
7827
8202
|
className = ""
|
|
7828
8203
|
}) {
|
|
7829
|
-
const errorId =
|
|
8204
|
+
const errorId = React29.useId();
|
|
7830
8205
|
const hasError = errorMessage != null;
|
|
7831
|
-
const [open, setOpen] =
|
|
7832
|
-
const [viewMonth, setViewMonth] =
|
|
7833
|
-
const [focusDate, setFocusDate] =
|
|
7834
|
-
const [view, setView] =
|
|
7835
|
-
const gridRef =
|
|
7836
|
-
|
|
8206
|
+
const [open, setOpen] = React29.useState(false);
|
|
8207
|
+
const [viewMonth, setViewMonth] = React29.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
8208
|
+
const [focusDate, setFocusDate] = React29.useState(() => value ?? /* @__PURE__ */ new Date());
|
|
8209
|
+
const [view, setView] = React29.useState("days");
|
|
8210
|
+
const gridRef = React29.useRef(null);
|
|
8211
|
+
React29.useEffect(() => {
|
|
7837
8212
|
if (!open) return;
|
|
7838
8213
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7839
8214
|
setViewMonth(startOfMonth2(target));
|
|
7840
8215
|
setFocusDate(target);
|
|
7841
8216
|
setView("days");
|
|
7842
8217
|
}, [open, value]);
|
|
7843
|
-
|
|
8218
|
+
React29.useEffect(() => {
|
|
7844
8219
|
if (!open) return;
|
|
7845
8220
|
const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
|
|
7846
8221
|
cell?.focus();
|
|
7847
8222
|
}, [open, focusDate]);
|
|
7848
|
-
const weekdays =
|
|
8223
|
+
const weekdays = React29.useMemo(() => {
|
|
7849
8224
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
7850
8225
|
return ordered;
|
|
7851
8226
|
}, [weekStartsOn]);
|
|
7852
|
-
const grid =
|
|
8227
|
+
const grid = React29.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
7853
8228
|
const isDisabled = (d) => {
|
|
7854
8229
|
if (min && d < min) return true;
|
|
7855
8230
|
if (max && d > max) return true;
|
|
@@ -8139,10 +8514,10 @@ function TextArea({
|
|
|
8139
8514
|
style,
|
|
8140
8515
|
inputStyle
|
|
8141
8516
|
}) {
|
|
8142
|
-
const errorId =
|
|
8517
|
+
const errorId = React29.useId();
|
|
8143
8518
|
const hasError = errorMessage != null;
|
|
8144
|
-
const ref =
|
|
8145
|
-
|
|
8519
|
+
const ref = React29.useRef(null);
|
|
8520
|
+
React29.useLayoutEffect(() => {
|
|
8146
8521
|
if (!autoGrow) return;
|
|
8147
8522
|
const el = ref.current;
|
|
8148
8523
|
if (!el) return;
|
|
@@ -8214,14 +8589,14 @@ function Slider({
|
|
|
8214
8589
|
name,
|
|
8215
8590
|
htmlFor
|
|
8216
8591
|
}) {
|
|
8217
|
-
const errorId =
|
|
8592
|
+
const errorId = React29.useId();
|
|
8218
8593
|
const hasError = errorMessage != null;
|
|
8219
8594
|
const isRange = Array.isArray(value ?? defaultValue);
|
|
8220
|
-
const [internal, setInternal] =
|
|
8595
|
+
const [internal, setInternal] = React29.useState(
|
|
8221
8596
|
() => toArray(value) ?? toArray(defaultValue) ?? [min]
|
|
8222
8597
|
);
|
|
8223
8598
|
const current = toArray(value) ?? internal;
|
|
8224
|
-
const [dragging, setDragging] =
|
|
8599
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
8225
8600
|
const emit = (arr) => {
|
|
8226
8601
|
setInternal(arr);
|
|
8227
8602
|
const next = isRange ? [arr[0], arr[1]] : arr[0];
|
|
@@ -8316,11 +8691,11 @@ function TagsInput({
|
|
|
8316
8691
|
validate,
|
|
8317
8692
|
separators = ["Enter", ","]
|
|
8318
8693
|
}) {
|
|
8319
|
-
const errorId =
|
|
8320
|
-
const inputRef =
|
|
8321
|
-
const [internal, setInternal] =
|
|
8322
|
-
const [draft, setDraft] =
|
|
8323
|
-
const [localError, setLocalError] =
|
|
8694
|
+
const errorId = React29.useId();
|
|
8695
|
+
const inputRef = React29.useRef(null);
|
|
8696
|
+
const [internal, setInternal] = React29.useState(defaultValue ?? []);
|
|
8697
|
+
const [draft, setDraft] = React29.useState("");
|
|
8698
|
+
const [localError, setLocalError] = React29.useState(null);
|
|
8324
8699
|
const tags = value ?? internal;
|
|
8325
8700
|
const hasError = errorMessage != null || localError != null;
|
|
8326
8701
|
const errorText = errorMessage ?? localError ?? void 0;
|
|
@@ -8451,9 +8826,9 @@ function OtpInput({
|
|
|
8451
8826
|
className,
|
|
8452
8827
|
groupAfter
|
|
8453
8828
|
}) {
|
|
8454
|
-
const errorId =
|
|
8829
|
+
const errorId = React29.useId();
|
|
8455
8830
|
const hasError = errorMessage != null;
|
|
8456
|
-
const refs =
|
|
8831
|
+
const refs = React29.useRef([]);
|
|
8457
8832
|
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
8458
8833
|
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
8459
8834
|
const emit = (next) => {
|
|
@@ -8502,7 +8877,7 @@ function OtpInput({
|
|
|
8502
8877
|
emit(valid.join(""));
|
|
8503
8878
|
focusBox(valid.length);
|
|
8504
8879
|
};
|
|
8505
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8880
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap 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: [
|
|
8506
8881
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8507
8882
|
"input",
|
|
8508
8883
|
{
|
|
@@ -8560,9 +8935,9 @@ function Rating({
|
|
|
8560
8935
|
className,
|
|
8561
8936
|
required
|
|
8562
8937
|
}) {
|
|
8563
|
-
const errorId =
|
|
8564
|
-
const [internal, setInternal] =
|
|
8565
|
-
const [hover, setHover] =
|
|
8938
|
+
const errorId = React29.useId();
|
|
8939
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
8940
|
+
const [hover, setHover] = React29.useState(null);
|
|
8566
8941
|
const current = value ?? internal;
|
|
8567
8942
|
const display2 = hover ?? current;
|
|
8568
8943
|
const interactive = !readOnly && !disabled;
|
|
@@ -8685,9 +9060,9 @@ function TimePicker({
|
|
|
8685
9060
|
required,
|
|
8686
9061
|
style
|
|
8687
9062
|
}) {
|
|
8688
|
-
const errorId =
|
|
9063
|
+
const errorId = React29.useId();
|
|
8689
9064
|
const hasError = errorMessage != null;
|
|
8690
|
-
const [open, setOpen] =
|
|
9065
|
+
const [open, setOpen] = React29.useState(false);
|
|
8691
9066
|
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
8692
9067
|
const update = (next) => {
|
|
8693
9068
|
const merged = { ...parsed, ...next };
|
|
@@ -8811,13 +9186,13 @@ function DateRangePicker({
|
|
|
8811
9186
|
required,
|
|
8812
9187
|
style
|
|
8813
9188
|
}) {
|
|
8814
|
-
const errorId =
|
|
9189
|
+
const errorId = React29.useId();
|
|
8815
9190
|
const hasError = errorMessage != null;
|
|
8816
|
-
const [open, setOpen] =
|
|
8817
|
-
const [leftMonth, setLeftMonth] =
|
|
8818
|
-
const [pendingStart, setPendingStart] =
|
|
8819
|
-
const [hoverDate, setHoverDate] =
|
|
8820
|
-
const weekdays =
|
|
9191
|
+
const [open, setOpen] = React29.useState(false);
|
|
9192
|
+
const [leftMonth, setLeftMonth] = React29.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
9193
|
+
const [pendingStart, setPendingStart] = React29.useState(null);
|
|
9194
|
+
const [hoverDate, setHoverDate] = React29.useState(null);
|
|
9195
|
+
const weekdays = React29.useMemo(
|
|
8821
9196
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8822
9197
|
[weekStartsOn]
|
|
8823
9198
|
);
|
|
@@ -8993,10 +9368,10 @@ function ColorPicker({
|
|
|
8993
9368
|
required,
|
|
8994
9369
|
placeholder = "Pick a colour\u2026"
|
|
8995
9370
|
}) {
|
|
8996
|
-
const errorId =
|
|
9371
|
+
const errorId = React29.useId();
|
|
8997
9372
|
const hasError = errorMessage != null;
|
|
8998
|
-
const [open, setOpen] =
|
|
8999
|
-
const [draft, setDraft] =
|
|
9373
|
+
const [open, setOpen] = React29.useState(false);
|
|
9374
|
+
const [draft, setDraft] = React29.useState(value);
|
|
9000
9375
|
const valid = HEX_RE.test(value);
|
|
9001
9376
|
const pick = (hex) => {
|
|
9002
9377
|
onChange?.(hex);
|
|
@@ -9083,7 +9458,7 @@ function ColorPicker({
|
|
|
9083
9458
|
}
|
|
9084
9459
|
var CUSTOM_EVENT = "oxy-local-storage";
|
|
9085
9460
|
function useLocalStorage(key, initialValue) {
|
|
9086
|
-
const read =
|
|
9461
|
+
const read = React29.useCallback(() => {
|
|
9087
9462
|
if (typeof window === "undefined") return initialValue;
|
|
9088
9463
|
try {
|
|
9089
9464
|
const item = window.localStorage.getItem(key);
|
|
@@ -9092,8 +9467,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
9092
9467
|
return initialValue;
|
|
9093
9468
|
}
|
|
9094
9469
|
}, [key]);
|
|
9095
|
-
const [stored, setStored] =
|
|
9096
|
-
const setValue =
|
|
9470
|
+
const [stored, setStored] = React29.useState(read);
|
|
9471
|
+
const setValue = React29.useCallback((value) => {
|
|
9097
9472
|
setStored((prev) => {
|
|
9098
9473
|
const next = value instanceof Function ? value(prev) : value;
|
|
9099
9474
|
try {
|
|
@@ -9106,7 +9481,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
9106
9481
|
return next;
|
|
9107
9482
|
});
|
|
9108
9483
|
}, [key]);
|
|
9109
|
-
const remove =
|
|
9484
|
+
const remove = React29.useCallback(() => {
|
|
9110
9485
|
try {
|
|
9111
9486
|
if (typeof window !== "undefined") {
|
|
9112
9487
|
window.localStorage.removeItem(key);
|
|
@@ -9116,10 +9491,10 @@ function useLocalStorage(key, initialValue) {
|
|
|
9116
9491
|
}
|
|
9117
9492
|
setStored(initialValue);
|
|
9118
9493
|
}, [key]);
|
|
9119
|
-
|
|
9494
|
+
React29.useEffect(() => {
|
|
9120
9495
|
setStored(read());
|
|
9121
9496
|
}, [key, read]);
|
|
9122
|
-
|
|
9497
|
+
React29.useEffect(() => {
|
|
9123
9498
|
if (typeof window === "undefined") return;
|
|
9124
9499
|
const onStorage = (e) => {
|
|
9125
9500
|
if (e.key === null || e.key === key) setStored(read());
|
|
@@ -9138,8 +9513,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
9138
9513
|
}
|
|
9139
9514
|
function useMediaQuery(query) {
|
|
9140
9515
|
const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
|
|
9141
|
-
const [matches, setMatches] =
|
|
9142
|
-
|
|
9516
|
+
const [matches, setMatches] = React29.useState(get);
|
|
9517
|
+
React29.useEffect(() => {
|
|
9143
9518
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
9144
9519
|
const mql = window.matchMedia(query);
|
|
9145
9520
|
const onChange = () => setMatches(mql.matches);
|
|
@@ -9170,8 +9545,8 @@ function decodeSegment(seg) {
|
|
|
9170
9545
|
}
|
|
9171
9546
|
}
|
|
9172
9547
|
function useJwt(token) {
|
|
9173
|
-
const [, tick] =
|
|
9174
|
-
const decoded =
|
|
9548
|
+
const [, tick] = React29.useState(0);
|
|
9549
|
+
const decoded = React29.useMemo(() => {
|
|
9175
9550
|
if (!token) return { payload: null, header: null, exp: null };
|
|
9176
9551
|
const [h, p] = token.split(".");
|
|
9177
9552
|
const header = decodeSegment(h);
|
|
@@ -9179,7 +9554,7 @@ function useJwt(token) {
|
|
|
9179
9554
|
const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
|
|
9180
9555
|
return { payload, header, exp };
|
|
9181
9556
|
}, [token]);
|
|
9182
|
-
|
|
9557
|
+
React29.useEffect(() => {
|
|
9183
9558
|
if (decoded.exp == null) return;
|
|
9184
9559
|
const ms = decoded.exp * 1e3 - Date.now();
|
|
9185
9560
|
if (ms <= 0) return;
|
|
@@ -9226,7 +9601,7 @@ function Jumbotron({
|
|
|
9226
9601
|
}
|
|
9227
9602
|
);
|
|
9228
9603
|
}
|
|
9229
|
-
var
|
|
9604
|
+
var COLS2 = {
|
|
9230
9605
|
2: "sm:grid-cols-2",
|
|
9231
9606
|
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
9232
9607
|
4: "sm:grid-cols-2 lg:grid-cols-4"
|
|
@@ -9248,7 +9623,7 @@ function FeatureGrid({
|
|
|
9248
9623
|
title != null && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
|
|
9249
9624
|
description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
|
|
9250
9625
|
] }),
|
|
9251
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6",
|
|
9626
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS2[columns]].join(" "), children: features.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border bg-surface p-5", children: [
|
|
9252
9627
|
f.icon != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9253
9628
|
"span",
|
|
9254
9629
|
{
|
|
@@ -9305,7 +9680,7 @@ function PricingPlans({ plans, eyebrow, title, description, className = "", styl
|
|
|
9305
9680
|
)) })
|
|
9306
9681
|
] });
|
|
9307
9682
|
}
|
|
9308
|
-
var
|
|
9683
|
+
var COLS3 = {
|
|
9309
9684
|
1: "mx-auto max-w-2xl",
|
|
9310
9685
|
2: "sm:grid-cols-2",
|
|
9311
9686
|
3: "sm:grid-cols-2 lg:grid-cols-3"
|
|
@@ -9322,7 +9697,7 @@ function Testimonials({ testimonials, eyebrow, title, description, columns = 3,
|
|
|
9322
9697
|
title != null && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
|
|
9323
9698
|
description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
|
|
9324
9699
|
] }),
|
|
9325
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6",
|
|
9700
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS3[columns]].join(" "), children: testimonials.map((tm, i) => /* @__PURE__ */ jsxRuntime.jsxs("figure", { className: "flex flex-col gap-4 rounded-xl border border-border bg-surface p-6", children: [
|
|
9326
9701
|
tm.rating != null && /* @__PURE__ */ jsxRuntime.jsx(Stars, { value: tm.rating }),
|
|
9327
9702
|
/* @__PURE__ */ jsxRuntime.jsxs("blockquote", { className: "flex-1 text-sm leading-relaxed text-foreground", children: [
|
|
9328
9703
|
"\u201C",
|
|
@@ -9353,13 +9728,13 @@ function SlideShow({
|
|
|
9353
9728
|
style
|
|
9354
9729
|
}) {
|
|
9355
9730
|
const reduced = framerMotion.useReducedMotion();
|
|
9356
|
-
const [index, setIndex] =
|
|
9357
|
-
const [paused, setPaused] =
|
|
9731
|
+
const [index, setIndex] = React29.useState(0);
|
|
9732
|
+
const [paused, setPaused] = React29.useState(false);
|
|
9358
9733
|
const count = slides.length;
|
|
9359
9734
|
const idx = count ? (index % count + count) % count : 0;
|
|
9360
|
-
const go =
|
|
9361
|
-
const timer =
|
|
9362
|
-
|
|
9735
|
+
const go = React29.useCallback((d) => setIndex((i) => i + d), []);
|
|
9736
|
+
const timer = React29.useRef(null);
|
|
9737
|
+
React29.useEffect(() => {
|
|
9363
9738
|
if (!autoPlay || paused || count <= 1) return;
|
|
9364
9739
|
timer.current = setInterval(() => setIndex((i) => i + 1), interval);
|
|
9365
9740
|
return () => {
|
|
@@ -9435,7 +9810,7 @@ function Video({
|
|
|
9435
9810
|
className = "",
|
|
9436
9811
|
style
|
|
9437
9812
|
}) {
|
|
9438
|
-
const [playing, setPlaying] =
|
|
9813
|
+
const [playing, setPlaying] = React29.useState(autoPlay);
|
|
9439
9814
|
const frame = cx("relative w-full overflow-hidden bg-backdrop", framed ? "rounded-2xl border border-border shadow-sm" : "", className);
|
|
9440
9815
|
const ratio = aspect.replace("/", " / ");
|
|
9441
9816
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frame, style: { aspectRatio: ratio, ...style }, children: embedUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9490,7 +9865,7 @@ function Parallax({
|
|
|
9490
9865
|
style
|
|
9491
9866
|
}) {
|
|
9492
9867
|
const reduced = framerMotion.useReducedMotion();
|
|
9493
|
-
const ref =
|
|
9868
|
+
const ref = React29.useRef(null);
|
|
9494
9869
|
const { scrollYProgress } = framerMotion.useScroll({ target: ref, offset: ["start end", "end start"] });
|
|
9495
9870
|
const shift = Math.max(0, Math.min(1, speed)) * 100;
|
|
9496
9871
|
const y = framerMotion.useTransform(scrollYProgress, [0, 1], reduced ? ["0%", "0%"] : [`-${shift / 2}%`, `${shift / 2}%`]);
|
|
@@ -9526,7 +9901,7 @@ function Parallax({
|
|
|
9526
9901
|
}
|
|
9527
9902
|
);
|
|
9528
9903
|
}
|
|
9529
|
-
var
|
|
9904
|
+
var COLS4 = {
|
|
9530
9905
|
2: "sm:grid-cols-2",
|
|
9531
9906
|
3: "sm:grid-cols-2 lg:grid-cols-3"
|
|
9532
9907
|
};
|
|
@@ -9547,7 +9922,7 @@ function Blog({
|
|
|
9547
9922
|
title != null && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground sm:text-3xl", children: title }),
|
|
9548
9923
|
description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
|
|
9549
9924
|
] }),
|
|
9550
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6",
|
|
9925
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS4[columns]].join(" "), children: posts.map((post, i) => {
|
|
9551
9926
|
const meta = [post.author, post.date, post.readTime].filter((m) => m != null);
|
|
9552
9927
|
const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9553
9928
|
post.image && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-video overflow-hidden bg-backdrop", children: [
|
|
@@ -9558,7 +9933,7 @@ function Blog({
|
|
|
9558
9933
|
post.tag != null && !post.image && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "accent", variant: "soft", size: "sm", children: post.tag }) }),
|
|
9559
9934
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold leading-snug text-foreground transition-colors group-hover:text-accent", children: post.title }),
|
|
9560
9935
|
post.excerpt != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-foreground-secondary", children: post.excerpt }),
|
|
9561
|
-
meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-wrap items-center gap-x-2 gap-y-1 pt-3 text-xs text-foreground-muted", children: meta.map((m, j) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9936
|
+
meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-wrap items-center gap-x-2 gap-y-1 pt-3 text-xs text-foreground-muted", children: meta.map((m, j) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
9562
9937
|
j > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
9563
9938
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: m })
|
|
9564
9939
|
] }, j)) })
|
|
@@ -9687,8 +10062,8 @@ function LeadCapture({
|
|
|
9687
10062
|
className = "",
|
|
9688
10063
|
style
|
|
9689
10064
|
}) {
|
|
9690
|
-
const [email, setEmail] =
|
|
9691
|
-
const [done, setDone] =
|
|
10065
|
+
const [email, setEmail] = React29.useState("");
|
|
10066
|
+
const [done, setDone] = React29.useState(false);
|
|
9692
10067
|
const submit = (e) => {
|
|
9693
10068
|
e.preventDefault();
|
|
9694
10069
|
const value = email.trim();
|
|
@@ -9814,10 +10189,12 @@ exports.OpaqueGridCard = OpaqueGridCard;
|
|
|
9814
10189
|
exports.OtpInput = OtpInput;
|
|
9815
10190
|
exports.Parallax = Parallax;
|
|
9816
10191
|
exports.Password = Password;
|
|
10192
|
+
exports.PasswordStrength = PasswordStrength;
|
|
9817
10193
|
exports.PopConfirm = PopConfirm;
|
|
9818
10194
|
exports.Portal = Portal;
|
|
9819
10195
|
exports.PricingPlans = PricingPlans;
|
|
9820
10196
|
exports.RadioGroup = RadioGroup;
|
|
10197
|
+
exports.RadioTile = RadioTile;
|
|
9821
10198
|
exports.Rating = Rating;
|
|
9822
10199
|
exports.ScalableContainer = ScalableContainer;
|
|
9823
10200
|
exports.Scheduler = Scheduler;
|
|
@@ -9853,10 +10230,12 @@ exports.Tree = Tree;
|
|
|
9853
10230
|
exports.TreeSelect = TreeSelect;
|
|
9854
10231
|
exports.Typography = Typography;
|
|
9855
10232
|
exports.Video = Video;
|
|
10233
|
+
exports.VirtualList = VirtualList;
|
|
9856
10234
|
exports.Wizard = Wizard;
|
|
9857
10235
|
exports.cardNumberError = cardNumberError;
|
|
9858
10236
|
exports.cvvError = cvvError;
|
|
9859
10237
|
exports.cx = cx;
|
|
10238
|
+
exports.defaultPasswordRules = defaultPasswordRules;
|
|
9860
10239
|
exports.detectBrand = detectBrand;
|
|
9861
10240
|
exports.expiryError = expiryError;
|
|
9862
10241
|
exports.fieldShell = fieldShell;
|
|
@@ -9867,6 +10246,7 @@ exports.luhnValid = luhnValid;
|
|
|
9867
10246
|
exports.onlyDigits = onlyDigits;
|
|
9868
10247
|
exports.patterns = patterns;
|
|
9869
10248
|
exports.runFieldRules = runFieldRules;
|
|
10249
|
+
exports.scorePassword = scorePassword;
|
|
9870
10250
|
exports.useBreakpoint = useBreakpoint;
|
|
9871
10251
|
exports.useCart = useCart;
|
|
9872
10252
|
exports.useFieldArray = useFieldArray;
|