@geomak/ui 1.5.0 → 1.5.2
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 +121 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +121 -52
- package/dist/index.js.map +1 -1
- package/dist/styles.css +37 -86
- package/package.json +15 -3
package/dist/index.d.cts
CHANGED
|
@@ -273,8 +273,13 @@ interface IconButtonProps {
|
|
|
273
273
|
declare function IconButton({ icon, onClick, type, buttonType, disabled, size, loading, loadingIcon, }: IconButtonProps): react_jsx_runtime.JSX.Element;
|
|
274
274
|
|
|
275
275
|
interface ModalProps {
|
|
276
|
-
/**
|
|
277
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Max width of the modal panel in pixels (default 600).
|
|
278
|
+
* On narrow viewports the panel fills the screen minus 1 rem on each side.
|
|
279
|
+
* Height is always content-driven — `size[1]` is accepted for backwards
|
|
280
|
+
* compatibility but is no longer used; remove it when convenient.
|
|
281
|
+
*/
|
|
282
|
+
size?: [number, number] | [number];
|
|
278
283
|
isOpen?: boolean;
|
|
279
284
|
onClose?: () => void;
|
|
280
285
|
onOk?: () => void;
|
|
@@ -375,7 +380,7 @@ interface TabsProps {
|
|
|
375
380
|
* Scrollable pill-style tabs powered by Radix Tabs.
|
|
376
381
|
*
|
|
377
382
|
* Radix handles roving-tabindex keyboard navigation and ARIA roles.
|
|
378
|
-
*
|
|
383
|
+
* Rounded pill style, fully themed via semantic design tokens.
|
|
379
384
|
* Supports dynamic tab add/remove with automatic activation.
|
|
380
385
|
*
|
|
381
386
|
* @example
|
|
@@ -932,6 +937,9 @@ interface AppShellProps {
|
|
|
932
937
|
/**
|
|
933
938
|
* Top navigation bar.
|
|
934
939
|
* Typically `<TopBar brand={...} actions={...} />`.
|
|
940
|
+
* On mobile, a hamburger button is injected to the left of this slot when
|
|
941
|
+
* `sidebarSections` is non-empty. The TopBar should leave some leading space
|
|
942
|
+
* (or use its `center` / `actions` props) to avoid overlap.
|
|
935
943
|
*/
|
|
936
944
|
topBar?: React$1.ReactNode;
|
|
937
945
|
/** Sidebar navigation sections */
|
|
@@ -953,7 +961,12 @@ interface AppShellProps {
|
|
|
953
961
|
* Full-page application layout skeleton.
|
|
954
962
|
*
|
|
955
963
|
* Composes a sticky TopBar + collapsible Sidebar + scrollable content area.
|
|
956
|
-
*
|
|
964
|
+
*
|
|
965
|
+
* **Responsive behaviour:**
|
|
966
|
+
* - **≥ md (768 px):** Sidebar renders inline, collapsible via its own toggle.
|
|
967
|
+
* - **< md (mobile):** Sidebar becomes a fixed overlay drawer. A hamburger
|
|
968
|
+
* button appears to the left of the TopBar slot to open it. Tapping the
|
|
969
|
+
* backdrop or the sidebar's own toggle closes it.
|
|
957
970
|
*
|
|
958
971
|
* @example
|
|
959
972
|
* <AppShell
|
package/dist/index.d.ts
CHANGED
|
@@ -273,8 +273,13 @@ interface IconButtonProps {
|
|
|
273
273
|
declare function IconButton({ icon, onClick, type, buttonType, disabled, size, loading, loadingIcon, }: IconButtonProps): react_jsx_runtime.JSX.Element;
|
|
274
274
|
|
|
275
275
|
interface ModalProps {
|
|
276
|
-
/**
|
|
277
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Max width of the modal panel in pixels (default 600).
|
|
278
|
+
* On narrow viewports the panel fills the screen minus 1 rem on each side.
|
|
279
|
+
* Height is always content-driven — `size[1]` is accepted for backwards
|
|
280
|
+
* compatibility but is no longer used; remove it when convenient.
|
|
281
|
+
*/
|
|
282
|
+
size?: [number, number] | [number];
|
|
278
283
|
isOpen?: boolean;
|
|
279
284
|
onClose?: () => void;
|
|
280
285
|
onOk?: () => void;
|
|
@@ -375,7 +380,7 @@ interface TabsProps {
|
|
|
375
380
|
* Scrollable pill-style tabs powered by Radix Tabs.
|
|
376
381
|
*
|
|
377
382
|
* Radix handles roving-tabindex keyboard navigation and ARIA roles.
|
|
378
|
-
*
|
|
383
|
+
* Rounded pill style, fully themed via semantic design tokens.
|
|
379
384
|
* Supports dynamic tab add/remove with automatic activation.
|
|
380
385
|
*
|
|
381
386
|
* @example
|
|
@@ -932,6 +937,9 @@ interface AppShellProps {
|
|
|
932
937
|
/**
|
|
933
938
|
* Top navigation bar.
|
|
934
939
|
* Typically `<TopBar brand={...} actions={...} />`.
|
|
940
|
+
* On mobile, a hamburger button is injected to the left of this slot when
|
|
941
|
+
* `sidebarSections` is non-empty. The TopBar should leave some leading space
|
|
942
|
+
* (or use its `center` / `actions` props) to avoid overlap.
|
|
935
943
|
*/
|
|
936
944
|
topBar?: React$1.ReactNode;
|
|
937
945
|
/** Sidebar navigation sections */
|
|
@@ -953,7 +961,12 @@ interface AppShellProps {
|
|
|
953
961
|
* Full-page application layout skeleton.
|
|
954
962
|
*
|
|
955
963
|
* Composes a sticky TopBar + collapsible Sidebar + scrollable content area.
|
|
956
|
-
*
|
|
964
|
+
*
|
|
965
|
+
* **Responsive behaviour:**
|
|
966
|
+
* - **≥ md (768 px):** Sidebar renders inline, collapsible via its own toggle.
|
|
967
|
+
* - **< md (mobile):** Sidebar becomes a fixed overlay drawer. A hamburger
|
|
968
|
+
* button appears to the left of the TopBar slot to open it. Tapping the
|
|
969
|
+
* backdrop or the sidebar's own toggle closes it.
|
|
957
970
|
*
|
|
958
971
|
* @example
|
|
959
972
|
* <AppShell
|
package/dist/index.js
CHANGED
|
@@ -305,7 +305,7 @@ function Modal({
|
|
|
305
305
|
/* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx(Dialog.Overlay, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
306
306
|
motion.div,
|
|
307
307
|
{
|
|
308
|
-
className: "fixed inset-0 bg-
|
|
308
|
+
className: "fixed inset-0 bg-black/40 z-overlay",
|
|
309
309
|
initial: { opacity: 0 },
|
|
310
310
|
animate: { opacity: 1 },
|
|
311
311
|
exit: { opacity: 0 },
|
|
@@ -315,10 +315,9 @@ function Modal({
|
|
|
315
315
|
/* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx(Dialog.Content, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
316
316
|
motion.div,
|
|
317
317
|
{
|
|
318
|
-
className: "fixed left-1/2 top-1/2 z-
|
|
318
|
+
className: "fixed left-1/2 top-1/2 z-modal flex flex-col w-[calc(100%-2rem)] max-h-[90dvh] bg-surface rounded-2xl shadow-xl overflow-hidden focus:outline-none",
|
|
319
319
|
style: {
|
|
320
|
-
|
|
321
|
-
height: size[1],
|
|
320
|
+
maxWidth: size[0],
|
|
322
321
|
x: "-50%",
|
|
323
322
|
y: "-50%"
|
|
324
323
|
},
|
|
@@ -332,19 +331,19 @@ function Modal({
|
|
|
332
331
|
duration: 0.25
|
|
333
332
|
},
|
|
334
333
|
children: [
|
|
335
|
-
/* @__PURE__ */ jsxs("div", { className: "flex h-14 flex-shrink-0 items-center justify-between border-b border-
|
|
336
|
-
/* @__PURE__ */ jsx(Dialog.Title, { className: "text-base font-semibold text-
|
|
334
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-14 flex-shrink-0 items-center justify-between border-b border-border px-5", children: [
|
|
335
|
+
/* @__PURE__ */ jsx(Dialog.Title, { className: "text-base font-semibold text-foreground tracking-tight", children: title }),
|
|
337
336
|
/* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
338
337
|
"button",
|
|
339
338
|
{
|
|
340
339
|
"aria-label": "Close",
|
|
341
|
-
className: "flex h-7 w-7 items-center justify-center rounded-lg text-
|
|
340
|
+
className: "flex h-7 w-7 items-center justify-center rounded-lg text-foreground-muted hover:bg-surface-raised hover:text-foreground transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
342
341
|
children: /* @__PURE__ */ jsx("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z", fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd" }) })
|
|
343
342
|
}
|
|
344
343
|
) })
|
|
345
344
|
] }),
|
|
346
345
|
/* @__PURE__ */ jsx("div", { className: `flex-1 overflow-y-auto p-5 ${hasFooter ? "" : "pb-5"}`, children: isOpen && children }),
|
|
347
|
-
hasFooter && /* @__PURE__ */ jsxs("div", { className: "flex flex-shrink-0 items-center justify-end gap-3 border-t border-
|
|
346
|
+
hasFooter && /* @__PURE__ */ jsxs("div", { className: "flex flex-shrink-0 items-center justify-end gap-3 border-t border-border px-5 py-3", children: [
|
|
348
347
|
/* @__PURE__ */ jsx(
|
|
349
348
|
Button,
|
|
350
349
|
{
|
|
@@ -389,7 +388,7 @@ function Drawer({
|
|
|
389
388
|
/* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx(Dialog.Overlay, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
390
389
|
motion.div,
|
|
391
390
|
{
|
|
392
|
-
className: "fixed inset-0 bg-
|
|
391
|
+
className: "fixed inset-0 bg-black/40 z-overlay",
|
|
393
392
|
initial: { opacity: 0 },
|
|
394
393
|
animate: { opacity: 1 },
|
|
395
394
|
exit: { opacity: 0 },
|
|
@@ -399,8 +398,8 @@ function Drawer({
|
|
|
399
398
|
/* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx(Dialog.Content, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
400
399
|
motion.div,
|
|
401
400
|
{
|
|
402
|
-
className: `fixed top-0 bottom-0 ${isRight ? "right-0" : "left-0"} z-
|
|
403
|
-
style: { width },
|
|
401
|
+
className: `fixed top-0 bottom-0 ${isRight ? "right-0" : "left-0"} z-modal flex flex-col bg-surface shadow-xl focus:outline-none`,
|
|
402
|
+
style: { width: `min(calc(100vw - 1rem), ${width}px)` },
|
|
404
403
|
initial: { x: reduced ? 0 : hiddenX, opacity: reduced ? 0 : 1 },
|
|
405
404
|
animate: { x: 0, opacity: 1 },
|
|
406
405
|
exit: { x: reduced ? 0 : hiddenX, opacity: reduced ? 0 : 1 },
|
|
@@ -414,19 +413,19 @@ function Drawer({
|
|
|
414
413
|
opacity: { duration: 0 }
|
|
415
414
|
},
|
|
416
415
|
children: [
|
|
417
|
-
/* @__PURE__ */ jsxs("div", { className: `flex h-14 flex-shrink-0 items-center justify-between border-b border-
|
|
418
|
-
/* @__PURE__ */ jsx(Dialog.Title, { className: "text-base font-semibold text-
|
|
416
|
+
/* @__PURE__ */ jsxs("div", { className: `flex h-14 flex-shrink-0 items-center justify-between border-b border-border px-5 ${isRight ? "flex-row-reverse" : ""}`, children: [
|
|
417
|
+
/* @__PURE__ */ jsx(Dialog.Title, { className: "text-base font-semibold text-foreground tracking-tight", children: title }),
|
|
419
418
|
/* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
420
419
|
"button",
|
|
421
420
|
{
|
|
422
421
|
"aria-label": "Close drawer",
|
|
423
|
-
className: "flex h-7 w-7 items-center justify-center rounded-lg text-
|
|
422
|
+
className: "flex h-7 w-7 items-center justify-center rounded-lg text-foreground-muted hover:bg-surface-raised hover:text-foreground transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
424
423
|
children: /* @__PURE__ */ jsx("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z", fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd" }) })
|
|
425
424
|
}
|
|
426
425
|
) })
|
|
427
426
|
] }),
|
|
428
427
|
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-5", children: isOpen && children }),
|
|
429
|
-
hasFooter && /* @__PURE__ */ jsxs("div", { className: `flex flex-shrink-0 items-center gap-3 border-t border-
|
|
428
|
+
hasFooter && /* @__PURE__ */ jsxs("div", { className: `flex flex-shrink-0 items-center gap-3 border-t border-border px-5 py-3 ${isRight ? "justify-start" : "justify-end"}`, children: [
|
|
430
429
|
/* @__PURE__ */ jsx(Button, { style: { width: 90 }, content: cancelText, onClick: onCancel }),
|
|
431
430
|
/* @__PURE__ */ jsx(Button, { style: { width: 90 }, content: okText, onClick: onOk })
|
|
432
431
|
] })
|
|
@@ -528,15 +527,15 @@ function Tabs({
|
|
|
528
527
|
onValueChange: handleValueChange,
|
|
529
528
|
className: "h-full max-w-full flex flex-col gap-2",
|
|
530
529
|
children: [
|
|
531
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
530
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-surface border border-border rounded-lg flex items-center justify-between flex-shrink-0 w-full p-1 overflow-hidden", children: [
|
|
532
531
|
/* @__PURE__ */ jsx(
|
|
533
532
|
"button",
|
|
534
533
|
{
|
|
535
534
|
type: "button",
|
|
536
535
|
onClick: toPreviousTab,
|
|
537
536
|
"aria-label": "Previous tab",
|
|
538
|
-
className: "cursor-pointer rounded-lg transition-
|
|
539
|
-
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke:
|
|
537
|
+
className: "cursor-pointer rounded-lg transition-colors duration-150 hover:bg-surface-raised text-foreground-secondary hover:text-foreground rotate-180 flex-shrink-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
538
|
+
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-6 w-6", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
540
539
|
}
|
|
541
540
|
),
|
|
542
541
|
/* @__PURE__ */ jsx(
|
|
@@ -548,7 +547,7 @@ function Tabs({
|
|
|
548
547
|
TabsPrimitive.Trigger,
|
|
549
548
|
{
|
|
550
549
|
value: tab.key,
|
|
551
|
-
className: "snap-start snap-always flex items-center justify-between gap-2
|
|
550
|
+
className: "snap-start snap-always flex items-center justify-between gap-2 px-3 py-2 rounded-3xl cursor-pointer transition-all duration-200 select-none h-10 flex-1 min-w-[120px] max-w-[220px] flex-shrink-0\n text-foreground-secondary bg-surface-raised\n hover:bg-surface hover:text-foreground\n data-[state=active]:bg-accent data-[state=active]:text-accent-foreground\n focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
552
551
|
children: [
|
|
553
552
|
/* @__PURE__ */ jsx("span", { className: "truncate text-sm", children: tab.title }),
|
|
554
553
|
tabsClosable && /* @__PURE__ */ jsx(
|
|
@@ -560,8 +559,8 @@ function Tabs({
|
|
|
560
559
|
e.stopPropagation();
|
|
561
560
|
onTabClose?.(tab.key);
|
|
562
561
|
},
|
|
563
|
-
className: "flex-shrink-0 rounded hover:bg-
|
|
564
|
-
children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke:
|
|
562
|
+
className: "flex-shrink-0 rounded hover:bg-black/10 p-0.5 transition-colors",
|
|
563
|
+
children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
565
564
|
}
|
|
566
565
|
)
|
|
567
566
|
]
|
|
@@ -576,12 +575,12 @@ function Tabs({
|
|
|
576
575
|
type: "button",
|
|
577
576
|
onClick: toNextTab,
|
|
578
577
|
"aria-label": "Next tab",
|
|
579
|
-
className: "cursor-pointer rounded-lg transition-
|
|
580
|
-
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke:
|
|
578
|
+
className: "cursor-pointer rounded-lg transition-colors duration-150 hover:bg-surface-raised text-foreground-secondary hover:text-foreground flex-shrink-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
579
|
+
children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-6 w-6", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
581
580
|
}
|
|
582
581
|
)
|
|
583
582
|
] }),
|
|
584
|
-
/* @__PURE__ */ jsx("div", { className: "p-2 rounded-lg w-full h-
|
|
583
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 rounded-lg w-full flex-1 min-h-0 bg-surface border border-border overflow-hidden", children: isLazy ? (
|
|
585
584
|
// Mount only the active content
|
|
586
585
|
tabs.filter((t) => t.key === value).map((t) => /* @__PURE__ */ jsx(TabsPrimitive.Content, { value: t.key, className: "w-full h-full focus:outline-none", children: t.content }, t.key))
|
|
587
586
|
) : (
|
|
@@ -605,7 +604,7 @@ function TreeNodeItem({
|
|
|
605
604
|
"button",
|
|
606
605
|
{
|
|
607
606
|
type: "button",
|
|
608
|
-
className: "flex w-full items-center gap-2.5 cursor-pointer select-none group text-left rounded-md px-2 py-1.5 hover:bg-
|
|
607
|
+
className: "flex w-full items-center gap-2.5 cursor-pointer select-none group text-left rounded-md px-2 py-1.5 hover:bg-surface-raised transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
609
608
|
style: { paddingLeft: depth * 12 + 8 },
|
|
610
609
|
onClick: () => onNodeClick({
|
|
611
610
|
isParent: false,
|
|
@@ -615,8 +614,8 @@ function TreeNodeItem({
|
|
|
615
614
|
parentLabel: item.parentLabel
|
|
616
615
|
}),
|
|
617
616
|
children: [
|
|
618
|
-
/* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full flex-shrink-0 bg-
|
|
619
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-
|
|
617
|
+
/* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full flex-shrink-0 bg-foreground-muted group-hover:bg-accent transition-colors duration-150" }),
|
|
618
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground-secondary group-hover:text-foreground transition-colors duration-150", children: item.label })
|
|
620
619
|
]
|
|
621
620
|
}
|
|
622
621
|
);
|
|
@@ -629,7 +628,7 @@ function TreeNodeItem({
|
|
|
629
628
|
defaultValue: initialOpen,
|
|
630
629
|
style: { paddingLeft: depth * 12 },
|
|
631
630
|
children: /* @__PURE__ */ jsxs(Accordion.Item, { value: item.key, className: "border-none", children: [
|
|
632
|
-
/* @__PURE__ */ jsxs(Accordion.Trigger, { className: "flex items-center gap-2 cursor-pointer py-1.5 px-2 group focus:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
631
|
+
/* @__PURE__ */ jsxs(Accordion.Trigger, { className: "flex items-center gap-2 cursor-pointer py-1.5 px-2 group focus:outline-none focus-visible:ring-2 focus-visible:ring-accent w-full text-left rounded-md hover:bg-surface-raised transition-colors duration-150", children: [
|
|
633
632
|
/* @__PURE__ */ jsx(
|
|
634
633
|
"svg",
|
|
635
634
|
{
|
|
@@ -637,7 +636,7 @@ function TreeNodeItem({
|
|
|
637
636
|
fill: "none",
|
|
638
637
|
stroke: "currentColor",
|
|
639
638
|
strokeWidth: 2.5,
|
|
640
|
-
className: "h-3.5 w-3.5 flex-shrink-0 text-
|
|
639
|
+
className: "h-3.5 w-3.5 flex-shrink-0 text-foreground-muted transition-transform duration-200 group-data-[state=open]:rotate-0 group-data-[state=closed]:-rotate-90",
|
|
641
640
|
children: /* @__PURE__ */ jsx(
|
|
642
641
|
"path",
|
|
643
642
|
{
|
|
@@ -651,7 +650,7 @@ function TreeNodeItem({
|
|
|
651
650
|
/* @__PURE__ */ jsx(
|
|
652
651
|
"span",
|
|
653
652
|
{
|
|
654
|
-
className: "text-sm font-semibold text-
|
|
653
|
+
className: "text-sm font-semibold text-foreground select-none",
|
|
655
654
|
onClick: () => onNodeClick({
|
|
656
655
|
isParent: true,
|
|
657
656
|
key: item.key,
|
|
@@ -663,7 +662,7 @@ function TreeNodeItem({
|
|
|
663
662
|
}
|
|
664
663
|
)
|
|
665
664
|
] }),
|
|
666
|
-
/* @__PURE__ */ jsx(Accordion.Content, { className: "overflow-hidden data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up", children: /* @__PURE__ */ jsx("div", { className: "ml-3.5 border-l border-
|
|
665
|
+
/* @__PURE__ */ jsx(Accordion.Content, { className: "overflow-hidden data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up", children: /* @__PURE__ */ jsx("div", { className: "ml-3.5 border-l border-border py-0.5", children: item.children.map((child) => /* @__PURE__ */ jsx(
|
|
667
666
|
TreeNodeItem,
|
|
668
667
|
{
|
|
669
668
|
item: child,
|
|
@@ -1617,10 +1616,10 @@ function createDatasets(rows, perPage) {
|
|
|
1617
1616
|
return all;
|
|
1618
1617
|
}
|
|
1619
1618
|
function TableHeader({ columns }) {
|
|
1620
|
-
return /* @__PURE__ */ jsx("thead", { className: "
|
|
1619
|
+
return /* @__PURE__ */ jsx("thead", { className: "bg-surface-raised min-h-[50px] border-b border-b-border flex items-center", children: /* @__PURE__ */ jsx("tr", { className: "flex w-full items-center justify-center", children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
1621
1620
|
"th",
|
|
1622
1621
|
{
|
|
1623
|
-
className: "text-center w-full text-[13px] text-
|
|
1622
|
+
className: "text-center w-full text-[13px] text-foreground",
|
|
1624
1623
|
children: col.label
|
|
1625
1624
|
},
|
|
1626
1625
|
col.key
|
|
@@ -1651,7 +1650,7 @@ function TableBody({
|
|
|
1651
1650
|
/* @__PURE__ */ jsxs(
|
|
1652
1651
|
"tr",
|
|
1653
1652
|
{
|
|
1654
|
-
className: `border-b border-b-
|
|
1653
|
+
className: `border-b border-b-border flex min-w-max hover:bg-surface-raised transition-all duration-150 ${i % 2 === 0 ? "bg-surface" : "bg-surface-raised"}`,
|
|
1655
1654
|
children: [
|
|
1656
1655
|
expandRow.enabled && /* @__PURE__ */ jsx("td", { className: "flex items-center", children: /* @__PURE__ */ jsx(
|
|
1657
1656
|
"span",
|
|
@@ -1659,13 +1658,13 @@ function TableBody({
|
|
|
1659
1658
|
onClick: () => toggleRow(row.key),
|
|
1660
1659
|
className: `p-2 cursor-pointer origin-center transition-all duration-200 ${visibleRows[row.key]?.visible ? "rotate-180" : "rotate-0"}`,
|
|
1661
1660
|
children: expandRow.expandIcon ?? /* PlusCircle */
|
|
1662
|
-
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill:
|
|
1661
|
+
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-5 h-5 text-foreground-muted", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75 9a.75.75 0 00-1.5 0v2.25H9a.75.75 0 000 1.5h2.25V15a.75.75 0 001.5 0v-2.25H15a.75.75 0 000-1.5h-2.25V9z", clipRule: "evenodd" }) })
|
|
1663
1662
|
}
|
|
1664
1663
|
) }),
|
|
1665
1664
|
columns.map((col, index) => /* @__PURE__ */ jsx(
|
|
1666
1665
|
"td",
|
|
1667
1666
|
{
|
|
1668
|
-
className: `text-center min-h-[40px] w-full flex items-center justify-center p-1 border-
|
|
1667
|
+
className: `text-center min-h-[40px] w-full flex items-center justify-center p-1 border-border ${index !== columns.length - 1 ? "border-r-2" : ""}`,
|
|
1669
1668
|
children: "component" in col && col.component ? col.component(row[col.keyBind], row) : row[col.keyBind]
|
|
1670
1669
|
},
|
|
1671
1670
|
index
|
|
@@ -1712,8 +1711,8 @@ function Pagination({
|
|
|
1712
1711
|
const navBtn = (icon, disabled, onClick) => /* @__PURE__ */ jsx(IconButton, { disabled, onClick, icon });
|
|
1713
1712
|
const chevronRight = (color) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2, className: "h-5 w-5", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
|
|
1714
1713
|
const doubleChevronRight = (color) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2, className: "h-5 w-5", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 5l7 7-7 7M5 5l7 7-7 7" }) });
|
|
1715
|
-
const disabledColor =
|
|
1716
|
-
const enabledColor =
|
|
1714
|
+
const disabledColor = "var(--color-foreground-muted)";
|
|
1715
|
+
const enabledColor = "var(--color-foreground)";
|
|
1717
1716
|
return /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center justify-end pt-2", children: [
|
|
1718
1717
|
navBtn(
|
|
1719
1718
|
/* @__PURE__ */ jsx("span", { className: "rotate-180 inline-flex", children: doubleChevronRight(activePage === 0 ? disabledColor : enabledColor) }),
|
|
@@ -1725,7 +1724,7 @@ function Pagination({
|
|
|
1725
1724
|
activePage === 0,
|
|
1726
1725
|
() => activePage > 0 && onPageChange(activePage - 1)
|
|
1727
1726
|
),
|
|
1728
|
-
/* @__PURE__ */ jsx("span", { className: "bg-
|
|
1727
|
+
/* @__PURE__ */ jsx("span", { className: "bg-surface-raised rounded-lg ml-2 mr-2 shadow-sm p-2 w-10 text-center select-none text-foreground", children: activePage + 1 }),
|
|
1729
1728
|
navBtn(
|
|
1730
1729
|
chevronRight(activePage === maxPage ? disabledColor : enabledColor),
|
|
1731
1730
|
activePage === maxPage,
|
|
@@ -1843,10 +1842,10 @@ function Table({
|
|
|
1843
1842
|
)
|
|
1844
1843
|
] }),
|
|
1845
1844
|
/* @__PURE__ */ jsx("div", { children: header }),
|
|
1846
|
-
/* @__PURE__ */ jsxs("table", { className: "w-full
|
|
1845
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg", children: /* @__PURE__ */ jsxs("table", { className: "w-full", children: [
|
|
1847
1846
|
/* @__PURE__ */ jsx(TableHeader, { columns }),
|
|
1848
1847
|
/* @__PURE__ */ jsx(TableBody, { columns, rows: currentPageRows, expandRow })
|
|
1849
|
-
] }),
|
|
1848
|
+
] }) }),
|
|
1850
1849
|
/* @__PURE__ */ jsx("div", { children: footer })
|
|
1851
1850
|
] });
|
|
1852
1851
|
}
|
|
@@ -2045,10 +2044,48 @@ function AppShell({
|
|
|
2045
2044
|
className = ""
|
|
2046
2045
|
}) {
|
|
2047
2046
|
const [expanded, setExpanded] = useState(sidebarDefaultExpanded);
|
|
2047
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
2048
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
2049
|
+
useEffect(() => {
|
|
2050
|
+
const mq = window.matchMedia("(max-width: 767px)");
|
|
2051
|
+
const update = (e) => setIsMobile(e.matches);
|
|
2052
|
+
update(mq);
|
|
2053
|
+
mq.addEventListener("change", update);
|
|
2054
|
+
return () => mq.removeEventListener("change", update);
|
|
2055
|
+
}, []);
|
|
2056
|
+
useEffect(() => {
|
|
2057
|
+
if (!isMobile) setMobileOpen(false);
|
|
2058
|
+
}, [isMobile]);
|
|
2059
|
+
const hasSidebar = sidebarSections.length > 0;
|
|
2048
2060
|
return /* @__PURE__ */ jsxs("div", { className: `flex flex-col h-screen bg-background ${className}`, children: [
|
|
2049
|
-
topBar && /* @__PURE__ */
|
|
2061
|
+
topBar && /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 flex items-stretch z-topbar", children: [
|
|
2062
|
+
hasSidebar && /* @__PURE__ */ jsx(
|
|
2063
|
+
"button",
|
|
2064
|
+
{
|
|
2065
|
+
type: "button",
|
|
2066
|
+
className: [
|
|
2067
|
+
"md:hidden flex-shrink-0 self-stretch flex items-center justify-center w-14",
|
|
2068
|
+
"border-r border-border",
|
|
2069
|
+
"text-foreground-secondary hover:bg-surface-raised hover:text-foreground",
|
|
2070
|
+
"transition-colors duration-100",
|
|
2071
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent"
|
|
2072
|
+
].join(" "),
|
|
2073
|
+
onClick: () => setMobileOpen((o) => !o),
|
|
2074
|
+
"aria-label": mobileOpen ? "Close navigation" : "Open navigation",
|
|
2075
|
+
"aria-expanded": mobileOpen,
|
|
2076
|
+
children: mobileOpen ? (
|
|
2077
|
+
/* X icon */
|
|
2078
|
+
/* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
2079
|
+
) : (
|
|
2080
|
+
/* Hamburger icon */
|
|
2081
|
+
/* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M4 6h16M4 12h16M4 18h16" }) })
|
|
2082
|
+
)
|
|
2083
|
+
}
|
|
2084
|
+
),
|
|
2085
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: topBar })
|
|
2086
|
+
] }),
|
|
2050
2087
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
2051
|
-
|
|
2088
|
+
hasSidebar && !isMobile && /* @__PURE__ */ jsx(
|
|
2052
2089
|
Sidebar,
|
|
2053
2090
|
{
|
|
2054
2091
|
sections: sidebarSections,
|
|
@@ -2059,15 +2096,47 @@ function AppShell({
|
|
|
2059
2096
|
footer: sidebarFooter
|
|
2060
2097
|
}
|
|
2061
2098
|
),
|
|
2062
|
-
/* @__PURE__ */
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2099
|
+
hasSidebar && isMobile && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2100
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: mobileOpen && /* @__PURE__ */ jsx(
|
|
2101
|
+
motion.div,
|
|
2102
|
+
{
|
|
2103
|
+
className: "fixed inset-0 bg-black/40 z-overlay md:hidden",
|
|
2104
|
+
initial: { opacity: 0 },
|
|
2105
|
+
animate: { opacity: 1 },
|
|
2106
|
+
exit: { opacity: 0 },
|
|
2107
|
+
transition: { duration: 0.2, ease: "easeOut" },
|
|
2108
|
+
onClick: () => setMobileOpen(false),
|
|
2109
|
+
"aria-hidden": "true"
|
|
2110
|
+
}
|
|
2111
|
+
) }),
|
|
2112
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: mobileOpen && /* @__PURE__ */ jsx(
|
|
2113
|
+
motion.div,
|
|
2114
|
+
{
|
|
2115
|
+
className: "fixed inset-y-0 left-0 z-modal md:hidden",
|
|
2116
|
+
initial: { x: "-100%" },
|
|
2117
|
+
animate: { x: 0 },
|
|
2118
|
+
exit: { x: "-100%" },
|
|
2119
|
+
transition: {
|
|
2120
|
+
type: "tween",
|
|
2121
|
+
duration: 0.26,
|
|
2122
|
+
ease: [0.16, 1, 0.3, 1]
|
|
2123
|
+
// ease-out-expo
|
|
2124
|
+
},
|
|
2125
|
+
children: /* @__PURE__ */ jsx(
|
|
2126
|
+
Sidebar,
|
|
2127
|
+
{
|
|
2128
|
+
sections: sidebarSections,
|
|
2129
|
+
isExpanded: true,
|
|
2130
|
+
onToggle: () => setMobileOpen(false),
|
|
2131
|
+
expandedWidth: sidebarExpandedWidth,
|
|
2132
|
+
collapsedWidth: sidebarCollapsedWidth,
|
|
2133
|
+
footer: sidebarFooter
|
|
2134
|
+
}
|
|
2135
|
+
)
|
|
2136
|
+
}
|
|
2137
|
+
) })
|
|
2138
|
+
] }),
|
|
2139
|
+
/* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto overflow-x-hidden", children: /* @__PURE__ */ jsx("div", { className: "h-full p-6", children }) })
|
|
2071
2140
|
] })
|
|
2072
2141
|
] });
|
|
2073
2142
|
}
|