@geomak/ui 6.26.1 → 6.27.1
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 +794 -755
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +560 -521
- package/dist/index.js.map +1 -1
- package/dist/styles.css +8 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkOAV4TA4B_cjs = require('./chunk-OAV4TA4B.cjs');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var
|
|
5
|
+
var React28 = require('react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var AvatarPrimitive = require('@radix-ui/react-avatar');
|
|
8
8
|
var DropdownMenu = require('@radix-ui/react-dropdown-menu');
|
|
@@ -40,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
40
40
|
return Object.freeze(n);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var React28__default = /*#__PURE__*/_interopDefault(React28);
|
|
44
44
|
var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
|
|
45
45
|
var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
|
|
46
46
|
var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
|
|
@@ -216,8 +216,8 @@ Icon.Copy = Copy;
|
|
|
216
216
|
Icon.CircleStack = CircleStack;
|
|
217
217
|
var icons_default = Icon;
|
|
218
218
|
function Portal({ children, target }) {
|
|
219
|
-
const [resolved, setResolved] =
|
|
220
|
-
|
|
219
|
+
const [resolved, setResolved] = React28.useState(null);
|
|
220
|
+
React28.useEffect(() => {
|
|
221
221
|
if (target === null) {
|
|
222
222
|
setResolved(null);
|
|
223
223
|
return;
|
|
@@ -651,7 +651,7 @@ function IconButton({
|
|
|
651
651
|
className = "",
|
|
652
652
|
style
|
|
653
653
|
}) {
|
|
654
|
-
const colorScheme =
|
|
654
|
+
const colorScheme = React28.useMemo(() => {
|
|
655
655
|
if (type === "primary") {
|
|
656
656
|
return "bg-accent text-accent-fg hover:bg-accent-hover";
|
|
657
657
|
}
|
|
@@ -730,7 +730,7 @@ var SIZE_CLASSES = {
|
|
|
730
730
|
md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
|
|
731
731
|
lg: "h-11 px-5 text-sm gap-2 rounded-xl"
|
|
732
732
|
};
|
|
733
|
-
var Button =
|
|
733
|
+
var Button = React28__default.default.forwardRef(function Button2({
|
|
734
734
|
content,
|
|
735
735
|
variant = "primary",
|
|
736
736
|
size = "md",
|
|
@@ -838,7 +838,7 @@ function MenuButton({
|
|
|
838
838
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
839
839
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
840
840
|
].join(" "),
|
|
841
|
-
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
841
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
|
|
842
842
|
item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border" }),
|
|
843
843
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
844
844
|
DropdownMenu__namespace.Item,
|
|
@@ -1081,9 +1081,9 @@ function Tooltip({
|
|
|
1081
1081
|
] }) });
|
|
1082
1082
|
}
|
|
1083
1083
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
1084
|
-
var TabsContext =
|
|
1084
|
+
var TabsContext = React28.createContext(null);
|
|
1085
1085
|
function useTabsContext() {
|
|
1086
|
-
const ctx =
|
|
1086
|
+
const ctx = React28.useContext(TabsContext);
|
|
1087
1087
|
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
|
|
1088
1088
|
return ctx;
|
|
1089
1089
|
}
|
|
@@ -1105,26 +1105,26 @@ function Tabs({
|
|
|
1105
1105
|
children
|
|
1106
1106
|
}) {
|
|
1107
1107
|
const isControlled = value !== void 0;
|
|
1108
|
-
const [internal, setInternal] =
|
|
1108
|
+
const [internal, setInternal] = React28.useState(defaultValue);
|
|
1109
1109
|
const current = isControlled ? value : internal;
|
|
1110
1110
|
const reduced = !!framerMotion.useReducedMotion();
|
|
1111
|
-
const indicatorId =
|
|
1112
|
-
const select =
|
|
1111
|
+
const indicatorId = React28.useId();
|
|
1112
|
+
const select = React28.useCallback((next) => {
|
|
1113
1113
|
if (!isControlled) setInternal(next);
|
|
1114
1114
|
onValueChange?.(next);
|
|
1115
1115
|
}, [isControlled, onValueChange]);
|
|
1116
|
-
const registry =
|
|
1117
|
-
const orderRef =
|
|
1118
|
-
const [, bump] =
|
|
1119
|
-
const registerTab =
|
|
1116
|
+
const registry = React28.useRef(/* @__PURE__ */ new Map());
|
|
1117
|
+
const orderRef = React28.useRef(0);
|
|
1118
|
+
const [, bump] = React28.useState(0);
|
|
1119
|
+
const registerTab = React28.useCallback((val, meta) => {
|
|
1120
1120
|
const existing = registry.current.get(val);
|
|
1121
1121
|
registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
|
|
1122
1122
|
if (!existing) bump((v) => v + 1);
|
|
1123
1123
|
}, []);
|
|
1124
|
-
const unregisterTab =
|
|
1124
|
+
const unregisterTab = React28.useCallback((val) => {
|
|
1125
1125
|
if (registry.current.delete(val)) bump((v) => v + 1);
|
|
1126
1126
|
}, []);
|
|
1127
|
-
const getTabs =
|
|
1127
|
+
const getTabs = React28.useCallback(() => [...registry.current.entries()].sort((a, b) => a[1].order - b[1].order).map(([val, m]) => ({ value: val, label: m.label, icon: m.icon, disabled: m.disabled })), []);
|
|
1128
1128
|
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1129
1129
|
TabsPrimitive__namespace.Root,
|
|
1130
1130
|
{
|
|
@@ -1144,10 +1144,10 @@ function Tabs({
|
|
|
1144
1144
|
function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
1145
1145
|
const { variant, orientation, reduced, value } = useTabsContext();
|
|
1146
1146
|
const horizontal = orientation === "horizontal";
|
|
1147
|
-
const scrollRef =
|
|
1148
|
-
const [edges, setEdges] =
|
|
1147
|
+
const scrollRef = React28.useRef(null);
|
|
1148
|
+
const [edges, setEdges] = React28.useState({ start: false, end: false });
|
|
1149
1149
|
const scrollable = variant !== "segmented";
|
|
1150
|
-
|
|
1150
|
+
React28.useLayoutEffect(() => {
|
|
1151
1151
|
const el = scrollRef.current;
|
|
1152
1152
|
if (!el || !scrollable) return;
|
|
1153
1153
|
const update = () => {
|
|
@@ -1172,13 +1172,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
|
1172
1172
|
ro.disconnect();
|
|
1173
1173
|
};
|
|
1174
1174
|
}, [horizontal, scrollable, children]);
|
|
1175
|
-
const nudge =
|
|
1175
|
+
const nudge = React28.useCallback((dir) => {
|
|
1176
1176
|
const el = scrollRef.current;
|
|
1177
1177
|
if (!el) return;
|
|
1178
1178
|
const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
|
|
1179
1179
|
el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
|
|
1180
1180
|
}, [horizontal, reduced]);
|
|
1181
|
-
|
|
1181
|
+
React28.useLayoutEffect(() => {
|
|
1182
1182
|
const el = scrollRef.current;
|
|
1183
1183
|
if (!el || !scrollable) return;
|
|
1184
1184
|
const active = el.querySelector("[role=tab][data-state=active]");
|
|
@@ -1236,9 +1236,9 @@ function Chevron2({ side, orientation, onClick }) {
|
|
|
1236
1236
|
function OverflowMenu() {
|
|
1237
1237
|
const { getTabs, value, select, orientation } = useTabsContext();
|
|
1238
1238
|
const horizontal = orientation === "horizontal";
|
|
1239
|
-
const [open, setOpen] =
|
|
1240
|
-
const wrapRef =
|
|
1241
|
-
const timer =
|
|
1239
|
+
const [open, setOpen] = React28.useState(false);
|
|
1240
|
+
const wrapRef = React28.useRef(null);
|
|
1241
|
+
const timer = React28.useRef(null);
|
|
1242
1242
|
const openNow = () => {
|
|
1243
1243
|
if (timer.current) clearTimeout(timer.current);
|
|
1244
1244
|
setOpen(true);
|
|
@@ -1246,7 +1246,7 @@ function OverflowMenu() {
|
|
|
1246
1246
|
const closeSoon = () => {
|
|
1247
1247
|
timer.current = setTimeout(() => setOpen(false), 160);
|
|
1248
1248
|
};
|
|
1249
|
-
|
|
1249
|
+
React28.useLayoutEffect(() => {
|
|
1250
1250
|
if (!open) return;
|
|
1251
1251
|
const onDoc = (e) => {
|
|
1252
1252
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1327,7 +1327,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
|
|
|
1327
1327
|
const isActive = active === value;
|
|
1328
1328
|
const horizontal = orientation === "horizontal";
|
|
1329
1329
|
const sz = SIZE[size];
|
|
1330
|
-
|
|
1330
|
+
React28.useLayoutEffect(() => {
|
|
1331
1331
|
registerTab(value, { label: children, icon, disabled });
|
|
1332
1332
|
return () => unregisterTab(value);
|
|
1333
1333
|
}, [value, children, icon, disabled, registerTab, unregisterTab]);
|
|
@@ -1525,7 +1525,7 @@ function Tree({
|
|
|
1525
1525
|
item.key
|
|
1526
1526
|
)) });
|
|
1527
1527
|
}
|
|
1528
|
-
var AccordionCtx =
|
|
1528
|
+
var AccordionCtx = React28.createContext({ variant: "separated" });
|
|
1529
1529
|
function Accordion2({
|
|
1530
1530
|
children,
|
|
1531
1531
|
type = "single",
|
|
@@ -1584,7 +1584,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
1584
1584
|
}
|
|
1585
1585
|
);
|
|
1586
1586
|
function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
|
|
1587
|
-
const { variant } =
|
|
1587
|
+
const { variant } = React28.useContext(AccordionCtx);
|
|
1588
1588
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1589
1589
|
AccordionPrimitive__namespace.Item,
|
|
1590
1590
|
{
|
|
@@ -1643,7 +1643,7 @@ function Breadcrumbs({
|
|
|
1643
1643
|
className = "",
|
|
1644
1644
|
style
|
|
1645
1645
|
}) {
|
|
1646
|
-
const [expanded, setExpanded] =
|
|
1646
|
+
const [expanded, setExpanded] = React28.useState(false);
|
|
1647
1647
|
const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
|
|
1648
1648
|
const visible = [];
|
|
1649
1649
|
if (shouldCollapse) {
|
|
@@ -1827,8 +1827,8 @@ function Stepper({
|
|
|
1827
1827
|
className = ""
|
|
1828
1828
|
}) {
|
|
1829
1829
|
const reduced = framerMotion.useReducedMotion();
|
|
1830
|
-
const [forcedVertical, setForcedVertical] =
|
|
1831
|
-
|
|
1830
|
+
const [forcedVertical, setForcedVertical] = React28.useState(false);
|
|
1831
|
+
React28.useEffect(() => {
|
|
1832
1832
|
if (!responsive || orientation === "vertical") return;
|
|
1833
1833
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1834
1834
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
@@ -1937,7 +1937,7 @@ function Kbd({
|
|
|
1937
1937
|
style
|
|
1938
1938
|
}) {
|
|
1939
1939
|
if (keys && keys.length > 0) {
|
|
1940
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1940
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
|
|
1941
1941
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
|
|
1942
1942
|
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
|
|
1943
1943
|
] }, `${k}-${i}`)) });
|
|
@@ -2028,13 +2028,13 @@ function FlatCarousel({
|
|
|
2028
2028
|
className = "",
|
|
2029
2029
|
style
|
|
2030
2030
|
}) {
|
|
2031
|
-
const scrollerRef =
|
|
2032
|
-
const slides =
|
|
2033
|
-
const [active, setActive] =
|
|
2034
|
-
const [atStart, setAtStart] =
|
|
2035
|
-
const [atEnd, setAtEnd] =
|
|
2031
|
+
const scrollerRef = React28.useRef(null);
|
|
2032
|
+
const slides = React28__default.default.Children.toArray(children);
|
|
2033
|
+
const [active, setActive] = React28.useState(0);
|
|
2034
|
+
const [atStart, setAtStart] = React28.useState(true);
|
|
2035
|
+
const [atEnd, setAtEnd] = React28.useState(false);
|
|
2036
2036
|
const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
|
|
2037
|
-
const update =
|
|
2037
|
+
const update = React28.useCallback(() => {
|
|
2038
2038
|
const el = scrollerRef.current;
|
|
2039
2039
|
if (!el) return;
|
|
2040
2040
|
setAtStart(el.scrollLeft <= 1);
|
|
@@ -2043,7 +2043,7 @@ function FlatCarousel({
|
|
|
2043
2043
|
const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
|
|
2044
2044
|
setActive(Math.round(el.scrollLeft / slideW));
|
|
2045
2045
|
}, [gap]);
|
|
2046
|
-
|
|
2046
|
+
React28.useEffect(() => {
|
|
2047
2047
|
update();
|
|
2048
2048
|
const el = scrollerRef.current;
|
|
2049
2049
|
if (!el) return;
|
|
@@ -2084,9 +2084,9 @@ function RotatingCarousel({
|
|
|
2084
2084
|
className = "",
|
|
2085
2085
|
style
|
|
2086
2086
|
}) {
|
|
2087
|
-
const slides =
|
|
2087
|
+
const slides = React28__default.default.Children.toArray(children);
|
|
2088
2088
|
const count = slides.length;
|
|
2089
|
-
const [active, setActive] =
|
|
2089
|
+
const [active, setActive] = React28.useState(0);
|
|
2090
2090
|
const reduced = framerMotion.useReducedMotion();
|
|
2091
2091
|
const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
|
|
2092
2092
|
const idx = wrap(active);
|
|
@@ -2236,7 +2236,7 @@ function FAB({
|
|
|
2236
2236
|
className = "",
|
|
2237
2237
|
style
|
|
2238
2238
|
}) {
|
|
2239
|
-
const [open, setOpen] =
|
|
2239
|
+
const [open, setOpen] = React28.useState(false);
|
|
2240
2240
|
const reduced = framerMotion.useReducedMotion();
|
|
2241
2241
|
const hasDial = !!actions && actions.length > 0;
|
|
2242
2242
|
const bottom = position.startsWith("bottom");
|
|
@@ -2338,8 +2338,8 @@ function PopConfirm({
|
|
|
2338
2338
|
onOpenChange,
|
|
2339
2339
|
className = ""
|
|
2340
2340
|
}) {
|
|
2341
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
2342
|
-
const [loading, setLoading] =
|
|
2341
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React28.useState(false);
|
|
2342
|
+
const [loading, setLoading] = React28.useState(false);
|
|
2343
2343
|
const isOpen = open ?? uncontrolledOpen;
|
|
2344
2344
|
const setOpen = (next) => {
|
|
2345
2345
|
onOpenChange?.(next);
|
|
@@ -2426,16 +2426,16 @@ function LogoutTimer({
|
|
|
2426
2426
|
logoutLabel = "Sign out now"
|
|
2427
2427
|
}) {
|
|
2428
2428
|
const reduced = framerMotion.useReducedMotion();
|
|
2429
|
-
const [warning, setWarning] =
|
|
2430
|
-
const [remaining, setRemaining] =
|
|
2431
|
-
const idleTimer =
|
|
2432
|
-
const tick =
|
|
2433
|
-
const deadline =
|
|
2434
|
-
const warningRef =
|
|
2435
|
-
const lastReset =
|
|
2436
|
-
const cbs =
|
|
2429
|
+
const [warning, setWarning] = React28.useState(false);
|
|
2430
|
+
const [remaining, setRemaining] = React28.useState(countdown);
|
|
2431
|
+
const idleTimer = React28.useRef(null);
|
|
2432
|
+
const tick = React28.useRef(null);
|
|
2433
|
+
const deadline = React28.useRef(0);
|
|
2434
|
+
const warningRef = React28.useRef(false);
|
|
2435
|
+
const lastReset = React28.useRef(0);
|
|
2436
|
+
const cbs = React28.useRef({ onLogout, onContinue, onWarning });
|
|
2437
2437
|
cbs.current = { onLogout, onContinue, onWarning };
|
|
2438
|
-
const clearTimers =
|
|
2438
|
+
const clearTimers = React28.useCallback(() => {
|
|
2439
2439
|
if (idleTimer.current) {
|
|
2440
2440
|
clearTimeout(idleTimer.current);
|
|
2441
2441
|
idleTimer.current = null;
|
|
@@ -2445,13 +2445,13 @@ function LogoutTimer({
|
|
|
2445
2445
|
tick.current = null;
|
|
2446
2446
|
}
|
|
2447
2447
|
}, []);
|
|
2448
|
-
const logout =
|
|
2448
|
+
const logout = React28.useCallback(() => {
|
|
2449
2449
|
clearTimers();
|
|
2450
2450
|
warningRef.current = false;
|
|
2451
2451
|
setWarning(false);
|
|
2452
2452
|
cbs.current.onLogout();
|
|
2453
2453
|
}, [clearTimers]);
|
|
2454
|
-
const startIdle =
|
|
2454
|
+
const startIdle = React28.useCallback(() => {
|
|
2455
2455
|
if (idleTimer.current) clearTimeout(idleTimer.current);
|
|
2456
2456
|
idleTimer.current = setTimeout(() => {
|
|
2457
2457
|
warningRef.current = true;
|
|
@@ -2466,7 +2466,7 @@ function LogoutTimer({
|
|
|
2466
2466
|
}, 250);
|
|
2467
2467
|
}, timeout);
|
|
2468
2468
|
}, [timeout, countdown, logout]);
|
|
2469
|
-
const stay =
|
|
2469
|
+
const stay = React28.useCallback(() => {
|
|
2470
2470
|
if (tick.current) {
|
|
2471
2471
|
clearInterval(tick.current);
|
|
2472
2472
|
tick.current = null;
|
|
@@ -2476,7 +2476,7 @@ function LogoutTimer({
|
|
|
2476
2476
|
cbs.current.onContinue?.();
|
|
2477
2477
|
startIdle();
|
|
2478
2478
|
}, [startIdle]);
|
|
2479
|
-
|
|
2479
|
+
React28.useEffect(() => {
|
|
2480
2480
|
if (!enabled) {
|
|
2481
2481
|
clearTimers();
|
|
2482
2482
|
warningRef.current = false;
|
|
@@ -2548,16 +2548,16 @@ function Calendar2({
|
|
|
2548
2548
|
className = "",
|
|
2549
2549
|
style
|
|
2550
2550
|
}) {
|
|
2551
|
-
const today =
|
|
2552
|
-
const [internalMonth, setInternalMonth] =
|
|
2551
|
+
const today = React28.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
2552
|
+
const [internalMonth, setInternalMonth] = React28.useState(() => month ?? defaultMonth ?? value ?? today);
|
|
2553
2553
|
const visible = month ?? internalMonth;
|
|
2554
2554
|
const setMonth = (next) => {
|
|
2555
2555
|
onMonthChange?.(next);
|
|
2556
2556
|
if (month === void 0) setInternalMonth(next);
|
|
2557
2557
|
};
|
|
2558
|
-
const grid =
|
|
2559
|
-
const weekdays =
|
|
2560
|
-
const eventsByDay =
|
|
2558
|
+
const grid = React28.useMemo(() => buildGrid(visible, weekStartsOn), [visible, weekStartsOn]);
|
|
2559
|
+
const weekdays = React28.useMemo(() => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]), [weekStartsOn]);
|
|
2560
|
+
const eventsByDay = React28.useMemo(() => {
|
|
2561
2561
|
const map = /* @__PURE__ */ new Map();
|
|
2562
2562
|
for (const ev of events ?? []) {
|
|
2563
2563
|
const key = startOfDay(ev.date).toDateString();
|
|
@@ -2788,11 +2788,11 @@ function SegmentedControl({
|
|
|
2788
2788
|
"aria-label": ariaLabel
|
|
2789
2789
|
}) {
|
|
2790
2790
|
const sz = SIZE5[size];
|
|
2791
|
-
const groupId =
|
|
2792
|
-
const errorId =
|
|
2791
|
+
const groupId = React28.useId();
|
|
2792
|
+
const errorId = React28.useId();
|
|
2793
2793
|
const hasError = errorMessage != null;
|
|
2794
2794
|
const isControlled = value !== void 0;
|
|
2795
|
-
const [internal, setInternal] =
|
|
2795
|
+
const [internal, setInternal] = React28.useState(defaultValue);
|
|
2796
2796
|
const current = isControlled ? value : internal;
|
|
2797
2797
|
const handle = (v) => {
|
|
2798
2798
|
if (!v) return;
|
|
@@ -2947,48 +2947,56 @@ function Scheduler({
|
|
|
2947
2947
|
onSelectSlot,
|
|
2948
2948
|
onSelectEvent,
|
|
2949
2949
|
onNewEvent,
|
|
2950
|
+
onError,
|
|
2950
2951
|
className = "",
|
|
2951
2952
|
style
|
|
2952
2953
|
}) {
|
|
2953
2954
|
const reduced = framerMotion.useReducedMotion();
|
|
2954
|
-
const [view, setView] =
|
|
2955
|
-
const [cursor, setCursor] =
|
|
2956
|
-
const [loaded, setLoaded] =
|
|
2957
|
-
const [loading, setLoading] =
|
|
2958
|
-
const [
|
|
2959
|
-
const
|
|
2960
|
-
|
|
2961
|
-
const
|
|
2955
|
+
const [view, setView] = React28.useState(defaultView);
|
|
2956
|
+
const [cursor, setCursor] = React28.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2957
|
+
const [loaded, setLoaded] = React28.useState([]);
|
|
2958
|
+
const [loading, setLoading] = React28.useState(false);
|
|
2959
|
+
const [error, setError] = React28.useState(null);
|
|
2960
|
+
const [reloadKey, setReloadKey] = React28.useState(0);
|
|
2961
|
+
const [dir, setDir] = React28.useState(0);
|
|
2962
|
+
const cbRef = React28.useRef({ loadEvents, onError });
|
|
2963
|
+
cbRef.current = { loadEvents, onError };
|
|
2964
|
+
const range = React28.useMemo(
|
|
2962
2965
|
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2963
2966
|
[view, cursor, weekStartsOn]
|
|
2964
2967
|
);
|
|
2965
2968
|
const fromKey = range.from.getTime();
|
|
2966
2969
|
const toKey = range.to.getTime();
|
|
2967
|
-
|
|
2968
|
-
const loader =
|
|
2970
|
+
React28.useEffect(() => {
|
|
2971
|
+
const { loadEvents: loader, onError: onErr } = cbRef.current;
|
|
2969
2972
|
if (!loader) return;
|
|
2970
2973
|
let cancelled = false;
|
|
2971
2974
|
setLoading(true);
|
|
2975
|
+
setError(null);
|
|
2972
2976
|
Promise.resolve(loader({ from: new Date(fromKey), to: new Date(toKey) }, view)).then((evts) => {
|
|
2973
2977
|
if (!cancelled) setLoaded(evts);
|
|
2974
|
-
}).catch(() => {
|
|
2975
|
-
if (!cancelled)
|
|
2978
|
+
}).catch((err) => {
|
|
2979
|
+
if (!cancelled) {
|
|
2980
|
+
setError(err ?? new Error("Failed to load events"));
|
|
2981
|
+
onErr?.(err);
|
|
2982
|
+
}
|
|
2976
2983
|
}).finally(() => {
|
|
2977
2984
|
if (!cancelled) setLoading(false);
|
|
2978
2985
|
});
|
|
2979
2986
|
return () => {
|
|
2980
2987
|
cancelled = true;
|
|
2981
2988
|
};
|
|
2982
|
-
}, [fromKey, toKey, view]);
|
|
2983
|
-
const
|
|
2989
|
+
}, [fromKey, toKey, view, reloadKey]);
|
|
2990
|
+
const retry = React28.useCallback(() => setReloadKey((k) => k + 1), []);
|
|
2991
|
+
const events = React28.useMemo(
|
|
2984
2992
|
() => (controlledEvents ?? loaded).map(normalize),
|
|
2985
2993
|
[controlledEvents, loaded]
|
|
2986
2994
|
);
|
|
2987
|
-
const go =
|
|
2995
|
+
const go = React28.useCallback((delta) => {
|
|
2988
2996
|
setDir(delta);
|
|
2989
2997
|
setCursor((c) => view === "month" ? addMonths2(c, delta) : addDays(c, delta * 7));
|
|
2990
2998
|
}, [view]);
|
|
2991
|
-
const goToday =
|
|
2999
|
+
const goToday = React28.useCallback(() => {
|
|
2992
3000
|
setDir(0);
|
|
2993
3001
|
setCursor(/* @__PURE__ */ new Date());
|
|
2994
3002
|
}, []);
|
|
@@ -3032,7 +3040,7 @@ function Scheduler({
|
|
|
3032
3040
|
onNewEvent && /* @__PURE__ */ jsxRuntime.jsx(Button_default, { size: "sm", icon: /* @__PURE__ */ jsxRuntime.jsx(Plus, {}), content: "New event", onClick: onNewEvent })
|
|
3033
3041
|
] })
|
|
3034
3042
|
] }),
|
|
3035
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3043
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden", children: error ? /* @__PURE__ */ jsxRuntime.jsx(SchedulerError, { onRetry: retry }) : loadEvents && loading && events.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(SchedulerSkeleton, { view }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3036
3044
|
framerMotion.motion.div,
|
|
3037
3045
|
{
|
|
3038
3046
|
initial: { opacity: 0, x: reduced ? 0 : dir * 24 },
|
|
@@ -3067,10 +3075,40 @@ function Scheduler({
|
|
|
3067
3075
|
}
|
|
3068
3076
|
);
|
|
3069
3077
|
}
|
|
3078
|
+
function SchedulerSkeleton({ view }) {
|
|
3079
|
+
const bar = "rounded bg-background animate-pulse";
|
|
3080
|
+
if (view === "week") {
|
|
3081
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col p-3", "aria-hidden": "true", children: [
|
|
3082
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 grid gap-2", style: { gridTemplateColumns: "3.5rem repeat(7, 1fr)" }, children: [
|
|
3083
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
3084
|
+
Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} mx-auto h-8 w-8 rounded-full` }, i))
|
|
3085
|
+
] }),
|
|
3086
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col gap-3", children: Array.from({ length: 8 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-6`, style: { width: `${60 + i * 13 % 35}%` } }, i)) })
|
|
3087
|
+
] });
|
|
3088
|
+
}
|
|
3089
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col p-3", "aria-hidden": "true", children: [
|
|
3090
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 grid grid-cols-7 gap-2", children: Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-2.5` }, i)) }),
|
|
3091
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-5 gap-2", children: Array.from({ length: 35 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3092
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-5 w-5 rounded-full` }),
|
|
3093
|
+
i % 3 === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-3` }),
|
|
3094
|
+
i % 5 === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-3`, style: { width: "70%" } })
|
|
3095
|
+
] }, i)) })
|
|
3096
|
+
] });
|
|
3097
|
+
}
|
|
3098
|
+
function SchedulerError({ onRetry }) {
|
|
3099
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: "flex h-full flex-col items-center justify-center gap-3 p-8 text-center", children: [
|
|
3100
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-10 w-10 items-center justify-center rounded-full text-status-error", style: { backgroundColor: "color-mix(in oklab, var(--color-error) 12%, var(--color-surface))" }, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-5 w-5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v4m0 4h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h16.94a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z" }) }) }),
|
|
3101
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3102
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-foreground", children: "Couldn\u2019t load events" }),
|
|
3103
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 text-xs text-foreground-muted", children: "Something went wrong fetching this range." })
|
|
3104
|
+
] }),
|
|
3105
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { size: "sm", variant: "secondary", content: "Retry", onClick: onRetry })
|
|
3106
|
+
] });
|
|
3107
|
+
}
|
|
3070
3108
|
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3071
|
-
const [open, setOpen] =
|
|
3072
|
-
const [viewYear, setViewYear] =
|
|
3073
|
-
|
|
3109
|
+
const [open, setOpen] = React28.useState(false);
|
|
3110
|
+
const [viewYear, setViewYear] = React28.useState(cursor.getFullYear());
|
|
3111
|
+
React28.useEffect(() => {
|
|
3074
3112
|
if (open) setViewYear(cursor.getFullYear());
|
|
3075
3113
|
}, [open, cursor]);
|
|
3076
3114
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open, onOpenChange: setOpen, children: [
|
|
@@ -3133,7 +3171,7 @@ function MonthView({
|
|
|
3133
3171
|
onSelectSlot,
|
|
3134
3172
|
onSelectEvent
|
|
3135
3173
|
}) {
|
|
3136
|
-
const grid =
|
|
3174
|
+
const grid = React28.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3137
3175
|
const labels = weekdayLabels(weekStartsOn);
|
|
3138
3176
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3139
3177
|
/* @__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)) }),
|
|
@@ -3207,11 +3245,11 @@ function WeekView({
|
|
|
3207
3245
|
onSelectSlot,
|
|
3208
3246
|
onSelectEvent
|
|
3209
3247
|
}) {
|
|
3210
|
-
const days =
|
|
3211
|
-
const labels =
|
|
3248
|
+
const days = React28.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3249
|
+
const labels = React28.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
|
|
3212
3250
|
const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
|
|
3213
3251
|
const [startHour, endHour] = dayHours;
|
|
3214
|
-
const hours =
|
|
3252
|
+
const hours = React28.useMemo(
|
|
3215
3253
|
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3216
3254
|
[startHour, endHour]
|
|
3217
3255
|
);
|
|
@@ -3402,17 +3440,17 @@ function Cart({
|
|
|
3402
3440
|
] })
|
|
3403
3441
|
] });
|
|
3404
3442
|
}
|
|
3405
|
-
var CartContext =
|
|
3443
|
+
var CartContext = React28.createContext(null);
|
|
3406
3444
|
var clampQty = (qty, max) => {
|
|
3407
3445
|
const lower = Math.max(1, Math.round(qty));
|
|
3408
3446
|
return max != null ? Math.min(lower, max) : lower;
|
|
3409
3447
|
};
|
|
3410
3448
|
function CartProvider({ children, initialItems = [], onChange }) {
|
|
3411
|
-
const [items, setItems] =
|
|
3412
|
-
|
|
3449
|
+
const [items, setItems] = React28.useState(initialItems);
|
|
3450
|
+
React28.useEffect(() => {
|
|
3413
3451
|
onChange?.(items);
|
|
3414
3452
|
}, [items]);
|
|
3415
|
-
const addToCart =
|
|
3453
|
+
const addToCart = React28.useCallback((item, quantity) => {
|
|
3416
3454
|
const addQty = quantity ?? item.quantity ?? 1;
|
|
3417
3455
|
setItems((prev) => {
|
|
3418
3456
|
const existing = prev.find((it) => it.id === item.id);
|
|
@@ -3425,29 +3463,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
|
|
|
3425
3463
|
return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
|
|
3426
3464
|
});
|
|
3427
3465
|
}, []);
|
|
3428
|
-
const removeFromCart =
|
|
3466
|
+
const removeFromCart = React28.useCallback((id) => {
|
|
3429
3467
|
setItems((prev) => prev.filter((it) => it.id !== id));
|
|
3430
3468
|
}, []);
|
|
3431
|
-
const updateQuantity =
|
|
3469
|
+
const updateQuantity = React28.useCallback((id, quantity) => {
|
|
3432
3470
|
setItems(
|
|
3433
3471
|
(prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
|
|
3434
3472
|
);
|
|
3435
3473
|
}, []);
|
|
3436
|
-
const clearCart =
|
|
3437
|
-
const isInCart =
|
|
3438
|
-
const getItemCount =
|
|
3439
|
-
const getCartTotal =
|
|
3474
|
+
const clearCart = React28.useCallback(() => setItems([]), []);
|
|
3475
|
+
const isInCart = React28.useCallback((id) => items.some((it) => it.id === id), [items]);
|
|
3476
|
+
const getItemCount = React28.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
|
|
3477
|
+
const getCartTotal = React28.useCallback(
|
|
3440
3478
|
() => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
|
|
3441
3479
|
[items]
|
|
3442
3480
|
);
|
|
3443
|
-
const value =
|
|
3481
|
+
const value = React28.useMemo(
|
|
3444
3482
|
() => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
|
|
3445
3483
|
[items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
|
|
3446
3484
|
);
|
|
3447
3485
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
3448
3486
|
}
|
|
3449
3487
|
function useCart() {
|
|
3450
|
-
const ctx =
|
|
3488
|
+
const ctx = React28.useContext(CartContext);
|
|
3451
3489
|
if (!ctx) {
|
|
3452
3490
|
throw new Error("useCart must be used within a <CartProvider>.");
|
|
3453
3491
|
}
|
|
@@ -3781,11 +3819,11 @@ function buildBindings(store, name, kind, snap) {
|
|
|
3781
3819
|
|
|
3782
3820
|
// src/form/useForm.ts
|
|
3783
3821
|
function useForm(options = {}) {
|
|
3784
|
-
const ref =
|
|
3822
|
+
const ref = React28.useRef(null);
|
|
3785
3823
|
if (ref.current === null) ref.current = new FormStore(options);
|
|
3786
3824
|
const store = ref.current;
|
|
3787
|
-
|
|
3788
|
-
const make =
|
|
3825
|
+
React28.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3826
|
+
const make = React28.useCallback(
|
|
3789
3827
|
(kind) => (name, rules) => {
|
|
3790
3828
|
if (rules !== void 0) store.setRule(name, rules);
|
|
3791
3829
|
return buildBindings(store, name, kind, store.getFieldSnapshot(name));
|
|
@@ -3814,9 +3852,9 @@ function useForm(options = {}) {
|
|
|
3814
3852
|
fieldTarget: make("target")
|
|
3815
3853
|
};
|
|
3816
3854
|
}
|
|
3817
|
-
var FormContext =
|
|
3855
|
+
var FormContext = React28.createContext(null);
|
|
3818
3856
|
function useFormStore() {
|
|
3819
|
-
const store =
|
|
3857
|
+
const store = React28.useContext(FormContext);
|
|
3820
3858
|
if (!store) {
|
|
3821
3859
|
throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
|
|
3822
3860
|
}
|
|
@@ -3830,8 +3868,8 @@ function Form({
|
|
|
3830
3868
|
children,
|
|
3831
3869
|
...rest
|
|
3832
3870
|
}) {
|
|
3833
|
-
const ref =
|
|
3834
|
-
const bypass =
|
|
3871
|
+
const ref = React28.useRef(null);
|
|
3872
|
+
const bypass = React28.useRef(false);
|
|
3835
3873
|
const handleSubmit = async (e) => {
|
|
3836
3874
|
if (bypass.current) {
|
|
3837
3875
|
bypass.current = false;
|
|
@@ -3883,12 +3921,12 @@ function useFormField(name, options = {}) {
|
|
|
3883
3921
|
const store = useFormStore();
|
|
3884
3922
|
const { kind = "value", rules } = options;
|
|
3885
3923
|
if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
|
|
3886
|
-
|
|
3924
|
+
React28.useEffect(() => {
|
|
3887
3925
|
return () => {
|
|
3888
3926
|
if (rules !== void 0) store.removeRule(name);
|
|
3889
3927
|
};
|
|
3890
3928
|
}, [store, name]);
|
|
3891
|
-
const snap =
|
|
3929
|
+
const snap = React28.useSyncExternalStore(
|
|
3892
3930
|
store.subscribe,
|
|
3893
3931
|
() => store.getFieldSnapshot(name)
|
|
3894
3932
|
);
|
|
@@ -3900,7 +3938,7 @@ function FormField({ name, kind, rules, children }) {
|
|
|
3900
3938
|
}
|
|
3901
3939
|
function useFieldArray(name) {
|
|
3902
3940
|
const store = useFormStore();
|
|
3903
|
-
|
|
3941
|
+
React28.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3904
3942
|
const arr = store.getValue(name) ?? [];
|
|
3905
3943
|
const keys = store.getKeys(name);
|
|
3906
3944
|
return {
|
|
@@ -3933,7 +3971,7 @@ function TextInput({
|
|
|
3933
3971
|
suffix,
|
|
3934
3972
|
id
|
|
3935
3973
|
}) {
|
|
3936
|
-
const errorId =
|
|
3974
|
+
const errorId = React28.useId();
|
|
3937
3975
|
const hasError = errorMessage != null;
|
|
3938
3976
|
const hasAdornment = prefix != null || suffix != null;
|
|
3939
3977
|
const inputId = htmlFor ?? id;
|
|
@@ -4094,7 +4132,7 @@ function CreditCardForm({
|
|
|
4094
4132
|
className = "",
|
|
4095
4133
|
style
|
|
4096
4134
|
}) {
|
|
4097
|
-
const initial =
|
|
4135
|
+
const initial = React28.useRef({
|
|
4098
4136
|
number: formatCardNumber(defaultValue?.number ?? ""),
|
|
4099
4137
|
name: defaultValue?.name ?? "",
|
|
4100
4138
|
expiry: formatExpiry(defaultValue?.expiry ?? ""),
|
|
@@ -4103,7 +4141,7 @@ function CreditCardForm({
|
|
|
4103
4141
|
const form = useForm({ initialValues: initial });
|
|
4104
4142
|
const numberStr = String(form.values.number ?? "");
|
|
4105
4143
|
const brand = detectBrand(numberStr);
|
|
4106
|
-
|
|
4144
|
+
React28.useEffect(() => {
|
|
4107
4145
|
onChange?.(toCard(form.values));
|
|
4108
4146
|
}, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
|
|
4109
4147
|
const numberBind = form.fieldNative("number", {
|
|
@@ -4226,7 +4264,7 @@ function Checkout({
|
|
|
4226
4264
|
] })
|
|
4227
4265
|
] });
|
|
4228
4266
|
}
|
|
4229
|
-
var NotificationContext =
|
|
4267
|
+
var NotificationContext = React28.createContext({
|
|
4230
4268
|
open: () => void 0,
|
|
4231
4269
|
close: () => void 0
|
|
4232
4270
|
});
|
|
@@ -4284,26 +4322,26 @@ function NotificationItem({
|
|
|
4284
4322
|
onClose,
|
|
4285
4323
|
reduced
|
|
4286
4324
|
}) {
|
|
4287
|
-
const [paused, setPaused] =
|
|
4325
|
+
const [paused, setPaused] = React28.useState(false);
|
|
4288
4326
|
const duration = n.duration ?? 4e3;
|
|
4289
4327
|
const isAutoDismissing = isFinite(duration) && duration > 0;
|
|
4290
4328
|
const showProgress = !reduced && isAutoDismissing;
|
|
4291
|
-
const timerRef =
|
|
4292
|
-
const startTimeRef =
|
|
4293
|
-
const remainingRef =
|
|
4294
|
-
const clearTimer =
|
|
4329
|
+
const timerRef = React28.useRef(null);
|
|
4330
|
+
const startTimeRef = React28.useRef(0);
|
|
4331
|
+
const remainingRef = React28.useRef(duration);
|
|
4332
|
+
const clearTimer = React28.useCallback(() => {
|
|
4295
4333
|
if (timerRef.current !== null) {
|
|
4296
4334
|
clearTimeout(timerRef.current);
|
|
4297
4335
|
timerRef.current = null;
|
|
4298
4336
|
}
|
|
4299
4337
|
}, []);
|
|
4300
|
-
const scheduleDismiss =
|
|
4338
|
+
const scheduleDismiss = React28.useCallback((ms) => {
|
|
4301
4339
|
clearTimer();
|
|
4302
4340
|
if (!isAutoDismissing) return;
|
|
4303
4341
|
startTimeRef.current = Date.now();
|
|
4304
4342
|
timerRef.current = setTimeout(() => onClose(n.id), ms);
|
|
4305
4343
|
}, [clearTimer, isAutoDismissing, n.id, onClose]);
|
|
4306
|
-
|
|
4344
|
+
React28.useEffect(() => {
|
|
4307
4345
|
if (paused || !isAutoDismissing) return;
|
|
4308
4346
|
scheduleDismiss(remainingRef.current);
|
|
4309
4347
|
return clearTimer;
|
|
@@ -4386,15 +4424,15 @@ function NotificationProvider({
|
|
|
4386
4424
|
children,
|
|
4387
4425
|
position = "top-right"
|
|
4388
4426
|
}) {
|
|
4389
|
-
const [notifications, setNotifications] =
|
|
4427
|
+
const [notifications, setNotifications] = React28.useState([]);
|
|
4390
4428
|
const reduced = framerMotion.useReducedMotion();
|
|
4391
|
-
const open =
|
|
4429
|
+
const open = React28.useCallback((payload) => {
|
|
4392
4430
|
setNotifications((prev) => [
|
|
4393
4431
|
...prev,
|
|
4394
4432
|
{ duration: 4e3, ...payload, id: Date.now() + Math.random() }
|
|
4395
4433
|
]);
|
|
4396
4434
|
}, []);
|
|
4397
|
-
const close =
|
|
4435
|
+
const close = React28.useCallback((id) => {
|
|
4398
4436
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
4399
4437
|
}, []);
|
|
4400
4438
|
return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
|
|
@@ -4423,7 +4461,7 @@ function NotificationProvider({
|
|
|
4423
4461
|
] });
|
|
4424
4462
|
}
|
|
4425
4463
|
function useNotification() {
|
|
4426
|
-
const { open } =
|
|
4464
|
+
const { open } = React28.useContext(NotificationContext);
|
|
4427
4465
|
return {
|
|
4428
4466
|
info: (props) => open({ type: "info", ...props }),
|
|
4429
4467
|
success: (props) => open({ type: "success", ...props }),
|
|
@@ -4540,10 +4578,10 @@ function FadingBase({
|
|
|
4540
4578
|
isMounted = false,
|
|
4541
4579
|
children
|
|
4542
4580
|
}) {
|
|
4543
|
-
const [shouldRender, setShouldRender] =
|
|
4544
|
-
const [visible, setVisible] =
|
|
4545
|
-
const timerRef =
|
|
4546
|
-
|
|
4581
|
+
const [shouldRender, setShouldRender] = React28.useState(isMounted);
|
|
4582
|
+
const [visible, setVisible] = React28.useState(false);
|
|
4583
|
+
const timerRef = React28.useRef(null);
|
|
4584
|
+
React28.useEffect(() => {
|
|
4547
4585
|
if (isMounted) {
|
|
4548
4586
|
setShouldRender(true);
|
|
4549
4587
|
const rafId = requestAnimationFrame(() => setVisible(true));
|
|
@@ -4641,8 +4679,8 @@ function ScalableContainer({
|
|
|
4641
4679
|
togglePosition = "top-right",
|
|
4642
4680
|
className = ""
|
|
4643
4681
|
}) {
|
|
4644
|
-
const containerRef =
|
|
4645
|
-
const [internalScaled, setInternalScaled] =
|
|
4682
|
+
const containerRef = React28.useRef(null);
|
|
4683
|
+
const [internalScaled, setInternalScaled] = React28.useState(false);
|
|
4646
4684
|
const isScaled = expanded ?? internalScaled;
|
|
4647
4685
|
const reduced = framerMotion.useReducedMotion();
|
|
4648
4686
|
const onToggle = () => {
|
|
@@ -4780,17 +4818,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
|
|
|
4780
4818
|
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)) });
|
|
4781
4819
|
}
|
|
4782
4820
|
function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
|
|
4783
|
-
const [activeIndex, setActiveIndex] =
|
|
4784
|
-
const [indexPool, setIndexPool] =
|
|
4785
|
-
const cardRefs =
|
|
4786
|
-
const getIndexes =
|
|
4821
|
+
const [activeIndex, setActiveIndex] = React28.useState(0);
|
|
4822
|
+
const [indexPool, setIndexPool] = React28.useState([]);
|
|
4823
|
+
const cardRefs = React28.useRef([]);
|
|
4824
|
+
const getIndexes = React28.useMemo(() => {
|
|
4787
4825
|
let nextIndex = activeIndex + 1;
|
|
4788
4826
|
let previousIndex = activeIndex - 1;
|
|
4789
4827
|
if (activeIndex === 0) previousIndex = items.length - 1;
|
|
4790
4828
|
if (activeIndex === items.length - 1) nextIndex = 0;
|
|
4791
4829
|
return { previousIndex, nextIndex };
|
|
4792
4830
|
}, [activeIndex, items.length]);
|
|
4793
|
-
|
|
4831
|
+
React28.useEffect(() => {
|
|
4794
4832
|
const { nextIndex, previousIndex } = getIndexes;
|
|
4795
4833
|
let indexes = [previousIndex, activeIndex, nextIndex];
|
|
4796
4834
|
if (activeIndex !== 0 && activeIndex !== items.length - 1) {
|
|
@@ -4963,8 +5001,8 @@ function writeDismissed(key) {
|
|
|
4963
5001
|
}
|
|
4964
5002
|
}
|
|
4965
5003
|
function useTargetBbox(ref) {
|
|
4966
|
-
const [bbox, setBbox] =
|
|
4967
|
-
|
|
5004
|
+
const [bbox, setBbox] = React28.useState(null);
|
|
5005
|
+
React28.useLayoutEffect(() => {
|
|
4968
5006
|
const el = ref?.current;
|
|
4969
5007
|
if (!el) {
|
|
4970
5008
|
setBbox(null);
|
|
@@ -4994,7 +5032,7 @@ function tooltipStyleFor(bbox, placement) {
|
|
|
4994
5032
|
return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
|
|
4995
5033
|
}
|
|
4996
5034
|
function useFocusTrap(containerRef, active) {
|
|
4997
|
-
|
|
5035
|
+
React28.useEffect(() => {
|
|
4998
5036
|
if (!active) return;
|
|
4999
5037
|
const el = containerRef.current;
|
|
5000
5038
|
if (!el) return;
|
|
@@ -5033,16 +5071,16 @@ function Wizard({
|
|
|
5033
5071
|
onComplete,
|
|
5034
5072
|
onSkip
|
|
5035
5073
|
}) {
|
|
5036
|
-
const tooltipRef =
|
|
5037
|
-
const tooltipTitleId =
|
|
5038
|
-
const tooltipBodyId =
|
|
5074
|
+
const tooltipRef = React28.useRef(null);
|
|
5075
|
+
const tooltipTitleId = React28.useId();
|
|
5076
|
+
const tooltipBodyId = React28.useId();
|
|
5039
5077
|
const reduced = framerMotion.useReducedMotion();
|
|
5040
|
-
const [open, setOpen] =
|
|
5041
|
-
const [activeIndex, setActiveIndex] =
|
|
5078
|
+
const [open, setOpen] = React28.useState(() => steps.length > 0 && !readDismissed(storageKey));
|
|
5079
|
+
const [activeIndex, setActiveIndex] = React28.useState(0);
|
|
5042
5080
|
const step = steps[activeIndex];
|
|
5043
5081
|
const bbox = useTargetBbox(step?.stepRef);
|
|
5044
5082
|
useFocusTrap(tooltipRef, open);
|
|
5045
|
-
|
|
5083
|
+
React28.useEffect(() => {
|
|
5046
5084
|
if (!open || !dismissible) return;
|
|
5047
5085
|
const onKey = (e) => {
|
|
5048
5086
|
if (e.key === "Escape") {
|
|
@@ -5053,12 +5091,12 @@ function Wizard({
|
|
|
5053
5091
|
document.addEventListener("keydown", onKey);
|
|
5054
5092
|
return () => document.removeEventListener("keydown", onKey);
|
|
5055
5093
|
}, [open, dismissible]);
|
|
5056
|
-
const handleSkip =
|
|
5094
|
+
const handleSkip = React28.useCallback(() => {
|
|
5057
5095
|
writeDismissed(storageKey);
|
|
5058
5096
|
setOpen(false);
|
|
5059
5097
|
onSkip?.();
|
|
5060
5098
|
}, [storageKey, onSkip]);
|
|
5061
|
-
const handleComplete =
|
|
5099
|
+
const handleComplete = React28.useCallback(() => {
|
|
5062
5100
|
writeDismissed(storageKey);
|
|
5063
5101
|
setOpen(false);
|
|
5064
5102
|
onComplete?.();
|
|
@@ -5201,7 +5239,7 @@ function Wizard({
|
|
|
5201
5239
|
] });
|
|
5202
5240
|
}
|
|
5203
5241
|
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" }) });
|
|
5204
|
-
var SearchInput =
|
|
5242
|
+
var SearchInput = React28__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
|
|
5205
5243
|
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5206
5244
|
"div",
|
|
5207
5245
|
{
|
|
@@ -5230,438 +5268,136 @@ var SearchInput = React29__default.default.forwardRef(function SearchInput2({ va
|
|
|
5230
5268
|
) });
|
|
5231
5269
|
});
|
|
5232
5270
|
var SearchInput_default = SearchInput;
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
className: "inline-flex items-center justify-center w-4 h-4 flex-shrink-0 rounded text-foreground-muted hover:text-status-error hover:bg-surface transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-accent disabled:cursor-not-allowed",
|
|
5247
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "10", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
|
|
5271
|
+
var SHIMMER = "oxy-skeleton rounded-sm bg-surface-raised";
|
|
5272
|
+
function SkeletonBox({ width, height = 16, radius, className = "", style }) {
|
|
5273
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5274
|
+
"span",
|
|
5275
|
+
{
|
|
5276
|
+
role: "presentation",
|
|
5277
|
+
"aria-hidden": "true",
|
|
5278
|
+
className: `block ${SHIMMER} ${className}`,
|
|
5279
|
+
style: {
|
|
5280
|
+
width: width ?? "100%",
|
|
5281
|
+
height,
|
|
5282
|
+
borderRadius: radius ?? "var(--radius-md)",
|
|
5283
|
+
...style
|
|
5248
5284
|
}
|
|
5249
|
-
|
|
5250
|
-
|
|
5285
|
+
}
|
|
5286
|
+
);
|
|
5251
5287
|
}
|
|
5252
|
-
function
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5288
|
+
function SkeletonText({
|
|
5289
|
+
lines = 3,
|
|
5290
|
+
lastLineWidth = 60,
|
|
5291
|
+
lineHeight = 14,
|
|
5292
|
+
gap = 8,
|
|
5293
|
+
className = "",
|
|
5294
|
+
style
|
|
5257
5295
|
}) {
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
}
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
count--;
|
|
5293
|
-
}
|
|
5294
|
-
}
|
|
5295
|
-
setVisibleCount(count);
|
|
5296
|
-
};
|
|
5297
|
-
recompute();
|
|
5298
|
-
const ro = new ResizeObserver(recompute);
|
|
5299
|
-
ro.observe(wrap);
|
|
5300
|
-
return () => ro.disconnect();
|
|
5301
|
-
}, [key]);
|
|
5302
|
-
const hidden = values.length - visibleCount;
|
|
5303
|
-
const moreChip = (n) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center flex-shrink-0 rounded-md border border-border bg-surface-raised text-foreground-secondary text-xs px-2 py-0.5", children: [
|
|
5304
|
-
"+",
|
|
5305
|
-
n,
|
|
5306
|
-
" more"
|
|
5307
|
-
] });
|
|
5308
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrapRef, className: "relative flex-1 min-w-0 flex flex-nowrap items-center gap-1.5 overflow-hidden", children: [
|
|
5309
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5310
|
-
"div",
|
|
5311
|
-
{
|
|
5312
|
-
ref: measureRef,
|
|
5313
|
-
"aria-hidden": "true",
|
|
5314
|
-
className: "absolute invisible pointer-events-none flex flex-nowrap items-center gap-1.5",
|
|
5315
|
-
style: { left: -9999, top: -9999 },
|
|
5316
|
-
children: [
|
|
5317
|
-
values.map((val) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-mt": true, children: /* @__PURE__ */ jsxRuntime.jsx(Tag, { removeLabel: "x", onRemove: () => {
|
|
5318
|
-
}, children: labelFor(val) }) }, `m-${val}`)),
|
|
5319
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-mm": true, children: moreChip(values.length) })
|
|
5320
|
-
]
|
|
5296
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5297
|
+
"div",
|
|
5298
|
+
{
|
|
5299
|
+
role: "presentation",
|
|
5300
|
+
"aria-hidden": "true",
|
|
5301
|
+
className: `flex flex-col ${className}`,
|
|
5302
|
+
style: { gap, ...style },
|
|
5303
|
+
children: Array.from({ length: lines }).map((_, i) => {
|
|
5304
|
+
const isLast = i === lines - 1;
|
|
5305
|
+
const width = isLast && lines > 1 ? `${lastLineWidth}%` : "100%";
|
|
5306
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5307
|
+
"span",
|
|
5308
|
+
{
|
|
5309
|
+
className: `block ${SHIMMER}`,
|
|
5310
|
+
style: { height: lineHeight, width, borderRadius: "var(--radius-sm)" }
|
|
5311
|
+
},
|
|
5312
|
+
i
|
|
5313
|
+
);
|
|
5314
|
+
})
|
|
5315
|
+
}
|
|
5316
|
+
);
|
|
5317
|
+
}
|
|
5318
|
+
function SkeletonCircle({ size = 40, className = "", style }) {
|
|
5319
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5320
|
+
"span",
|
|
5321
|
+
{
|
|
5322
|
+
role: "presentation",
|
|
5323
|
+
"aria-hidden": "true",
|
|
5324
|
+
className: `block flex-shrink-0 ${SHIMMER} ${className}`,
|
|
5325
|
+
style: {
|
|
5326
|
+
width: size,
|
|
5327
|
+
height: size,
|
|
5328
|
+
borderRadius: "50%",
|
|
5329
|
+
...style
|
|
5321
5330
|
}
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5331
|
+
}
|
|
5332
|
+
);
|
|
5333
|
+
}
|
|
5334
|
+
function SkeletonCard({ hasAvatar = true, lines = 3, className = "", style }) {
|
|
5335
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5336
|
+
"div",
|
|
5337
|
+
{
|
|
5338
|
+
role: "presentation",
|
|
5339
|
+
"aria-hidden": "true",
|
|
5340
|
+
className: `rounded-lg border border-border bg-surface p-4 ${className}`,
|
|
5341
|
+
style,
|
|
5342
|
+
children: [
|
|
5343
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
|
|
5344
|
+
hasAvatar && /* @__PURE__ */ jsxRuntime.jsx(SkeletonCircle, { size: 36 }),
|
|
5345
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-2", children: [
|
|
5346
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 12, width: "55%" }),
|
|
5347
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 10, width: "35%" })
|
|
5348
|
+
] })
|
|
5349
|
+
] }),
|
|
5350
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonText, { lines, lastLineWidth: 55 }),
|
|
5351
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex gap-2", children: [
|
|
5352
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 28, width: 72 }),
|
|
5353
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 28, width: 56 })
|
|
5354
|
+
] })
|
|
5355
|
+
]
|
|
5356
|
+
}
|
|
5357
|
+
);
|
|
5358
|
+
}
|
|
5359
|
+
var DEFAULT_PICKER = [
|
|
5360
|
+
{ key: 1, value: 5, label: 5 },
|
|
5361
|
+
{ key: 2, value: 10, label: 10 },
|
|
5362
|
+
{ key: 3, value: 15, label: 15 },
|
|
5363
|
+
{ key: 4, value: 20, label: 20 }
|
|
5364
|
+
];
|
|
5365
|
+
var DEFAULT_PAGINATION = {
|
|
5366
|
+
enabled: true,
|
|
5367
|
+
perPage: 15,
|
|
5368
|
+
withPicker: true,
|
|
5369
|
+
pickerOptions: DEFAULT_PICKER
|
|
5370
|
+
};
|
|
5371
|
+
var DEFAULT_EXPAND = {
|
|
5372
|
+
enabled: false
|
|
5373
|
+
};
|
|
5374
|
+
function createDatasets(rows, perPage) {
|
|
5375
|
+
if (!perPage) return [rows.slice()];
|
|
5376
|
+
const all = [];
|
|
5377
|
+
for (let i = 0; i < rows.length; i += perPage) {
|
|
5378
|
+
all.push(rows.slice(i, i + perPage));
|
|
5379
|
+
}
|
|
5380
|
+
return all;
|
|
5381
|
+
}
|
|
5382
|
+
var defaultGetRowKey = (_row, index) => index;
|
|
5383
|
+
var cellAlign = (align) => align === "left" ? "text-left" : align === "right" ? "text-right" : "text-center";
|
|
5384
|
+
function TableHeader({
|
|
5385
|
+
columns,
|
|
5386
|
+
hasExpand
|
|
5387
|
+
}) {
|
|
5388
|
+
return /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-surface-raised border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
5389
|
+
hasExpand && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", className: "w-9" }),
|
|
5390
|
+
columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5391
|
+
"th",
|
|
5325
5392
|
{
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
children:
|
|
5393
|
+
scope: "col",
|
|
5394
|
+
className: `${cellAlign(col.align)} text-sm font-semibold text-foreground py-3 px-3`,
|
|
5395
|
+
style: col.width != null ? { width: col.width } : void 0,
|
|
5396
|
+
children: col.label
|
|
5330
5397
|
},
|
|
5331
|
-
|
|
5332
|
-
))
|
|
5333
|
-
|
|
5334
|
-
] });
|
|
5335
|
-
}
|
|
5336
|
-
function Dropdown({
|
|
5337
|
-
isMultiselect = false,
|
|
5338
|
-
hasSearch = true,
|
|
5339
|
-
label,
|
|
5340
|
-
name,
|
|
5341
|
-
value,
|
|
5342
|
-
onChange,
|
|
5343
|
-
disabled,
|
|
5344
|
-
layout = "horizontal",
|
|
5345
|
-
helperText,
|
|
5346
|
-
required,
|
|
5347
|
-
errorMessage,
|
|
5348
|
-
style = {},
|
|
5349
|
-
htmlFor,
|
|
5350
|
-
items = [],
|
|
5351
|
-
labelStyle = {},
|
|
5352
|
-
placeholder,
|
|
5353
|
-
size = "md",
|
|
5354
|
-
className = ""
|
|
5355
|
-
}) {
|
|
5356
|
-
const [open, setOpen] = React29.useState(false);
|
|
5357
|
-
const [selectedItems, setSelectedItems] = React29.useState([]);
|
|
5358
|
-
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
5359
|
-
const [innerItems, setInnerItems] = React29.useState([]);
|
|
5360
|
-
const errorId = React29.useId();
|
|
5361
|
-
const hasError = errorMessage != null;
|
|
5362
|
-
React29.useEffect(() => {
|
|
5363
|
-
setInnerItems(items);
|
|
5364
|
-
}, [items]);
|
|
5365
|
-
React29.useEffect(() => {
|
|
5366
|
-
if (isMultiselect && Array.isArray(value)) {
|
|
5367
|
-
setSelectedItems(value);
|
|
5368
|
-
}
|
|
5369
|
-
}, [isMultiselect, value]);
|
|
5370
|
-
const selectItem = (key) => {
|
|
5371
|
-
if (isMultiselect) {
|
|
5372
|
-
const next = selectedItems.includes(key) ? selectedItems.filter((it) => it !== key) : [...selectedItems, key];
|
|
5373
|
-
setSelectedItems(next);
|
|
5374
|
-
onChange?.({ target: { value: next, id: htmlFor, name } });
|
|
5375
|
-
} else {
|
|
5376
|
-
setSelectedItems([key]);
|
|
5377
|
-
onChange?.({ target: { value: key, id: htmlFor, name } });
|
|
5378
|
-
setOpen(false);
|
|
5379
|
-
}
|
|
5380
|
-
};
|
|
5381
|
-
const removeSelected = (key) => {
|
|
5382
|
-
if (isMultiselect) {
|
|
5383
|
-
const next = selectedItems.filter((it) => it !== key);
|
|
5384
|
-
setSelectedItems(next);
|
|
5385
|
-
onChange?.({ target: { value: next, id: htmlFor, name } });
|
|
5386
|
-
} else {
|
|
5387
|
-
setSelectedItems([]);
|
|
5388
|
-
onChange?.({ target: { value: "", id: htmlFor, name } });
|
|
5389
|
-
}
|
|
5390
|
-
};
|
|
5391
|
-
const labelFor = (key) => innerItems.find((it) => it.key === key)?.label ?? String(key);
|
|
5392
|
-
const onSearchChange = (e) => {
|
|
5393
|
-
const term = e.target.value;
|
|
5394
|
-
setSearchTerm(term);
|
|
5395
|
-
setInnerItems(
|
|
5396
|
-
term.trim() === "" ? items : items.filter(
|
|
5397
|
-
(it) => String(it.label).toLowerCase().includes(term.toLowerCase())
|
|
5398
|
-
)
|
|
5399
|
-
);
|
|
5400
|
-
};
|
|
5401
|
-
const isSelected = (key) => Array.isArray(value) ? value.includes(key) : value === key;
|
|
5402
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: className || void 0, children: [
|
|
5403
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5404
|
-
"div",
|
|
5405
|
-
{
|
|
5406
|
-
className: `flex ${layout === "vertical" ? "flex-col gap-1.5" : "flex-row items-start gap-3"}`,
|
|
5407
|
-
children: [
|
|
5408
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5409
|
-
FieldLabel,
|
|
5410
|
-
{
|
|
5411
|
-
label,
|
|
5412
|
-
htmlFor,
|
|
5413
|
-
required,
|
|
5414
|
-
helperText,
|
|
5415
|
-
horizontal: layout === "horizontal",
|
|
5416
|
-
style: labelStyle
|
|
5417
|
-
}
|
|
5418
|
-
),
|
|
5419
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
5420
|
-
/* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5421
|
-
"div",
|
|
5422
|
-
{
|
|
5423
|
-
id: htmlFor,
|
|
5424
|
-
role: "combobox",
|
|
5425
|
-
"aria-expanded": open,
|
|
5426
|
-
"aria-haspopup": "listbox",
|
|
5427
|
-
"aria-invalid": hasError || void 0,
|
|
5428
|
-
"aria-describedby": hasError ? errorId : void 0,
|
|
5429
|
-
style: { width: 240, ...style },
|
|
5430
|
-
className: `flex items-center justify-between gap-2 cursor-pointer select-none min-h-[36px] px-3 py-1.5 ${fieldShell({ size, hasError, disabled, sized: false })}`,
|
|
5431
|
-
tabIndex: disabled ? -1 : 0,
|
|
5432
|
-
onKeyDown: (e) => {
|
|
5433
|
-
if (disabled) return;
|
|
5434
|
-
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
5435
|
-
e.preventDefault();
|
|
5436
|
-
setOpen(true);
|
|
5437
|
-
}
|
|
5438
|
-
},
|
|
5439
|
-
children: [
|
|
5440
|
-
!value || Array.isArray(value) && value.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 min-w-0 truncate text-foreground-muted text-sm", children: placeholder }) : Array.isArray(value) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5441
|
-
MultiTagRow,
|
|
5442
|
-
{
|
|
5443
|
-
values: value,
|
|
5444
|
-
disabled,
|
|
5445
|
-
labelFor,
|
|
5446
|
-
onRemove: removeSelected
|
|
5447
|
-
}
|
|
5448
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0 flex items-center overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5449
|
-
Tag,
|
|
5450
|
-
{
|
|
5451
|
-
disabled,
|
|
5452
|
-
removeLabel: `Remove ${labelFor(value)}`,
|
|
5453
|
-
onRemove: () => removeSelected(value),
|
|
5454
|
-
children: labelFor(value)
|
|
5455
|
-
}
|
|
5456
|
-
) }),
|
|
5457
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 text-foreground-muted transition-transform duration-200 ${open ? "rotate-180" : "rotate-0"}`, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }) })
|
|
5458
|
-
]
|
|
5459
|
-
}
|
|
5460
|
-
) }),
|
|
5461
|
-
/* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5462
|
-
Popover__namespace.Content,
|
|
5463
|
-
{
|
|
5464
|
-
align: "start",
|
|
5465
|
-
sideOffset: 4,
|
|
5466
|
-
style: { width: style?.width || 240 },
|
|
5467
|
-
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-2 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
5468
|
-
onInteractOutside: () => setOpen(false),
|
|
5469
|
-
children: [
|
|
5470
|
-
hasSearch && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5471
|
-
SearchInput_default,
|
|
5472
|
-
{
|
|
5473
|
-
style: { width: "100%" },
|
|
5474
|
-
inputStyle: { width: "100%" },
|
|
5475
|
-
value: searchTerm,
|
|
5476
|
-
onChange: onSearchChange,
|
|
5477
|
-
placeholder: "Search..."
|
|
5478
|
-
}
|
|
5479
|
-
) }),
|
|
5480
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", "aria-multiselectable": isMultiselect, className: "max-h-40 overflow-y-auto", children: innerItems.map((item) => (
|
|
5481
|
-
// aria-rowindex was previously set here but
|
|
5482
|
-
// it's invalid ARIA on role="option" (it
|
|
5483
|
-
// belongs on rows of a grid/treegrid). Dropped.
|
|
5484
|
-
// tabIndex={0} + Enter/Space handler makes the
|
|
5485
|
-
// option keyboard-activatable; the full
|
|
5486
|
-
// combobox roving-tabindex pattern is deferred
|
|
5487
|
-
// until the planned Phase-5 rewrite.
|
|
5488
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5489
|
-
"div",
|
|
5490
|
-
{
|
|
5491
|
-
role: "option",
|
|
5492
|
-
"aria-selected": isSelected(item.key),
|
|
5493
|
-
tabIndex: 0,
|
|
5494
|
-
className: `flex items-center justify-between p-2 hover:bg-accent hover:text-accent-fg transition-colors duration-150 text-sm rounded-lg cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${selectedItems.includes(item.key) ? "bg-surface-raised text-foreground" : "text-foreground"}`,
|
|
5495
|
-
onClick: () => selectItem(item.key),
|
|
5496
|
-
onKeyDown: (e) => {
|
|
5497
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
5498
|
-
e.preventDefault();
|
|
5499
|
-
selectItem(item.key);
|
|
5500
|
-
}
|
|
5501
|
-
},
|
|
5502
|
-
children: [
|
|
5503
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
5504
|
-
item.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { children: item.icon }),
|
|
5505
|
-
item.label
|
|
5506
|
-
] }),
|
|
5507
|
-
isSelected(item.key) && // currentColor — checkmark follows
|
|
5508
|
-
// the item's text colour, which
|
|
5509
|
-
// flips automatically on hover.
|
|
5510
|
-
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5511
|
-
"path",
|
|
5512
|
-
{
|
|
5513
|
-
d: "M4 10l4.5 4.5L16 6",
|
|
5514
|
-
stroke: "currentColor",
|
|
5515
|
-
strokeWidth: "2",
|
|
5516
|
-
strokeLinecap: "round",
|
|
5517
|
-
strokeLinejoin: "round"
|
|
5518
|
-
}
|
|
5519
|
-
) })
|
|
5520
|
-
]
|
|
5521
|
-
},
|
|
5522
|
-
item.key
|
|
5523
|
-
)
|
|
5524
|
-
)) })
|
|
5525
|
-
]
|
|
5526
|
-
}
|
|
5527
|
-
) })
|
|
5528
|
-
] })
|
|
5529
|
-
]
|
|
5530
|
-
}
|
|
5531
|
-
),
|
|
5532
|
-
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
5533
|
-
] });
|
|
5534
|
-
}
|
|
5535
|
-
var SHIMMER = "oxy-skeleton rounded-sm bg-surface-raised";
|
|
5536
|
-
function SkeletonBox({ width, height = 16, radius, className = "", style }) {
|
|
5537
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5538
|
-
"span",
|
|
5539
|
-
{
|
|
5540
|
-
role: "presentation",
|
|
5541
|
-
"aria-hidden": "true",
|
|
5542
|
-
className: `block ${SHIMMER} ${className}`,
|
|
5543
|
-
style: {
|
|
5544
|
-
width: width ?? "100%",
|
|
5545
|
-
height,
|
|
5546
|
-
borderRadius: radius ?? "var(--radius-md)",
|
|
5547
|
-
...style
|
|
5548
|
-
}
|
|
5549
|
-
}
|
|
5550
|
-
);
|
|
5551
|
-
}
|
|
5552
|
-
function SkeletonText({
|
|
5553
|
-
lines = 3,
|
|
5554
|
-
lastLineWidth = 60,
|
|
5555
|
-
lineHeight = 14,
|
|
5556
|
-
gap = 8,
|
|
5557
|
-
className = "",
|
|
5558
|
-
style
|
|
5559
|
-
}) {
|
|
5560
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5561
|
-
"div",
|
|
5562
|
-
{
|
|
5563
|
-
role: "presentation",
|
|
5564
|
-
"aria-hidden": "true",
|
|
5565
|
-
className: `flex flex-col ${className}`,
|
|
5566
|
-
style: { gap, ...style },
|
|
5567
|
-
children: Array.from({ length: lines }).map((_, i) => {
|
|
5568
|
-
const isLast = i === lines - 1;
|
|
5569
|
-
const width = isLast && lines > 1 ? `${lastLineWidth}%` : "100%";
|
|
5570
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5571
|
-
"span",
|
|
5572
|
-
{
|
|
5573
|
-
className: `block ${SHIMMER}`,
|
|
5574
|
-
style: { height: lineHeight, width, borderRadius: "var(--radius-sm)" }
|
|
5575
|
-
},
|
|
5576
|
-
i
|
|
5577
|
-
);
|
|
5578
|
-
})
|
|
5579
|
-
}
|
|
5580
|
-
);
|
|
5581
|
-
}
|
|
5582
|
-
function SkeletonCircle({ size = 40, className = "", style }) {
|
|
5583
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5584
|
-
"span",
|
|
5585
|
-
{
|
|
5586
|
-
role: "presentation",
|
|
5587
|
-
"aria-hidden": "true",
|
|
5588
|
-
className: `block flex-shrink-0 ${SHIMMER} ${className}`,
|
|
5589
|
-
style: {
|
|
5590
|
-
width: size,
|
|
5591
|
-
height: size,
|
|
5592
|
-
borderRadius: "50%",
|
|
5593
|
-
...style
|
|
5594
|
-
}
|
|
5595
|
-
}
|
|
5596
|
-
);
|
|
5597
|
-
}
|
|
5598
|
-
function SkeletonCard({ hasAvatar = true, lines = 3, className = "", style }) {
|
|
5599
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5600
|
-
"div",
|
|
5601
|
-
{
|
|
5602
|
-
role: "presentation",
|
|
5603
|
-
"aria-hidden": "true",
|
|
5604
|
-
className: `rounded-lg border border-border bg-surface p-4 ${className}`,
|
|
5605
|
-
style,
|
|
5606
|
-
children: [
|
|
5607
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
|
|
5608
|
-
hasAvatar && /* @__PURE__ */ jsxRuntime.jsx(SkeletonCircle, { size: 36 }),
|
|
5609
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col gap-2", children: [
|
|
5610
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 12, width: "55%" }),
|
|
5611
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 10, width: "35%" })
|
|
5612
|
-
] })
|
|
5613
|
-
] }),
|
|
5614
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonText, { lines, lastLineWidth: 55 }),
|
|
5615
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex gap-2", children: [
|
|
5616
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 28, width: 72 }),
|
|
5617
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 28, width: 56 })
|
|
5618
|
-
] })
|
|
5619
|
-
]
|
|
5620
|
-
}
|
|
5621
|
-
);
|
|
5622
|
-
}
|
|
5623
|
-
var DEFAULT_PICKER = [
|
|
5624
|
-
{ key: 1, value: 5, label: 5 },
|
|
5625
|
-
{ key: 2, value: 10, label: 10 },
|
|
5626
|
-
{ key: 3, value: 15, label: 15 },
|
|
5627
|
-
{ key: 4, value: 20, label: 20 }
|
|
5628
|
-
];
|
|
5629
|
-
var DEFAULT_PAGINATION = {
|
|
5630
|
-
enabled: true,
|
|
5631
|
-
perPage: 15,
|
|
5632
|
-
withPicker: true,
|
|
5633
|
-
pickerOptions: DEFAULT_PICKER
|
|
5634
|
-
};
|
|
5635
|
-
var DEFAULT_EXPAND = {
|
|
5636
|
-
enabled: false
|
|
5637
|
-
};
|
|
5638
|
-
function createDatasets(rows, perPage) {
|
|
5639
|
-
if (!perPage) return [rows.slice()];
|
|
5640
|
-
const all = [];
|
|
5641
|
-
for (let i = 0; i < rows.length; i += perPage) {
|
|
5642
|
-
all.push(rows.slice(i, i + perPage));
|
|
5643
|
-
}
|
|
5644
|
-
return all;
|
|
5645
|
-
}
|
|
5646
|
-
var defaultGetRowKey = (_row, index) => index;
|
|
5647
|
-
var cellAlign = (align) => align === "left" ? "text-left" : align === "right" ? "text-right" : "text-center";
|
|
5648
|
-
function TableHeader({
|
|
5649
|
-
columns,
|
|
5650
|
-
hasExpand
|
|
5651
|
-
}) {
|
|
5652
|
-
return /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-surface-raised border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
5653
|
-
hasExpand && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", className: "w-9" }),
|
|
5654
|
-
columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5655
|
-
"th",
|
|
5656
|
-
{
|
|
5657
|
-
scope: "col",
|
|
5658
|
-
className: `${cellAlign(col.align)} text-sm font-semibold text-foreground py-3 px-3`,
|
|
5659
|
-
style: col.width != null ? { width: col.width } : void 0,
|
|
5660
|
-
children: col.label
|
|
5661
|
-
},
|
|
5662
|
-
col.key
|
|
5663
|
-
))
|
|
5664
|
-
] }) });
|
|
5398
|
+
col.key
|
|
5399
|
+
))
|
|
5400
|
+
] }) });
|
|
5665
5401
|
}
|
|
5666
5402
|
var DefaultExpandIcon = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5667
5403
|
"svg",
|
|
@@ -5687,7 +5423,7 @@ function TableBody({
|
|
|
5687
5423
|
expandRow,
|
|
5688
5424
|
getRowKey
|
|
5689
5425
|
}) {
|
|
5690
|
-
const [expanded, setExpanded] =
|
|
5426
|
+
const [expanded, setExpanded] = React28.useState(() => /* @__PURE__ */ new Set());
|
|
5691
5427
|
const reduced = framerMotion.useReducedMotion();
|
|
5692
5428
|
const toggleRow = (rowKey) => {
|
|
5693
5429
|
setExpanded((prev) => {
|
|
@@ -5702,7 +5438,7 @@ function TableBody({
|
|
|
5702
5438
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
|
|
5703
5439
|
const rowKey = getRowKey(row, i);
|
|
5704
5440
|
const isExpanded = expanded.has(rowKey);
|
|
5705
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5441
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
|
|
5706
5442
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5707
5443
|
"tr",
|
|
5708
5444
|
{
|
|
@@ -5758,14 +5494,16 @@ function Pagination({
|
|
|
5758
5494
|
const matchedOption = picker.find(
|
|
5759
5495
|
(o) => o.label === options.perPage || o.value === options.perPage
|
|
5760
5496
|
);
|
|
5761
|
-
const [perPageKey, setPerPageKey] =
|
|
5497
|
+
const [perPageKey, setPerPageKey] = React28.useState(() => matchedOption?.key ?? picker[0]?.key);
|
|
5762
5498
|
const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
|
|
5763
|
-
|
|
5499
|
+
React28.useEffect(() => {
|
|
5764
5500
|
if (serverSide && options.perPage != null) {
|
|
5765
5501
|
const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
|
|
5766
5502
|
if (next) setPerPageKey(next.key);
|
|
5767
5503
|
}
|
|
5768
5504
|
}, [serverSide, options.perPage, picker]);
|
|
5505
|
+
const currentOpt = picker.find((o) => o.key === displayPerPageKey);
|
|
5506
|
+
const currentPerPageLabel = currentOpt?.label ?? currentOpt?.value ?? options.perPage ?? "";
|
|
5769
5507
|
const navBtn = (icon, disabled, onClick, title) => /* @__PURE__ */ jsxRuntime.jsx(IconButton, { type: "bordered", size: "sm", disabled, onClick, icon, title });
|
|
5770
5508
|
const chevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
|
|
5771
5509
|
const doubleChevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 5l7 7-7 7M5 5l7 7-7 7" }) });
|
|
@@ -5773,21 +5511,20 @@ function Pagination({
|
|
|
5773
5511
|
options.withPicker && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mr-auto flex items-center gap-2", children: [
|
|
5774
5512
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap text-xs text-foreground-muted", children: "Rows per page" }),
|
|
5775
5513
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5776
|
-
|
|
5514
|
+
MenuButton,
|
|
5777
5515
|
{
|
|
5516
|
+
variant: "secondary",
|
|
5778
5517
|
size: "sm",
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
items: picker
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
onPerPageChange(opt?.label ?? opt?.value ?? numKey);
|
|
5790
|
-
}
|
|
5518
|
+
side: "top",
|
|
5519
|
+
label: String(currentPerPageLabel),
|
|
5520
|
+
items: picker.map((o) => ({
|
|
5521
|
+
key: o.key,
|
|
5522
|
+
label: String(o.label ?? o.value ?? o.key),
|
|
5523
|
+
onSelect: () => {
|
|
5524
|
+
if (!serverSide) setPerPageKey(o.key);
|
|
5525
|
+
onPerPageChange(o.label ?? o.value ?? o.key);
|
|
5526
|
+
}
|
|
5527
|
+
}))
|
|
5791
5528
|
}
|
|
5792
5529
|
)
|
|
5793
5530
|
] }),
|
|
@@ -5821,14 +5558,14 @@ function Table({
|
|
|
5821
5558
|
className = "",
|
|
5822
5559
|
style
|
|
5823
5560
|
}) {
|
|
5824
|
-
const searchRef =
|
|
5825
|
-
const [searchTerm, setSearchTerm] =
|
|
5826
|
-
const [perPage, setPerPage] =
|
|
5561
|
+
const searchRef = React28.useRef(null);
|
|
5562
|
+
const [searchTerm, setSearchTerm] = React28.useState("");
|
|
5563
|
+
const [perPage, setPerPage] = React28.useState(
|
|
5827
5564
|
typeof pagination.perPage === "number" ? pagination.perPage : 15
|
|
5828
5565
|
);
|
|
5829
|
-
const [activePage, setActivePage] =
|
|
5566
|
+
const [activePage, setActivePage] = React28.useState(0);
|
|
5830
5567
|
const isServerSide = !!(pagination.enabled && pagination.serverSide);
|
|
5831
|
-
const filteredRows =
|
|
5568
|
+
const filteredRows = React28.useMemo(() => {
|
|
5832
5569
|
if (isServerSide || !searchTerm) return rows;
|
|
5833
5570
|
const term = searchTerm.toLowerCase();
|
|
5834
5571
|
return rows.filter(
|
|
@@ -5837,29 +5574,29 @@ function Table({
|
|
|
5837
5574
|
)
|
|
5838
5575
|
);
|
|
5839
5576
|
}, [rows, searchTerm, isServerSide]);
|
|
5840
|
-
const datasets =
|
|
5577
|
+
const datasets = React28.useMemo(() => {
|
|
5841
5578
|
if (isServerSide) return [rows];
|
|
5842
5579
|
return createDatasets(filteredRows, pagination.enabled ? perPage : null);
|
|
5843
5580
|
}, [filteredRows, perPage, pagination.enabled, isServerSide, rows]);
|
|
5844
|
-
const MAX_PAGE =
|
|
5581
|
+
const MAX_PAGE = React28.useMemo(() => {
|
|
5845
5582
|
if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
|
|
5846
5583
|
if (isServerSide && typeof pagination.totalCount === "number")
|
|
5847
5584
|
return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
|
|
5848
5585
|
return datasets.length ? datasets.length - 1 : 0;
|
|
5849
5586
|
}, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
|
|
5850
|
-
const currentPageRows =
|
|
5587
|
+
const currentPageRows = React28.useMemo(() => {
|
|
5851
5588
|
if (isServerSide) return rows;
|
|
5852
5589
|
return datasets[activePage] ?? [];
|
|
5853
5590
|
}, [isServerSide, rows, datasets, activePage]);
|
|
5854
|
-
|
|
5591
|
+
React28.useEffect(() => {
|
|
5855
5592
|
if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
|
|
5856
5593
|
setPerPage(pagination.perPage);
|
|
5857
5594
|
}
|
|
5858
5595
|
}, [pagination.enabled, pagination.perPage, isServerSide]);
|
|
5859
|
-
|
|
5596
|
+
React28.useEffect(() => {
|
|
5860
5597
|
if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
|
|
5861
5598
|
}, [isServerSide, pagination.perPage]);
|
|
5862
|
-
|
|
5599
|
+
React28.useEffect(() => {
|
|
5863
5600
|
if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
|
|
5864
5601
|
setActivePage(pagination.page - 1);
|
|
5865
5602
|
}, [isServerSide, pagination.page]);
|
|
@@ -5943,7 +5680,7 @@ function TableSkeletonBody({
|
|
|
5943
5680
|
)) });
|
|
5944
5681
|
}
|
|
5945
5682
|
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
|
|
5946
|
-
const id =
|
|
5683
|
+
const id = React28.useId();
|
|
5947
5684
|
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5948
5685
|
SwitchPrimitive__namespace.Root,
|
|
5949
5686
|
{
|
|
@@ -6127,7 +5864,7 @@ function Sidebar({
|
|
|
6127
5864
|
}
|
|
6128
5865
|
) });
|
|
6129
5866
|
}
|
|
6130
|
-
var MegaMenuContext =
|
|
5867
|
+
var MegaMenuContext = React28.createContext({ align: "start" });
|
|
6131
5868
|
function MegaMenu({
|
|
6132
5869
|
children,
|
|
6133
5870
|
align = "start",
|
|
@@ -6158,7 +5895,7 @@ function MegaMenu({
|
|
|
6158
5895
|
}
|
|
6159
5896
|
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";
|
|
6160
5897
|
function MegaMenuItem({ label, icon, href, children, className = "" }) {
|
|
6161
|
-
const { align } =
|
|
5898
|
+
const { align } = React28.useContext(MegaMenuContext);
|
|
6162
5899
|
const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
|
|
6163
5900
|
if (!children) {
|
|
6164
5901
|
return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: [TOP_ITEM, className].filter(Boolean).join(" "), children: [
|
|
@@ -6243,8 +5980,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
6243
5980
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
6244
5981
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
|
|
6245
5982
|
}
|
|
6246
|
-
var elementsOfType = (children, type) =>
|
|
6247
|
-
(c) =>
|
|
5983
|
+
var elementsOfType = (children, type) => React28__default.default.Children.toArray(children).filter(
|
|
5984
|
+
(c) => React28__default.default.isValidElement(c) && c.type === type
|
|
6248
5985
|
);
|
|
6249
5986
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6250
5987
|
"svg",
|
|
@@ -6281,9 +6018,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
6281
6018
|
);
|
|
6282
6019
|
}
|
|
6283
6020
|
function MobilePanel({ panel, onNavigate }) {
|
|
6284
|
-
const nodes =
|
|
6021
|
+
const nodes = React28__default.default.Children.toArray(panel.props.children);
|
|
6285
6022
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
6286
|
-
if (!
|
|
6023
|
+
if (!React28__default.default.isValidElement(node)) return null;
|
|
6287
6024
|
const el = node;
|
|
6288
6025
|
if (el.type === MegaMenuSection) {
|
|
6289
6026
|
const { title, children } = el.props;
|
|
@@ -6302,8 +6039,8 @@ function MegaMenuMobile({
|
|
|
6302
6039
|
children,
|
|
6303
6040
|
label
|
|
6304
6041
|
}) {
|
|
6305
|
-
const [open, setOpen] =
|
|
6306
|
-
const [expanded, setExpanded] =
|
|
6042
|
+
const [open, setOpen] = React28.useState(false);
|
|
6043
|
+
const [expanded, setExpanded] = React28.useState(null);
|
|
6307
6044
|
const items = elementsOfType(children, MegaMenuItem);
|
|
6308
6045
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
|
|
6309
6046
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6376,17 +6113,17 @@ function AppShell({
|
|
|
6376
6113
|
children,
|
|
6377
6114
|
className = ""
|
|
6378
6115
|
}) {
|
|
6379
|
-
const [expanded, setExpanded] =
|
|
6380
|
-
const [isMobile, setIsMobile] =
|
|
6381
|
-
const [mobileOpen, setMobileOpen] =
|
|
6382
|
-
|
|
6116
|
+
const [expanded, setExpanded] = React28.useState(sidebarDefaultExpanded);
|
|
6117
|
+
const [isMobile, setIsMobile] = React28.useState(false);
|
|
6118
|
+
const [mobileOpen, setMobileOpen] = React28.useState(false);
|
|
6119
|
+
React28.useEffect(() => {
|
|
6383
6120
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
6384
6121
|
const update = (e) => setIsMobile(e.matches);
|
|
6385
6122
|
update(mq);
|
|
6386
6123
|
mq.addEventListener("change", update);
|
|
6387
6124
|
return () => mq.removeEventListener("change", update);
|
|
6388
6125
|
}, []);
|
|
6389
|
-
|
|
6126
|
+
React28.useEffect(() => {
|
|
6390
6127
|
if (!isMobile) setMobileOpen(false);
|
|
6391
6128
|
}, [isMobile]);
|
|
6392
6129
|
const hasSidebar = sidebarSections.length > 0;
|
|
@@ -6513,7 +6250,7 @@ function SecureLayout({
|
|
|
6513
6250
|
className = ""
|
|
6514
6251
|
}) {
|
|
6515
6252
|
const reduced = framerMotion.useReducedMotion();
|
|
6516
|
-
const cbs =
|
|
6253
|
+
const cbs = React28.useRef({ canAccess, onGranted, onDeny });
|
|
6517
6254
|
cbs.current = { canAccess, onGranted, onDeny };
|
|
6518
6255
|
const rolesKey = JSON.stringify(roles);
|
|
6519
6256
|
const requiredRolesKey = JSON.stringify(requiredRoles);
|
|
@@ -6528,10 +6265,10 @@ function SecureLayout({
|
|
|
6528
6265
|
if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
|
|
6529
6266
|
return true;
|
|
6530
6267
|
};
|
|
6531
|
-
const [state, setState] =
|
|
6268
|
+
const [state, setState] = React28.useState(
|
|
6532
6269
|
() => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
|
|
6533
6270
|
);
|
|
6534
|
-
|
|
6271
|
+
React28.useEffect(() => {
|
|
6535
6272
|
let cancelled = false;
|
|
6536
6273
|
const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
|
|
6537
6274
|
const finish = (ok) => {
|
|
@@ -6692,10 +6429,10 @@ function ThemeProvider({
|
|
|
6692
6429
|
className = "",
|
|
6693
6430
|
style
|
|
6694
6431
|
}) {
|
|
6695
|
-
const id =
|
|
6432
|
+
const id = React28__default.default.useId().replace(/:/g, "");
|
|
6696
6433
|
const scopeClass = `geo-th-${id}`;
|
|
6697
|
-
const divRef =
|
|
6698
|
-
|
|
6434
|
+
const divRef = React28.useRef(null);
|
|
6435
|
+
React28.useEffect(() => {
|
|
6699
6436
|
const el = divRef.current;
|
|
6700
6437
|
if (!el) return;
|
|
6701
6438
|
if (colorScheme === "auto") return;
|
|
@@ -6710,8 +6447,8 @@ function ThemeProvider({
|
|
|
6710
6447
|
}
|
|
6711
6448
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
6712
6449
|
}, [colorScheme]);
|
|
6713
|
-
const lightVars =
|
|
6714
|
-
const darkVarStr =
|
|
6450
|
+
const lightVars = React28.useMemo(() => toCssVars(theme), [theme]);
|
|
6451
|
+
const darkVarStr = React28.useMemo(() => {
|
|
6715
6452
|
if (!darkTheme) return "";
|
|
6716
6453
|
const dvars = toCssVars(darkTheme);
|
|
6717
6454
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -6753,7 +6490,7 @@ function NumberInput({
|
|
|
6753
6490
|
readOnly = false,
|
|
6754
6491
|
precision
|
|
6755
6492
|
}) {
|
|
6756
|
-
const errorId =
|
|
6493
|
+
const errorId = React28.useId();
|
|
6757
6494
|
const hasError = errorMessage != null;
|
|
6758
6495
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
6759
6496
|
const round = (n) => {
|
|
@@ -6884,8 +6621,8 @@ function Password({
|
|
|
6884
6621
|
showIcon,
|
|
6885
6622
|
hideIcon
|
|
6886
6623
|
}) {
|
|
6887
|
-
const [visible, setVisible] =
|
|
6888
|
-
const errorId =
|
|
6624
|
+
const [visible, setVisible] = React28.useState(false);
|
|
6625
|
+
const errorId = React28.useId();
|
|
6889
6626
|
const hasError = errorMessage != null;
|
|
6890
6627
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6891
6628
|
Field,
|
|
@@ -6958,7 +6695,7 @@ function Checkbox({
|
|
|
6958
6695
|
}) {
|
|
6959
6696
|
const isChecked = checked ?? value ?? false;
|
|
6960
6697
|
const labelFirst = labelPosition === "left";
|
|
6961
|
-
const errorId =
|
|
6698
|
+
const errorId = React28.useId();
|
|
6962
6699
|
const hasError = errorMessage != null;
|
|
6963
6700
|
const box = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6964
6701
|
CheckboxPrimitive__namespace.Root,
|
|
@@ -7066,8 +6803,8 @@ function RadioGroup({
|
|
|
7066
6803
|
className,
|
|
7067
6804
|
errorMessage
|
|
7068
6805
|
}) {
|
|
7069
|
-
const errorId =
|
|
7070
|
-
const groupId =
|
|
6806
|
+
const errorId = React28.useId();
|
|
6807
|
+
const groupId = React28.useId();
|
|
7071
6808
|
const hasError = errorMessage != null;
|
|
7072
6809
|
const labelFirst = labelPosition === "left";
|
|
7073
6810
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7150,77 +6887,379 @@ function RadioGroup({
|
|
|
7150
6887
|
}
|
|
7151
6888
|
);
|
|
7152
6889
|
}
|
|
7153
|
-
function Switch({
|
|
7154
|
-
checked,
|
|
7155
|
-
defaultChecked = false,
|
|
7156
|
-
onChange,
|
|
7157
|
-
checkedIcon,
|
|
7158
|
-
uncheckedIcon,
|
|
6890
|
+
function Switch({
|
|
6891
|
+
checked,
|
|
6892
|
+
defaultChecked = false,
|
|
6893
|
+
onChange,
|
|
6894
|
+
checkedIcon,
|
|
6895
|
+
uncheckedIcon,
|
|
6896
|
+
label,
|
|
6897
|
+
layout = "horizontal",
|
|
6898
|
+
helperText,
|
|
6899
|
+
className,
|
|
6900
|
+
offLabel,
|
|
6901
|
+
onLabel,
|
|
6902
|
+
name,
|
|
6903
|
+
required,
|
|
6904
|
+
disabled,
|
|
6905
|
+
errorMessage
|
|
6906
|
+
}) {
|
|
6907
|
+
const id = React28.useId();
|
|
6908
|
+
const errorId = React28.useId();
|
|
6909
|
+
const hasError = errorMessage != null;
|
|
6910
|
+
const isControlled = checked !== void 0;
|
|
6911
|
+
const [internal, setInternal] = React28.useState(defaultChecked);
|
|
6912
|
+
const isOn = isControlled ? checked : internal;
|
|
6913
|
+
const handle = (c) => {
|
|
6914
|
+
if (!isControlled) setInternal(c);
|
|
6915
|
+
onChange?.({ target: { checked: c, name } });
|
|
6916
|
+
};
|
|
6917
|
+
const stateLabel = (active) => [
|
|
6918
|
+
"text-sm select-none transition-colors",
|
|
6919
|
+
active ? "text-foreground font-medium" : "text-foreground-muted",
|
|
6920
|
+
disabled ? "opacity-50" : "cursor-pointer"
|
|
6921
|
+
].filter(Boolean).join(" ");
|
|
6922
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6923
|
+
Field,
|
|
6924
|
+
{
|
|
6925
|
+
className,
|
|
6926
|
+
label,
|
|
6927
|
+
htmlFor: id,
|
|
6928
|
+
errorId,
|
|
6929
|
+
errorMessage,
|
|
6930
|
+
layout,
|
|
6931
|
+
required,
|
|
6932
|
+
helperText,
|
|
6933
|
+
labelAlign: "center",
|
|
6934
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
6935
|
+
offLabel != null && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: stateLabel(!isOn), children: offLabel }),
|
|
6936
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6937
|
+
SwitchPrimitive__namespace.Root,
|
|
6938
|
+
{
|
|
6939
|
+
id,
|
|
6940
|
+
name,
|
|
6941
|
+
checked: isOn,
|
|
6942
|
+
onCheckedChange: handle,
|
|
6943
|
+
disabled,
|
|
6944
|
+
required,
|
|
6945
|
+
"aria-invalid": hasError || void 0,
|
|
6946
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
6947
|
+
className: "relative inline-flex h-6 w-11 flex-shrink-0 items-center rounded-full bg-foreground-secondary data-[state=checked]:bg-accent transition-colors focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring disabled:opacity-50 disabled:cursor-not-allowed",
|
|
6948
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6949
|
+
SwitchPrimitive__namespace.Thumb,
|
|
6950
|
+
{
|
|
6951
|
+
className: "pointer-events-none flex h-5 w-5 items-center justify-center rounded-full bg-background text-foreground shadow transition-transform duration-200 data-[state=checked]:translate-x-[22px] data-[state=unchecked]:translate-x-[2px]",
|
|
6952
|
+
children: checkedIcon && uncheckedIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center justify-center w-3 h-3", children: isOn ? checkedIcon : uncheckedIcon }) : null
|
|
6953
|
+
}
|
|
6954
|
+
)
|
|
6955
|
+
}
|
|
6956
|
+
),
|
|
6957
|
+
onLabel != null && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: stateLabel(isOn), children: onLabel })
|
|
6958
|
+
] })
|
|
6959
|
+
}
|
|
6960
|
+
);
|
|
6961
|
+
}
|
|
6962
|
+
function Tag({ children, onRemove, removeLabel, disabled }) {
|
|
6963
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 rounded-md border border-border bg-surface-raised text-foreground text-xs pl-2 pr-1 py-0.5 max-w-full", children: [
|
|
6964
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children }),
|
|
6965
|
+
onRemove && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6966
|
+
"button",
|
|
6967
|
+
{
|
|
6968
|
+
type: "button",
|
|
6969
|
+
disabled,
|
|
6970
|
+
onClick: (e) => {
|
|
6971
|
+
e.stopPropagation();
|
|
6972
|
+
onRemove();
|
|
6973
|
+
},
|
|
6974
|
+
"aria-label": removeLabel ?? "Remove",
|
|
6975
|
+
className: "inline-flex items-center justify-center w-4 h-4 flex-shrink-0 rounded text-foreground-muted hover:text-status-error hover:bg-surface transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-accent disabled:cursor-not-allowed",
|
|
6976
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "10", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
|
|
6977
|
+
}
|
|
6978
|
+
)
|
|
6979
|
+
] });
|
|
6980
|
+
}
|
|
6981
|
+
function MultiTagRow({
|
|
6982
|
+
values,
|
|
6983
|
+
disabled,
|
|
6984
|
+
labelFor,
|
|
6985
|
+
onRemove
|
|
6986
|
+
}) {
|
|
6987
|
+
const wrapRef = React28.useRef(null);
|
|
6988
|
+
const measureRef = React28.useRef(null);
|
|
6989
|
+
const [visibleCount, setVisibleCount] = React28.useState(values.length);
|
|
6990
|
+
const key = values.map(String).join("|");
|
|
6991
|
+
React28.useLayoutEffect(() => {
|
|
6992
|
+
const wrap = wrapRef.current;
|
|
6993
|
+
const measure = measureRef.current;
|
|
6994
|
+
if (!wrap || !measure) return;
|
|
6995
|
+
const GAP = 6;
|
|
6996
|
+
const recompute = () => {
|
|
6997
|
+
const avail = wrap.clientWidth;
|
|
6998
|
+
const tagEls = Array.from(measure.querySelectorAll("[data-mt]"));
|
|
6999
|
+
const moreEl = measure.querySelector("[data-mm]");
|
|
7000
|
+
const widths = tagEls.map((e) => e.offsetWidth);
|
|
7001
|
+
const moreW = moreEl ? moreEl.offsetWidth : 0;
|
|
7002
|
+
if (widths.length === 0) {
|
|
7003
|
+
setVisibleCount(0);
|
|
7004
|
+
return;
|
|
7005
|
+
}
|
|
7006
|
+
let used = 0;
|
|
7007
|
+
let count = 0;
|
|
7008
|
+
for (let i = 0; i < widths.length; i++) {
|
|
7009
|
+
const w = widths[i] + (i > 0 ? GAP : 0);
|
|
7010
|
+
if (used + w <= avail) {
|
|
7011
|
+
used += w;
|
|
7012
|
+
count++;
|
|
7013
|
+
} else break;
|
|
7014
|
+
}
|
|
7015
|
+
if (count < widths.length) {
|
|
7016
|
+
while (count > 0) {
|
|
7017
|
+
let t = 0;
|
|
7018
|
+
for (let i = 0; i < count; i++) t += widths[i] + (i > 0 ? GAP : 0);
|
|
7019
|
+
t += GAP + moreW;
|
|
7020
|
+
if (t <= avail) break;
|
|
7021
|
+
count--;
|
|
7022
|
+
}
|
|
7023
|
+
}
|
|
7024
|
+
setVisibleCount(count);
|
|
7025
|
+
};
|
|
7026
|
+
recompute();
|
|
7027
|
+
const ro = new ResizeObserver(recompute);
|
|
7028
|
+
ro.observe(wrap);
|
|
7029
|
+
return () => ro.disconnect();
|
|
7030
|
+
}, [key]);
|
|
7031
|
+
const hidden = values.length - visibleCount;
|
|
7032
|
+
const moreChip = (n) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center flex-shrink-0 rounded-md border border-border bg-surface-raised text-foreground-secondary text-xs px-2 py-0.5", children: [
|
|
7033
|
+
"+",
|
|
7034
|
+
n,
|
|
7035
|
+
" more"
|
|
7036
|
+
] });
|
|
7037
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrapRef, className: "relative flex-1 min-w-0 flex flex-nowrap items-center gap-1.5 overflow-hidden", children: [
|
|
7038
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7039
|
+
"div",
|
|
7040
|
+
{
|
|
7041
|
+
ref: measureRef,
|
|
7042
|
+
"aria-hidden": "true",
|
|
7043
|
+
className: "absolute invisible pointer-events-none flex flex-nowrap items-center gap-1.5",
|
|
7044
|
+
style: { left: -9999, top: -9999 },
|
|
7045
|
+
children: [
|
|
7046
|
+
values.map((val) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-mt": true, children: /* @__PURE__ */ jsxRuntime.jsx(Tag, { removeLabel: "x", onRemove: () => {
|
|
7047
|
+
}, children: labelFor(val) }) }, `m-${val}`)),
|
|
7048
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-mm": true, children: moreChip(values.length) })
|
|
7049
|
+
]
|
|
7050
|
+
}
|
|
7051
|
+
),
|
|
7052
|
+
values.slice(0, visibleCount).map((val) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7053
|
+
Tag,
|
|
7054
|
+
{
|
|
7055
|
+
disabled,
|
|
7056
|
+
removeLabel: `Remove ${labelFor(val)}`,
|
|
7057
|
+
onRemove: () => onRemove(val),
|
|
7058
|
+
children: labelFor(val)
|
|
7059
|
+
},
|
|
7060
|
+
String(val)
|
|
7061
|
+
)),
|
|
7062
|
+
hidden > 0 && moreChip(hidden)
|
|
7063
|
+
] });
|
|
7064
|
+
}
|
|
7065
|
+
function Dropdown({
|
|
7066
|
+
isMultiselect = false,
|
|
7067
|
+
hasSearch = true,
|
|
7159
7068
|
label,
|
|
7069
|
+
name,
|
|
7070
|
+
value,
|
|
7071
|
+
onChange,
|
|
7072
|
+
disabled,
|
|
7160
7073
|
layout = "horizontal",
|
|
7161
7074
|
helperText,
|
|
7162
|
-
className,
|
|
7163
|
-
offLabel,
|
|
7164
|
-
onLabel,
|
|
7165
|
-
name,
|
|
7166
7075
|
required,
|
|
7167
|
-
|
|
7168
|
-
|
|
7076
|
+
errorMessage,
|
|
7077
|
+
style = {},
|
|
7078
|
+
htmlFor,
|
|
7079
|
+
items = [],
|
|
7080
|
+
labelStyle = {},
|
|
7081
|
+
placeholder,
|
|
7082
|
+
size = "md",
|
|
7083
|
+
className = ""
|
|
7169
7084
|
}) {
|
|
7170
|
-
const
|
|
7171
|
-
const
|
|
7085
|
+
const [open, setOpen] = React28.useState(false);
|
|
7086
|
+
const [selectedItems, setSelectedItems] = React28.useState([]);
|
|
7087
|
+
const [searchTerm, setSearchTerm] = React28.useState("");
|
|
7088
|
+
const [innerItems, setInnerItems] = React28.useState([]);
|
|
7089
|
+
const errorId = React28.useId();
|
|
7172
7090
|
const hasError = errorMessage != null;
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
if (
|
|
7178
|
-
|
|
7091
|
+
React28.useEffect(() => {
|
|
7092
|
+
setInnerItems(items);
|
|
7093
|
+
}, [items]);
|
|
7094
|
+
React28.useEffect(() => {
|
|
7095
|
+
if (isMultiselect && Array.isArray(value)) {
|
|
7096
|
+
setSelectedItems(value);
|
|
7097
|
+
}
|
|
7098
|
+
}, [isMultiselect, value]);
|
|
7099
|
+
const selectItem = (key) => {
|
|
7100
|
+
if (isMultiselect) {
|
|
7101
|
+
const next = selectedItems.includes(key) ? selectedItems.filter((it) => it !== key) : [...selectedItems, key];
|
|
7102
|
+
setSelectedItems(next);
|
|
7103
|
+
onChange?.({ target: { value: next, id: htmlFor, name } });
|
|
7104
|
+
} else {
|
|
7105
|
+
setSelectedItems([key]);
|
|
7106
|
+
onChange?.({ target: { value: key, id: htmlFor, name } });
|
|
7107
|
+
setOpen(false);
|
|
7108
|
+
}
|
|
7179
7109
|
};
|
|
7180
|
-
const
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7110
|
+
const removeSelected = (key) => {
|
|
7111
|
+
if (isMultiselect) {
|
|
7112
|
+
const next = selectedItems.filter((it) => it !== key);
|
|
7113
|
+
setSelectedItems(next);
|
|
7114
|
+
onChange?.({ target: { value: next, id: htmlFor, name } });
|
|
7115
|
+
} else {
|
|
7116
|
+
setSelectedItems([]);
|
|
7117
|
+
onChange?.({ target: { value: "", id: htmlFor, name } });
|
|
7118
|
+
}
|
|
7119
|
+
};
|
|
7120
|
+
const labelFor = (key) => innerItems.find((it) => it.key === key)?.label ?? String(key);
|
|
7121
|
+
const onSearchChange = (e) => {
|
|
7122
|
+
const term = e.target.value;
|
|
7123
|
+
setSearchTerm(term);
|
|
7124
|
+
setInnerItems(
|
|
7125
|
+
term.trim() === "" ? items : items.filter(
|
|
7126
|
+
(it) => String(it.label).toLowerCase().includes(term.toLowerCase())
|
|
7127
|
+
)
|
|
7128
|
+
);
|
|
7129
|
+
};
|
|
7130
|
+
const isSelected = (key) => Array.isArray(value) ? value.includes(key) : value === key;
|
|
7131
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: className || void 0, children: [
|
|
7132
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7133
|
+
"div",
|
|
7134
|
+
{
|
|
7135
|
+
className: `flex ${layout === "vertical" ? "flex-col gap-1.5" : "flex-row items-start gap-3"}`,
|
|
7136
|
+
children: [
|
|
7137
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7138
|
+
FieldLabel,
|
|
7139
|
+
{
|
|
7140
|
+
label,
|
|
7141
|
+
htmlFor,
|
|
7142
|
+
required,
|
|
7143
|
+
helperText,
|
|
7144
|
+
horizontal: layout === "horizontal",
|
|
7145
|
+
style: labelStyle
|
|
7146
|
+
}
|
|
7147
|
+
),
|
|
7148
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
7149
|
+
/* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7150
|
+
"div",
|
|
7213
7151
|
{
|
|
7214
|
-
|
|
7215
|
-
|
|
7152
|
+
id: htmlFor,
|
|
7153
|
+
role: "combobox",
|
|
7154
|
+
"aria-expanded": open,
|
|
7155
|
+
"aria-haspopup": "listbox",
|
|
7156
|
+
"aria-invalid": hasError || void 0,
|
|
7157
|
+
"aria-describedby": hasError ? errorId : void 0,
|
|
7158
|
+
style: { width: 240, ...style },
|
|
7159
|
+
className: `flex items-center justify-between gap-2 cursor-pointer select-none min-h-[36px] px-3 py-1.5 ${fieldShell({ size, hasError, disabled, sized: false })}`,
|
|
7160
|
+
tabIndex: disabled ? -1 : 0,
|
|
7161
|
+
onKeyDown: (e) => {
|
|
7162
|
+
if (disabled) return;
|
|
7163
|
+
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
7164
|
+
e.preventDefault();
|
|
7165
|
+
setOpen(true);
|
|
7166
|
+
}
|
|
7167
|
+
},
|
|
7168
|
+
children: [
|
|
7169
|
+
!value || Array.isArray(value) && value.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 min-w-0 truncate text-foreground-muted text-sm", children: placeholder }) : Array.isArray(value) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7170
|
+
MultiTagRow,
|
|
7171
|
+
{
|
|
7172
|
+
values: value,
|
|
7173
|
+
disabled,
|
|
7174
|
+
labelFor,
|
|
7175
|
+
onRemove: removeSelected
|
|
7176
|
+
}
|
|
7177
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0 flex items-center overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7178
|
+
Tag,
|
|
7179
|
+
{
|
|
7180
|
+
disabled,
|
|
7181
|
+
removeLabel: `Remove ${labelFor(value)}`,
|
|
7182
|
+
onRemove: () => removeSelected(value),
|
|
7183
|
+
children: labelFor(value)
|
|
7184
|
+
}
|
|
7185
|
+
) }),
|
|
7186
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 text-foreground-muted transition-transform duration-200 ${open ? "rotate-180" : "rotate-0"}`, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }) })
|
|
7187
|
+
]
|
|
7216
7188
|
}
|
|
7217
|
-
)
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7189
|
+
) }),
|
|
7190
|
+
/* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7191
|
+
Popover__namespace.Content,
|
|
7192
|
+
{
|
|
7193
|
+
align: "start",
|
|
7194
|
+
sideOffset: 4,
|
|
7195
|
+
style: { width: style?.width || 240 },
|
|
7196
|
+
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-2 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7197
|
+
onInteractOutside: () => setOpen(false),
|
|
7198
|
+
children: [
|
|
7199
|
+
hasSearch && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7200
|
+
SearchInput_default,
|
|
7201
|
+
{
|
|
7202
|
+
style: { width: "100%" },
|
|
7203
|
+
inputStyle: { width: "100%" },
|
|
7204
|
+
value: searchTerm,
|
|
7205
|
+
onChange: onSearchChange,
|
|
7206
|
+
placeholder: "Search..."
|
|
7207
|
+
}
|
|
7208
|
+
) }),
|
|
7209
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", "aria-multiselectable": isMultiselect, className: "max-h-40 overflow-y-auto", children: innerItems.map((item) => (
|
|
7210
|
+
// aria-rowindex was previously set here but
|
|
7211
|
+
// it's invalid ARIA on role="option" (it
|
|
7212
|
+
// belongs on rows of a grid/treegrid). Dropped.
|
|
7213
|
+
// tabIndex={0} + Enter/Space handler makes the
|
|
7214
|
+
// option keyboard-activatable; the full
|
|
7215
|
+
// combobox roving-tabindex pattern is deferred
|
|
7216
|
+
// until the planned Phase-5 rewrite.
|
|
7217
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7218
|
+
"div",
|
|
7219
|
+
{
|
|
7220
|
+
role: "option",
|
|
7221
|
+
"aria-selected": isSelected(item.key),
|
|
7222
|
+
tabIndex: 0,
|
|
7223
|
+
className: `flex items-center justify-between p-2 hover:bg-accent hover:text-accent-fg transition-colors duration-150 text-sm rounded-lg cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${selectedItems.includes(item.key) ? "bg-surface-raised text-foreground" : "text-foreground"}`,
|
|
7224
|
+
onClick: () => selectItem(item.key),
|
|
7225
|
+
onKeyDown: (e) => {
|
|
7226
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
7227
|
+
e.preventDefault();
|
|
7228
|
+
selectItem(item.key);
|
|
7229
|
+
}
|
|
7230
|
+
},
|
|
7231
|
+
children: [
|
|
7232
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
7233
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { children: item.icon }),
|
|
7234
|
+
item.label
|
|
7235
|
+
] }),
|
|
7236
|
+
isSelected(item.key) && // currentColor — checkmark follows
|
|
7237
|
+
// the item's text colour, which
|
|
7238
|
+
// flips automatically on hover.
|
|
7239
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7240
|
+
"path",
|
|
7241
|
+
{
|
|
7242
|
+
d: "M4 10l4.5 4.5L16 6",
|
|
7243
|
+
stroke: "currentColor",
|
|
7244
|
+
strokeWidth: "2",
|
|
7245
|
+
strokeLinecap: "round",
|
|
7246
|
+
strokeLinejoin: "round"
|
|
7247
|
+
}
|
|
7248
|
+
) })
|
|
7249
|
+
]
|
|
7250
|
+
},
|
|
7251
|
+
item.key
|
|
7252
|
+
)
|
|
7253
|
+
)) })
|
|
7254
|
+
]
|
|
7255
|
+
}
|
|
7256
|
+
) })
|
|
7257
|
+
] })
|
|
7258
|
+
]
|
|
7259
|
+
}
|
|
7260
|
+
),
|
|
7261
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
7262
|
+
] });
|
|
7224
7263
|
}
|
|
7225
7264
|
function AutoComplete({
|
|
7226
7265
|
disabled,
|
|
@@ -7244,19 +7283,19 @@ function AutoComplete({
|
|
|
7244
7283
|
required,
|
|
7245
7284
|
htmlFor
|
|
7246
7285
|
}) {
|
|
7247
|
-
const errorId =
|
|
7286
|
+
const errorId = React28.useId();
|
|
7248
7287
|
const hasError = errorMessage != null;
|
|
7249
|
-
const [term, setTerm] =
|
|
7250
|
-
const [open, setOpen] =
|
|
7251
|
-
const [asyncItems, setAsyncItems] =
|
|
7252
|
-
const [loading, setLoading] =
|
|
7288
|
+
const [term, setTerm] = React28.useState("");
|
|
7289
|
+
const [open, setOpen] = React28.useState(false);
|
|
7290
|
+
const [asyncItems, setAsyncItems] = React28.useState([]);
|
|
7291
|
+
const [loading, setLoading] = React28.useState(false);
|
|
7253
7292
|
const isAsync = typeof onSearch === "function";
|
|
7254
|
-
const debounceRef =
|
|
7255
|
-
const requestIdRef =
|
|
7293
|
+
const debounceRef = React28.useRef(null);
|
|
7294
|
+
const requestIdRef = React28.useRef(0);
|
|
7256
7295
|
const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
|
|
7257
7296
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
7258
7297
|
) : [];
|
|
7259
|
-
|
|
7298
|
+
React28.useEffect(() => {
|
|
7260
7299
|
if (!isAsync) return;
|
|
7261
7300
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
7262
7301
|
if (!term.trim()) {
|
|
@@ -7412,15 +7451,15 @@ function TreeSelect({
|
|
|
7412
7451
|
defaultExpandedKeys = [],
|
|
7413
7452
|
size = "md"
|
|
7414
7453
|
}) {
|
|
7415
|
-
const errorId =
|
|
7454
|
+
const errorId = React28.useId();
|
|
7416
7455
|
const hasError = errorMessage != null;
|
|
7417
|
-
const [open, setOpen] =
|
|
7418
|
-
const [expanded, setExpanded] =
|
|
7419
|
-
const [activeIndex, setActiveIndex] =
|
|
7420
|
-
const listRef =
|
|
7421
|
-
const visible =
|
|
7422
|
-
const didSyncOnOpenRef =
|
|
7423
|
-
|
|
7456
|
+
const [open, setOpen] = React28.useState(false);
|
|
7457
|
+
const [expanded, setExpanded] = React28.useState(() => new Set(defaultExpandedKeys));
|
|
7458
|
+
const [activeIndex, setActiveIndex] = React28.useState(0);
|
|
7459
|
+
const listRef = React28.useRef(null);
|
|
7460
|
+
const visible = React28.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
|
|
7461
|
+
const didSyncOnOpenRef = React28.useRef(false);
|
|
7462
|
+
React28.useEffect(() => {
|
|
7424
7463
|
if (!open) {
|
|
7425
7464
|
didSyncOnOpenRef.current = false;
|
|
7426
7465
|
return;
|
|
@@ -7430,7 +7469,7 @@ function TreeSelect({
|
|
|
7430
7469
|
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
7431
7470
|
didSyncOnOpenRef.current = true;
|
|
7432
7471
|
}, [open, value]);
|
|
7433
|
-
const selectedNode =
|
|
7472
|
+
const selectedNode = React28.useMemo(
|
|
7434
7473
|
() => value != null ? findNodeByKey(items, value) : null,
|
|
7435
7474
|
[items, value]
|
|
7436
7475
|
);
|
|
@@ -7661,11 +7700,11 @@ function FileInput({
|
|
|
7661
7700
|
required,
|
|
7662
7701
|
icon
|
|
7663
7702
|
}) {
|
|
7664
|
-
const inputRef =
|
|
7665
|
-
const errorId =
|
|
7666
|
-
const [files, setFiles] =
|
|
7667
|
-
const [dragging, setDragging] =
|
|
7668
|
-
const [sizeError, setSizeError] =
|
|
7703
|
+
const inputRef = React28.useRef(null);
|
|
7704
|
+
const errorId = React28.useId();
|
|
7705
|
+
const [files, setFiles] = React28.useState([]);
|
|
7706
|
+
const [dragging, setDragging] = React28.useState(false);
|
|
7707
|
+
const [sizeError, setSizeError] = React28.useState(null);
|
|
7669
7708
|
const effectiveError = errorMessage ?? sizeError ?? void 0;
|
|
7670
7709
|
const openPicker = () => {
|
|
7671
7710
|
if (!disabled) inputRef.current?.click();
|
|
@@ -7856,30 +7895,30 @@ function DatePicker({
|
|
|
7856
7895
|
size = "md",
|
|
7857
7896
|
className = ""
|
|
7858
7897
|
}) {
|
|
7859
|
-
const errorId =
|
|
7898
|
+
const errorId = React28.useId();
|
|
7860
7899
|
const hasError = errorMessage != null;
|
|
7861
|
-
const [open, setOpen] =
|
|
7862
|
-
const [viewMonth, setViewMonth] =
|
|
7863
|
-
const [focusDate, setFocusDate] =
|
|
7864
|
-
const [view, setView] =
|
|
7865
|
-
const gridRef =
|
|
7866
|
-
|
|
7900
|
+
const [open, setOpen] = React28.useState(false);
|
|
7901
|
+
const [viewMonth, setViewMonth] = React28.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
7902
|
+
const [focusDate, setFocusDate] = React28.useState(() => value ?? /* @__PURE__ */ new Date());
|
|
7903
|
+
const [view, setView] = React28.useState("days");
|
|
7904
|
+
const gridRef = React28.useRef(null);
|
|
7905
|
+
React28.useEffect(() => {
|
|
7867
7906
|
if (!open) return;
|
|
7868
7907
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7869
7908
|
setViewMonth(startOfMonth2(target));
|
|
7870
7909
|
setFocusDate(target);
|
|
7871
7910
|
setView("days");
|
|
7872
7911
|
}, [open, value]);
|
|
7873
|
-
|
|
7912
|
+
React28.useEffect(() => {
|
|
7874
7913
|
if (!open) return;
|
|
7875
7914
|
const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
|
|
7876
7915
|
cell?.focus();
|
|
7877
7916
|
}, [open, focusDate]);
|
|
7878
|
-
const weekdays =
|
|
7917
|
+
const weekdays = React28.useMemo(() => {
|
|
7879
7918
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
7880
7919
|
return ordered;
|
|
7881
7920
|
}, [weekStartsOn]);
|
|
7882
|
-
const grid =
|
|
7921
|
+
const grid = React28.useMemo(() => buildGrid2(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
7883
7922
|
const isDisabled = (d) => {
|
|
7884
7923
|
if (min && d < min) return true;
|
|
7885
7924
|
if (max && d > max) return true;
|
|
@@ -8169,10 +8208,10 @@ function TextArea({
|
|
|
8169
8208
|
style,
|
|
8170
8209
|
inputStyle
|
|
8171
8210
|
}) {
|
|
8172
|
-
const errorId =
|
|
8211
|
+
const errorId = React28.useId();
|
|
8173
8212
|
const hasError = errorMessage != null;
|
|
8174
|
-
const ref =
|
|
8175
|
-
|
|
8213
|
+
const ref = React28.useRef(null);
|
|
8214
|
+
React28.useLayoutEffect(() => {
|
|
8176
8215
|
if (!autoGrow) return;
|
|
8177
8216
|
const el = ref.current;
|
|
8178
8217
|
if (!el) return;
|
|
@@ -8244,14 +8283,14 @@ function Slider({
|
|
|
8244
8283
|
name,
|
|
8245
8284
|
htmlFor
|
|
8246
8285
|
}) {
|
|
8247
|
-
const errorId =
|
|
8286
|
+
const errorId = React28.useId();
|
|
8248
8287
|
const hasError = errorMessage != null;
|
|
8249
8288
|
const isRange = Array.isArray(value ?? defaultValue);
|
|
8250
|
-
const [internal, setInternal] =
|
|
8289
|
+
const [internal, setInternal] = React28.useState(
|
|
8251
8290
|
() => toArray(value) ?? toArray(defaultValue) ?? [min]
|
|
8252
8291
|
);
|
|
8253
8292
|
const current = toArray(value) ?? internal;
|
|
8254
|
-
const [dragging, setDragging] =
|
|
8293
|
+
const [dragging, setDragging] = React28.useState(false);
|
|
8255
8294
|
const emit = (arr) => {
|
|
8256
8295
|
setInternal(arr);
|
|
8257
8296
|
const next = isRange ? [arr[0], arr[1]] : arr[0];
|
|
@@ -8346,11 +8385,11 @@ function TagsInput({
|
|
|
8346
8385
|
validate,
|
|
8347
8386
|
separators = ["Enter", ","]
|
|
8348
8387
|
}) {
|
|
8349
|
-
const errorId =
|
|
8350
|
-
const inputRef =
|
|
8351
|
-
const [internal, setInternal] =
|
|
8352
|
-
const [draft, setDraft] =
|
|
8353
|
-
const [localError, setLocalError] =
|
|
8388
|
+
const errorId = React28.useId();
|
|
8389
|
+
const inputRef = React28.useRef(null);
|
|
8390
|
+
const [internal, setInternal] = React28.useState(defaultValue ?? []);
|
|
8391
|
+
const [draft, setDraft] = React28.useState("");
|
|
8392
|
+
const [localError, setLocalError] = React28.useState(null);
|
|
8354
8393
|
const tags = value ?? internal;
|
|
8355
8394
|
const hasError = errorMessage != null || localError != null;
|
|
8356
8395
|
const errorText = errorMessage ?? localError ?? void 0;
|
|
@@ -8481,9 +8520,9 @@ function OtpInput({
|
|
|
8481
8520
|
className,
|
|
8482
8521
|
groupAfter
|
|
8483
8522
|
}) {
|
|
8484
|
-
const errorId =
|
|
8523
|
+
const errorId = React28.useId();
|
|
8485
8524
|
const hasError = errorMessage != null;
|
|
8486
|
-
const refs =
|
|
8525
|
+
const refs = React28.useRef([]);
|
|
8487
8526
|
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
8488
8527
|
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
8489
8528
|
const emit = (next) => {
|
|
@@ -8532,7 +8571,7 @@ function OtpInput({
|
|
|
8532
8571
|
emit(valid.join(""));
|
|
8533
8572
|
focusBox(valid.length);
|
|
8534
8573
|
};
|
|
8535
|
-
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(
|
|
8574
|
+
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(React28__default.default.Fragment, { children: [
|
|
8536
8575
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8537
8576
|
"input",
|
|
8538
8577
|
{
|
|
@@ -8590,9 +8629,9 @@ function Rating({
|
|
|
8590
8629
|
className,
|
|
8591
8630
|
required
|
|
8592
8631
|
}) {
|
|
8593
|
-
const errorId =
|
|
8594
|
-
const [internal, setInternal] =
|
|
8595
|
-
const [hover, setHover] =
|
|
8632
|
+
const errorId = React28.useId();
|
|
8633
|
+
const [internal, setInternal] = React28.useState(defaultValue);
|
|
8634
|
+
const [hover, setHover] = React28.useState(null);
|
|
8596
8635
|
const current = value ?? internal;
|
|
8597
8636
|
const display2 = hover ?? current;
|
|
8598
8637
|
const interactive = !readOnly && !disabled;
|
|
@@ -8715,9 +8754,9 @@ function TimePicker({
|
|
|
8715
8754
|
required,
|
|
8716
8755
|
style
|
|
8717
8756
|
}) {
|
|
8718
|
-
const errorId =
|
|
8757
|
+
const errorId = React28.useId();
|
|
8719
8758
|
const hasError = errorMessage != null;
|
|
8720
|
-
const [open, setOpen] =
|
|
8759
|
+
const [open, setOpen] = React28.useState(false);
|
|
8721
8760
|
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
8722
8761
|
const update = (next) => {
|
|
8723
8762
|
const merged = { ...parsed, ...next };
|
|
@@ -8841,13 +8880,13 @@ function DateRangePicker({
|
|
|
8841
8880
|
required,
|
|
8842
8881
|
style
|
|
8843
8882
|
}) {
|
|
8844
|
-
const errorId =
|
|
8883
|
+
const errorId = React28.useId();
|
|
8845
8884
|
const hasError = errorMessage != null;
|
|
8846
|
-
const [open, setOpen] =
|
|
8847
|
-
const [leftMonth, setLeftMonth] =
|
|
8848
|
-
const [pendingStart, setPendingStart] =
|
|
8849
|
-
const [hoverDate, setHoverDate] =
|
|
8850
|
-
const weekdays =
|
|
8885
|
+
const [open, setOpen] = React28.useState(false);
|
|
8886
|
+
const [leftMonth, setLeftMonth] = React28.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
8887
|
+
const [pendingStart, setPendingStart] = React28.useState(null);
|
|
8888
|
+
const [hoverDate, setHoverDate] = React28.useState(null);
|
|
8889
|
+
const weekdays = React28.useMemo(
|
|
8851
8890
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8852
8891
|
[weekStartsOn]
|
|
8853
8892
|
);
|
|
@@ -9023,10 +9062,10 @@ function ColorPicker({
|
|
|
9023
9062
|
required,
|
|
9024
9063
|
placeholder = "Pick a colour\u2026"
|
|
9025
9064
|
}) {
|
|
9026
|
-
const errorId =
|
|
9065
|
+
const errorId = React28.useId();
|
|
9027
9066
|
const hasError = errorMessage != null;
|
|
9028
|
-
const [open, setOpen] =
|
|
9029
|
-
const [draft, setDraft] =
|
|
9067
|
+
const [open, setOpen] = React28.useState(false);
|
|
9068
|
+
const [draft, setDraft] = React28.useState(value);
|
|
9030
9069
|
const valid = HEX_RE.test(value);
|
|
9031
9070
|
const pick = (hex) => {
|
|
9032
9071
|
onChange?.(hex);
|