@geomak/ui 1.9.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +364 -266
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -39
- package/dist/index.d.ts +129 -39
- package/dist/index.js +279 -182
- package/dist/index.js.map +1 -1
- package/dist/styles.css +74 -35
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunk255PCZIW_cjs = require('./chunk-255PCZIW.cjs');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var
|
|
5
|
+
var React8 = require('react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var Dialog = require('@radix-ui/react-dialog');
|
|
8
8
|
var framerMotion = require('framer-motion');
|
|
@@ -11,6 +11,7 @@ var TabsPrimitive = require('@radix-ui/react-tabs');
|
|
|
11
11
|
var Accordion = require('@radix-ui/react-accordion');
|
|
12
12
|
var ToggleGroup = require('@radix-ui/react-toggle-group');
|
|
13
13
|
var Toast = require('@radix-ui/react-toast');
|
|
14
|
+
var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
|
|
14
15
|
var Popover = require('@radix-ui/react-popover');
|
|
15
16
|
var SwitchPrimitive = require('@radix-ui/react-switch');
|
|
16
17
|
var CheckboxPrimitive = require('@radix-ui/react-checkbox');
|
|
@@ -35,13 +36,14 @@ function _interopNamespace(e) {
|
|
|
35
36
|
return Object.freeze(n);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
var
|
|
39
|
+
var React8__default = /*#__PURE__*/_interopDefault(React8);
|
|
39
40
|
var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
|
|
40
41
|
var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
|
|
41
42
|
var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
|
|
42
43
|
var Accordion__namespace = /*#__PURE__*/_interopNamespace(Accordion);
|
|
43
44
|
var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
|
|
44
45
|
var Toast__namespace = /*#__PURE__*/_interopNamespace(Toast);
|
|
46
|
+
var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
|
|
45
47
|
var Popover__namespace = /*#__PURE__*/_interopNamespace(Popover);
|
|
46
48
|
var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
|
|
47
49
|
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
@@ -206,8 +208,8 @@ Icon.Copy = Copy;
|
|
|
206
208
|
Icon.CircleStack = CircleStack;
|
|
207
209
|
var icons_default = Icon;
|
|
208
210
|
function Portal({ children, target }) {
|
|
209
|
-
const [resolved, setResolved] =
|
|
210
|
-
|
|
211
|
+
const [resolved, setResolved] = React8.useState(null);
|
|
212
|
+
React8.useEffect(() => {
|
|
211
213
|
if (target === null) {
|
|
212
214
|
setResolved(null);
|
|
213
215
|
return;
|
|
@@ -227,7 +229,7 @@ function IconButton({
|
|
|
227
229
|
loading = false,
|
|
228
230
|
loadingIcon
|
|
229
231
|
}) {
|
|
230
|
-
const colorScheme =
|
|
232
|
+
const colorScheme = React8.useMemo(() => {
|
|
231
233
|
if (type === "primary") {
|
|
232
234
|
return "bg-accent text-accent-fg hover:bg-accent-hover";
|
|
233
235
|
}
|
|
@@ -540,11 +542,11 @@ function Tabs({
|
|
|
540
542
|
tabsClosable = true,
|
|
541
543
|
defaultActiveTab
|
|
542
544
|
}) {
|
|
543
|
-
const [value, setValue] =
|
|
544
|
-
|
|
545
|
+
const [value, setValue] = React8.useState(() => defaultActiveTab ?? tabs[0]?.key ?? "");
|
|
546
|
+
React8.useEffect(() => {
|
|
545
547
|
if (defaultActiveTab) setValue(defaultActiveTab);
|
|
546
548
|
}, [defaultActiveTab]);
|
|
547
|
-
|
|
549
|
+
React8.useEffect(() => {
|
|
548
550
|
if (tabs.length === 0) {
|
|
549
551
|
setValue("");
|
|
550
552
|
return;
|
|
@@ -793,7 +795,7 @@ function ToggleButton({ items, onChange, activeKey }) {
|
|
|
793
795
|
}
|
|
794
796
|
);
|
|
795
797
|
}
|
|
796
|
-
var NotificationContext =
|
|
798
|
+
var NotificationContext = React8.createContext({
|
|
797
799
|
open: () => void 0,
|
|
798
800
|
close: () => void 0
|
|
799
801
|
});
|
|
@@ -851,7 +853,7 @@ function NotificationItem({
|
|
|
851
853
|
onClose,
|
|
852
854
|
reduced
|
|
853
855
|
}) {
|
|
854
|
-
const [hovered, setHovered] =
|
|
856
|
+
const [hovered, setHovered] = React8.useState(false);
|
|
855
857
|
const initial = getInitialMotion(pos, reduced);
|
|
856
858
|
const center = pos.endsWith("center");
|
|
857
859
|
const duration = n.duration ?? 4e3;
|
|
@@ -932,7 +934,7 @@ function NotificationProvider({
|
|
|
932
934
|
children,
|
|
933
935
|
position = "top-right"
|
|
934
936
|
}) {
|
|
935
|
-
const [notifications, setNotifications] =
|
|
937
|
+
const [notifications, setNotifications] = React8.useState([]);
|
|
936
938
|
const reduced = framerMotion.useReducedMotion();
|
|
937
939
|
const open = (payload) => {
|
|
938
940
|
setNotifications((prev) => [
|
|
@@ -968,7 +970,7 @@ function NotificationProvider({
|
|
|
968
970
|
] }) });
|
|
969
971
|
}
|
|
970
972
|
function useNotification() {
|
|
971
|
-
const { open } =
|
|
973
|
+
const { open } = React8.useContext(NotificationContext);
|
|
972
974
|
return {
|
|
973
975
|
info: (props) => open({ type: "info", ...props }),
|
|
974
976
|
success: (props) => open({ type: "success", ...props }),
|
|
@@ -1081,10 +1083,10 @@ function FadingBase({
|
|
|
1081
1083
|
isMounted = false,
|
|
1082
1084
|
children
|
|
1083
1085
|
}) {
|
|
1084
|
-
const [shouldRender, setShouldRender] =
|
|
1085
|
-
const [visible, setVisible] =
|
|
1086
|
-
const timerRef =
|
|
1087
|
-
|
|
1086
|
+
const [shouldRender, setShouldRender] = React8.useState(isMounted);
|
|
1087
|
+
const [visible, setVisible] = React8.useState(false);
|
|
1088
|
+
const timerRef = React8.useRef(null);
|
|
1089
|
+
React8.useEffect(() => {
|
|
1088
1090
|
if (isMounted) {
|
|
1089
1091
|
setShouldRender(true);
|
|
1090
1092
|
const rafId = requestAnimationFrame(() => setVisible(true));
|
|
@@ -1143,9 +1145,9 @@ function ScalableContainer({
|
|
|
1143
1145
|
children,
|
|
1144
1146
|
assignClassOnClick
|
|
1145
1147
|
}) {
|
|
1146
|
-
const containerRef =
|
|
1147
|
-
const [isScaled, setScaled] =
|
|
1148
|
-
const [wrapperClass, setWrapperClass] =
|
|
1148
|
+
const containerRef = React8.useRef(null);
|
|
1149
|
+
const [isScaled, setScaled] = React8.useState(false);
|
|
1150
|
+
const [wrapperClass, setWrapperClass] = React8.useState("");
|
|
1149
1151
|
const onClick = () => {
|
|
1150
1152
|
const next = !isScaled;
|
|
1151
1153
|
setScaled(next);
|
|
@@ -1255,17 +1257,17 @@ function CatalogGrid({ items, buttonText, onOpen }) {
|
|
|
1255
1257
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(GridCard, { item, buttonText, onOpen }, item.key)) });
|
|
1256
1258
|
}
|
|
1257
1259
|
function CatalogCarousel({ items, buttonText, onOpen }) {
|
|
1258
|
-
const [activeIndex, setActiveIndex] =
|
|
1259
|
-
const [indexPool, setIndexPool] =
|
|
1260
|
-
const cardRefs =
|
|
1261
|
-
const getIndexes =
|
|
1260
|
+
const [activeIndex, setActiveIndex] = React8.useState(0);
|
|
1261
|
+
const [indexPool, setIndexPool] = React8.useState([]);
|
|
1262
|
+
const cardRefs = React8.useRef([]);
|
|
1263
|
+
const getIndexes = React8.useMemo(() => {
|
|
1262
1264
|
let nextIndex = activeIndex + 1;
|
|
1263
1265
|
let previousIndex = activeIndex - 1;
|
|
1264
1266
|
if (activeIndex === 0) previousIndex = items.length - 1;
|
|
1265
1267
|
if (activeIndex === items.length - 1) nextIndex = 0;
|
|
1266
1268
|
return { previousIndex, nextIndex };
|
|
1267
1269
|
}, [activeIndex, items.length]);
|
|
1268
|
-
|
|
1270
|
+
React8.useEffect(() => {
|
|
1269
1271
|
const { nextIndex, previousIndex } = getIndexes;
|
|
1270
1272
|
let indexes = [previousIndex, activeIndex, nextIndex];
|
|
1271
1273
|
if (activeIndex !== 0 && activeIndex !== items.length - 1) {
|
|
@@ -1387,191 +1389,287 @@ function MenuBar({ items }) {
|
|
|
1387
1389
|
)
|
|
1388
1390
|
);
|
|
1389
1391
|
}
|
|
1390
|
-
function ContextMenu({ items,
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
const clickAway = ({ target }) => {
|
|
1400
|
-
if (contextRef.current && !contextRef.current.contains(target)) {
|
|
1401
|
-
if (childMenuRef.current) {
|
|
1402
|
-
childMenuRef.current.classList.add("opacity-0");
|
|
1403
|
-
childMenuRef.current.style.left = "0px";
|
|
1404
|
-
childMenuRef.current.style.top = "0px";
|
|
1405
|
-
}
|
|
1406
|
-
setActiveChildren([]);
|
|
1407
|
-
onClose();
|
|
1408
|
-
}
|
|
1409
|
-
};
|
|
1410
|
-
window.addEventListener("click", clickAway);
|
|
1411
|
-
return () => window.removeEventListener("click", clickAway);
|
|
1412
|
-
}, [onClose]);
|
|
1413
|
-
React9.useEffect(() => {
|
|
1414
|
-
const current = contextRef.current;
|
|
1415
|
-
const child = childMenuRef.current;
|
|
1416
|
-
if (!current || !child) return;
|
|
1417
|
-
const { height, width } = current.getBoundingClientRect();
|
|
1418
|
-
if (position.y + height >= window.innerHeight) {
|
|
1419
|
-
current.style.top = `${position.y - (height - 40)}px`;
|
|
1420
|
-
setHasArrowUp(false);
|
|
1421
|
-
} else {
|
|
1422
|
-
current.style.top = `${position.y}px`;
|
|
1423
|
-
setHasArrowUp(true);
|
|
1424
|
-
}
|
|
1425
|
-
current.style.left = `${position.x}px`;
|
|
1426
|
-
child.style.width = `${width}px`;
|
|
1427
|
-
child.classList.add("opacity-0");
|
|
1428
|
-
}, [position]);
|
|
1429
|
-
const onItemClick = (e, item) => {
|
|
1430
|
-
if (item.onClick) {
|
|
1431
|
-
if (childMenuRef.current) {
|
|
1432
|
-
childMenuRef.current.classList.add("opacity-0");
|
|
1433
|
-
childMenuRef.current.style.left = "0px";
|
|
1434
|
-
childMenuRef.current.style.top = "0px";
|
|
1435
|
-
}
|
|
1436
|
-
setActiveChildren([]);
|
|
1437
|
-
item.onClick(item.path, item.reportType);
|
|
1438
|
-
} else if (item.children?.length) {
|
|
1439
|
-
const targetBbox = e.target.getBoundingClientRect();
|
|
1440
|
-
const childHeight = childMenuRef.current?.getBoundingClientRect().height ?? 0;
|
|
1441
|
-
const contextBbox = contextRef.current?.getBoundingClientRect() ?? { y: 0, width: 0};
|
|
1442
|
-
const contextWidth = contextBbox.width;
|
|
1443
|
-
if (targetBbox.y + childHeight >= window.innerHeight) {
|
|
1444
|
-
setChildArrowUp(false);
|
|
1445
|
-
if (childMenuRef.current) childMenuRef.current.style.top = `${targetBbox.y - childHeight}px`;
|
|
1446
|
-
} else {
|
|
1447
|
-
setChildArrowUp(true);
|
|
1448
|
-
if (childMenuRef.current)
|
|
1449
|
-
childMenuRef.current.style.top = `${targetBbox.y - contextBbox.y + targetBbox.height / 2 - 10}px`;
|
|
1450
|
-
}
|
|
1451
|
-
setActiveChildren(item.children);
|
|
1452
|
-
if (childMenuRef.current) {
|
|
1453
|
-
childMenuRef.current.classList.remove("opacity-0");
|
|
1454
|
-
childMenuRef.current.style.left = `${Math.round(contextWidth + 10)}px`;
|
|
1392
|
+
function ContextMenu({ items, children }) {
|
|
1393
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ContextMenuPrimitive__namespace.Root, { children: [
|
|
1394
|
+
/* @__PURE__ */ jsxRuntime.jsx(ContextMenuPrimitive__namespace.Trigger, { asChild: true, children }),
|
|
1395
|
+
/* @__PURE__ */ jsxRuntime.jsx(ContextMenuPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1396
|
+
ContextMenuPrimitive__namespace.Content,
|
|
1397
|
+
{
|
|
1398
|
+
className: CONTENT_CLASSNAME,
|
|
1399
|
+
collisionPadding: 8,
|
|
1400
|
+
children: items.map((item) => renderItem(item))
|
|
1455
1401
|
}
|
|
1456
|
-
}
|
|
1457
|
-
};
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1402
|
+
) })
|
|
1403
|
+
] });
|
|
1404
|
+
}
|
|
1405
|
+
var CONTENT_CLASSNAME = [
|
|
1406
|
+
// Surface — semantic tokens, both modes covered
|
|
1407
|
+
"min-w-[180px] rounded-lg border border-border bg-surface shadow-lg",
|
|
1408
|
+
"p-1 z-[500000] text-sm text-foreground",
|
|
1409
|
+
// Entry animation matches the Tooltip / Dropdown style
|
|
1410
|
+
"animate-in fade-in-0 zoom-in-95",
|
|
1411
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
1412
|
+
// Outline reset — Radix handles focus internally
|
|
1413
|
+
"focus:outline-none"
|
|
1414
|
+
].join(" ");
|
|
1415
|
+
var ITEM_CLASSNAME = [
|
|
1416
|
+
"flex items-center justify-between gap-3 rounded-md px-2 py-1.5 cursor-pointer select-none",
|
|
1417
|
+
"transition-colors duration-100",
|
|
1418
|
+
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-fg",
|
|
1419
|
+
"data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed data-[disabled]:bg-transparent data-[disabled]:text-foreground-muted",
|
|
1420
|
+
"focus:outline-none"
|
|
1421
|
+
].join(" ");
|
|
1422
|
+
function renderItem(item) {
|
|
1423
|
+
if (item.children && item.children.length > 0) {
|
|
1424
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ContextMenuPrimitive__namespace.Sub, { children: [
|
|
1425
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1426
|
+
ContextMenuPrimitive__namespace.SubTrigger,
|
|
1427
|
+
{
|
|
1428
|
+
disabled: item.disabled,
|
|
1429
|
+
className: ITEM_CLASSNAME,
|
|
1430
|
+
children: [
|
|
1431
|
+
/* @__PURE__ */ jsxRuntime.jsx(ContextMenuLabel, { icon: item.icon, value: item.value }),
|
|
1432
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronRight2, {})
|
|
1433
|
+
]
|
|
1434
|
+
}
|
|
1435
|
+
),
|
|
1436
|
+
/* @__PURE__ */ jsxRuntime.jsx(ContextMenuPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1437
|
+
ContextMenuPrimitive__namespace.SubContent,
|
|
1438
|
+
{
|
|
1439
|
+
className: CONTENT_CLASSNAME,
|
|
1440
|
+
sideOffset: 2,
|
|
1441
|
+
alignOffset: -4,
|
|
1442
|
+
collisionPadding: 8,
|
|
1443
|
+
children: item.children.map((sub) => renderItem(sub))
|
|
1444
|
+
}
|
|
1445
|
+
) })
|
|
1446
|
+
] }, item.key);
|
|
1447
|
+
}
|
|
1448
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1449
|
+
ContextMenuPrimitive__namespace.Item,
|
|
1461
1450
|
{
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
onContextMenu: (e) => e.preventDefault(),
|
|
1469
|
-
onMouseEnter: () => setHoveredItem(index),
|
|
1470
|
-
onMouseLeave: () => setHoveredItem(-1),
|
|
1471
|
-
className: `flex items-center justify-between transition-all duration-300 p-2 cursor-pointer hover:bg-ice-dark ${index === 0 ? "rounded-tl-lg rounded-tr-lg" : ""} ${index === items.length - 1 ? "rounded-bl-lg rounded-br-lg" : ""}`,
|
|
1472
|
-
onClick: (e) => onItemClick(e, item),
|
|
1473
|
-
children: [
|
|
1474
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pointer-events-none", children: [
|
|
1475
|
-
item.icon,
|
|
1476
|
-
item.value
|
|
1477
|
-
] }),
|
|
1478
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none", children: item.children && /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: chunk255PCZIW_cjs.colors_default.PALETTE["prussian-blue"], strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) }) })
|
|
1479
|
-
]
|
|
1480
|
-
},
|
|
1481
|
-
item.key
|
|
1482
|
-
)) }),
|
|
1483
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1484
|
-
"div",
|
|
1485
|
-
{
|
|
1486
|
-
ref: childMenuRef,
|
|
1487
|
-
className: `transition-all duration-150 absolute rounded-lg bg-ice text-prussian-blue ${childArrowUp && hoveredChild === 0 ? "context-arrow-up context-arrow-hovered" : !childArrowUp && hoveredChild === activeChildren.length - 1 ? "context-arrow-down context-arrow-hovered" : childArrowUp ? "context-arrow-up" : "context-arrow-down"}`,
|
|
1488
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: activeChildren.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1489
|
-
"li",
|
|
1490
|
-
{
|
|
1491
|
-
className: `flex items-center gap-2 p-2 cursor-pointer transition-all duration-150 hover:bg-ice-dark ${index === 0 ? "rounded-tl-lg rounded-tr-lg" : ""} ${index === activeChildren.length - 1 ? "rounded-bl-lg rounded-br-lg" : ""}`,
|
|
1492
|
-
onClick: () => item.onClick?.(item.path, item.reportType),
|
|
1493
|
-
onMouseEnter: () => setHoveredChild(index),
|
|
1494
|
-
onMouseLeave: () => setHoveredChild(-1),
|
|
1495
|
-
children: [
|
|
1496
|
-
item.icon,
|
|
1497
|
-
item.value
|
|
1498
|
-
]
|
|
1499
|
-
},
|
|
1500
|
-
index
|
|
1501
|
-
)) })
|
|
1502
|
-
}
|
|
1503
|
-
)
|
|
1504
|
-
]
|
|
1505
|
-
}
|
|
1451
|
+
disabled: item.disabled,
|
|
1452
|
+
onSelect: () => item.onClick?.(),
|
|
1453
|
+
className: ITEM_CLASSNAME,
|
|
1454
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ContextMenuLabel, { icon: item.icon, value: item.value })
|
|
1455
|
+
},
|
|
1456
|
+
item.key
|
|
1506
1457
|
);
|
|
1507
1458
|
}
|
|
1508
|
-
function
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
);
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1459
|
+
function ContextMenuLabel({ icon, value }) {
|
|
1460
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
|
|
1461
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: icon }),
|
|
1462
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: value })
|
|
1463
|
+
] });
|
|
1464
|
+
}
|
|
1465
|
+
function ChevronRight2() {
|
|
1466
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4 flex-shrink-0", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
|
|
1467
|
+
}
|
|
1468
|
+
function readDismissed(key) {
|
|
1469
|
+
if (key === null) return false;
|
|
1470
|
+
if (typeof window === "undefined") return false;
|
|
1471
|
+
try {
|
|
1472
|
+
return window.localStorage.getItem(key) === "true";
|
|
1473
|
+
} catch {
|
|
1474
|
+
return false;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
function writeDismissed(key) {
|
|
1478
|
+
if (key === null) return;
|
|
1479
|
+
if (typeof window === "undefined") return;
|
|
1480
|
+
try {
|
|
1481
|
+
window.localStorage.setItem(key, "true");
|
|
1482
|
+
} catch {
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
function useTargetBbox(ref) {
|
|
1486
|
+
const [bbox, setBbox] = React8.useState(null);
|
|
1487
|
+
React8.useLayoutEffect(() => {
|
|
1488
|
+
const el = ref?.current;
|
|
1489
|
+
if (!el) {
|
|
1490
|
+
setBbox(null);
|
|
1524
1491
|
return;
|
|
1525
1492
|
}
|
|
1526
|
-
const
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1493
|
+
const update = () => setBbox(el.getBoundingClientRect());
|
|
1494
|
+
update();
|
|
1495
|
+
window.addEventListener("scroll", update, true);
|
|
1496
|
+
window.addEventListener("resize", update);
|
|
1497
|
+
const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(update) : null;
|
|
1498
|
+
ro?.observe(el);
|
|
1499
|
+
return () => {
|
|
1500
|
+
window.removeEventListener("scroll", update, true);
|
|
1501
|
+
window.removeEventListener("resize", update);
|
|
1502
|
+
ro?.disconnect();
|
|
1503
|
+
};
|
|
1504
|
+
}, [ref]);
|
|
1505
|
+
return bbox;
|
|
1506
|
+
}
|
|
1507
|
+
var TOOLTIP_WIDTH = 280;
|
|
1508
|
+
var TOOLTIP_GAP = 12;
|
|
1509
|
+
function tooltipStyleFor(bbox, placement) {
|
|
1510
|
+
const pl = placement ?? "right";
|
|
1511
|
+
if (pl === "right") return { left: bbox.right + TOOLTIP_GAP, top: bbox.top + bbox.height / 2, transform: "translateY(-50%)", width: TOOLTIP_WIDTH };
|
|
1512
|
+
if (pl === "left") return { left: bbox.left - TOOLTIP_WIDTH - TOOLTIP_GAP, top: bbox.top + bbox.height / 2, transform: "translateY(-50%)", width: TOOLTIP_WIDTH };
|
|
1513
|
+
if (pl === "bottom") return { left: bbox.left + bbox.width / 2, top: bbox.bottom + TOOLTIP_GAP, transform: "translateX(-50%)", width: TOOLTIP_WIDTH };
|
|
1514
|
+
return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
|
|
1515
|
+
}
|
|
1516
|
+
function useFocusTrap(containerRef, active) {
|
|
1517
|
+
React8.useEffect(() => {
|
|
1518
|
+
if (!active) return;
|
|
1519
|
+
const el = containerRef.current;
|
|
1520
|
+
if (!el) return;
|
|
1521
|
+
const t = setTimeout(() => {
|
|
1522
|
+
const first = el.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
1523
|
+
first?.focus();
|
|
1524
|
+
}, 0);
|
|
1525
|
+
const onKey = (e) => {
|
|
1526
|
+
if (e.key !== "Tab") return;
|
|
1527
|
+
const focusables = el.querySelectorAll(
|
|
1528
|
+
'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
1529
|
+
);
|
|
1530
|
+
if (focusables.length === 0) return;
|
|
1531
|
+
const first = focusables[0];
|
|
1532
|
+
const last = focusables[focusables.length - 1];
|
|
1533
|
+
if (e.shiftKey && document.activeElement === first) {
|
|
1534
|
+
e.preventDefault();
|
|
1535
|
+
last.focus();
|
|
1536
|
+
} else if (!e.shiftKey && document.activeElement === last) {
|
|
1537
|
+
e.preventDefault();
|
|
1538
|
+
first.focus();
|
|
1569
1539
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1540
|
+
};
|
|
1541
|
+
document.addEventListener("keydown", onKey);
|
|
1542
|
+
return () => {
|
|
1543
|
+
clearTimeout(t);
|
|
1544
|
+
document.removeEventListener("keydown", onKey);
|
|
1545
|
+
};
|
|
1546
|
+
}, [containerRef, active]);
|
|
1547
|
+
}
|
|
1548
|
+
function Wizard({
|
|
1549
|
+
children,
|
|
1550
|
+
steps,
|
|
1551
|
+
storageKey = "oxygen.wizard.completed",
|
|
1552
|
+
dismissible = true,
|
|
1553
|
+
onComplete,
|
|
1554
|
+
onSkip
|
|
1555
|
+
}) {
|
|
1556
|
+
const tooltipRef = React8.useRef(null);
|
|
1557
|
+
const tooltipTitleId = React8.useId();
|
|
1558
|
+
const tooltipBodyId = React8.useId();
|
|
1559
|
+
const [open, setOpen] = React8.useState(() => steps.length > 0 && !readDismissed(storageKey));
|
|
1560
|
+
const [activeIndex, setActiveIndex] = React8.useState(0);
|
|
1561
|
+
const step = steps[activeIndex];
|
|
1562
|
+
const bbox = useTargetBbox(step?.stepRef);
|
|
1563
|
+
useFocusTrap(tooltipRef, open);
|
|
1564
|
+
React8.useEffect(() => {
|
|
1565
|
+
if (!open || !dismissible) return;
|
|
1566
|
+
const onKey = (e) => {
|
|
1567
|
+
if (e.key === "Escape") {
|
|
1568
|
+
e.preventDefault();
|
|
1569
|
+
handleSkip();
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
document.addEventListener("keydown", onKey);
|
|
1573
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
1574
|
+
}, [open, dismissible]);
|
|
1575
|
+
const handleSkip = React8.useCallback(() => {
|
|
1576
|
+
writeDismissed(storageKey);
|
|
1577
|
+
setOpen(false);
|
|
1578
|
+
onSkip?.();
|
|
1579
|
+
}, [storageKey, onSkip]);
|
|
1580
|
+
const handleComplete = React8.useCallback(() => {
|
|
1581
|
+
writeDismissed(storageKey);
|
|
1582
|
+
setOpen(false);
|
|
1583
|
+
onComplete?.();
|
|
1584
|
+
}, [storageKey, onComplete]);
|
|
1585
|
+
const handleNext = () => {
|
|
1586
|
+
if (activeIndex < steps.length - 1) setActiveIndex((i) => i + 1);
|
|
1587
|
+
else handleComplete();
|
|
1588
|
+
};
|
|
1589
|
+
const handlePrev = () => {
|
|
1590
|
+
if (activeIndex > 0) setActiveIndex((i) => i - 1);
|
|
1591
|
+
};
|
|
1592
|
+
const highlightStyle = bbox ? {
|
|
1593
|
+
left: bbox.left - 4,
|
|
1594
|
+
top: bbox.top - 4,
|
|
1595
|
+
width: bbox.width + 8,
|
|
1596
|
+
height: bbox.height + 8
|
|
1597
|
+
} : { display: "none" };
|
|
1598
|
+
const tooltipStyle = bbox ? tooltipStyleFor(bbox, step?.placement) : { display: "none" };
|
|
1599
|
+
const isLast = activeIndex === steps.length - 1;
|
|
1600
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1601
|
+
children,
|
|
1602
|
+
open && step && /* @__PURE__ */ jsxRuntime.jsxs(Portal, { children: [
|
|
1603
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1604
|
+
"div",
|
|
1605
|
+
{
|
|
1606
|
+
className: "fixed inset-0 z-[7000000] bg-foreground/40 backdrop-blur-[1px] pointer-events-auto",
|
|
1607
|
+
"aria-hidden": "true"
|
|
1608
|
+
}
|
|
1609
|
+
),
|
|
1610
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1611
|
+
"div",
|
|
1612
|
+
{
|
|
1613
|
+
className: "fixed z-[7000001] pointer-events-none rounded-md ring-2 ring-accent ring-offset-2 ring-offset-background transition-all duration-200",
|
|
1614
|
+
style: highlightStyle,
|
|
1615
|
+
"aria-hidden": "true"
|
|
1616
|
+
}
|
|
1617
|
+
),
|
|
1618
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1619
|
+
"div",
|
|
1620
|
+
{
|
|
1621
|
+
ref: tooltipRef,
|
|
1622
|
+
role: "dialog",
|
|
1623
|
+
"aria-modal": "true",
|
|
1624
|
+
"aria-labelledby": step.title ? tooltipTitleId : void 0,
|
|
1625
|
+
"aria-describedby": tooltipBodyId,
|
|
1626
|
+
className: "fixed z-[7000002] rounded-lg bg-surface text-foreground border border-border shadow-xl p-4 pointer-events-auto",
|
|
1627
|
+
style: tooltipStyle,
|
|
1628
|
+
children: [
|
|
1629
|
+
step.title && /* @__PURE__ */ jsxRuntime.jsx("h3", { id: tooltipTitleId, className: "text-sm font-semibold text-foreground mb-1", children: step.title }),
|
|
1630
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { id: tooltipBodyId, className: "text-sm text-foreground-secondary leading-relaxed", children: step.description }),
|
|
1631
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex items-center justify-between", children: [
|
|
1632
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-foreground-muted tabular-nums", children: [
|
|
1633
|
+
activeIndex + 1,
|
|
1634
|
+
" / ",
|
|
1635
|
+
steps.length
|
|
1636
|
+
] }),
|
|
1637
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1638
|
+
dismissible && !isLast && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1639
|
+
Button,
|
|
1640
|
+
{
|
|
1641
|
+
variant: "ghost",
|
|
1642
|
+
size: "sm",
|
|
1643
|
+
content: "Skip",
|
|
1644
|
+
onClick: handleSkip
|
|
1645
|
+
}
|
|
1646
|
+
),
|
|
1647
|
+
activeIndex > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1648
|
+
Button,
|
|
1649
|
+
{
|
|
1650
|
+
variant: "secondary",
|
|
1651
|
+
size: "sm",
|
|
1652
|
+
content: "Back",
|
|
1653
|
+
onClick: handlePrev
|
|
1654
|
+
}
|
|
1655
|
+
),
|
|
1656
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1657
|
+
Button,
|
|
1658
|
+
{
|
|
1659
|
+
size: "sm",
|
|
1660
|
+
content: isLast ? "Done" : "Next",
|
|
1661
|
+
onClick: handleNext
|
|
1662
|
+
}
|
|
1663
|
+
)
|
|
1664
|
+
] })
|
|
1665
|
+
] })
|
|
1666
|
+
]
|
|
1667
|
+
}
|
|
1668
|
+
)
|
|
1669
|
+
] })
|
|
1572
1670
|
] });
|
|
1573
1671
|
}
|
|
1574
|
-
var SearchInput =
|
|
1672
|
+
var SearchInput = React8__default.default.forwardRef(function SearchInput2({
|
|
1575
1673
|
value,
|
|
1576
1674
|
onChange,
|
|
1577
1675
|
disabled,
|
|
@@ -1639,16 +1737,16 @@ function Dropdown({
|
|
|
1639
1737
|
labelStyle = {},
|
|
1640
1738
|
placeholder
|
|
1641
1739
|
}) {
|
|
1642
|
-
const [open, setOpen] =
|
|
1643
|
-
const [selectedItems, setSelectedItems] =
|
|
1644
|
-
const [searchTerm, setSearchTerm] =
|
|
1645
|
-
const [innerItems, setInnerItems] =
|
|
1646
|
-
const errorId =
|
|
1740
|
+
const [open, setOpen] = React8.useState(false);
|
|
1741
|
+
const [selectedItems, setSelectedItems] = React8.useState([]);
|
|
1742
|
+
const [searchTerm, setSearchTerm] = React8.useState("");
|
|
1743
|
+
const [innerItems, setInnerItems] = React8.useState([]);
|
|
1744
|
+
const errorId = React8.useId();
|
|
1647
1745
|
const hasError = errorMessage != null;
|
|
1648
|
-
|
|
1746
|
+
React8.useEffect(() => {
|
|
1649
1747
|
setInnerItems(items);
|
|
1650
1748
|
}, [items]);
|
|
1651
|
-
|
|
1749
|
+
React8.useEffect(() => {
|
|
1652
1750
|
if (isMultiselect && Array.isArray(value)) {
|
|
1653
1751
|
setSelectedItems(value);
|
|
1654
1752
|
}
|
|
@@ -1872,7 +1970,7 @@ function TableBody({
|
|
|
1872
1970
|
expandRow,
|
|
1873
1971
|
getRowKey
|
|
1874
1972
|
}) {
|
|
1875
|
-
const [expanded, setExpanded] =
|
|
1973
|
+
const [expanded, setExpanded] = React8.useState(() => /* @__PURE__ */ new Set());
|
|
1876
1974
|
const toggleRow = (rowKey) => {
|
|
1877
1975
|
setExpanded((prev) => {
|
|
1878
1976
|
const next = new Set(prev);
|
|
@@ -1886,7 +1984,7 @@ function TableBody({
|
|
|
1886
1984
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
|
|
1887
1985
|
const rowKey = getRowKey(row, i);
|
|
1888
1986
|
const isExpanded = expanded.has(rowKey);
|
|
1889
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1987
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
|
|
1890
1988
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1891
1989
|
"tr",
|
|
1892
1990
|
{
|
|
@@ -1930,9 +2028,9 @@ function Pagination({
|
|
|
1930
2028
|
const matchedOption = picker.find(
|
|
1931
2029
|
(o) => o.label === options.perPage || o.value === options.perPage
|
|
1932
2030
|
);
|
|
1933
|
-
const [perPageKey, setPerPageKey] =
|
|
2031
|
+
const [perPageKey, setPerPageKey] = React8.useState(() => matchedOption?.key ?? picker[0]?.key);
|
|
1934
2032
|
const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
|
|
1935
|
-
|
|
2033
|
+
React8.useEffect(() => {
|
|
1936
2034
|
if (serverSide && options.perPage != null) {
|
|
1937
2035
|
const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
|
|
1938
2036
|
if (next) setPerPageKey(next.key);
|
|
@@ -1992,14 +2090,14 @@ function Table({
|
|
|
1992
2090
|
footer = null,
|
|
1993
2091
|
header = null
|
|
1994
2092
|
}) {
|
|
1995
|
-
const searchRef =
|
|
1996
|
-
const [searchTerm, setSearchTerm] =
|
|
1997
|
-
const [perPage, setPerPage] =
|
|
2093
|
+
const searchRef = React8.useRef(null);
|
|
2094
|
+
const [searchTerm, setSearchTerm] = React8.useState("");
|
|
2095
|
+
const [perPage, setPerPage] = React8.useState(
|
|
1998
2096
|
typeof pagination.perPage === "number" ? pagination.perPage : 15
|
|
1999
2097
|
);
|
|
2000
|
-
const [activePage, setActivePage] =
|
|
2098
|
+
const [activePage, setActivePage] = React8.useState(0);
|
|
2001
2099
|
const isServerSide = !!(pagination.enabled && pagination.serverSide);
|
|
2002
|
-
const filteredRows =
|
|
2100
|
+
const filteredRows = React8.useMemo(() => {
|
|
2003
2101
|
if (isServerSide || !searchTerm) return rows;
|
|
2004
2102
|
const term = searchTerm.toLowerCase();
|
|
2005
2103
|
return rows.filter(
|
|
@@ -2008,29 +2106,29 @@ function Table({
|
|
|
2008
2106
|
)
|
|
2009
2107
|
);
|
|
2010
2108
|
}, [rows, searchTerm, isServerSide]);
|
|
2011
|
-
const datasets =
|
|
2109
|
+
const datasets = React8.useMemo(() => {
|
|
2012
2110
|
if (isServerSide) return [rows];
|
|
2013
2111
|
return createDatasets(filteredRows, pagination.enabled ? perPage : null);
|
|
2014
2112
|
}, [filteredRows, perPage, pagination.enabled, isServerSide, rows]);
|
|
2015
|
-
const MAX_PAGE =
|
|
2113
|
+
const MAX_PAGE = React8.useMemo(() => {
|
|
2016
2114
|
if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
|
|
2017
2115
|
if (isServerSide && typeof pagination.totalCount === "number")
|
|
2018
2116
|
return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
|
|
2019
2117
|
return datasets.length ? datasets.length - 1 : 0;
|
|
2020
2118
|
}, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
|
|
2021
|
-
const currentPageRows =
|
|
2119
|
+
const currentPageRows = React8.useMemo(() => {
|
|
2022
2120
|
if (isServerSide) return rows;
|
|
2023
2121
|
return datasets[activePage] ?? [];
|
|
2024
2122
|
}, [isServerSide, rows, datasets, activePage]);
|
|
2025
|
-
|
|
2123
|
+
React8.useEffect(() => {
|
|
2026
2124
|
if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
|
|
2027
2125
|
setPerPage(pagination.perPage);
|
|
2028
2126
|
}
|
|
2029
2127
|
}, [pagination.enabled, pagination.perPage, isServerSide]);
|
|
2030
|
-
|
|
2128
|
+
React8.useEffect(() => {
|
|
2031
2129
|
if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
|
|
2032
2130
|
}, [isServerSide, pagination.perPage]);
|
|
2033
|
-
|
|
2131
|
+
React8.useEffect(() => {
|
|
2034
2132
|
if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
|
|
2035
2133
|
setActivePage(pagination.page - 1);
|
|
2036
2134
|
}, [isServerSide, pagination.page]);
|
|
@@ -2090,7 +2188,7 @@ function Table({
|
|
|
2090
2188
|
] });
|
|
2091
2189
|
}
|
|
2092
2190
|
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode" }) {
|
|
2093
|
-
const id =
|
|
2191
|
+
const id = React8.useId();
|
|
2094
2192
|
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: "flex items-center gap-2 cursor-pointer select-none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2095
2193
|
SwitchPrimitive__namespace.Root,
|
|
2096
2194
|
{
|
|
@@ -2283,17 +2381,17 @@ function AppShell({
|
|
|
2283
2381
|
children,
|
|
2284
2382
|
className = ""
|
|
2285
2383
|
}) {
|
|
2286
|
-
const [expanded, setExpanded] =
|
|
2287
|
-
const [isMobile, setIsMobile] =
|
|
2288
|
-
const [mobileOpen, setMobileOpen] =
|
|
2289
|
-
|
|
2384
|
+
const [expanded, setExpanded] = React8.useState(sidebarDefaultExpanded);
|
|
2385
|
+
const [isMobile, setIsMobile] = React8.useState(false);
|
|
2386
|
+
const [mobileOpen, setMobileOpen] = React8.useState(false);
|
|
2387
|
+
React8.useEffect(() => {
|
|
2290
2388
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
2291
2389
|
const update = (e) => setIsMobile(e.matches);
|
|
2292
2390
|
update(mq);
|
|
2293
2391
|
mq.addEventListener("change", update);
|
|
2294
2392
|
return () => mq.removeEventListener("change", update);
|
|
2295
2393
|
}, []);
|
|
2296
|
-
|
|
2394
|
+
React8.useEffect(() => {
|
|
2297
2395
|
if (!isMobile) setMobileOpen(false);
|
|
2298
2396
|
}, [isMobile]);
|
|
2299
2397
|
const hasSidebar = sidebarSections.length > 0;
|
|
@@ -2483,10 +2581,10 @@ function ThemeProvider({
|
|
|
2483
2581
|
className = "",
|
|
2484
2582
|
style
|
|
2485
2583
|
}) {
|
|
2486
|
-
const id =
|
|
2584
|
+
const id = React8__default.default.useId().replace(/:/g, "");
|
|
2487
2585
|
const scopeClass = `geo-th-${id}`;
|
|
2488
|
-
const divRef =
|
|
2489
|
-
|
|
2586
|
+
const divRef = React8.useRef(null);
|
|
2587
|
+
React8.useEffect(() => {
|
|
2490
2588
|
const el = divRef.current;
|
|
2491
2589
|
if (!el) return;
|
|
2492
2590
|
if (colorScheme === "auto") return;
|
|
@@ -2501,8 +2599,8 @@ function ThemeProvider({
|
|
|
2501
2599
|
}
|
|
2502
2600
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
2503
2601
|
}, [colorScheme]);
|
|
2504
|
-
const lightVars =
|
|
2505
|
-
const darkVarStr =
|
|
2602
|
+
const lightVars = React8.useMemo(() => toCssVars(theme), [theme]);
|
|
2603
|
+
const darkVarStr = React8.useMemo(() => {
|
|
2506
2604
|
if (!darkTheme) return "";
|
|
2507
2605
|
const dvars = toCssVars(darkTheme);
|
|
2508
2606
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -2629,7 +2727,7 @@ function TextInput({
|
|
|
2629
2727
|
errorMessage,
|
|
2630
2728
|
labelColor
|
|
2631
2729
|
}) {
|
|
2632
|
-
const errorId =
|
|
2730
|
+
const errorId = React8.useId();
|
|
2633
2731
|
const hasError = errorMessage != null;
|
|
2634
2732
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col items-center justify-center", children: [
|
|
2635
2733
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2693,7 +2791,7 @@ function NumberInput({
|
|
|
2693
2791
|
readOnly = false,
|
|
2694
2792
|
precision
|
|
2695
2793
|
}) {
|
|
2696
|
-
const errorId =
|
|
2794
|
+
const errorId = React8.useId();
|
|
2697
2795
|
const hasError = errorMessage != null;
|
|
2698
2796
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
2699
2797
|
const round = (n) => {
|
|
@@ -2811,8 +2909,8 @@ function Password({
|
|
|
2811
2909
|
labelColor,
|
|
2812
2910
|
iconColor
|
|
2813
2911
|
}) {
|
|
2814
|
-
const [passwordVisible, setPasswordVisible] =
|
|
2815
|
-
const errorId =
|
|
2912
|
+
const [passwordVisible, setPasswordVisible] = React8.useState(false);
|
|
2913
|
+
const errorId = React8.useId();
|
|
2816
2914
|
const hasError = errorMessage != null;
|
|
2817
2915
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col items-center justify-center", style: style ?? {}, children: [
|
|
2818
2916
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex ${layout === "vertical" ? "flex-col" : "flex-row items-center gap-2"}`, children: [
|
|
@@ -2958,7 +3056,7 @@ function Switch({
|
|
|
2958
3056
|
checkedIcon,
|
|
2959
3057
|
uncheckedIcon
|
|
2960
3058
|
}) {
|
|
2961
|
-
const id =
|
|
3059
|
+
const id = React8.useId();
|
|
2962
3060
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2963
3061
|
"// mr-12 was a hardcoded right margin that broke layouts; spacing // is the parent's responsibility now.",
|
|
2964
3062
|
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: "flex items-center cursor-pointer select-none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2991,8 +3089,8 @@ function AutoComplete({
|
|
|
2991
3089
|
onItemClick,
|
|
2992
3090
|
emptyText = "No results found"
|
|
2993
3091
|
}) {
|
|
2994
|
-
const [term, setTerm] =
|
|
2995
|
-
const [open, setOpen] =
|
|
3092
|
+
const [term, setTerm] = React8.useState("");
|
|
3093
|
+
const [open, setOpen] = React8.useState(false);
|
|
2996
3094
|
const foundItems = term.trim() ? items.filter(
|
|
2997
3095
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
2998
3096
|
) : [];
|
|
@@ -3090,10 +3188,10 @@ function TreeSelect({
|
|
|
3090
3188
|
htmlFor,
|
|
3091
3189
|
items = []
|
|
3092
3190
|
}) {
|
|
3093
|
-
const [open, setOpen] =
|
|
3094
|
-
const [hoveredItem, setHoveredItem] =
|
|
3095
|
-
const [innerItems, setInnerItems] =
|
|
3096
|
-
|
|
3191
|
+
const [open, setOpen] = React8.useState(false);
|
|
3192
|
+
const [hoveredItem, setHoveredItem] = React8.useState(null);
|
|
3193
|
+
const [innerItems, setInnerItems] = React8.useState([]);
|
|
3194
|
+
React8.useEffect(() => {
|
|
3097
3195
|
setInnerItems(items);
|
|
3098
3196
|
}, [items]);
|
|
3099
3197
|
const selectItem = (key) => {
|
|
@@ -3192,8 +3290,8 @@ function FileInput({
|
|
|
3192
3290
|
name,
|
|
3193
3291
|
accept = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xlsx"
|
|
3194
3292
|
}) {
|
|
3195
|
-
const fileInput =
|
|
3196
|
-
const [files, setFiles] =
|
|
3293
|
+
const fileInput = React8.useRef(null);
|
|
3294
|
+
const [files, setFiles] = React8.useState([]);
|
|
3197
3295
|
const openPicker = () => {
|
|
3198
3296
|
fileInput.current?.click();
|
|
3199
3297
|
};
|
|
@@ -3325,7 +3423,7 @@ function getMonthDays(year, month) {
|
|
|
3325
3423
|
}
|
|
3326
3424
|
return days;
|
|
3327
3425
|
}
|
|
3328
|
-
var
|
|
3426
|
+
var ChevronRight3 = ({ color = chunk255PCZIW_cjs.colors_default.PALETTE["prussian-blue"] }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
|
|
3329
3427
|
var DoubleChevronRight2 = ({ color = chunk255PCZIW_cjs.colors_default.PALETTE["prussian-blue"] }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 5l7 7-7 7M5 5l7 7-7 7" }) });
|
|
3330
3428
|
var ChevronDown2 = ({ color = chunk255PCZIW_cjs.colors_default.PALETTE["prussian-blue"] }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) });
|
|
3331
3429
|
function DatePickerBase({
|
|
@@ -3341,12 +3439,12 @@ function DatePickerBase({
|
|
|
3341
3439
|
disableAfter,
|
|
3342
3440
|
disabled
|
|
3343
3441
|
}) {
|
|
3344
|
-
const pickerRef =
|
|
3345
|
-
const calendarRef =
|
|
3346
|
-
const [isExpanded, setExpanded] =
|
|
3347
|
-
const [isCloseToBottom, setCloseToBottom] =
|
|
3348
|
-
const [currentYear, setCurrentYear] =
|
|
3349
|
-
const [currentMonth, setCurrentMonth] =
|
|
3442
|
+
const pickerRef = React8.useRef(null);
|
|
3443
|
+
const calendarRef = React8.useRef(null);
|
|
3444
|
+
const [isExpanded, setExpanded] = React8.useState(false);
|
|
3445
|
+
const [isCloseToBottom, setCloseToBottom] = React8.useState(false);
|
|
3446
|
+
const [currentYear, setCurrentYear] = React8.useState(value.getFullYear());
|
|
3447
|
+
const [currentMonth, setCurrentMonth] = React8.useState(value.getMonth() + 1);
|
|
3350
3448
|
const toggle = () => {
|
|
3351
3449
|
if (!disabled) setExpanded((p) => !p);
|
|
3352
3450
|
};
|
|
@@ -3390,14 +3488,14 @@ function DatePickerBase({
|
|
|
3390
3488
|
}
|
|
3391
3489
|
return ordered;
|
|
3392
3490
|
};
|
|
3393
|
-
|
|
3491
|
+
React8.useEffect(() => {
|
|
3394
3492
|
const clickAway = (e) => {
|
|
3395
3493
|
if (pickerRef.current && !pickerRef.current.contains(e.target) && calendarRef.current && !calendarRef.current.contains(e.target)) setExpanded(false);
|
|
3396
3494
|
};
|
|
3397
3495
|
document.addEventListener("mousedown", clickAway);
|
|
3398
3496
|
return () => document.removeEventListener("mousedown", clickAway);
|
|
3399
3497
|
}, []);
|
|
3400
|
-
|
|
3498
|
+
React8.useEffect(() => {
|
|
3401
3499
|
const bbox = pickerRef.current?.getBoundingClientRect();
|
|
3402
3500
|
if (bbox && (bbox.y > window.innerHeight - 220 || bbox.bottom > window.innerHeight - 400)) {
|
|
3403
3501
|
setCloseToBottom(true);
|
|
@@ -3440,13 +3538,13 @@ function DatePickerBase({
|
|
|
3440
3538
|
children: isExpanded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-3", children: [
|
|
3441
3539
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center mx-auto w-max", children: [
|
|
3442
3540
|
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => setCurrentYear((y) => y - 1), className: "cursor-pointer rotate-180 p-1 rounded-lg hover:bg-ice-dark transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx(DoubleChevronRight2, {}) }),
|
|
3443
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: toPrevMonth, className: "cursor-pointer rotate-180 p-1 rounded-lg hover:bg-ice-dark transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3541
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: toPrevMonth, className: "cursor-pointer rotate-180 p-1 rounded-lg hover:bg-ice-dark transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight3, {}) }),
|
|
3444
3542
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold text-prussian-blue select-none w-[130px] text-center", children: [
|
|
3445
3543
|
currentYear,
|
|
3446
3544
|
" ",
|
|
3447
3545
|
MONTHS[currentMonth]
|
|
3448
3546
|
] }),
|
|
3449
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: toNextMonth, className: "cursor-pointer p-1 rounded-lg hover:bg-ice-dark transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3547
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: toNextMonth, className: "cursor-pointer p-1 rounded-lg hover:bg-ice-dark transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight3, {}) }),
|
|
3450
3548
|
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => setCurrentYear((y) => y + 1), className: "cursor-pointer p-1 rounded-lg hover:bg-ice-dark transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx(DoubleChevronRight2, {}) })
|
|
3451
3549
|
] }),
|
|
3452
3550
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3 p-2", children: renderCalendar().map((weekDay, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
@@ -3490,29 +3588,29 @@ function TemporalPickerBase({
|
|
|
3490
3588
|
layout,
|
|
3491
3589
|
style = {}
|
|
3492
3590
|
}) {
|
|
3493
|
-
const pickerRef =
|
|
3494
|
-
const calendarRef =
|
|
3495
|
-
const valueRefs =
|
|
3496
|
-
const [isExpanded, setExpanded] =
|
|
3497
|
-
const [isCloseToBottom, setCloseToBottom] =
|
|
3498
|
-
const innerValues =
|
|
3591
|
+
const pickerRef = React8.useRef(null);
|
|
3592
|
+
const calendarRef = React8.useRef(null);
|
|
3593
|
+
const valueRefs = React8.useRef([]);
|
|
3594
|
+
const [isExpanded, setExpanded] = React8.useState(false);
|
|
3595
|
+
const [isCloseToBottom, setCloseToBottom] = React8.useState(false);
|
|
3596
|
+
const innerValues = React8.useMemo(() => {
|
|
3499
3597
|
const vals = [];
|
|
3500
3598
|
for (let i = lowerLimit; i <= upperLimit; i++) vals.push(i);
|
|
3501
3599
|
return vals;
|
|
3502
3600
|
}, [lowerLimit, upperLimit]);
|
|
3503
|
-
|
|
3601
|
+
React8.useEffect(() => {
|
|
3504
3602
|
const clickAway = (e) => {
|
|
3505
3603
|
if (pickerRef.current && !pickerRef.current.contains(e.target) && calendarRef.current && !calendarRef.current.contains(e.target)) setExpanded(false);
|
|
3506
3604
|
};
|
|
3507
3605
|
document.addEventListener("mousedown", clickAway);
|
|
3508
3606
|
return () => document.removeEventListener("mousedown", clickAway);
|
|
3509
3607
|
}, []);
|
|
3510
|
-
|
|
3608
|
+
React8.useEffect(() => {
|
|
3511
3609
|
const bbox = pickerRef.current?.getBoundingClientRect();
|
|
3512
3610
|
if (bbox && bbox.y > window.innerHeight - 220) setCloseToBottom(true);
|
|
3513
3611
|
else setCloseToBottom(false);
|
|
3514
3612
|
}, []);
|
|
3515
|
-
|
|
3613
|
+
React8.useEffect(() => {
|
|
3516
3614
|
if (!isExpanded) return;
|
|
3517
3615
|
const t = setTimeout(() => {
|
|
3518
3616
|
const node = valueRefs.current.find((n) => n.value === value);
|