@memelabui/ui 0.8.1 → 0.9.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/README.md +427 -429
- package/dist/index.cjs +2308 -844
- package/dist/index.d.cts +272 -25
- package/dist/index.d.ts +272 -25
- package/dist/index.js +2307 -846
- package/dist/styles/index.css +2775 -2496
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useState, useId, useRef, useMemo, useEffect, createContext, useCallback, isValidElement, cloneElement, useReducer, useContext, Component } from 'react';
|
|
1
|
+
import React, { forwardRef, useState, useId, useRef, useMemo, useEffect, createContext, useCallback, isValidElement, cloneElement, useReducer, useContext, Fragment as Fragment$1, Component } from 'react';
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
|
|
@@ -95,11 +95,11 @@ function useDisclosure(defaultOpen = false) {
|
|
|
95
95
|
}
|
|
96
96
|
function useMediaQuery(query) {
|
|
97
97
|
const [matches, setMatches] = useState(() => {
|
|
98
|
-
if (typeof window === "undefined") return false;
|
|
98
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
99
99
|
return window.matchMedia(query).matches;
|
|
100
100
|
});
|
|
101
101
|
useEffect(() => {
|
|
102
|
-
if (typeof window === "undefined") return;
|
|
102
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
103
103
|
const mediaQueryList = window.matchMedia(query);
|
|
104
104
|
setMatches(mediaQueryList.matches);
|
|
105
105
|
const handler = (event) => {
|
|
@@ -454,6 +454,765 @@ var SearchInput = forwardRef(function SearchInput2({ label, onClear, className,
|
|
|
454
454
|
wrapper
|
|
455
455
|
] });
|
|
456
456
|
});
|
|
457
|
+
var sizeClass4 = {
|
|
458
|
+
left: { sm: "w-64", md: "w-80", lg: "w-96", full: "w-screen" },
|
|
459
|
+
right: { sm: "w-64", md: "w-80", lg: "w-96", full: "w-screen" },
|
|
460
|
+
bottom: { sm: "h-1/4", md: "h-1/3", lg: "h-1/2", full: "h-screen" }
|
|
461
|
+
};
|
|
462
|
+
var positionClass = {
|
|
463
|
+
left: "inset-y-0 left-0",
|
|
464
|
+
right: "inset-y-0 right-0",
|
|
465
|
+
bottom: "inset-x-0 bottom-0"
|
|
466
|
+
};
|
|
467
|
+
var slideIn = {
|
|
468
|
+
left: "translate-x-0",
|
|
469
|
+
right: "translate-x-0",
|
|
470
|
+
bottom: "translate-y-0"
|
|
471
|
+
};
|
|
472
|
+
var slideOut = {
|
|
473
|
+
left: "-translate-x-full",
|
|
474
|
+
right: "translate-x-full",
|
|
475
|
+
bottom: "translate-y-full"
|
|
476
|
+
};
|
|
477
|
+
function Drawer({
|
|
478
|
+
isOpen,
|
|
479
|
+
onClose,
|
|
480
|
+
children,
|
|
481
|
+
side = "right",
|
|
482
|
+
size = "md",
|
|
483
|
+
ariaLabel,
|
|
484
|
+
closeOnBackdrop = true,
|
|
485
|
+
closeOnEsc = true,
|
|
486
|
+
className
|
|
487
|
+
}) {
|
|
488
|
+
const panelRef = useRef(null);
|
|
489
|
+
const lastActiveRef = useRef(null);
|
|
490
|
+
useEffect(() => {
|
|
491
|
+
if (!isOpen) return;
|
|
492
|
+
lastActiveRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
493
|
+
const raf = requestAnimationFrame(() => {
|
|
494
|
+
const el = panelRef.current;
|
|
495
|
+
if (!el) return;
|
|
496
|
+
const focusables = getFocusableElements(el);
|
|
497
|
+
focusSafely(focusables[0] ?? el);
|
|
498
|
+
});
|
|
499
|
+
return () => {
|
|
500
|
+
cancelAnimationFrame(raf);
|
|
501
|
+
const lastActive = lastActiveRef.current;
|
|
502
|
+
lastActiveRef.current = null;
|
|
503
|
+
if (lastActive?.isConnected) focusSafely(lastActive);
|
|
504
|
+
};
|
|
505
|
+
}, [isOpen]);
|
|
506
|
+
useScrollLock(isOpen);
|
|
507
|
+
if (!isOpen) return null;
|
|
508
|
+
return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50", role: "presentation", children: [
|
|
509
|
+
/* @__PURE__ */ jsx(
|
|
510
|
+
"div",
|
|
511
|
+
{
|
|
512
|
+
className: "absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity duration-200",
|
|
513
|
+
"aria-hidden": "true",
|
|
514
|
+
onClick: closeOnBackdrop ? onClose : void 0
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
/* @__PURE__ */ jsx(
|
|
518
|
+
"div",
|
|
519
|
+
{
|
|
520
|
+
ref: panelRef,
|
|
521
|
+
role: "dialog",
|
|
522
|
+
"aria-modal": "true",
|
|
523
|
+
"aria-label": ariaLabel,
|
|
524
|
+
tabIndex: -1,
|
|
525
|
+
className: cn(
|
|
526
|
+
"fixed flex flex-col bg-surface-50 shadow-2xl ring-1 ring-white/10 transition-transform duration-300 ease-out focus:outline-none",
|
|
527
|
+
positionClass[side],
|
|
528
|
+
sizeClass4[side][size],
|
|
529
|
+
isOpen ? slideIn[side] : slideOut[side],
|
|
530
|
+
className
|
|
531
|
+
),
|
|
532
|
+
onKeyDownCapture: (e) => {
|
|
533
|
+
if (closeOnEsc && e.key === "Escape") {
|
|
534
|
+
e.preventDefault();
|
|
535
|
+
e.stopPropagation();
|
|
536
|
+
onClose();
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (e.key !== "Tab") return;
|
|
540
|
+
const el = panelRef.current;
|
|
541
|
+
if (!el) return;
|
|
542
|
+
const focusables = getFocusableElements(el);
|
|
543
|
+
if (focusables.length === 0) {
|
|
544
|
+
e.preventDefault();
|
|
545
|
+
focusSafely(el);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
const active = document.activeElement;
|
|
549
|
+
const first = focusables[0];
|
|
550
|
+
const last = focusables[focusables.length - 1];
|
|
551
|
+
if (e.shiftKey) {
|
|
552
|
+
if (active === first) {
|
|
553
|
+
e.preventDefault();
|
|
554
|
+
focusSafely(last);
|
|
555
|
+
}
|
|
556
|
+
} else {
|
|
557
|
+
if (active === last) {
|
|
558
|
+
e.preventDefault();
|
|
559
|
+
focusSafely(first);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
children
|
|
564
|
+
}
|
|
565
|
+
)
|
|
566
|
+
] });
|
|
567
|
+
}
|
|
568
|
+
function Popover({
|
|
569
|
+
content,
|
|
570
|
+
children,
|
|
571
|
+
placement = "bottom",
|
|
572
|
+
closeOnClickOutside = true,
|
|
573
|
+
closeOnEsc = true,
|
|
574
|
+
open: controlledOpen,
|
|
575
|
+
onOpenChange,
|
|
576
|
+
offset = 8,
|
|
577
|
+
className
|
|
578
|
+
}) {
|
|
579
|
+
const popoverId = useId();
|
|
580
|
+
const anchorRef = useRef(null);
|
|
581
|
+
const popoverRef = useRef(null);
|
|
582
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
583
|
+
const [pos, setPos] = useState(null);
|
|
584
|
+
const isControlled = controlledOpen !== void 0;
|
|
585
|
+
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
586
|
+
const setOpen = useCallback(
|
|
587
|
+
(value) => {
|
|
588
|
+
if (!isControlled) setInternalOpen(value);
|
|
589
|
+
onOpenChange?.(value);
|
|
590
|
+
},
|
|
591
|
+
[isControlled, onOpenChange]
|
|
592
|
+
);
|
|
593
|
+
const toggle = useCallback(() => setOpen(!isOpen), [isOpen, setOpen]);
|
|
594
|
+
const close = useCallback(() => setOpen(false), [setOpen]);
|
|
595
|
+
const updatePosition = useCallback(() => {
|
|
596
|
+
const el = anchorRef.current;
|
|
597
|
+
if (!el) return;
|
|
598
|
+
const r = el.getBoundingClientRect();
|
|
599
|
+
let left;
|
|
600
|
+
let top;
|
|
601
|
+
let effPlacement = placement;
|
|
602
|
+
if (placement === "bottom" || placement === "top") {
|
|
603
|
+
left = r.left + r.width / 2;
|
|
604
|
+
if (placement === "bottom") {
|
|
605
|
+
top = r.bottom + offset;
|
|
606
|
+
if (top + 200 > window.innerHeight && r.top - offset > 200) {
|
|
607
|
+
effPlacement = "top";
|
|
608
|
+
top = r.top - offset;
|
|
609
|
+
}
|
|
610
|
+
} else {
|
|
611
|
+
top = r.top - offset;
|
|
612
|
+
if (top < 8) {
|
|
613
|
+
effPlacement = "bottom";
|
|
614
|
+
top = r.bottom + offset;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
} else {
|
|
618
|
+
top = r.top + r.height / 2;
|
|
619
|
+
if (placement === "right") {
|
|
620
|
+
left = r.right + offset;
|
|
621
|
+
} else {
|
|
622
|
+
left = r.left - offset;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
setPos({ left: Math.round(left), top: Math.round(top), placement: effPlacement });
|
|
626
|
+
}, [placement, offset]);
|
|
627
|
+
useEffect(() => {
|
|
628
|
+
if (!isOpen) return;
|
|
629
|
+
updatePosition();
|
|
630
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
631
|
+
window.addEventListener("resize", updatePosition);
|
|
632
|
+
return () => {
|
|
633
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
634
|
+
window.removeEventListener("resize", updatePosition);
|
|
635
|
+
};
|
|
636
|
+
}, [isOpen, updatePosition]);
|
|
637
|
+
useEffect(() => {
|
|
638
|
+
if (!isOpen || !closeOnClickOutside) return;
|
|
639
|
+
const handleClick = (e) => {
|
|
640
|
+
const target = e.target;
|
|
641
|
+
if (anchorRef.current?.contains(target) || popoverRef.current?.contains(target)) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
close();
|
|
645
|
+
};
|
|
646
|
+
document.addEventListener("mousedown", handleClick);
|
|
647
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
648
|
+
}, [isOpen, closeOnClickOutside, close]);
|
|
649
|
+
useEffect(() => {
|
|
650
|
+
if (!isOpen || !closeOnEsc) return;
|
|
651
|
+
const handleKey = (e) => {
|
|
652
|
+
if (e.key === "Escape") {
|
|
653
|
+
e.preventDefault();
|
|
654
|
+
close();
|
|
655
|
+
anchorRef.current?.focus();
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
document.addEventListener("keydown", handleKey);
|
|
659
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
660
|
+
}, [isOpen, closeOnEsc, close]);
|
|
661
|
+
if (!isValidElement(children)) return children;
|
|
662
|
+
const child = cloneElement(children, {
|
|
663
|
+
ref: (node) => {
|
|
664
|
+
anchorRef.current = node;
|
|
665
|
+
const childProps = children.props;
|
|
666
|
+
const prevRef = childProps.ref;
|
|
667
|
+
if (typeof prevRef === "function") prevRef(node);
|
|
668
|
+
else if (prevRef && typeof prevRef === "object") prevRef.current = node;
|
|
669
|
+
},
|
|
670
|
+
onClick: (e) => {
|
|
671
|
+
const childProps = children.props;
|
|
672
|
+
if (typeof childProps.onClick === "function") childProps.onClick(e);
|
|
673
|
+
toggle();
|
|
674
|
+
},
|
|
675
|
+
"aria-expanded": isOpen,
|
|
676
|
+
"aria-haspopup": "dialog",
|
|
677
|
+
"aria-controls": isOpen ? popoverId : void 0
|
|
678
|
+
});
|
|
679
|
+
const getTransform = () => {
|
|
680
|
+
if (!pos) return "translate(-9999px, -9999px)";
|
|
681
|
+
switch (pos.placement) {
|
|
682
|
+
case "top":
|
|
683
|
+
return "translate(-50%, -100%)";
|
|
684
|
+
case "bottom":
|
|
685
|
+
return "translate(-50%, 0%)";
|
|
686
|
+
case "left":
|
|
687
|
+
return "translate(-100%, -50%)";
|
|
688
|
+
case "right":
|
|
689
|
+
return "translate(0%, -50%)";
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
693
|
+
child,
|
|
694
|
+
isOpen && typeof document !== "undefined" ? createPortal(
|
|
695
|
+
/* @__PURE__ */ jsx(
|
|
696
|
+
"div",
|
|
697
|
+
{
|
|
698
|
+
ref: popoverRef,
|
|
699
|
+
id: popoverId,
|
|
700
|
+
role: "dialog",
|
|
701
|
+
className: cn(
|
|
702
|
+
"fixed z-[9999] rounded-xl shadow-xl ring-1 ring-white/10 bg-surface-50 backdrop-blur-md p-4",
|
|
703
|
+
className
|
|
704
|
+
),
|
|
705
|
+
style: {
|
|
706
|
+
left: pos?.left ?? 0,
|
|
707
|
+
top: pos?.top ?? 0,
|
|
708
|
+
transform: getTransform()
|
|
709
|
+
},
|
|
710
|
+
children: content
|
|
711
|
+
}
|
|
712
|
+
),
|
|
713
|
+
document.body
|
|
714
|
+
) : null
|
|
715
|
+
] });
|
|
716
|
+
}
|
|
717
|
+
var DAY_NAMES = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
|
718
|
+
var DAY_IN_MS = 24 * 60 * 60 * 1e3;
|
|
719
|
+
function startOfDay(date) {
|
|
720
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
721
|
+
}
|
|
722
|
+
function startOfMonth(date) {
|
|
723
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
724
|
+
}
|
|
725
|
+
function addDays(date, amount) {
|
|
726
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount);
|
|
727
|
+
}
|
|
728
|
+
function addMonths(date, amount) {
|
|
729
|
+
return new Date(date.getFullYear(), date.getMonth() + amount, 1);
|
|
730
|
+
}
|
|
731
|
+
function getCalendarStart(date) {
|
|
732
|
+
const monthStart = startOfMonth(date);
|
|
733
|
+
const day = monthStart.getDay();
|
|
734
|
+
const diff = day === 0 ? 6 : day - 1;
|
|
735
|
+
return addDays(monthStart, -diff);
|
|
736
|
+
}
|
|
737
|
+
function isSameDay(a, b) {
|
|
738
|
+
if (!a || !b) return false;
|
|
739
|
+
return startOfDay(a).getTime() === startOfDay(b).getTime();
|
|
740
|
+
}
|
|
741
|
+
function isBetween(day, from, to) {
|
|
742
|
+
if (!from || !to) return false;
|
|
743
|
+
const current = startOfDay(day).getTime();
|
|
744
|
+
return current > startOfDay(from).getTime() && current < startOfDay(to).getTime();
|
|
745
|
+
}
|
|
746
|
+
function diffInDays(from, to) {
|
|
747
|
+
return Math.round((startOfDay(to).getTime() - startOfDay(from).getTime()) / DAY_IN_MS);
|
|
748
|
+
}
|
|
749
|
+
function pad(value) {
|
|
750
|
+
return String(value).padStart(2, "0");
|
|
751
|
+
}
|
|
752
|
+
function formatDate(date, pattern) {
|
|
753
|
+
return pattern.replace("dd", pad(date.getDate())).replace("MM", pad(date.getMonth() + 1)).replace("yyyy", String(date.getFullYear()));
|
|
754
|
+
}
|
|
755
|
+
function formatMonthLabel(date) {
|
|
756
|
+
return new Intl.DateTimeFormat(void 0, { month: "long", year: "numeric" }).format(date);
|
|
757
|
+
}
|
|
758
|
+
function formatFullDate(date) {
|
|
759
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
760
|
+
year: "numeric",
|
|
761
|
+
month: "long",
|
|
762
|
+
day: "numeric"
|
|
763
|
+
}).format(date);
|
|
764
|
+
}
|
|
765
|
+
function parseDateInput(value) {
|
|
766
|
+
const trimmed = value.trim();
|
|
767
|
+
if (!trimmed) return null;
|
|
768
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
|
|
769
|
+
const [year2, month2, day2] = trimmed.split("-").map(Number);
|
|
770
|
+
const parsed2 = new Date(year2, month2 - 1, day2);
|
|
771
|
+
if (parsed2.getFullYear() === year2 && parsed2.getMonth() === month2 - 1 && parsed2.getDate() === day2) {
|
|
772
|
+
return startOfDay(parsed2);
|
|
773
|
+
}
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
const match = trimmed.match(/^(\d{1,2})[./-](\d{1,2})[./-](\d{4})$/);
|
|
777
|
+
if (!match) return null;
|
|
778
|
+
const day = Number(match[1]);
|
|
779
|
+
const month = Number(match[2]);
|
|
780
|
+
const year = Number(match[3]);
|
|
781
|
+
const parsed = new Date(year, month - 1, day);
|
|
782
|
+
if (parsed.getFullYear() !== year || parsed.getMonth() !== month - 1 || parsed.getDate() !== day) {
|
|
783
|
+
return null;
|
|
784
|
+
}
|
|
785
|
+
return startOfDay(parsed);
|
|
786
|
+
}
|
|
787
|
+
function getPlaceholder(placeholder, key, fallback) {
|
|
788
|
+
if (typeof placeholder === "string") {
|
|
789
|
+
return key === "trigger" ? placeholder : fallback;
|
|
790
|
+
}
|
|
791
|
+
return placeholder?.[key] ?? fallback;
|
|
792
|
+
}
|
|
793
|
+
function buildCalendarDays(month) {
|
|
794
|
+
const start = getCalendarStart(month);
|
|
795
|
+
return Array.from({ length: 42 }, (_, index) => addDays(start, index));
|
|
796
|
+
}
|
|
797
|
+
function getRangeSummary(range, formatPattern) {
|
|
798
|
+
if (range.from && range.to) {
|
|
799
|
+
return `${formatDate(range.from, formatPattern)} - ${formatDate(range.to, formatPattern)}`;
|
|
800
|
+
}
|
|
801
|
+
if (range.from) {
|
|
802
|
+
return `${formatDate(range.from, formatPattern)} - ...`;
|
|
803
|
+
}
|
|
804
|
+
return "No date range selected";
|
|
805
|
+
}
|
|
806
|
+
function normalizeRange(range) {
|
|
807
|
+
return {
|
|
808
|
+
from: range.from ? startOfDay(range.from) : null,
|
|
809
|
+
to: range.to ? startOfDay(range.to) : null
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function clampRange(range, min, max, maxRangeDays) {
|
|
813
|
+
let nextFrom = range.from ? startOfDay(range.from) : null;
|
|
814
|
+
let nextTo = range.to ? startOfDay(range.to) : null;
|
|
815
|
+
if (min) {
|
|
816
|
+
const minDay = startOfDay(min);
|
|
817
|
+
if (nextFrom && nextFrom < minDay) nextFrom = minDay;
|
|
818
|
+
if (nextTo && nextTo < minDay) nextTo = minDay;
|
|
819
|
+
}
|
|
820
|
+
if (max) {
|
|
821
|
+
const maxDay = startOfDay(max);
|
|
822
|
+
if (nextFrom && nextFrom > maxDay) nextFrom = maxDay;
|
|
823
|
+
if (nextTo && nextTo > maxDay) nextTo = maxDay;
|
|
824
|
+
}
|
|
825
|
+
if (nextFrom && nextTo && nextFrom > nextTo) {
|
|
826
|
+
const swap = nextFrom;
|
|
827
|
+
nextFrom = nextTo;
|
|
828
|
+
nextTo = swap;
|
|
829
|
+
}
|
|
830
|
+
if (nextFrom && nextTo && maxRangeDays && diffInDays(nextFrom, nextTo) + 1 > maxRangeDays) {
|
|
831
|
+
nextTo = addDays(nextFrom, maxRangeDays - 1);
|
|
832
|
+
}
|
|
833
|
+
return { from: nextFrom, to: nextTo };
|
|
834
|
+
}
|
|
835
|
+
function isDateDisabled(day, range, min, max, maxRangeDays) {
|
|
836
|
+
const normalized = startOfDay(day);
|
|
837
|
+
const minDay = min ? startOfDay(min) : null;
|
|
838
|
+
const maxDay = max ? startOfDay(max) : null;
|
|
839
|
+
if (minDay && normalized < minDay) return true;
|
|
840
|
+
if (maxDay && normalized > maxDay) return true;
|
|
841
|
+
if (range.from && !range.to && maxRangeDays) {
|
|
842
|
+
return Math.abs(diffInDays(range.from, normalized)) + 1 > maxRangeDays;
|
|
843
|
+
}
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
function CalendarIcon() {
|
|
847
|
+
return /* @__PURE__ */ jsxs(
|
|
848
|
+
"svg",
|
|
849
|
+
{
|
|
850
|
+
"aria-hidden": "true",
|
|
851
|
+
className: "h-4 w-4",
|
|
852
|
+
viewBox: "0 0 20 20",
|
|
853
|
+
fill: "none",
|
|
854
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
855
|
+
children: [
|
|
856
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "14", height: "13", rx: "2.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
857
|
+
/* @__PURE__ */ jsx("path", { d: "M6.5 2.75V5.5M13.5 2.75V5.5M3 8h14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
858
|
+
]
|
|
859
|
+
}
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
function ChevronIcon({ className }) {
|
|
863
|
+
return /* @__PURE__ */ jsx(
|
|
864
|
+
"svg",
|
|
865
|
+
{
|
|
866
|
+
"aria-hidden": "true",
|
|
867
|
+
className: cn("h-4 w-4", className),
|
|
868
|
+
viewBox: "0 0 20 20",
|
|
869
|
+
fill: "none",
|
|
870
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
871
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 8l4 4 4-4", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
872
|
+
}
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
function CalendarMonth({
|
|
876
|
+
month,
|
|
877
|
+
viewMonth,
|
|
878
|
+
range,
|
|
879
|
+
formatPattern,
|
|
880
|
+
min,
|
|
881
|
+
max,
|
|
882
|
+
maxRangeDays,
|
|
883
|
+
onPrevMonth,
|
|
884
|
+
onNextMonth,
|
|
885
|
+
onSelectDay
|
|
886
|
+
}) {
|
|
887
|
+
const days = useMemo(() => buildCalendarDays(month), [month]);
|
|
888
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-3", children: [
|
|
889
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between gap-2", children: [
|
|
890
|
+
/* @__PURE__ */ jsx(
|
|
891
|
+
"button",
|
|
892
|
+
{
|
|
893
|
+
type: "button",
|
|
894
|
+
onClick: onPrevMonth,
|
|
895
|
+
disabled: !onPrevMonth,
|
|
896
|
+
"aria-label": "Previous month",
|
|
897
|
+
className: cn(
|
|
898
|
+
"inline-flex h-8 w-8 items-center justify-center rounded-lg text-white/70 transition-colors",
|
|
899
|
+
onPrevMonth ? "hover:bg-white/10 hover:text-white" : "pointer-events-none opacity-0"
|
|
900
|
+
),
|
|
901
|
+
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "h-4 w-4", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M12 5l-5 5 5 5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
902
|
+
}
|
|
903
|
+
),
|
|
904
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium capitalize text-white", children: formatMonthLabel(month) }),
|
|
905
|
+
/* @__PURE__ */ jsx(
|
|
906
|
+
"button",
|
|
907
|
+
{
|
|
908
|
+
type: "button",
|
|
909
|
+
onClick: onNextMonth,
|
|
910
|
+
disabled: !onNextMonth,
|
|
911
|
+
"aria-label": "Next month",
|
|
912
|
+
className: cn(
|
|
913
|
+
"inline-flex h-8 w-8 items-center justify-center rounded-lg text-white/70 transition-colors",
|
|
914
|
+
onNextMonth ? "hover:bg-white/10 hover:text-white" : "pointer-events-none opacity-0"
|
|
915
|
+
),
|
|
916
|
+
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "h-4 w-4", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M8 5l5 5-5 5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
917
|
+
}
|
|
918
|
+
)
|
|
919
|
+
] }),
|
|
920
|
+
/* @__PURE__ */ jsx("div", { className: "mb-2 grid grid-cols-7 gap-1 text-center text-[11px] font-medium uppercase tracking-[0.14em] text-white/35", children: DAY_NAMES.map((day) => /* @__PURE__ */ jsx("span", { children: day }, day)) }),
|
|
921
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-1", children: days.map((day) => {
|
|
922
|
+
const inMonth = day.getMonth() === month.getMonth();
|
|
923
|
+
const disabled = isDateDisabled(day, range, min, max, maxRangeDays);
|
|
924
|
+
const selectedStart = isSameDay(day, range.from);
|
|
925
|
+
const selectedEnd = isSameDay(day, range.to);
|
|
926
|
+
const inRange = isBetween(day, range.from, range.to);
|
|
927
|
+
const isToday = isSameDay(day, /* @__PURE__ */ new Date());
|
|
928
|
+
const roundedClass = selectedStart && selectedEnd ? "rounded-xl" : selectedStart ? "rounded-l-xl rounded-r-md" : selectedEnd ? "rounded-r-xl rounded-l-md" : inRange ? "rounded-md" : "rounded-xl";
|
|
929
|
+
return /* @__PURE__ */ jsxs(
|
|
930
|
+
"button",
|
|
931
|
+
{
|
|
932
|
+
type: "button",
|
|
933
|
+
disabled,
|
|
934
|
+
onClick: () => onSelectDay(day),
|
|
935
|
+
"aria-label": formatFullDate(day),
|
|
936
|
+
"aria-pressed": selectedStart || selectedEnd || inRange,
|
|
937
|
+
className: cn(
|
|
938
|
+
"relative h-9 w-full text-sm tabular-nums transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
939
|
+
roundedClass,
|
|
940
|
+
!inMonth && "text-white/25",
|
|
941
|
+
inMonth && !selectedStart && !selectedEnd && !inRange && "text-white/75",
|
|
942
|
+
(selectedStart || selectedEnd) && "bg-primary text-white shadow-glow",
|
|
943
|
+
inRange && !selectedStart && !selectedEnd && "bg-primary/15 text-white",
|
|
944
|
+
!selectedStart && !selectedEnd && !inRange && !disabled && "hover:bg-white/10 hover:text-white",
|
|
945
|
+
disabled && "cursor-not-allowed opacity-35"
|
|
946
|
+
),
|
|
947
|
+
children: [
|
|
948
|
+
/* @__PURE__ */ jsx("span", { children: formatDate(day, "dd") }),
|
|
949
|
+
isToday && !selectedStart && !selectedEnd && !inRange ? /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute inset-x-2 bottom-1 h-0.5 rounded-full bg-primary/70" }) : null,
|
|
950
|
+
isSameDay(day, viewMonth) ? null : null
|
|
951
|
+
]
|
|
952
|
+
},
|
|
953
|
+
day.toISOString()
|
|
954
|
+
);
|
|
955
|
+
}) }),
|
|
956
|
+
range.from || range.to ? /* @__PURE__ */ jsx("p", { className: "mt-3 text-xs text-white/45", children: getRangeSummary(range, formatPattern) }) : null
|
|
957
|
+
] });
|
|
958
|
+
}
|
|
959
|
+
function DateRangePicker({
|
|
960
|
+
value,
|
|
961
|
+
onChange,
|
|
962
|
+
presets,
|
|
963
|
+
format = "dd.MM.yyyy",
|
|
964
|
+
placeholder,
|
|
965
|
+
min,
|
|
966
|
+
max,
|
|
967
|
+
maxRangeDays,
|
|
968
|
+
label,
|
|
969
|
+
helperText,
|
|
970
|
+
clearable = true,
|
|
971
|
+
disabled,
|
|
972
|
+
hasError,
|
|
973
|
+
error,
|
|
974
|
+
closeOnSelect = false,
|
|
975
|
+
compact = false,
|
|
976
|
+
className
|
|
977
|
+
}) {
|
|
978
|
+
const isMobile = useMediaQuery("(max-width: 767px)");
|
|
979
|
+
const [open, setOpen] = useState(false);
|
|
980
|
+
const normalizedValue = useMemo(() => normalizeRange(value), [value]);
|
|
981
|
+
const [viewMonth, setViewMonth] = useState(() => startOfMonth(normalizedValue.from ?? normalizedValue.to ?? /* @__PURE__ */ new Date()));
|
|
982
|
+
const [fromInput, setFromInput] = useState("");
|
|
983
|
+
const [toInput, setToInput] = useState("");
|
|
984
|
+
const showError = hasError || Boolean(error);
|
|
985
|
+
const hasValue = normalizedValue.from !== null || normalizedValue.to !== null;
|
|
986
|
+
const triggerPlaceholder = getPlaceholder(placeholder, "trigger", compact ? "Any date" : "Select date range");
|
|
987
|
+
const fromPlaceholder = getPlaceholder(placeholder, "from", "dd.mm.yyyy");
|
|
988
|
+
const toPlaceholder = getPlaceholder(placeholder, "to", "dd.mm.yyyy");
|
|
989
|
+
const monthsToRender = isMobile ? [viewMonth] : [viewMonth, addMonths(viewMonth, 1)];
|
|
990
|
+
useEffect(() => {
|
|
991
|
+
setFromInput(normalizedValue.from ? formatDate(normalizedValue.from, format) : "");
|
|
992
|
+
setToInput(normalizedValue.to ? formatDate(normalizedValue.to, format) : "");
|
|
993
|
+
}, [normalizedValue.from, normalizedValue.to, format]);
|
|
994
|
+
useEffect(() => {
|
|
995
|
+
if (!open) {
|
|
996
|
+
setViewMonth(startOfMonth(normalizedValue.from ?? normalizedValue.to ?? /* @__PURE__ */ new Date()));
|
|
997
|
+
}
|
|
998
|
+
}, [normalizedValue.from, normalizedValue.to, open]);
|
|
999
|
+
const selectedText = useMemo(() => {
|
|
1000
|
+
if (normalizedValue.from && normalizedValue.to) {
|
|
1001
|
+
return `${formatDate(normalizedValue.from, format)} - ${formatDate(normalizedValue.to, format)}`;
|
|
1002
|
+
}
|
|
1003
|
+
if (normalizedValue.from) {
|
|
1004
|
+
return `${formatDate(normalizedValue.from, format)} - ...`;
|
|
1005
|
+
}
|
|
1006
|
+
return triggerPlaceholder;
|
|
1007
|
+
}, [format, normalizedValue.from, normalizedValue.to, triggerPlaceholder]);
|
|
1008
|
+
const handleRangeChange = (nextRange) => {
|
|
1009
|
+
onChange(clampRange(nextRange, min, max, maxRangeDays));
|
|
1010
|
+
};
|
|
1011
|
+
const handleSelectDay = (day) => {
|
|
1012
|
+
if (isDateDisabled(day, normalizedValue, min, max, maxRangeDays)) {
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
const normalizedDay = startOfDay(day);
|
|
1016
|
+
if (!normalizedValue.from || normalizedValue.to) {
|
|
1017
|
+
handleRangeChange({ from: normalizedDay, to: null });
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
const nextRange = normalizedDay < normalizedValue.from ? { from: normalizedDay, to: normalizedValue.from } : { from: normalizedValue.from, to: normalizedDay };
|
|
1021
|
+
handleRangeChange(nextRange);
|
|
1022
|
+
if (closeOnSelect) {
|
|
1023
|
+
setOpen(false);
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
const commitInput = (kind, rawValue) => {
|
|
1027
|
+
const parsed = parseDateInput(rawValue);
|
|
1028
|
+
if (!rawValue.trim()) {
|
|
1029
|
+
handleRangeChange({
|
|
1030
|
+
from: kind === "from" ? null : normalizedValue.from,
|
|
1031
|
+
to: kind === "to" ? null : normalizedValue.to
|
|
1032
|
+
});
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
if (!parsed || isDateDisabled(parsed, normalizedValue, min, max, maxRangeDays)) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
if (kind === "from") {
|
|
1039
|
+
handleRangeChange({ from: parsed, to: normalizedValue.to });
|
|
1040
|
+
setViewMonth(startOfMonth(parsed));
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
handleRangeChange({ from: normalizedValue.from, to: parsed });
|
|
1044
|
+
setViewMonth(startOfMonth(parsed));
|
|
1045
|
+
};
|
|
1046
|
+
const handleClear = () => {
|
|
1047
|
+
handleRangeChange({ from: null, to: null });
|
|
1048
|
+
setOpen(false);
|
|
1049
|
+
};
|
|
1050
|
+
const panel = /* @__PURE__ */ jsxs("div", { className: cn("space-y-4 p-4", isMobile ? "h-full overflow-y-auto" : "w-[min(42rem,calc(100vw-1.5rem))] max-w-[calc(100vw-1.5rem)]"), children: [
|
|
1051
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1052
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1053
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-white", children: "Date range" }),
|
|
1054
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-white/50", children: "Pick a start and end date or use a preset." })
|
|
1055
|
+
] }),
|
|
1056
|
+
!isMobile ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: () => setOpen(false), children: "Done" }) : null
|
|
1057
|
+
] }),
|
|
1058
|
+
presets && presets.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: presets.map((preset) => {
|
|
1059
|
+
const presetRange = clampRange(preset.range, min, max, maxRangeDays);
|
|
1060
|
+
const active = isSameDay(presetRange.from, normalizedValue.from) && isSameDay(presetRange.to, normalizedValue.to);
|
|
1061
|
+
return /* @__PURE__ */ jsx(
|
|
1062
|
+
"button",
|
|
1063
|
+
{
|
|
1064
|
+
type: "button",
|
|
1065
|
+
onClick: () => {
|
|
1066
|
+
handleRangeChange(presetRange);
|
|
1067
|
+
if (closeOnSelect) {
|
|
1068
|
+
setOpen(false);
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
className: cn(
|
|
1072
|
+
"rounded-xl border px-3 py-1.5 text-xs font-medium transition-colors",
|
|
1073
|
+
active ? "border-primary/60 bg-primary/15 text-white" : "border-white/10 bg-white/[0.03] text-white/70 hover:bg-white/10 hover:text-white"
|
|
1074
|
+
),
|
|
1075
|
+
children: preset.label
|
|
1076
|
+
},
|
|
1077
|
+
preset.label
|
|
1078
|
+
);
|
|
1079
|
+
}) }) : null,
|
|
1080
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
1081
|
+
/* @__PURE__ */ jsx(
|
|
1082
|
+
Input,
|
|
1083
|
+
{
|
|
1084
|
+
label: "From",
|
|
1085
|
+
value: fromInput,
|
|
1086
|
+
placeholder: fromPlaceholder,
|
|
1087
|
+
onChange: (event) => setFromInput(event.target.value),
|
|
1088
|
+
onBlur: (event) => commitInput("from", event.target.value),
|
|
1089
|
+
onKeyDown: (event) => {
|
|
1090
|
+
if (event.key === "Enter") {
|
|
1091
|
+
event.preventDefault();
|
|
1092
|
+
commitInput("from", fromInput);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
/* @__PURE__ */ jsx(
|
|
1098
|
+
Input,
|
|
1099
|
+
{
|
|
1100
|
+
label: "To",
|
|
1101
|
+
value: toInput,
|
|
1102
|
+
placeholder: toPlaceholder,
|
|
1103
|
+
onChange: (event) => setToInput(event.target.value),
|
|
1104
|
+
onBlur: (event) => commitInput("to", event.target.value),
|
|
1105
|
+
onKeyDown: (event) => {
|
|
1106
|
+
if (event.key === "Enter") {
|
|
1107
|
+
event.preventDefault();
|
|
1108
|
+
commitInput("to", toInput);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
)
|
|
1113
|
+
] }),
|
|
1114
|
+
/* @__PURE__ */ jsx("div", { className: cn("grid gap-4", isMobile ? "grid-cols-1" : "md:grid-cols-2"), children: monthsToRender.map((month, index) => /* @__PURE__ */ jsx(
|
|
1115
|
+
CalendarMonth,
|
|
1116
|
+
{
|
|
1117
|
+
month,
|
|
1118
|
+
viewMonth,
|
|
1119
|
+
range: normalizedValue,
|
|
1120
|
+
formatPattern: format,
|
|
1121
|
+
min,
|
|
1122
|
+
max,
|
|
1123
|
+
maxRangeDays,
|
|
1124
|
+
onPrevMonth: index === 0 ? () => setViewMonth((prev) => addMonths(prev, -1)) : void 0,
|
|
1125
|
+
onNextMonth: index === monthsToRender.length - 1 ? () => setViewMonth((prev) => addMonths(prev, 1)) : void 0,
|
|
1126
|
+
onSelectDay: handleSelectDay
|
|
1127
|
+
},
|
|
1128
|
+
month.toISOString()
|
|
1129
|
+
)) }),
|
|
1130
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 border-t border-white/10 pt-3", children: [
|
|
1131
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-white/45", children: getRangeSummary(normalizedValue, format) }),
|
|
1132
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1133
|
+
clearable ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: handleClear, children: "Clear" }) : null,
|
|
1134
|
+
isMobile ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "secondary", onClick: () => setOpen(false), children: "Done" }) : null
|
|
1135
|
+
] })
|
|
1136
|
+
] })
|
|
1137
|
+
] });
|
|
1138
|
+
const triggerButton = /* @__PURE__ */ jsxs(
|
|
1139
|
+
"button",
|
|
1140
|
+
{
|
|
1141
|
+
type: "button",
|
|
1142
|
+
disabled,
|
|
1143
|
+
onClick: () => {
|
|
1144
|
+
if (isMobile) {
|
|
1145
|
+
setOpen(true);
|
|
1146
|
+
}
|
|
1147
|
+
},
|
|
1148
|
+
"aria-label": `Date range: ${selectedText}`,
|
|
1149
|
+
className: cn(
|
|
1150
|
+
"flex w-full items-center justify-between gap-3 rounded-xl bg-white/10 text-left text-white shadow-sm outline-none transition-shadow focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
1151
|
+
compact ? "min-h-10 px-3 py-2 text-sm" : "min-h-11 px-3 py-2.5 text-sm",
|
|
1152
|
+
hasValue && clearable && "pr-16",
|
|
1153
|
+
showError && "ring-2 ring-rose-500/40 focus-visible:ring-rose-500/40",
|
|
1154
|
+
disabled && "cursor-not-allowed opacity-60",
|
|
1155
|
+
className
|
|
1156
|
+
),
|
|
1157
|
+
children: [
|
|
1158
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1159
|
+
/* @__PURE__ */ jsx("span", { className: cn(hasValue ? "text-primary" : "text-white/40"), children: /* @__PURE__ */ jsx(CalendarIcon, {}) }),
|
|
1160
|
+
/* @__PURE__ */ jsx("span", { className: cn("truncate", hasValue ? "text-white" : "text-white/40"), children: selectedText })
|
|
1161
|
+
] }),
|
|
1162
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-white/45", children: [
|
|
1163
|
+
normalizedValue.from && normalizedValue.to ? /* @__PURE__ */ jsxs("span", { className: "hidden rounded-full bg-white/10 px-2 py-0.5 text-[11px] text-white/60 sm:inline-flex", children: [
|
|
1164
|
+
diffInDays(normalizedValue.from, normalizedValue.to) + 1,
|
|
1165
|
+
"d"
|
|
1166
|
+
] }) : null,
|
|
1167
|
+
/* @__PURE__ */ jsx(ChevronIcon, { className: cn(open && "rotate-180 transition-transform") })
|
|
1168
|
+
] })
|
|
1169
|
+
]
|
|
1170
|
+
}
|
|
1171
|
+
);
|
|
1172
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
1173
|
+
label ? /* @__PURE__ */ jsx("label", { className: "mb-1.5 block text-sm text-white/70", children: label }) : null,
|
|
1174
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1175
|
+
isMobile ? triggerButton : /* @__PURE__ */ jsx(
|
|
1176
|
+
Popover,
|
|
1177
|
+
{
|
|
1178
|
+
open,
|
|
1179
|
+
onOpenChange: setOpen,
|
|
1180
|
+
placement: "bottom",
|
|
1181
|
+
className: "overflow-hidden p-0",
|
|
1182
|
+
content: panel,
|
|
1183
|
+
children: triggerButton
|
|
1184
|
+
}
|
|
1185
|
+
),
|
|
1186
|
+
clearable && hasValue ? /* @__PURE__ */ jsx(
|
|
1187
|
+
"button",
|
|
1188
|
+
{
|
|
1189
|
+
type: "button",
|
|
1190
|
+
onClick: (event) => {
|
|
1191
|
+
event.stopPropagation();
|
|
1192
|
+
handleClear();
|
|
1193
|
+
},
|
|
1194
|
+
"aria-label": "Clear date range",
|
|
1195
|
+
className: "absolute right-10 top-1/2 -translate-y-1/2 rounded-md p-1 text-white/35 transition-colors hover:bg-white/10 hover:text-white",
|
|
1196
|
+
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "h-3.5 w-3.5", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4 4l8 8M12 4l-8 8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) })
|
|
1197
|
+
}
|
|
1198
|
+
) : null
|
|
1199
|
+
] }),
|
|
1200
|
+
error ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-rose-400", children: error }) : null,
|
|
1201
|
+
helperText && !error ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-white/40", children: helperText }) : null,
|
|
1202
|
+
isMobile ? /* @__PURE__ */ jsx(
|
|
1203
|
+
Drawer,
|
|
1204
|
+
{
|
|
1205
|
+
isOpen: open,
|
|
1206
|
+
onClose: () => setOpen(false),
|
|
1207
|
+
side: "bottom",
|
|
1208
|
+
size: "full",
|
|
1209
|
+
ariaLabel: "Date range picker",
|
|
1210
|
+
className: "rounded-t-3xl",
|
|
1211
|
+
children: panel
|
|
1212
|
+
}
|
|
1213
|
+
) : null
|
|
1214
|
+
] });
|
|
1215
|
+
}
|
|
457
1216
|
var selectBase = "w-full rounded-xl px-3 py-2.5 text-sm bg-white/10 text-white shadow-sm outline-none focus-visible:ring-2 focus-visible:ring-primary/40 transition-shadow";
|
|
458
1217
|
var Select = forwardRef(function Select2({ hasError, label, error, helperText, className, id: externalId, children, ...props }, ref) {
|
|
459
1218
|
const generatedId = useId();
|
|
@@ -631,7 +1390,7 @@ var TagInput = forwardRef(
|
|
|
631
1390
|
}
|
|
632
1391
|
);
|
|
633
1392
|
var base3 = "inline-flex items-center justify-center rounded-full font-semibold ring-1 ring-white/10";
|
|
634
|
-
var
|
|
1393
|
+
var sizeClass5 = {
|
|
635
1394
|
sm: "text-xs px-2.5 py-1",
|
|
636
1395
|
md: "text-sm px-3 py-1.5"
|
|
637
1396
|
};
|
|
@@ -646,7 +1405,7 @@ var variantClass3 = {
|
|
|
646
1405
|
accent: "bg-accent/15 text-accent-light ring-accent/20"
|
|
647
1406
|
};
|
|
648
1407
|
var Badge = forwardRef(function Badge2({ children, variant = "neutral", size = "sm", className, ...props }, ref) {
|
|
649
|
-
return /* @__PURE__ */ jsx("span", { ref, ...props, className: cn(base3,
|
|
1408
|
+
return /* @__PURE__ */ jsx("span", { ref, ...props, className: cn(base3, sizeClass5[size], variantClass3[variant], className), children });
|
|
650
1409
|
});
|
|
651
1410
|
var Pill = Badge;
|
|
652
1411
|
var trackSize = {
|
|
@@ -1096,7 +1855,7 @@ function RadioItem({ value, disabled: itemDisabled, children, className }) {
|
|
|
1096
1855
|
}
|
|
1097
1856
|
);
|
|
1098
1857
|
}
|
|
1099
|
-
var
|
|
1858
|
+
var sizeClass6 = {
|
|
1100
1859
|
sm: "h-3 w-3 border",
|
|
1101
1860
|
md: "h-4 w-4 border-2",
|
|
1102
1861
|
lg: "h-6 w-6 border-2"
|
|
@@ -1105,7 +1864,7 @@ function Spinner({ className, size = "md", label }) {
|
|
|
1105
1864
|
return /* @__PURE__ */ jsx(
|
|
1106
1865
|
"span",
|
|
1107
1866
|
{
|
|
1108
|
-
className: cn("inline-block rounded-full border-white/15 border-t-primary animate-spin",
|
|
1867
|
+
className: cn("inline-block rounded-full border-white/15 border-t-primary animate-spin", sizeClass6[size], className),
|
|
1109
1868
|
role: label ? "status" : void 0,
|
|
1110
1869
|
"aria-hidden": label ? void 0 : "true",
|
|
1111
1870
|
"aria-label": label || void 0
|
|
@@ -2025,93 +2784,203 @@ function Divider({ orientation = "horizontal", label, className }) {
|
|
|
2025
2784
|
}
|
|
2026
2785
|
);
|
|
2027
2786
|
}
|
|
2028
|
-
var Table = forwardRef(({ children, className }, ref)
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
);
|
|
2033
|
-
|
|
2034
|
-
var TableBody = forwardRef(
|
|
2035
|
-
|
|
2036
|
-
);
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
children
|
|
2045
|
-
}
|
|
2046
|
-
)
|
|
2047
|
-
);
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2787
|
+
var Table = forwardRef(function Table2({ children, className, ...props }, ref) {
|
|
2788
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded-xl ring-1 ring-white/10 overflow-hidden bg-white/5", children: /* @__PURE__ */ jsx("table", { ref, className: cn("w-full text-sm text-white", className), ...props, children }) });
|
|
2789
|
+
});
|
|
2790
|
+
var TableHeader = forwardRef(function TableHeader2({ children, className, ...props }, ref) {
|
|
2791
|
+
return /* @__PURE__ */ jsx("thead", { ref, className: cn("bg-white/5 border-b border-white/10", className), ...props, children });
|
|
2792
|
+
});
|
|
2793
|
+
var TableBody = forwardRef(function TableBody2({ children, className, ...props }, ref) {
|
|
2794
|
+
return /* @__PURE__ */ jsx("tbody", { ref, className: cn("divide-y divide-white/[0.06]", className), ...props, children });
|
|
2795
|
+
});
|
|
2796
|
+
var TableRow = forwardRef(function TableRow2({ children, className, hoverable, ...props }, ref) {
|
|
2797
|
+
return /* @__PURE__ */ jsx(
|
|
2798
|
+
"tr",
|
|
2799
|
+
{
|
|
2800
|
+
ref,
|
|
2801
|
+
className: cn(hoverable && "hover:bg-white/[0.03] transition-colors", className),
|
|
2802
|
+
...props,
|
|
2803
|
+
children
|
|
2804
|
+
}
|
|
2805
|
+
);
|
|
2806
|
+
});
|
|
2807
|
+
var TableHead = forwardRef(function TableHead2({ children, className, ...props }, ref) {
|
|
2808
|
+
return /* @__PURE__ */ jsx(
|
|
2809
|
+
"th",
|
|
2810
|
+
{
|
|
2811
|
+
ref,
|
|
2812
|
+
className: cn(
|
|
2813
|
+
"px-4 py-3 text-left text-xs font-semibold text-white/50 uppercase tracking-wider",
|
|
2814
|
+
className
|
|
2815
|
+
),
|
|
2816
|
+
...props,
|
|
2817
|
+
children
|
|
2818
|
+
}
|
|
2819
|
+
);
|
|
2820
|
+
});
|
|
2821
|
+
var alignClass = {
|
|
2822
|
+
left: "text-left",
|
|
2823
|
+
center: "text-center",
|
|
2824
|
+
right: "text-right"
|
|
2825
|
+
};
|
|
2826
|
+
var TableCell = forwardRef(function TableCell2({ children, className, align = "left", ...props }, ref) {
|
|
2827
|
+
return /* @__PURE__ */ jsx("td", { ref, className: cn("px-4 py-3 text-white/80", alignClass[align], className), ...props, children });
|
|
2828
|
+
});
|
|
2829
|
+
var variantBorderColor = {
|
|
2830
|
+
info: "border-blue-500",
|
|
2831
|
+
success: "border-emerald-500",
|
|
2832
|
+
warning: "border-amber-500",
|
|
2833
|
+
error: "border-rose-500"
|
|
2834
|
+
};
|
|
2835
|
+
var variantIconColor = {
|
|
2836
|
+
info: "text-blue-400",
|
|
2837
|
+
success: "text-emerald-400",
|
|
2838
|
+
warning: "text-amber-400",
|
|
2839
|
+
error: "text-rose-400"
|
|
2840
|
+
};
|
|
2841
|
+
function InfoIcon() {
|
|
2842
|
+
return /* @__PURE__ */ jsxs(
|
|
2843
|
+
"svg",
|
|
2844
|
+
{
|
|
2845
|
+
"aria-hidden": "true",
|
|
2846
|
+
width: "18",
|
|
2847
|
+
height: "18",
|
|
2848
|
+
viewBox: "0 0 18 18",
|
|
2849
|
+
fill: "none",
|
|
2850
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2851
|
+
children: [
|
|
2852
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2853
|
+
/* @__PURE__ */ jsx("path", { d: "M9 8v5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" }),
|
|
2854
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "5.5", r: "0.875", fill: "currentColor" })
|
|
2855
|
+
]
|
|
2856
|
+
}
|
|
2857
|
+
);
|
|
2858
|
+
}
|
|
2859
|
+
function SuccessIcon() {
|
|
2860
|
+
return /* @__PURE__ */ jsxs(
|
|
2861
|
+
"svg",
|
|
2862
|
+
{
|
|
2863
|
+
"aria-hidden": "true",
|
|
2864
|
+
width: "18",
|
|
2865
|
+
height: "18",
|
|
2866
|
+
viewBox: "0 0 18 18",
|
|
2867
|
+
fill: "none",
|
|
2868
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2869
|
+
children: [
|
|
2870
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2871
|
+
/* @__PURE__ */ jsx(
|
|
2872
|
+
"path",
|
|
2873
|
+
{
|
|
2874
|
+
d: "M5.5 9.5l2.5 2.5 4.5-5",
|
|
2875
|
+
stroke: "currentColor",
|
|
2876
|
+
strokeWidth: "1.75",
|
|
2877
|
+
strokeLinecap: "round",
|
|
2878
|
+
strokeLinejoin: "round"
|
|
2879
|
+
}
|
|
2880
|
+
)
|
|
2881
|
+
]
|
|
2882
|
+
}
|
|
2883
|
+
);
|
|
2884
|
+
}
|
|
2885
|
+
function WarningIcon() {
|
|
2886
|
+
return /* @__PURE__ */ jsxs(
|
|
2887
|
+
"svg",
|
|
2888
|
+
{
|
|
2889
|
+
"aria-hidden": "true",
|
|
2890
|
+
width: "18",
|
|
2891
|
+
height: "18",
|
|
2892
|
+
viewBox: "0 0 18 18",
|
|
2893
|
+
fill: "none",
|
|
2894
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2895
|
+
children: [
|
|
2896
|
+
/* @__PURE__ */ jsx(
|
|
2897
|
+
"path",
|
|
2898
|
+
{
|
|
2899
|
+
d: "M7.634 2.896a1.6 1.6 0 0 1 2.732 0l5.866 10.167A1.6 1.6 0 0 1 14.866 15.5H3.134a1.6 1.6 0 0 1-1.366-2.437L7.634 2.896Z",
|
|
2900
|
+
stroke: "currentColor",
|
|
2901
|
+
strokeWidth: "1.5",
|
|
2902
|
+
strokeLinejoin: "round"
|
|
2903
|
+
}
|
|
2904
|
+
),
|
|
2905
|
+
/* @__PURE__ */ jsx("path", { d: "M9 7v4", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" }),
|
|
2906
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "12.5", r: "0.875", fill: "currentColor" })
|
|
2907
|
+
]
|
|
2908
|
+
}
|
|
2909
|
+
);
|
|
2910
|
+
}
|
|
2911
|
+
function ErrorIcon() {
|
|
2912
|
+
return /* @__PURE__ */ jsxs(
|
|
2913
|
+
"svg",
|
|
2052
2914
|
{
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2915
|
+
"aria-hidden": "true",
|
|
2916
|
+
width: "18",
|
|
2917
|
+
height: "18",
|
|
2918
|
+
viewBox: "0 0 18 18",
|
|
2919
|
+
fill: "none",
|
|
2920
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2921
|
+
children: [
|
|
2922
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2923
|
+
/* @__PURE__ */ jsx(
|
|
2924
|
+
"path",
|
|
2925
|
+
{
|
|
2926
|
+
d: "M6.5 6.5l5 5M11.5 6.5l-5 5",
|
|
2927
|
+
stroke: "currentColor",
|
|
2928
|
+
strokeWidth: "1.75",
|
|
2929
|
+
strokeLinecap: "round"
|
|
2930
|
+
}
|
|
2931
|
+
)
|
|
2932
|
+
]
|
|
2059
2933
|
}
|
|
2060
|
-
)
|
|
2061
|
-
);
|
|
2062
|
-
TableHead.displayName = "TableHead";
|
|
2063
|
-
var alignClass = {
|
|
2064
|
-
left: "text-left",
|
|
2065
|
-
center: "text-center",
|
|
2066
|
-
right: "text-right"
|
|
2067
|
-
};
|
|
2068
|
-
var TableCell = forwardRef(
|
|
2069
|
-
({ children, className, align = "left" }, ref) => /* @__PURE__ */ jsx("td", { ref, className: cn("px-4 py-3 text-white/80", alignClass[align], className), children })
|
|
2070
|
-
);
|
|
2071
|
-
TableCell.displayName = "TableCell";
|
|
2072
|
-
function TrendIndicator({ trend }) {
|
|
2073
|
-
if (trend.value > 0) {
|
|
2074
|
-
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-emerald-400", children: [
|
|
2075
|
-
/* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "w-3 h-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9V3M3 6l3-3 3 3" }) }),
|
|
2076
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
2077
|
-
"+",
|
|
2078
|
-
trend.value,
|
|
2079
|
-
trend.label ? ` ${trend.label}` : ""
|
|
2080
|
-
] })
|
|
2081
|
-
] });
|
|
2082
|
-
}
|
|
2083
|
-
if (trend.value < 0) {
|
|
2084
|
-
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-rose-400", children: [
|
|
2085
|
-
/* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "w-3 h-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 3v6M3 6l3 3 3-3" }) }),
|
|
2086
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
2087
|
-
trend.value,
|
|
2088
|
-
trend.label ? ` ${trend.label}` : ""
|
|
2089
|
-
] })
|
|
2090
|
-
] });
|
|
2091
|
-
}
|
|
2092
|
-
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-white/40", children: [
|
|
2093
|
-
/* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "w-3 h-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2 6h8" }) }),
|
|
2094
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
2095
|
-
trend.value,
|
|
2096
|
-
trend.label ? ` ${trend.label}` : ""
|
|
2097
|
-
] })
|
|
2098
|
-
] });
|
|
2934
|
+
);
|
|
2099
2935
|
}
|
|
2100
|
-
|
|
2936
|
+
var variantIcon = {
|
|
2937
|
+
info: InfoIcon,
|
|
2938
|
+
success: SuccessIcon,
|
|
2939
|
+
warning: WarningIcon,
|
|
2940
|
+
error: ErrorIcon
|
|
2941
|
+
};
|
|
2942
|
+
function Alert({ variant = "info", title, children, onDismiss, className }) {
|
|
2943
|
+
const Icon = variantIcon[variant];
|
|
2101
2944
|
return /* @__PURE__ */ jsxs(
|
|
2102
2945
|
"div",
|
|
2103
2946
|
{
|
|
2947
|
+
role: "alert",
|
|
2104
2948
|
className: cn(
|
|
2105
|
-
"
|
|
2949
|
+
"flex items-start gap-3 rounded-xl bg-white/5 ring-1 ring-white/10",
|
|
2950
|
+
"border-l-4 pl-4 pr-3 py-3",
|
|
2951
|
+
variantBorderColor[variant],
|
|
2106
2952
|
className
|
|
2107
2953
|
),
|
|
2108
2954
|
children: [
|
|
2109
|
-
|
|
2110
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
2111
|
-
/* @__PURE__ */ jsx("
|
|
2112
|
-
/* @__PURE__ */ jsx("
|
|
2113
|
-
|
|
2114
|
-
|
|
2955
|
+
/* @__PURE__ */ jsx("span", { className: cn("mt-0.5 shrink-0", variantIconColor[variant]), children: /* @__PURE__ */ jsx(Icon, {}) }),
|
|
2956
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2957
|
+
title && /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-white leading-snug mb-0.5", children: title }),
|
|
2958
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-white/70 leading-relaxed", children })
|
|
2959
|
+
] }),
|
|
2960
|
+
onDismiss && /* @__PURE__ */ jsx(
|
|
2961
|
+
"button",
|
|
2962
|
+
{
|
|
2963
|
+
type: "button",
|
|
2964
|
+
"aria-label": "Dismiss",
|
|
2965
|
+
onClick: onDismiss,
|
|
2966
|
+
className: cn(
|
|
2967
|
+
"shrink-0 flex items-center justify-center h-6 w-6 rounded-lg mt-0.5",
|
|
2968
|
+
"text-white/40 transition-colors hover:bg-white/10 hover:text-white/80",
|
|
2969
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
|
|
2970
|
+
),
|
|
2971
|
+
children: /* @__PURE__ */ jsx(
|
|
2972
|
+
"svg",
|
|
2973
|
+
{
|
|
2974
|
+
"aria-hidden": "true",
|
|
2975
|
+
width: "10",
|
|
2976
|
+
height: "10",
|
|
2977
|
+
viewBox: "0 0 10 10",
|
|
2978
|
+
fill: "none",
|
|
2979
|
+
children: /* @__PURE__ */ jsx("path", { d: "M1 1l8 8M9 1L1 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
2980
|
+
}
|
|
2981
|
+
)
|
|
2982
|
+
}
|
|
2983
|
+
)
|
|
2115
2984
|
]
|
|
2116
2985
|
}
|
|
2117
2986
|
);
|
|
@@ -2247,6 +3116,567 @@ function Pagination({
|
|
|
2247
3116
|
}
|
|
2248
3117
|
);
|
|
2249
3118
|
}
|
|
3119
|
+
function useControllableState(controlledValue, defaultValue, onChange) {
|
|
3120
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
3121
|
+
const value = controlledValue ?? internalValue;
|
|
3122
|
+
const setValue = (nextValue) => {
|
|
3123
|
+
const resolvedValue = typeof nextValue === "function" ? nextValue(value) : nextValue;
|
|
3124
|
+
if (controlledValue === void 0) {
|
|
3125
|
+
setInternalValue(resolvedValue);
|
|
3126
|
+
}
|
|
3127
|
+
onChange?.(resolvedValue);
|
|
3128
|
+
};
|
|
3129
|
+
return [value, setValue];
|
|
3130
|
+
}
|
|
3131
|
+
function startOfDay2(date) {
|
|
3132
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
3133
|
+
}
|
|
3134
|
+
function endOfDay(date) {
|
|
3135
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
|
|
3136
|
+
}
|
|
3137
|
+
function isDateRangeValue(value) {
|
|
3138
|
+
return typeof value === "object" && value !== null && "from" in value && "to" in value;
|
|
3139
|
+
}
|
|
3140
|
+
function hasActiveDateRange(range) {
|
|
3141
|
+
return range.from !== null || range.to !== null;
|
|
3142
|
+
}
|
|
3143
|
+
function isFilterValueActive(value) {
|
|
3144
|
+
if (value == null) return false;
|
|
3145
|
+
if (typeof value === "string") return value.trim() !== "";
|
|
3146
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
3147
|
+
if (isDateRangeValue(value)) return hasActiveDateRange(value);
|
|
3148
|
+
return true;
|
|
3149
|
+
}
|
|
3150
|
+
function getColumnValue(column, row) {
|
|
3151
|
+
if (column.accessorFn) {
|
|
3152
|
+
return column.accessorFn(row);
|
|
3153
|
+
}
|
|
3154
|
+
if (column.accessorKey) {
|
|
3155
|
+
return row[column.accessorKey];
|
|
3156
|
+
}
|
|
3157
|
+
return void 0;
|
|
3158
|
+
}
|
|
3159
|
+
function coerceDate(value) {
|
|
3160
|
+
if (value instanceof Date && !Number.isNaN(value.getTime())) {
|
|
3161
|
+
return value;
|
|
3162
|
+
}
|
|
3163
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
3164
|
+
const parsed = new Date(value);
|
|
3165
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
3166
|
+
}
|
|
3167
|
+
return null;
|
|
3168
|
+
}
|
|
3169
|
+
function compareValues(left, right) {
|
|
3170
|
+
if (left == null && right == null) return 0;
|
|
3171
|
+
if (left == null) return 1;
|
|
3172
|
+
if (right == null) return -1;
|
|
3173
|
+
if (left instanceof Date || right instanceof Date) {
|
|
3174
|
+
const leftDate = coerceDate(left);
|
|
3175
|
+
const rightDate = coerceDate(right);
|
|
3176
|
+
if (!leftDate && !rightDate) return 0;
|
|
3177
|
+
if (!leftDate) return 1;
|
|
3178
|
+
if (!rightDate) return -1;
|
|
3179
|
+
return leftDate.getTime() - rightDate.getTime();
|
|
3180
|
+
}
|
|
3181
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
3182
|
+
return left - right;
|
|
3183
|
+
}
|
|
3184
|
+
return String(left).localeCompare(String(right), void 0, {
|
|
3185
|
+
numeric: true,
|
|
3186
|
+
sensitivity: "base"
|
|
3187
|
+
});
|
|
3188
|
+
}
|
|
3189
|
+
function matchColumnFilter(column, row, filterValue) {
|
|
3190
|
+
if (!isFilterValueActive(filterValue)) {
|
|
3191
|
+
return true;
|
|
3192
|
+
}
|
|
3193
|
+
const rawValue = getColumnValue(column, row);
|
|
3194
|
+
if (column.filterFn) {
|
|
3195
|
+
return column.filterFn(rawValue, row, filterValue);
|
|
3196
|
+
}
|
|
3197
|
+
if (typeof column.filter === "function") {
|
|
3198
|
+
return true;
|
|
3199
|
+
}
|
|
3200
|
+
switch (column.filter) {
|
|
3201
|
+
case "select":
|
|
3202
|
+
case "boolean":
|
|
3203
|
+
return String(rawValue ?? "") === String(filterValue);
|
|
3204
|
+
case "date-range": {
|
|
3205
|
+
if (!isDateRangeValue(filterValue)) return true;
|
|
3206
|
+
const dateValue = coerceDate(rawValue);
|
|
3207
|
+
if (!dateValue) return false;
|
|
3208
|
+
if (filterValue.from && dateValue < startOfDay2(filterValue.from)) return false;
|
|
3209
|
+
if (filterValue.to && dateValue > endOfDay(filterValue.to)) return false;
|
|
3210
|
+
return true;
|
|
3211
|
+
}
|
|
3212
|
+
case "text":
|
|
3213
|
+
default:
|
|
3214
|
+
return String(rawValue ?? "").toLowerCase().includes(String(filterValue).trim().toLowerCase());
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
function defaultResultsLabel(meta) {
|
|
3218
|
+
return `Showing ${meta.from} - ${meta.to} of ${meta.total}`;
|
|
3219
|
+
}
|
|
3220
|
+
function SortIndicator({ active, desc }) {
|
|
3221
|
+
return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex flex-col text-[10px] leading-none", active ? "text-white" : "text-white/25"), children: [
|
|
3222
|
+
/* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: cn("h-2.5 w-2.5", active && !desc && "text-primary"), viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4.5 9.5 8 6l3.5 3.5", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
3223
|
+
/* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: cn("h-2.5 w-2.5 -mt-0.5", active && desc && "text-primary"), viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4.5 6.5 8 10l3.5-3.5", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
3224
|
+
] });
|
|
3225
|
+
}
|
|
3226
|
+
function DataTable({
|
|
3227
|
+
data,
|
|
3228
|
+
columns,
|
|
3229
|
+
caption,
|
|
3230
|
+
searchValue,
|
|
3231
|
+
defaultSearchValue = "",
|
|
3232
|
+
onSearchValueChange,
|
|
3233
|
+
searchPlaceholder = "Search records...",
|
|
3234
|
+
enableSearch,
|
|
3235
|
+
sortBy,
|
|
3236
|
+
defaultSortBy = null,
|
|
3237
|
+
onSortChange,
|
|
3238
|
+
filters,
|
|
3239
|
+
defaultFilters = {},
|
|
3240
|
+
onFiltersChange,
|
|
3241
|
+
showFilters,
|
|
3242
|
+
defaultShowFilters = false,
|
|
3243
|
+
onShowFiltersChange,
|
|
3244
|
+
page,
|
|
3245
|
+
defaultPage = 1,
|
|
3246
|
+
onPageChange,
|
|
3247
|
+
pageSize,
|
|
3248
|
+
defaultPageSize = 25,
|
|
3249
|
+
onPageSizeChange,
|
|
3250
|
+
pageSizeOptions = [25, 50, 100],
|
|
3251
|
+
totalItems,
|
|
3252
|
+
loading,
|
|
3253
|
+
loadingRows = 5,
|
|
3254
|
+
error,
|
|
3255
|
+
onRetry,
|
|
3256
|
+
emptyState,
|
|
3257
|
+
emptyTitle = "Nothing to show yet",
|
|
3258
|
+
emptyDescription = "No rows matched the current filters.",
|
|
3259
|
+
filterToggleLabel = "Filters",
|
|
3260
|
+
clearFiltersLabel = "Clear",
|
|
3261
|
+
pageSizeLabel = "Rows",
|
|
3262
|
+
resultsLabel = defaultResultsLabel,
|
|
3263
|
+
toolbarActions,
|
|
3264
|
+
stickyHeader,
|
|
3265
|
+
dense,
|
|
3266
|
+
className,
|
|
3267
|
+
manualSorting,
|
|
3268
|
+
manualFiltering,
|
|
3269
|
+
manualPagination,
|
|
3270
|
+
onRowClick,
|
|
3271
|
+
rowHref,
|
|
3272
|
+
getRowId,
|
|
3273
|
+
getRowClassName
|
|
3274
|
+
}) {
|
|
3275
|
+
const visibleColumns = useMemo(() => columns.filter((column) => !column.hidden), [columns]);
|
|
3276
|
+
const [currentSearch, setCurrentSearch] = useControllableState(searchValue, defaultSearchValue, onSearchValueChange);
|
|
3277
|
+
const [currentSort, setCurrentSort] = useControllableState(sortBy, defaultSortBy, onSortChange);
|
|
3278
|
+
const [currentFilters, setCurrentFilters] = useControllableState(filters, defaultFilters, onFiltersChange);
|
|
3279
|
+
const [filtersVisible, setFiltersVisible] = useControllableState(showFilters, defaultShowFilters, onShowFiltersChange);
|
|
3280
|
+
const [currentPage, setCurrentPage] = useControllableState(page, defaultPage, onPageChange);
|
|
3281
|
+
const [currentPageSize, setCurrentPageSize] = useControllableState(pageSize, defaultPageSize, onPageSizeChange);
|
|
3282
|
+
const hasSearchControl = enableSearch || searchValue !== void 0 || defaultSearchValue !== "";
|
|
3283
|
+
const searchTerm = currentSearch.trim().toLowerCase();
|
|
3284
|
+
const searchableColumns = useMemo(
|
|
3285
|
+
() => visibleColumns.filter((column) => column.searchable !== false),
|
|
3286
|
+
[visibleColumns]
|
|
3287
|
+
);
|
|
3288
|
+
const filteredRows = useMemo(() => {
|
|
3289
|
+
if (manualFiltering) {
|
|
3290
|
+
return data;
|
|
3291
|
+
}
|
|
3292
|
+
return data.filter((row) => {
|
|
3293
|
+
const matchesSearch = !searchTerm || searchableColumns.some((column) => {
|
|
3294
|
+
const value = getColumnValue(column, row);
|
|
3295
|
+
return String(value ?? "").toLowerCase().includes(searchTerm);
|
|
3296
|
+
});
|
|
3297
|
+
if (!matchesSearch) {
|
|
3298
|
+
return false;
|
|
3299
|
+
}
|
|
3300
|
+
return visibleColumns.every((column) => matchColumnFilter(column, row, currentFilters[column.id]));
|
|
3301
|
+
});
|
|
3302
|
+
}, [currentFilters, data, manualFiltering, searchTerm, searchableColumns, visibleColumns]);
|
|
3303
|
+
const sortedRows = useMemo(() => {
|
|
3304
|
+
if (manualSorting || currentSort == null) {
|
|
3305
|
+
return filteredRows;
|
|
3306
|
+
}
|
|
3307
|
+
const sortColumn = visibleColumns.find((column) => column.id === currentSort.id);
|
|
3308
|
+
if (!sortColumn) {
|
|
3309
|
+
return filteredRows;
|
|
3310
|
+
}
|
|
3311
|
+
return [...filteredRows].sort((left, right) => {
|
|
3312
|
+
const result = compareValues(getColumnValue(sortColumn, left), getColumnValue(sortColumn, right));
|
|
3313
|
+
return currentSort.desc ? -result : result;
|
|
3314
|
+
});
|
|
3315
|
+
}, [currentSort, filteredRows, manualSorting, visibleColumns]);
|
|
3316
|
+
const derivedTotalItems = manualPagination ? totalItems ?? data.length : sortedRows.length;
|
|
3317
|
+
const totalPages = Math.max(1, Math.ceil(derivedTotalItems / currentPageSize));
|
|
3318
|
+
useEffect(() => {
|
|
3319
|
+
if (currentPage > totalPages) {
|
|
3320
|
+
setCurrentPage(totalPages);
|
|
3321
|
+
}
|
|
3322
|
+
}, [currentPage, setCurrentPage, totalPages]);
|
|
3323
|
+
const pagedRows = useMemo(() => {
|
|
3324
|
+
if (manualPagination) {
|
|
3325
|
+
return data;
|
|
3326
|
+
}
|
|
3327
|
+
const startIndex = (currentPage - 1) * currentPageSize;
|
|
3328
|
+
return sortedRows.slice(startIndex, startIndex + currentPageSize);
|
|
3329
|
+
}, [currentPage, currentPageSize, data, manualPagination, sortedRows]);
|
|
3330
|
+
const activeFilterCount = useMemo(
|
|
3331
|
+
() => Object.values(currentFilters).filter(isFilterValueActive).length + (searchTerm ? 1 : 0),
|
|
3332
|
+
[currentFilters, searchTerm]
|
|
3333
|
+
);
|
|
3334
|
+
const from = derivedTotalItems === 0 ? 0 : (currentPage - 1) * currentPageSize + 1;
|
|
3335
|
+
const to = derivedTotalItems === 0 ? 0 : manualPagination ? Math.min(from + pagedRows.length - 1, derivedTotalItems) : Math.min(currentPage * currentPageSize, derivedTotalItems);
|
|
3336
|
+
const handleSortToggle = (column) => {
|
|
3337
|
+
if (!column.sortable) return;
|
|
3338
|
+
setCurrentPage(1);
|
|
3339
|
+
setCurrentSort((previousSort) => {
|
|
3340
|
+
if (!previousSort || previousSort.id !== column.id) {
|
|
3341
|
+
return { id: column.id, desc: Boolean(column.sortDescFirst) };
|
|
3342
|
+
}
|
|
3343
|
+
if (previousSort.desc === Boolean(column.sortDescFirst)) {
|
|
3344
|
+
return { id: column.id, desc: !previousSort.desc };
|
|
3345
|
+
}
|
|
3346
|
+
return null;
|
|
3347
|
+
});
|
|
3348
|
+
};
|
|
3349
|
+
const handleFilterChange = (columnId, value) => {
|
|
3350
|
+
setCurrentPage(1);
|
|
3351
|
+
setCurrentFilters((previousFilters) => ({
|
|
3352
|
+
...previousFilters,
|
|
3353
|
+
[columnId]: value
|
|
3354
|
+
}));
|
|
3355
|
+
};
|
|
3356
|
+
const handleClear = () => {
|
|
3357
|
+
setCurrentSearch("");
|
|
3358
|
+
setCurrentPage(1);
|
|
3359
|
+
setCurrentFilters({});
|
|
3360
|
+
};
|
|
3361
|
+
const handlePageSizeChange = (value) => {
|
|
3362
|
+
setCurrentPage(1);
|
|
3363
|
+
setCurrentPageSize(value);
|
|
3364
|
+
};
|
|
3365
|
+
const handleRowActivate = (row) => {
|
|
3366
|
+
onRowClick?.(row);
|
|
3367
|
+
const href = rowHref?.(row);
|
|
3368
|
+
if (href && typeof window !== "undefined") {
|
|
3369
|
+
window.location.assign(href);
|
|
3370
|
+
}
|
|
3371
|
+
};
|
|
3372
|
+
const renderFilterControl = (column) => {
|
|
3373
|
+
const filterValue = currentFilters[column.id];
|
|
3374
|
+
if (typeof column.filter === "function") {
|
|
3375
|
+
return column.filter({
|
|
3376
|
+
column,
|
|
3377
|
+
value: filterValue,
|
|
3378
|
+
onChange: (value) => handleFilterChange(column.id, value),
|
|
3379
|
+
data
|
|
3380
|
+
});
|
|
3381
|
+
}
|
|
3382
|
+
switch (column.filter) {
|
|
3383
|
+
case "select":
|
|
3384
|
+
case "boolean":
|
|
3385
|
+
return /* @__PURE__ */ jsxs(
|
|
3386
|
+
"select",
|
|
3387
|
+
{
|
|
3388
|
+
"aria-label": `Filter ${typeof column.header === "string" ? column.header : column.id}`,
|
|
3389
|
+
value: typeof filterValue === "string" ? filterValue : "",
|
|
3390
|
+
onChange: (event) => handleFilterChange(column.id, event.target.value),
|
|
3391
|
+
className: "w-full rounded-lg border border-white/10 bg-white/5 px-2.5 py-2 text-sm text-white outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
3392
|
+
children: [
|
|
3393
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "All" }),
|
|
3394
|
+
column.filterOptions?.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
3395
|
+
]
|
|
3396
|
+
}
|
|
3397
|
+
);
|
|
3398
|
+
case "date-range":
|
|
3399
|
+
return /* @__PURE__ */ jsx(
|
|
3400
|
+
DateRangePicker,
|
|
3401
|
+
{
|
|
3402
|
+
compact: true,
|
|
3403
|
+
value: isDateRangeValue(filterValue) ? filterValue : { from: null, to: null },
|
|
3404
|
+
onChange: (range) => handleFilterChange(column.id, range),
|
|
3405
|
+
placeholder: { trigger: "Any date" }
|
|
3406
|
+
}
|
|
3407
|
+
);
|
|
3408
|
+
case "text":
|
|
3409
|
+
default:
|
|
3410
|
+
return /* @__PURE__ */ jsx(
|
|
3411
|
+
"input",
|
|
3412
|
+
{
|
|
3413
|
+
"aria-label": `Filter ${typeof column.header === "string" ? column.header : column.id}`,
|
|
3414
|
+
type: "text",
|
|
3415
|
+
value: typeof filterValue === "string" ? filterValue : "",
|
|
3416
|
+
onChange: (event) => handleFilterChange(column.id, event.target.value),
|
|
3417
|
+
className: "w-full rounded-lg border border-white/10 bg-white/5 px-2.5 py-2 text-sm text-white outline-none placeholder:text-white/25 focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
3418
|
+
placeholder: "Filter..."
|
|
3419
|
+
}
|
|
3420
|
+
);
|
|
3421
|
+
}
|
|
3422
|
+
};
|
|
3423
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
3424
|
+
hasSearchControl || toolbarActions || visibleColumns.some((column) => column.filter) ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between", children: [
|
|
3425
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
3426
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-white/60", children: [
|
|
3427
|
+
/* @__PURE__ */ jsx("span", { children: pageSizeLabel }),
|
|
3428
|
+
/* @__PURE__ */ jsx(
|
|
3429
|
+
"select",
|
|
3430
|
+
{
|
|
3431
|
+
"aria-label": "Rows per page",
|
|
3432
|
+
value: currentPageSize,
|
|
3433
|
+
onChange: (event) => handlePageSizeChange(Number(event.target.value)),
|
|
3434
|
+
className: "rounded-lg border border-white/10 bg-white/5 px-2.5 py-2 text-sm text-white outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
3435
|
+
children: pageSizeOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option, children: option }, option))
|
|
3436
|
+
}
|
|
3437
|
+
)
|
|
3438
|
+
] }),
|
|
3439
|
+
visibleColumns.some((column) => column.filter) ? /* @__PURE__ */ jsxs(
|
|
3440
|
+
Button,
|
|
3441
|
+
{
|
|
3442
|
+
size: "sm",
|
|
3443
|
+
variant: filtersVisible ? "secondary" : "ghost",
|
|
3444
|
+
onClick: () => setFiltersVisible((previousValue) => !previousValue),
|
|
3445
|
+
children: [
|
|
3446
|
+
filterToggleLabel,
|
|
3447
|
+
activeFilterCount > 0 ? ` (${activeFilterCount})` : ""
|
|
3448
|
+
]
|
|
3449
|
+
}
|
|
3450
|
+
) : null,
|
|
3451
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: handleClear, children: clearFiltersLabel }) : null
|
|
3452
|
+
] }),
|
|
3453
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end", children: [
|
|
3454
|
+
hasSearchControl ? /* @__PURE__ */ jsx(
|
|
3455
|
+
SearchInput,
|
|
3456
|
+
{
|
|
3457
|
+
value: currentSearch,
|
|
3458
|
+
onChange: (event) => {
|
|
3459
|
+
setCurrentPage(1);
|
|
3460
|
+
setCurrentSearch(event.target.value);
|
|
3461
|
+
},
|
|
3462
|
+
onClear: () => {
|
|
3463
|
+
setCurrentPage(1);
|
|
3464
|
+
setCurrentSearch("");
|
|
3465
|
+
},
|
|
3466
|
+
placeholder: searchPlaceholder,
|
|
3467
|
+
className: "min-w-[16rem]"
|
|
3468
|
+
}
|
|
3469
|
+
) : null,
|
|
3470
|
+
toolbarActions
|
|
3471
|
+
] })
|
|
3472
|
+
] }) : null,
|
|
3473
|
+
error ? /* @__PURE__ */ jsx(Alert, { variant: "error", title: "Unable to load table data", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
3474
|
+
/* @__PURE__ */ jsx("span", { children: error }),
|
|
3475
|
+
onRetry ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "secondary", onClick: onRetry, children: "Retry" }) : null
|
|
3476
|
+
] }) }) : null,
|
|
3477
|
+
/* @__PURE__ */ jsxs(Table, { className: "min-w-full", children: [
|
|
3478
|
+
caption ? /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
3479
|
+
/* @__PURE__ */ jsxs(TableHeader, { children: [
|
|
3480
|
+
/* @__PURE__ */ jsx(TableRow, { children: visibleColumns.map((column) => {
|
|
3481
|
+
const sorted = currentSort?.id === column.id ? currentSort : null;
|
|
3482
|
+
const ariaSort = column.sortable ? sorted ? sorted.desc ? "descending" : "ascending" : "none" : void 0;
|
|
3483
|
+
return /* @__PURE__ */ jsx(
|
|
3484
|
+
TableHead,
|
|
3485
|
+
{
|
|
3486
|
+
className: cn(
|
|
3487
|
+
stickyHeader && "sticky top-0 z-10 bg-[#121420] backdrop-blur-sm",
|
|
3488
|
+
column.headerClassName
|
|
3489
|
+
),
|
|
3490
|
+
style: { width: column.width, minWidth: column.minWidth },
|
|
3491
|
+
"aria-sort": ariaSort,
|
|
3492
|
+
children: column.sortable ? /* @__PURE__ */ jsxs(
|
|
3493
|
+
"button",
|
|
3494
|
+
{
|
|
3495
|
+
type: "button",
|
|
3496
|
+
onClick: () => handleSortToggle(column),
|
|
3497
|
+
className: "flex w-full items-center gap-2 text-left transition-colors hover:text-white",
|
|
3498
|
+
children: [
|
|
3499
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: typeof column.header === "function" ? column.header({ column, sort: sorted }) : column.header }),
|
|
3500
|
+
/* @__PURE__ */ jsx(SortIndicator, { active: sorted !== null, desc: sorted?.desc })
|
|
3501
|
+
]
|
|
3502
|
+
}
|
|
3503
|
+
) : typeof column.header === "function" ? column.header({ column, sort: sorted }) : column.header
|
|
3504
|
+
},
|
|
3505
|
+
column.id
|
|
3506
|
+
);
|
|
3507
|
+
}) }),
|
|
3508
|
+
filtersVisible ? /* @__PURE__ */ jsx(TableRow, { className: "bg-white/[0.025]", children: visibleColumns.map((column) => /* @__PURE__ */ jsx(
|
|
3509
|
+
TableHead,
|
|
3510
|
+
{
|
|
3511
|
+
className: "normal-case text-white/70 tracking-normal",
|
|
3512
|
+
style: { width: column.width, minWidth: column.minWidth },
|
|
3513
|
+
children: column.filter ? renderFilterControl(column) : null
|
|
3514
|
+
},
|
|
3515
|
+
`${column.id}-filter`
|
|
3516
|
+
)) }) : null
|
|
3517
|
+
] }),
|
|
3518
|
+
/* @__PURE__ */ jsx(TableBody, { children: loading ? Array.from({ length: loadingRows }).map((_, rowIndex) => /* @__PURE__ */ jsx(TableRow, { children: visibleColumns.map((column) => /* @__PURE__ */ jsx(TableCell, { className: dense ? "py-2" : void 0, align: column.align, children: /* @__PURE__ */ jsx(Skeleton, { className: cn(column.align === "right" ? "ml-auto" : "", "h-5 w-full max-w-[12rem]") }) }, `${column.id}-${rowIndex}`)) }, `loading-${rowIndex}`)) : pagedRows.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: visibleColumns.length, className: "py-10", align: "center", children: emptyState ?? /* @__PURE__ */ jsx(
|
|
3519
|
+
EmptyState,
|
|
3520
|
+
{
|
|
3521
|
+
title: emptyTitle,
|
|
3522
|
+
description: emptyDescription
|
|
3523
|
+
}
|
|
3524
|
+
) }) }) : pagedRows.map((row, rowIndex) => {
|
|
3525
|
+
const key = getRowId?.(row, rowIndex) ?? String(rowIndex);
|
|
3526
|
+
const href = rowHref?.(row);
|
|
3527
|
+
const interactive = Boolean(onRowClick || href);
|
|
3528
|
+
return /* @__PURE__ */ jsx(
|
|
3529
|
+
TableRow,
|
|
3530
|
+
{
|
|
3531
|
+
hoverable: interactive,
|
|
3532
|
+
className: cn(
|
|
3533
|
+
dense && "[&>td]:py-2",
|
|
3534
|
+
interactive && "cursor-pointer",
|
|
3535
|
+
getRowClassName?.(row, rowIndex)
|
|
3536
|
+
),
|
|
3537
|
+
...interactive ? {
|
|
3538
|
+
tabIndex: 0,
|
|
3539
|
+
onClick: () => handleRowActivate(row),
|
|
3540
|
+
onKeyDown: (event) => {
|
|
3541
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
3542
|
+
event.preventDefault();
|
|
3543
|
+
handleRowActivate(row);
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
} : {},
|
|
3547
|
+
children: visibleColumns.map((column) => {
|
|
3548
|
+
const value = getColumnValue(column, row);
|
|
3549
|
+
return /* @__PURE__ */ jsx(
|
|
3550
|
+
TableCell,
|
|
3551
|
+
{
|
|
3552
|
+
align: column.align,
|
|
3553
|
+
className: column.className,
|
|
3554
|
+
children: column.cell ? column.cell({ row, value, rowIndex, column }) : value == null ? "\u2014" : String(value)
|
|
3555
|
+
},
|
|
3556
|
+
column.id
|
|
3557
|
+
);
|
|
3558
|
+
})
|
|
3559
|
+
},
|
|
3560
|
+
key
|
|
3561
|
+
);
|
|
3562
|
+
}) })
|
|
3563
|
+
] }),
|
|
3564
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 border-t border-white/10 pt-3 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
3565
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-white/50", children: resultsLabel({ from, to, total: derivedTotalItems }) }),
|
|
3566
|
+
/* @__PURE__ */ jsx(Pagination, { page: currentPage, totalPages, onPageChange: (nextPage) => setCurrentPage(nextPage) })
|
|
3567
|
+
] })
|
|
3568
|
+
] });
|
|
3569
|
+
}
|
|
3570
|
+
var sizeStyles = {
|
|
3571
|
+
sm: "p-3 gap-3",
|
|
3572
|
+
md: "p-4 gap-3",
|
|
3573
|
+
lg: "p-5 gap-4"
|
|
3574
|
+
};
|
|
3575
|
+
var valueStyles = {
|
|
3576
|
+
sm: "text-xl",
|
|
3577
|
+
md: "text-2xl",
|
|
3578
|
+
lg: "text-3xl"
|
|
3579
|
+
};
|
|
3580
|
+
var labelStyles = {
|
|
3581
|
+
sm: "text-[11px] uppercase tracking-[0.16em]",
|
|
3582
|
+
md: "text-sm",
|
|
3583
|
+
lg: "text-sm uppercase tracking-[0.18em]"
|
|
3584
|
+
};
|
|
3585
|
+
var iconStyles = {
|
|
3586
|
+
sm: "h-9 w-9 rounded-xl text-sm",
|
|
3587
|
+
md: "h-10 w-10 rounded-xl text-base",
|
|
3588
|
+
lg: "h-11 w-11 rounded-2xl text-base"
|
|
3589
|
+
};
|
|
3590
|
+
function getSignedValue(value) {
|
|
3591
|
+
if (value > 0) return `+${value}`;
|
|
3592
|
+
return `${value}`;
|
|
3593
|
+
}
|
|
3594
|
+
function getValueColorClass(valueColor, value) {
|
|
3595
|
+
if (valueColor === "default") return "text-white";
|
|
3596
|
+
if (valueColor === "success") return "text-emerald-400";
|
|
3597
|
+
if (valueColor === "danger") return "text-rose-400";
|
|
3598
|
+
if (valueColor === "warning") return "text-amber-400";
|
|
3599
|
+
const raw = typeof value === "number" ? value : Number(String(value).replace(/[%,$\s]/g, ""));
|
|
3600
|
+
if (!Number.isNaN(raw)) {
|
|
3601
|
+
if (raw > 0) return "text-emerald-400";
|
|
3602
|
+
if (raw < 0) return "text-rose-400";
|
|
3603
|
+
}
|
|
3604
|
+
const trimmed = String(value).trim();
|
|
3605
|
+
if (trimmed.startsWith("+")) return "text-emerald-400";
|
|
3606
|
+
if (trimmed.startsWith("-")) return "text-rose-400";
|
|
3607
|
+
return "text-white";
|
|
3608
|
+
}
|
|
3609
|
+
function TrendIndicator({ trend }) {
|
|
3610
|
+
const tone = trend.value > 0 ? "text-emerald-400" : trend.value < 0 ? "text-rose-400" : "text-white/40";
|
|
3611
|
+
const icon = trend.value > 0 ? /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9V3M3 6l3-3 3 3" }) : trend.value < 0 ? /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 3v6M3 6l3 3 3-3" }) : /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2 6h8" });
|
|
3612
|
+
const text = trend.format ? trend.format({ value: trend.value, percentValue: trend.percentValue }) : `${getSignedValue(trend.value)}${trend.percentValue != null ? ` (${getSignedValue(trend.percentValue)}%)` : ""}${trend.label ? ` ${trend.label}` : ""}`;
|
|
3613
|
+
return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center gap-1 text-xs", tone), children: [
|
|
3614
|
+
/* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "h-3 w-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: icon }),
|
|
3615
|
+
/* @__PURE__ */ jsx("span", { children: text })
|
|
3616
|
+
] });
|
|
3617
|
+
}
|
|
3618
|
+
function MetricContent({ value, label, trend, size, valueColor }) {
|
|
3619
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
3620
|
+
/* @__PURE__ */ jsx("span", { className: cn("block font-bold leading-none tabular-nums", valueStyles[size], getValueColorClass(valueColor, value)), children: value }),
|
|
3621
|
+
/* @__PURE__ */ jsx("span", { className: cn("block truncate text-white/55", labelStyles[size]), children: label }),
|
|
3622
|
+
trend ? /* @__PURE__ */ jsx(TrendIndicator, { trend }) : null
|
|
3623
|
+
] });
|
|
3624
|
+
}
|
|
3625
|
+
function ChevronIcon2() {
|
|
3626
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "h-4 w-4", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M8 5l5 5-5 5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
3627
|
+
}
|
|
3628
|
+
function StatCard({
|
|
3629
|
+
value,
|
|
3630
|
+
label,
|
|
3631
|
+
icon,
|
|
3632
|
+
trend,
|
|
3633
|
+
size = "md",
|
|
3634
|
+
valueColor = "default",
|
|
3635
|
+
href,
|
|
3636
|
+
onClick,
|
|
3637
|
+
loading,
|
|
3638
|
+
secondaryMetric,
|
|
3639
|
+
className
|
|
3640
|
+
}) {
|
|
3641
|
+
const clickable = Boolean(href || onClick);
|
|
3642
|
+
const rootClassName = cn(
|
|
3643
|
+
"glass rounded-xl transition-[transform,background-color,box-shadow,ring-color]",
|
|
3644
|
+
sizeStyles[size],
|
|
3645
|
+
clickable && "group hover:bg-white/[0.08] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-black/20",
|
|
3646
|
+
className
|
|
3647
|
+
);
|
|
3648
|
+
const content = loading ? /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start gap-3", children: [
|
|
3649
|
+
icon ? /* @__PURE__ */ jsx(Skeleton, { className: cn(iconStyles[size]) }) : null,
|
|
3650
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
3651
|
+
/* @__PURE__ */ jsx(Skeleton, { className: cn("h-7 max-w-[8rem]", size === "lg" && "h-8 max-w-[10rem]") }),
|
|
3652
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 max-w-[11rem]" }),
|
|
3653
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 max-w-[9rem]" })
|
|
3654
|
+
] })
|
|
3655
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3656
|
+
icon ? /* @__PURE__ */ jsx("div", { className: cn("shrink-0 bg-white/10 flex items-center justify-center text-primary", iconStyles[size]), children: icon }) : null,
|
|
3657
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
3658
|
+
/* @__PURE__ */ jsx(MetricContent, { value, label, trend, size, valueColor }),
|
|
3659
|
+
secondaryMetric ? /* @__PURE__ */ jsx("div", { className: "mt-4 border-t border-white/10 pt-4", children: /* @__PURE__ */ jsx(
|
|
3660
|
+
MetricContent,
|
|
3661
|
+
{
|
|
3662
|
+
value: secondaryMetric.value,
|
|
3663
|
+
label: secondaryMetric.label,
|
|
3664
|
+
trend: secondaryMetric.trend,
|
|
3665
|
+
size: size === "lg" ? "md" : size,
|
|
3666
|
+
valueColor: "default"
|
|
3667
|
+
}
|
|
3668
|
+
) }) : null
|
|
3669
|
+
] }),
|
|
3670
|
+
clickable ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 text-white/35 transition-colors group-hover:text-white/70", children: /* @__PURE__ */ jsx(ChevronIcon2, {}) }) : null
|
|
3671
|
+
] });
|
|
3672
|
+
if (href) {
|
|
3673
|
+
return /* @__PURE__ */ jsx("a", { href, className: cn("flex items-start", rootClassName), children: content });
|
|
3674
|
+
}
|
|
3675
|
+
if (onClick) {
|
|
3676
|
+
return /* @__PURE__ */ jsx("button", { type: "button", onClick, className: cn("flex w-full items-start text-left", rootClassName), children: content });
|
|
3677
|
+
}
|
|
3678
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex items-start", rootClassName), children: content });
|
|
3679
|
+
}
|
|
2250
3680
|
function Stepper({ steps, activeStep, className }) {
|
|
2251
3681
|
return /* @__PURE__ */ jsx("div", { className: cn("flex items-start w-full", className), children: steps.map((step, index) => {
|
|
2252
3682
|
const isCompleted = index < activeStep;
|
|
@@ -2579,8 +4009,221 @@ function DotIndicator({
|
|
|
2579
4009
|
);
|
|
2580
4010
|
})
|
|
2581
4011
|
}
|
|
2582
|
-
),
|
|
2583
|
-
showLabel && /* @__PURE__ */ jsx("span", { className: cn("text-xs font-medium tabular-nums", urgency.label), children: label })
|
|
4012
|
+
),
|
|
4013
|
+
showLabel && /* @__PURE__ */ jsx("span", { className: cn("text-xs font-medium tabular-nums", urgency.label), children: label })
|
|
4014
|
+
] });
|
|
4015
|
+
}
|
|
4016
|
+
var toneClass = {
|
|
4017
|
+
default: "text-white/55 bg-white/[0.04] ring-white/10",
|
|
4018
|
+
primary: "text-primary bg-primary/10 ring-primary/20",
|
|
4019
|
+
success: "text-emerald-400 bg-emerald-500/10 ring-emerald-500/20",
|
|
4020
|
+
warning: "text-amber-400 bg-amber-500/10 ring-amber-500/20",
|
|
4021
|
+
danger: "text-rose-400 bg-rose-500/10 ring-rose-500/20",
|
|
4022
|
+
accent: "text-accent-light bg-accent/10 ring-accent/20"
|
|
4023
|
+
};
|
|
4024
|
+
var variantStyles = {
|
|
4025
|
+
default: {
|
|
4026
|
+
gap: "gap-4",
|
|
4027
|
+
icon: "h-10 w-10 text-sm",
|
|
4028
|
+
textGap: "gap-2"
|
|
4029
|
+
},
|
|
4030
|
+
compact: {
|
|
4031
|
+
gap: "gap-3",
|
|
4032
|
+
icon: "h-8 w-8 text-xs",
|
|
4033
|
+
textGap: "gap-1.5"
|
|
4034
|
+
}
|
|
4035
|
+
};
|
|
4036
|
+
function toDate(value) {
|
|
4037
|
+
if (!value) return null;
|
|
4038
|
+
if (value instanceof Date) {
|
|
4039
|
+
return Number.isNaN(value.getTime()) ? null : value;
|
|
4040
|
+
}
|
|
4041
|
+
const parsed = new Date(value);
|
|
4042
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
4043
|
+
}
|
|
4044
|
+
function formatTimestamp(value) {
|
|
4045
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
4046
|
+
year: "numeric",
|
|
4047
|
+
month: "2-digit",
|
|
4048
|
+
day: "2-digit",
|
|
4049
|
+
hour: "2-digit",
|
|
4050
|
+
minute: "2-digit",
|
|
4051
|
+
second: "2-digit"
|
|
4052
|
+
}).format(value);
|
|
4053
|
+
}
|
|
4054
|
+
function formatGroupHeader(value, groupBy) {
|
|
4055
|
+
if (groupBy === "day") {
|
|
4056
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
4057
|
+
year: "numeric",
|
|
4058
|
+
month: "long",
|
|
4059
|
+
day: "numeric"
|
|
4060
|
+
}).format(value);
|
|
4061
|
+
}
|
|
4062
|
+
if (groupBy === "month") {
|
|
4063
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
4064
|
+
year: "numeric",
|
|
4065
|
+
month: "long"
|
|
4066
|
+
}).format(value);
|
|
4067
|
+
}
|
|
4068
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
4069
|
+
year: "numeric"
|
|
4070
|
+
}).format(value);
|
|
4071
|
+
}
|
|
4072
|
+
function getGroupKey(value, groupBy) {
|
|
4073
|
+
const year = value.getFullYear();
|
|
4074
|
+
const month = String(value.getMonth() + 1).padStart(2, "0");
|
|
4075
|
+
const day = String(value.getDate()).padStart(2, "0");
|
|
4076
|
+
if (groupBy === "year") return `${year}`;
|
|
4077
|
+
if (groupBy === "month") return `${year}-${month}`;
|
|
4078
|
+
return `${year}-${month}-${day}`;
|
|
4079
|
+
}
|
|
4080
|
+
function DefaultIcon() {
|
|
4081
|
+
return /* @__PURE__ */ jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-current", "aria-hidden": "true" });
|
|
4082
|
+
}
|
|
4083
|
+
function getToneStyle(iconColor) {
|
|
4084
|
+
if (!iconColor || iconColor in toneClass) {
|
|
4085
|
+
const tone = iconColor ?? "default";
|
|
4086
|
+
return { className: toneClass[tone] };
|
|
4087
|
+
}
|
|
4088
|
+
return {
|
|
4089
|
+
className: "bg-white/[0.04] ring-white/10",
|
|
4090
|
+
style: { color: iconColor }
|
|
4091
|
+
};
|
|
4092
|
+
}
|
|
4093
|
+
function getLineClass(lineStyle) {
|
|
4094
|
+
if (lineStyle === "dashed") {
|
|
4095
|
+
return "border-l border-dashed border-white/10";
|
|
4096
|
+
}
|
|
4097
|
+
if (lineStyle === "solid") {
|
|
4098
|
+
return "border-l border-white/10";
|
|
4099
|
+
}
|
|
4100
|
+
return "border-l border-transparent";
|
|
4101
|
+
}
|
|
4102
|
+
function LoadingTimeline({ variant }) {
|
|
4103
|
+
const styles = variantStyles[variant];
|
|
4104
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: Array.from({ length: 4 }).map((_, index) => /* @__PURE__ */ jsxs("div", { className: cn("flex items-start", styles.gap), children: [
|
|
4105
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex w-10 shrink-0 justify-center", children: /* @__PURE__ */ jsx(Skeleton, { circle: true, className: styles.icon }) }),
|
|
4106
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
4107
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 max-w-[12rem]" }),
|
|
4108
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 max-w-[14rem]" }),
|
|
4109
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 max-w-[18rem]" })
|
|
4110
|
+
] })
|
|
4111
|
+
] }, index)) });
|
|
4112
|
+
}
|
|
4113
|
+
function Timeline({
|
|
4114
|
+
events,
|
|
4115
|
+
timestampFormatter = formatTimestamp,
|
|
4116
|
+
timestampPosition = "above",
|
|
4117
|
+
groupBy = "none",
|
|
4118
|
+
groupHeaderFormatter = formatGroupHeader,
|
|
4119
|
+
variant = "default",
|
|
4120
|
+
lineStyle = "solid",
|
|
4121
|
+
order = "asc",
|
|
4122
|
+
maxVisible,
|
|
4123
|
+
onLoadMore,
|
|
4124
|
+
hasMore,
|
|
4125
|
+
loading,
|
|
4126
|
+
emptyState,
|
|
4127
|
+
className
|
|
4128
|
+
}) {
|
|
4129
|
+
const styles = variantStyles[variant];
|
|
4130
|
+
const orderedEvents = useMemo(() => {
|
|
4131
|
+
const nextEvents = [...events].map((event, index) => ({
|
|
4132
|
+
event,
|
|
4133
|
+
index,
|
|
4134
|
+
timestamp: toDate(event.timestamp)
|
|
4135
|
+
}));
|
|
4136
|
+
nextEvents.sort((left, right) => {
|
|
4137
|
+
const leftTime = left.timestamp?.getTime();
|
|
4138
|
+
const rightTime = right.timestamp?.getTime();
|
|
4139
|
+
if (leftTime == null && rightTime == null) return left.index - right.index;
|
|
4140
|
+
if (leftTime == null) return 1;
|
|
4141
|
+
if (rightTime == null) return -1;
|
|
4142
|
+
return order === "asc" ? leftTime - rightTime : rightTime - leftTime;
|
|
4143
|
+
});
|
|
4144
|
+
return nextEvents.map((entry) => entry.event);
|
|
4145
|
+
}, [events, order]);
|
|
4146
|
+
const visibleEvents = maxVisible ? orderedEvents.slice(0, maxVisible) : orderedEvents;
|
|
4147
|
+
const groupedEvents = useMemo(() => {
|
|
4148
|
+
if (groupBy === "none") {
|
|
4149
|
+
return [{ key: "all", date: null, items: visibleEvents }];
|
|
4150
|
+
}
|
|
4151
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4152
|
+
visibleEvents.forEach((event) => {
|
|
4153
|
+
const timestamp = toDate(event.timestamp);
|
|
4154
|
+
const key = timestamp ? getGroupKey(timestamp, groupBy) : "ungrouped";
|
|
4155
|
+
const existing = groups.get(key);
|
|
4156
|
+
if (existing) {
|
|
4157
|
+
existing.items.push(event);
|
|
4158
|
+
return;
|
|
4159
|
+
}
|
|
4160
|
+
groups.set(key, {
|
|
4161
|
+
key,
|
|
4162
|
+
date: timestamp,
|
|
4163
|
+
items: [event]
|
|
4164
|
+
});
|
|
4165
|
+
});
|
|
4166
|
+
return Array.from(groups.values());
|
|
4167
|
+
}, [groupBy, visibleEvents]);
|
|
4168
|
+
const showLoadMore = Boolean(onLoadMore) && (hasMore ?? orderedEvents.length > visibleEvents.length);
|
|
4169
|
+
if (loading) {
|
|
4170
|
+
return /* @__PURE__ */ jsx(LoadingTimeline, { variant });
|
|
4171
|
+
}
|
|
4172
|
+
if (visibleEvents.length === 0) {
|
|
4173
|
+
return /* @__PURE__ */ jsx("div", { className, children: emptyState ?? /* @__PURE__ */ jsx(EmptyState, { title: "No events yet", description: "Timeline entries will appear here once activity starts." }) });
|
|
4174
|
+
}
|
|
4175
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", className), children: [
|
|
4176
|
+
groupedEvents.map((group) => /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
4177
|
+
groupBy !== "none" && group.date ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-[0.18em] text-white/35", children: groupHeaderFormatter(group.date, groupBy) }) : null,
|
|
4178
|
+
/* @__PURE__ */ jsx("ol", { className: "space-y-4", children: group.items.map((event, index) => {
|
|
4179
|
+
const timestamp = toDate(event.timestamp);
|
|
4180
|
+
const tone = getToneStyle(event.iconColor);
|
|
4181
|
+
const isLast = index === group.items.length - 1;
|
|
4182
|
+
const timestampNode = timestamp ? /* @__PURE__ */ jsx("time", { dateTime: timestamp.toISOString(), className: "text-xs text-white/45", children: timestampFormatter(timestamp) }) : null;
|
|
4183
|
+
return /* @__PURE__ */ jsxs("li", { className: cn(timestampPosition === "side" ? "grid gap-3 md:grid-cols-[11rem_1fr]" : ""), children: [
|
|
4184
|
+
timestampPosition === "side" ? /* @__PURE__ */ jsx("div", { className: "pt-1 text-xs text-white/45", children: timestampNode }) : null,
|
|
4185
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex items-start", styles.gap), "aria-label": timestamp ? `${timestampFormatter(timestamp)} ${String(event.title)}` : void 0, children: [
|
|
4186
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex w-10 shrink-0 justify-center", children: [
|
|
4187
|
+
lineStyle !== "none" && !isLast ? /* @__PURE__ */ jsx(
|
|
4188
|
+
"span",
|
|
4189
|
+
{
|
|
4190
|
+
"aria-hidden": "true",
|
|
4191
|
+
className: cn("absolute left-1/2 top-10 bottom-[-1rem] -translate-x-1/2", getLineClass(lineStyle))
|
|
4192
|
+
}
|
|
4193
|
+
) : null,
|
|
4194
|
+
/* @__PURE__ */ jsx(
|
|
4195
|
+
"span",
|
|
4196
|
+
{
|
|
4197
|
+
className: cn(
|
|
4198
|
+
"relative z-[1] inline-flex shrink-0 items-center justify-center rounded-full ring-1",
|
|
4199
|
+
styles.icon,
|
|
4200
|
+
tone.className
|
|
4201
|
+
),
|
|
4202
|
+
style: tone.style,
|
|
4203
|
+
"aria-hidden": "true",
|
|
4204
|
+
children: event.icon ?? /* @__PURE__ */ jsx(DefaultIcon, {})
|
|
4205
|
+
}
|
|
4206
|
+
)
|
|
4207
|
+
] }),
|
|
4208
|
+
/* @__PURE__ */ jsxs("div", { className: cn("min-w-0 flex-1", styles.textGap, timestampPosition === "inline" ? "space-y-1.5" : "space-y-2"), children: [
|
|
4209
|
+
timestampPosition === "above" ? timestampNode : null,
|
|
4210
|
+
/* @__PURE__ */ jsxs("div", { className: cn(timestampPosition === "inline" ? "flex flex-wrap items-start justify-between gap-2" : "space-y-2"), children: [
|
|
4211
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-2", children: [
|
|
4212
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium leading-relaxed text-white", children: event.title }),
|
|
4213
|
+
event.description ? /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed text-white/60", children: event.description }) : null
|
|
4214
|
+
] }),
|
|
4215
|
+
timestampPosition === "inline" ? timestampNode : null
|
|
4216
|
+
] }),
|
|
4217
|
+
event.metadata && Object.keys(event.metadata).length > 0 ? /* @__PURE__ */ jsx("dl", { className: "grid gap-2 rounded-xl border border-white/10 bg-white/[0.03] p-3 sm:grid-cols-2", children: Object.entries(event.metadata).map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
4218
|
+
/* @__PURE__ */ jsx("dt", { className: "text-[11px] uppercase tracking-[0.14em] text-white/35", children: key }),
|
|
4219
|
+
/* @__PURE__ */ jsx("dd", { className: "text-sm text-white/70", children: value })
|
|
4220
|
+
] }, key)) }) : null
|
|
4221
|
+
] })
|
|
4222
|
+
] })
|
|
4223
|
+
] }, event.id);
|
|
4224
|
+
}) })
|
|
4225
|
+
] }, group.key)),
|
|
4226
|
+
showLoadMore ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", onClick: onLoadMore, children: "Load more" }) }) : null
|
|
2584
4227
|
] });
|
|
2585
4228
|
}
|
|
2586
4229
|
function ActiveFilterPills({
|
|
@@ -2755,7 +4398,7 @@ function Sidebar({ children, collapsed = false, onToggle, className }) {
|
|
|
2755
4398
|
}
|
|
2756
4399
|
);
|
|
2757
4400
|
}
|
|
2758
|
-
var
|
|
4401
|
+
var widthClass = {
|
|
2759
4402
|
sm: "max-w-2xl",
|
|
2760
4403
|
md: "max-w-4xl",
|
|
2761
4404
|
lg: "max-w-5xl",
|
|
@@ -2763,309 +4406,247 @@ var maxWidthClass2 = {
|
|
|
2763
4406
|
"2xl": "max-w-[92rem]",
|
|
2764
4407
|
full: "max-w-full"
|
|
2765
4408
|
};
|
|
2766
|
-
function
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
/* @__PURE__ */ jsx("div", { className: "orb orb-blue w-[300px] h-[300px] top-[60%] -right-[100px] opacity-10" })
|
|
2771
|
-
] }),
|
|
2772
|
-
navbar,
|
|
2773
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex", navbar && "pt-16"), children: [
|
|
2774
|
-
sidebar,
|
|
2775
|
-
/* @__PURE__ */ jsx("main", { className: cn("flex-1 min-w-0 py-8 px-6", mainClassName), children: /* @__PURE__ */ jsx("div", { className: cn("mx-auto", maxWidthClass2[maxWidth]), children }) })
|
|
2776
|
-
] })
|
|
2777
|
-
] });
|
|
2778
|
-
}
|
|
2779
|
-
var variantBorderColor = {
|
|
2780
|
-
info: "border-blue-500",
|
|
2781
|
-
success: "border-emerald-500",
|
|
2782
|
-
warning: "border-amber-500",
|
|
2783
|
-
error: "border-rose-500"
|
|
2784
|
-
};
|
|
2785
|
-
var variantIconColor = {
|
|
2786
|
-
info: "text-blue-400",
|
|
2787
|
-
success: "text-emerald-400",
|
|
2788
|
-
warning: "text-amber-400",
|
|
2789
|
-
error: "text-rose-400"
|
|
2790
|
-
};
|
|
2791
|
-
function InfoIcon() {
|
|
2792
|
-
return /* @__PURE__ */ jsxs(
|
|
2793
|
-
"svg",
|
|
2794
|
-
{
|
|
2795
|
-
"aria-hidden": "true",
|
|
2796
|
-
width: "18",
|
|
2797
|
-
height: "18",
|
|
2798
|
-
viewBox: "0 0 18 18",
|
|
2799
|
-
fill: "none",
|
|
2800
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2801
|
-
children: [
|
|
2802
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2803
|
-
/* @__PURE__ */ jsx("path", { d: "M9 8v5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" }),
|
|
2804
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "5.5", r: "0.875", fill: "currentColor" })
|
|
2805
|
-
]
|
|
2806
|
-
}
|
|
2807
|
-
);
|
|
4409
|
+
function getItemKey(item, index) {
|
|
4410
|
+
if (item.key) return item.key;
|
|
4411
|
+
if (item.href) return item.href;
|
|
4412
|
+
return `dashboard-nav-item-${index}`;
|
|
2808
4413
|
}
|
|
2809
|
-
function
|
|
2810
|
-
return
|
|
2811
|
-
"
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
width: "18",
|
|
2815
|
-
height: "18",
|
|
2816
|
-
viewBox: "0 0 18 18",
|
|
2817
|
-
fill: "none",
|
|
2818
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2819
|
-
children: [
|
|
2820
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2821
|
-
/* @__PURE__ */ jsx(
|
|
2822
|
-
"path",
|
|
2823
|
-
{
|
|
2824
|
-
d: "M5.5 9.5l2.5 2.5 4.5-5",
|
|
2825
|
-
stroke: "currentColor",
|
|
2826
|
-
strokeWidth: "1.75",
|
|
2827
|
-
strokeLinecap: "round",
|
|
2828
|
-
strokeLinejoin: "round"
|
|
2829
|
-
}
|
|
2830
|
-
)
|
|
2831
|
-
]
|
|
2832
|
-
}
|
|
4414
|
+
function getDesktopNavItemClass(item) {
|
|
4415
|
+
return cn(
|
|
4416
|
+
"flex items-center gap-3 rounded-lg px-4 py-2.5 text-sm transition-all duration-200",
|
|
4417
|
+
item.active ? "bg-accent/20 text-accent" : "text-white/60 hover:bg-white/5 hover:text-white",
|
|
4418
|
+
item.disabled && "pointer-events-none opacity-50"
|
|
2833
4419
|
);
|
|
2834
4420
|
}
|
|
2835
|
-
function
|
|
2836
|
-
return
|
|
2837
|
-
"
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
width: "18",
|
|
2841
|
-
height: "18",
|
|
2842
|
-
viewBox: "0 0 18 18",
|
|
2843
|
-
fill: "none",
|
|
2844
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2845
|
-
children: [
|
|
2846
|
-
/* @__PURE__ */ jsx(
|
|
2847
|
-
"path",
|
|
2848
|
-
{
|
|
2849
|
-
d: "M7.634 2.896a1.6 1.6 0 0 1 2.732 0l5.866 10.167A1.6 1.6 0 0 1 14.866 15.5H3.134a1.6 1.6 0 0 1-1.366-2.437L7.634 2.896Z",
|
|
2850
|
-
stroke: "currentColor",
|
|
2851
|
-
strokeWidth: "1.5",
|
|
2852
|
-
strokeLinejoin: "round"
|
|
2853
|
-
}
|
|
2854
|
-
),
|
|
2855
|
-
/* @__PURE__ */ jsx("path", { d: "M9 7v4", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" }),
|
|
2856
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "12.5", r: "0.875", fill: "currentColor" })
|
|
2857
|
-
]
|
|
2858
|
-
}
|
|
4421
|
+
function getMobileNavItemClass(item) {
|
|
4422
|
+
return cn(
|
|
4423
|
+
"flex flex-col items-center px-3 py-2 text-xs transition-colors",
|
|
4424
|
+
item.active ? "text-accent" : "text-white/50",
|
|
4425
|
+
item.disabled && "pointer-events-none opacity-50"
|
|
2859
4426
|
);
|
|
2860
4427
|
}
|
|
2861
|
-
function
|
|
2862
|
-
|
|
2863
|
-
"
|
|
4428
|
+
function renderDefaultNavItem(item, context) {
|
|
4429
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4430
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: context.type === "mobile" ? "text-lg" : void 0, children: item.icon }) : null,
|
|
4431
|
+
/* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", context.type === "desktop" && item.badge && "flex-1"), children: item.label }),
|
|
4432
|
+
context.type === "desktop" && item.badge ? /* @__PURE__ */ jsx("span", { className: "shrink-0", children: item.badge }) : null
|
|
4433
|
+
] });
|
|
4434
|
+
if (item.href) {
|
|
4435
|
+
return /* @__PURE__ */ jsx(
|
|
4436
|
+
"a",
|
|
4437
|
+
{
|
|
4438
|
+
href: item.href,
|
|
4439
|
+
target: item.target,
|
|
4440
|
+
rel: item.rel,
|
|
4441
|
+
"aria-current": item.active ? "page" : void 0,
|
|
4442
|
+
className: context.className,
|
|
4443
|
+
children: content
|
|
4444
|
+
}
|
|
4445
|
+
);
|
|
4446
|
+
}
|
|
4447
|
+
return /* @__PURE__ */ jsx(
|
|
4448
|
+
"button",
|
|
2864
4449
|
{
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
children: [
|
|
2872
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2873
|
-
/* @__PURE__ */ jsx(
|
|
2874
|
-
"path",
|
|
2875
|
-
{
|
|
2876
|
-
d: "M6.5 6.5l5 5M11.5 6.5l-5 5",
|
|
2877
|
-
stroke: "currentColor",
|
|
2878
|
-
strokeWidth: "1.75",
|
|
2879
|
-
strokeLinecap: "round"
|
|
2880
|
-
}
|
|
2881
|
-
)
|
|
2882
|
-
]
|
|
4450
|
+
type: "button",
|
|
4451
|
+
onClick: item.onClick,
|
|
4452
|
+
disabled: item.disabled,
|
|
4453
|
+
"aria-current": item.active ? "page" : void 0,
|
|
4454
|
+
className: context.className,
|
|
4455
|
+
children: content
|
|
2883
4456
|
}
|
|
2884
4457
|
);
|
|
2885
4458
|
}
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
4459
|
+
function DashboardLayout({
|
|
4460
|
+
children,
|
|
4461
|
+
navbar,
|
|
4462
|
+
sidebar,
|
|
4463
|
+
brand,
|
|
4464
|
+
user,
|
|
4465
|
+
headerActions,
|
|
4466
|
+
navItems,
|
|
4467
|
+
renderNavItem,
|
|
4468
|
+
navigationLabel = "Main navigation",
|
|
4469
|
+
mobileNavigationLabel = "Mobile navigation",
|
|
4470
|
+
shellClassName,
|
|
4471
|
+
shellWidth = "xl",
|
|
4472
|
+
className,
|
|
4473
|
+
mainClassName,
|
|
4474
|
+
maxWidth = "lg"
|
|
4475
|
+
}) {
|
|
4476
|
+
const hasGeneratedHeader = !navbar && Boolean(brand || user || headerActions);
|
|
4477
|
+
const hasGeneratedNavigation = !sidebar && Boolean(navItems?.length);
|
|
4478
|
+
const hasGeneratedShell = hasGeneratedHeader || hasGeneratedNavigation;
|
|
4479
|
+
const renderNav = renderNavItem ?? renderDefaultNavItem;
|
|
4480
|
+
const generatedHeader = hasGeneratedHeader ? /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 glass border-b border-white/10", children: /* @__PURE__ */ jsxs(
|
|
2895
4481
|
"div",
|
|
2896
4482
|
{
|
|
2897
|
-
role: "alert",
|
|
2898
4483
|
className: cn(
|
|
2899
|
-
"flex items-
|
|
2900
|
-
|
|
2901
|
-
variantBorderColor[variant],
|
|
2902
|
-
className
|
|
4484
|
+
"mx-auto flex h-16 items-center justify-between gap-4 px-4 sm:px-6 lg:px-8",
|
|
4485
|
+
widthClass[shellWidth]
|
|
2903
4486
|
),
|
|
2904
4487
|
children: [
|
|
2905
|
-
/* @__PURE__ */ jsx("
|
|
2906
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
] })
|
|
2910
|
-
onDismiss && /* @__PURE__ */ jsx(
|
|
2911
|
-
"button",
|
|
2912
|
-
{
|
|
2913
|
-
type: "button",
|
|
2914
|
-
"aria-label": "Dismiss",
|
|
2915
|
-
onClick: onDismiss,
|
|
2916
|
-
className: cn(
|
|
2917
|
-
"shrink-0 flex items-center justify-center h-6 w-6 rounded-lg mt-0.5",
|
|
2918
|
-
"text-white/40 transition-colors hover:bg-white/10 hover:text-white/80",
|
|
2919
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
|
|
2920
|
-
),
|
|
2921
|
-
children: /* @__PURE__ */ jsx(
|
|
2922
|
-
"svg",
|
|
2923
|
-
{
|
|
2924
|
-
"aria-hidden": "true",
|
|
2925
|
-
width: "10",
|
|
2926
|
-
height: "10",
|
|
2927
|
-
viewBox: "0 0 10 10",
|
|
2928
|
-
fill: "none",
|
|
2929
|
-
children: /* @__PURE__ */ jsx("path", { d: "M1 1l8 8M9 1L1 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
2930
|
-
}
|
|
2931
|
-
)
|
|
2932
|
-
}
|
|
2933
|
-
)
|
|
2934
|
-
]
|
|
2935
|
-
}
|
|
2936
|
-
);
|
|
2937
|
-
}
|
|
2938
|
-
function CopyIcon() {
|
|
2939
|
-
return /* @__PURE__ */ jsxs(
|
|
2940
|
-
"svg",
|
|
2941
|
-
{
|
|
2942
|
-
"aria-hidden": "true",
|
|
2943
|
-
width: "16",
|
|
2944
|
-
height: "16",
|
|
2945
|
-
viewBox: "0 0 16 16",
|
|
2946
|
-
fill: "none",
|
|
2947
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2948
|
-
children: [
|
|
2949
|
-
/* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "9", height: "9", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2950
|
-
/* @__PURE__ */ jsx(
|
|
2951
|
-
"path",
|
|
2952
|
-
{
|
|
2953
|
-
d: "M3.5 11H3a1.5 1.5 0 0 1-1.5-1.5V3A1.5 1.5 0 0 1 3 1.5h6.5A1.5 1.5 0 0 1 11 3v.5",
|
|
2954
|
-
stroke: "currentColor",
|
|
2955
|
-
strokeWidth: "1.5",
|
|
2956
|
-
strokeLinecap: "round"
|
|
2957
|
-
}
|
|
2958
|
-
)
|
|
4488
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex items-center gap-3", children: brand }),
|
|
4489
|
+
(user || headerActions) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
4490
|
+
user,
|
|
4491
|
+
headerActions
|
|
4492
|
+
] })
|
|
2959
4493
|
]
|
|
2960
4494
|
}
|
|
2961
|
-
);
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
4495
|
+
) }) : null;
|
|
4496
|
+
const generatedSidebar = hasGeneratedNavigation ? /* @__PURE__ */ jsx("nav", { className: "hidden w-56 shrink-0 md:block", "aria-label": navigationLabel, children: /* @__PURE__ */ jsx("div", { className: "glass sticky top-24 rounded-xl p-3", children: navItems.map((item, index) => {
|
|
4497
|
+
const navContext = {
|
|
4498
|
+
type: "desktop",
|
|
4499
|
+
className: getDesktopNavItemClass(item)
|
|
4500
|
+
};
|
|
4501
|
+
return /* @__PURE__ */ jsx("div", { children: renderNav(item, navContext) }, getItemKey(item, index));
|
|
4502
|
+
}) }) }) : null;
|
|
4503
|
+
const generatedMobileNavigation = hasGeneratedNavigation ? /* @__PURE__ */ jsx(
|
|
4504
|
+
"nav",
|
|
2966
4505
|
{
|
|
2967
|
-
"
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
"
|
|
2975
|
-
|
|
2976
|
-
d: "M3 8.5l3.5 3.5 6.5-7",
|
|
2977
|
-
stroke: "currentColor",
|
|
2978
|
-
strokeWidth: "1.75",
|
|
2979
|
-
strokeLinecap: "round",
|
|
2980
|
-
strokeLinejoin: "round"
|
|
2981
|
-
}
|
|
2982
|
-
)
|
|
4506
|
+
className: "glass pb-safe fixed bottom-0 left-0 right-0 z-40 border-t border-white/10 px-2 py-1 md:hidden",
|
|
4507
|
+
"aria-label": mobileNavigationLabel,
|
|
4508
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex justify-around", children: navItems.map((item, index) => {
|
|
4509
|
+
const navContext = {
|
|
4510
|
+
type: "mobile",
|
|
4511
|
+
className: getMobileNavItemClass(item)
|
|
4512
|
+
};
|
|
4513
|
+
return /* @__PURE__ */ jsx("div", { children: renderNav(item, navContext) }, getItemKey(item, index));
|
|
4514
|
+
}) })
|
|
2983
4515
|
}
|
|
2984
|
-
);
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
4516
|
+
) : null;
|
|
4517
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("min-h-screen bg-surface relative overflow-hidden", className), children: [
|
|
4518
|
+
/* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: "pointer-events-none fixed inset-0", children: [
|
|
4519
|
+
/* @__PURE__ */ jsx("div", { className: "orb orb-purple w-[400px] h-[400px] -top-[150px] -left-[150px] opacity-15" }),
|
|
4520
|
+
/* @__PURE__ */ jsx("div", { className: "orb orb-blue w-[300px] h-[300px] top-[60%] -right-[100px] opacity-10" })
|
|
4521
|
+
] }),
|
|
4522
|
+
generatedHeader ?? navbar,
|
|
4523
|
+
hasGeneratedShell ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4524
|
+
/* @__PURE__ */ jsxs("div", { className: cn("mx-auto flex gap-6 px-4 py-6 sm:px-6 lg:px-8", widthClass[shellWidth], shellClassName), children: [
|
|
4525
|
+
generatedSidebar ?? sidebar,
|
|
4526
|
+
/* @__PURE__ */ jsx("main", { className: cn("flex-1 min-w-0", hasGeneratedNavigation && "pb-20 md:pb-0", mainClassName), children: /* @__PURE__ */ jsx("div", { className: cn("mx-auto", widthClass[maxWidth]), children }) })
|
|
4527
|
+
] }),
|
|
4528
|
+
generatedMobileNavigation
|
|
4529
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: cn("flex", navbar && "pt-16", shellClassName), children: [
|
|
4530
|
+
sidebar,
|
|
4531
|
+
/* @__PURE__ */ jsx("main", { className: cn("flex-1 min-w-0 py-8 px-6", mainClassName), children: /* @__PURE__ */ jsx("div", { className: cn("mx-auto", widthClass[maxWidth]), children }) })
|
|
4532
|
+
] })
|
|
4533
|
+
] });
|
|
4534
|
+
}
|
|
4535
|
+
function CopyIcon() {
|
|
4536
|
+
return /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
4537
|
+
/* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "9", height: "9", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
4538
|
+
/* @__PURE__ */ jsx(
|
|
4539
|
+
"path",
|
|
4540
|
+
{
|
|
4541
|
+
d: "M3.5 11H3a1.5 1.5 0 0 1-1.5-1.5V3A1.5 1.5 0 0 1 3 1.5h6.5A1.5 1.5 0 0 1 11 3v.5",
|
|
4542
|
+
stroke: "currentColor",
|
|
4543
|
+
strokeWidth: "1.5",
|
|
4544
|
+
strokeLinecap: "round"
|
|
4545
|
+
}
|
|
4546
|
+
)
|
|
4547
|
+
] });
|
|
4548
|
+
}
|
|
4549
|
+
function CheckIcon() {
|
|
4550
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx(
|
|
4551
|
+
"path",
|
|
4552
|
+
{
|
|
4553
|
+
d: "M3 8.5l3.5 3.5 6.5-7",
|
|
4554
|
+
stroke: "currentColor",
|
|
4555
|
+
strokeWidth: "1.75",
|
|
4556
|
+
strokeLinecap: "round",
|
|
4557
|
+
strokeLinejoin: "round"
|
|
3008
4558
|
}
|
|
3009
|
-
);
|
|
4559
|
+
) });
|
|
4560
|
+
}
|
|
4561
|
+
function EyeIcon() {
|
|
4562
|
+
return /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
4563
|
+
/* @__PURE__ */ jsx(
|
|
4564
|
+
"path",
|
|
4565
|
+
{
|
|
4566
|
+
d: "M1.5 8S3.5 3.5 8 3.5 14.5 8 14.5 8 12.5 12.5 8 12.5 1.5 8 1.5 8Z",
|
|
4567
|
+
stroke: "currentColor",
|
|
4568
|
+
strokeWidth: "1.5",
|
|
4569
|
+
strokeLinejoin: "round"
|
|
4570
|
+
}
|
|
4571
|
+
),
|
|
4572
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "2", stroke: "currentColor", strokeWidth: "1.5" })
|
|
4573
|
+
] });
|
|
3010
4574
|
}
|
|
3011
4575
|
function EyeOffIcon() {
|
|
3012
|
-
return /* @__PURE__ */ jsx(
|
|
3013
|
-
"
|
|
4576
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx(
|
|
4577
|
+
"path",
|
|
3014
4578
|
{
|
|
3015
|
-
"
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3021
|
-
children: /* @__PURE__ */ jsx(
|
|
3022
|
-
"path",
|
|
3023
|
-
{
|
|
3024
|
-
d: "M2 2l12 12M6.5 6.6A2 2 0 0 0 9.4 9.5M4.3 4.4C2.9 5.4 1.5 8 1.5 8S3.5 12.5 8 12.5c1.4 0 2.6-.4 3.7-1.1M6.7 3.6C7.1 3.5 7.5 3.5 8 3.5c4.5 0 6.5 4.5 6.5 4.5s-.5 1.2-1.5 2.3",
|
|
3025
|
-
stroke: "currentColor",
|
|
3026
|
-
strokeWidth: "1.5",
|
|
3027
|
-
strokeLinecap: "round",
|
|
3028
|
-
strokeLinejoin: "round"
|
|
3029
|
-
}
|
|
3030
|
-
)
|
|
4579
|
+
d: "M2 2l12 12M6.5 6.6A2 2 0 0 0 9.4 9.5M4.3 4.4C2.9 5.4 1.5 8 1.5 8S3.5 12.5 8 12.5c1.4 0 2.6-.4 3.7-1.1M6.7 3.6C7.1 3.5 7.5 3.5 8 3.5c4.5 0 6.5 4.5 6.5 4.5s-.5 1.2-1.5 2.3",
|
|
4580
|
+
stroke: "currentColor",
|
|
4581
|
+
strokeWidth: "1.5",
|
|
4582
|
+
strokeLinecap: "round",
|
|
4583
|
+
strokeLinejoin: "round"
|
|
3031
4584
|
}
|
|
3032
|
-
);
|
|
4585
|
+
) });
|
|
3033
4586
|
}
|
|
3034
4587
|
var iconButtonBase = cn(
|
|
3035
4588
|
"flex items-center justify-center h-7 w-7 rounded-lg shrink-0",
|
|
3036
4589
|
"text-white/40 transition-colors hover:bg-white/10 hover:text-white/80",
|
|
3037
4590
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
|
|
3038
4591
|
);
|
|
3039
|
-
function
|
|
4592
|
+
function defaultMaskFormatter(rawValue) {
|
|
4593
|
+
return "\u2022".repeat(Math.min(rawValue.length, 24));
|
|
4594
|
+
}
|
|
4595
|
+
function CopyField({
|
|
4596
|
+
value,
|
|
4597
|
+
label,
|
|
4598
|
+
description,
|
|
4599
|
+
masked = false,
|
|
4600
|
+
emptyText = "\u2014",
|
|
4601
|
+
rightActions,
|
|
4602
|
+
copyOnClick = false,
|
|
4603
|
+
maskFormatter = defaultMaskFormatter,
|
|
4604
|
+
className,
|
|
4605
|
+
id: externalId
|
|
4606
|
+
}) {
|
|
3040
4607
|
const generatedId = useId();
|
|
3041
4608
|
const fieldId = externalId || generatedId;
|
|
4609
|
+
const labelId = label ? `${fieldId}-label` : void 0;
|
|
3042
4610
|
const { copy, copied } = useClipboard();
|
|
3043
4611
|
const [revealed, setRevealed] = useState(false);
|
|
3044
|
-
const
|
|
4612
|
+
const hasValue = value.trim().length > 0;
|
|
4613
|
+
const displayValue = !hasValue ? emptyText : masked && !revealed ? maskFormatter(value) : value;
|
|
4614
|
+
const handleCopy = () => {
|
|
4615
|
+
if (!hasValue) return;
|
|
4616
|
+
void copy(value);
|
|
4617
|
+
};
|
|
3045
4618
|
const field = /* @__PURE__ */ jsxs(
|
|
3046
4619
|
"div",
|
|
3047
4620
|
{
|
|
3048
4621
|
className: cn(
|
|
3049
4622
|
"flex items-center gap-1 w-full rounded-xl px-3 py-2.5",
|
|
3050
4623
|
"bg-white/10 ring-1 ring-white/10",
|
|
4624
|
+
copyOnClick && hasValue && "cursor-pointer hover:bg-white/15 focus-within:ring-primary/30",
|
|
4625
|
+
copyOnClick && !hasValue && "cursor-not-allowed opacity-70",
|
|
3051
4626
|
className
|
|
3052
4627
|
),
|
|
4628
|
+
"aria-labelledby": labelId,
|
|
4629
|
+
role: copyOnClick && hasValue ? "button" : void 0,
|
|
4630
|
+
tabIndex: copyOnClick && hasValue ? 0 : void 0,
|
|
4631
|
+
onClick: copyOnClick ? handleCopy : void 0,
|
|
4632
|
+
onKeyDown: copyOnClick && hasValue ? (event) => {
|
|
4633
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
4634
|
+
event.preventDefault();
|
|
4635
|
+
handleCopy();
|
|
4636
|
+
}
|
|
4637
|
+
} : void 0,
|
|
3053
4638
|
children: [
|
|
3054
|
-
/* @__PURE__ */ jsx(
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
id: fieldId,
|
|
3058
|
-
className: "flex-1 min-w-0 truncate text-sm text-white select-all font-mono",
|
|
3059
|
-
"aria-label": label,
|
|
3060
|
-
children: displayValue
|
|
3061
|
-
}
|
|
3062
|
-
),
|
|
3063
|
-
masked && /* @__PURE__ */ jsx(
|
|
4639
|
+
/* @__PURE__ */ jsx("span", { id: fieldId, className: "flex-1 min-w-0 truncate text-sm text-white select-all font-mono", children: displayValue }),
|
|
4640
|
+
rightActions,
|
|
4641
|
+
masked && hasValue && /* @__PURE__ */ jsx(
|
|
3064
4642
|
"button",
|
|
3065
4643
|
{
|
|
3066
4644
|
type: "button",
|
|
3067
4645
|
"aria-label": revealed ? "Hide value" : "Reveal value",
|
|
3068
|
-
onClick: () =>
|
|
4646
|
+
onClick: (event) => {
|
|
4647
|
+
event.stopPropagation();
|
|
4648
|
+
setRevealed((currentValue) => !currentValue);
|
|
4649
|
+
},
|
|
3069
4650
|
className: iconButtonBase,
|
|
3070
4651
|
children: revealed ? /* @__PURE__ */ jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsx(EyeIcon, {})
|
|
3071
4652
|
}
|
|
@@ -3075,7 +4656,11 @@ function CopyField({ value, label, masked = false, className, id: externalId })
|
|
|
3075
4656
|
{
|
|
3076
4657
|
type: "button",
|
|
3077
4658
|
"aria-label": copied ? "Copied!" : "Copy to clipboard",
|
|
3078
|
-
onClick: () =>
|
|
4659
|
+
onClick: (event) => {
|
|
4660
|
+
event.stopPropagation();
|
|
4661
|
+
handleCopy();
|
|
4662
|
+
},
|
|
4663
|
+
disabled: !hasValue,
|
|
3079
4664
|
className: cn(iconButtonBase, copied && "text-emerald-400 hover:text-emerald-400"),
|
|
3080
4665
|
children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
|
|
3081
4666
|
}
|
|
@@ -3085,8 +4670,9 @@ function CopyField({ value, label, masked = false, className, id: externalId })
|
|
|
3085
4670
|
);
|
|
3086
4671
|
if (!label) return field;
|
|
3087
4672
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3088
|
-
/* @__PURE__ */ jsx("
|
|
3089
|
-
field
|
|
4673
|
+
/* @__PURE__ */ jsx("div", { id: labelId, className: "block text-sm text-white/70 mb-1.5", children: label }),
|
|
4674
|
+
field,
|
|
4675
|
+
description ? /* @__PURE__ */ jsx("div", { className: "mt-1.5 text-xs text-white/50", children: description }) : null
|
|
3090
4676
|
] });
|
|
3091
4677
|
}
|
|
3092
4678
|
var ProgressButton = forwardRef(
|
|
@@ -3153,7 +4739,7 @@ var variantIconColor2 = {
|
|
|
3153
4739
|
warning: "text-amber-400",
|
|
3154
4740
|
info: "text-primary"
|
|
3155
4741
|
};
|
|
3156
|
-
var
|
|
4742
|
+
var positionClass2 = {
|
|
3157
4743
|
"top-right": "top-4 right-4 items-end",
|
|
3158
4744
|
"top-center": "top-4 left-1/2 -translate-x-1/2 items-center",
|
|
3159
4745
|
"bottom-right": "bottom-4 right-4 items-end",
|
|
@@ -3300,7 +4886,7 @@ function ToastProvider({ children, position = "top-right", maxToasts = 5 }) {
|
|
|
3300
4886
|
"div",
|
|
3301
4887
|
{
|
|
3302
4888
|
"aria-label": "Notifications",
|
|
3303
|
-
className: cn("fixed z-[9999] flex flex-col gap-3 pointer-events-none",
|
|
4889
|
+
className: cn("fixed z-[9999] flex flex-col gap-3 pointer-events-none", positionClass2[position]),
|
|
3304
4890
|
children: toasts.map((t) => /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx(ToastCard, { toast: t, onDismiss: dismiss }) }, t.id))
|
|
3305
4891
|
}
|
|
3306
4892
|
),
|
|
@@ -3430,7 +5016,7 @@ function MutationOverlay({
|
|
|
3430
5016
|
}
|
|
3431
5017
|
);
|
|
3432
5018
|
}
|
|
3433
|
-
var
|
|
5019
|
+
var sizeClass7 = {
|
|
3434
5020
|
sm: "w-8 h-8",
|
|
3435
5021
|
md: "w-10 h-10",
|
|
3436
5022
|
lg: "w-12 h-12"
|
|
@@ -3448,503 +5034,345 @@ var badgeSizeClass = {
|
|
|
3448
5034
|
var DefaultBellIcon = ({ className }) => /* @__PURE__ */ jsxs(
|
|
3449
5035
|
"svg",
|
|
3450
5036
|
{
|
|
3451
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3452
|
-
viewBox: "0 0 24 24",
|
|
3453
|
-
fill: "none",
|
|
3454
|
-
stroke: "currentColor",
|
|
3455
|
-
strokeWidth: 2,
|
|
3456
|
-
strokeLinecap: "round",
|
|
3457
|
-
strokeLinejoin: "round",
|
|
3458
|
-
className,
|
|
3459
|
-
"aria-hidden": "true",
|
|
3460
|
-
children: [
|
|
3461
|
-
/* @__PURE__ */ jsx("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }),
|
|
3462
|
-
/* @__PURE__ */ jsx("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })
|
|
3463
|
-
]
|
|
3464
|
-
}
|
|
3465
|
-
);
|
|
3466
|
-
var NotificationBell = forwardRef(
|
|
3467
|
-
function NotificationBell2({ icon, count, maxCount = 99, size = "md", ping, className, disabled, ...props }, ref) {
|
|
3468
|
-
const displayCount = count && count > maxCount ? `${maxCount}+` : count;
|
|
3469
|
-
const hasCount = count !== void 0 && count > 0;
|
|
3470
|
-
return /* @__PURE__ */ jsxs(
|
|
3471
|
-
"button",
|
|
3472
|
-
{
|
|
3473
|
-
ref,
|
|
3474
|
-
type: "button",
|
|
3475
|
-
...props,
|
|
3476
|
-
disabled,
|
|
3477
|
-
"aria-label": props["aria-label"] || `Notifications${hasCount ? ` (${count})` : ""}`,
|
|
3478
|
-
className: cn(
|
|
3479
|
-
"relative inline-flex items-center justify-center rounded-xl text-white/70 transition-colors hover:text-white hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent disabled:opacity-60 disabled:pointer-events-none",
|
|
3480
|
-
sizeClass6[size],
|
|
3481
|
-
className
|
|
3482
|
-
),
|
|
3483
|
-
children: [
|
|
3484
|
-
icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: icon }) : /* @__PURE__ */ jsx(DefaultBellIcon, { className: iconSizeClass[size] }),
|
|
3485
|
-
hasCount && /* @__PURE__ */ jsxs(
|
|
3486
|
-
"span",
|
|
3487
|
-
{
|
|
3488
|
-
className: cn(
|
|
3489
|
-
"absolute top-0 right-0 flex items-center justify-center rounded-full bg-rose-500 text-white font-semibold leading-none",
|
|
3490
|
-
badgeSizeClass[size]
|
|
3491
|
-
),
|
|
3492
|
-
children: [
|
|
3493
|
-
ping && /* @__PURE__ */ jsx("span", { className: "absolute inset-0 rounded-full bg-rose-500 animate-ping opacity-75" }),
|
|
3494
|
-
/* @__PURE__ */ jsx("span", { className: "relative", children: displayCount })
|
|
3495
|
-
]
|
|
3496
|
-
}
|
|
3497
|
-
)
|
|
3498
|
-
]
|
|
3499
|
-
}
|
|
3500
|
-
);
|
|
3501
|
-
}
|
|
3502
|
-
);
|
|
3503
|
-
var sizeClass7 = {
|
|
3504
|
-
xs: "text-sm font-semibold",
|
|
3505
|
-
sm: "text-base font-semibold",
|
|
3506
|
-
md: "text-lg font-bold",
|
|
3507
|
-
lg: "text-xl font-bold",
|
|
3508
|
-
xl: "text-2xl font-bold tracking-tight",
|
|
3509
|
-
"2xl": "text-3xl font-bold tracking-tight sm:text-4xl"
|
|
3510
|
-
};
|
|
3511
|
-
var levelToSize = {
|
|
3512
|
-
1: "2xl",
|
|
3513
|
-
2: "xl",
|
|
3514
|
-
3: "lg",
|
|
3515
|
-
4: "md",
|
|
3516
|
-
5: "sm",
|
|
3517
|
-
6: "xs"
|
|
3518
|
-
};
|
|
3519
|
-
var colorClass = {
|
|
3520
|
-
default: "text-white",
|
|
3521
|
-
muted: "text-white/70",
|
|
3522
|
-
gradient: "text-gradient"
|
|
3523
|
-
};
|
|
3524
|
-
var Heading = forwardRef(function Heading2({ level = 2, size, color = "default", className, ...props }, ref) {
|
|
3525
|
-
const Tag = `h${level}`;
|
|
3526
|
-
const effectiveSize = size ?? levelToSize[level];
|
|
3527
|
-
return /* @__PURE__ */ jsx(
|
|
3528
|
-
Tag,
|
|
3529
|
-
{
|
|
3530
|
-
ref,
|
|
3531
|
-
...props,
|
|
3532
|
-
className: cn(sizeClass7[effectiveSize], colorClass[color], className)
|
|
3533
|
-
}
|
|
3534
|
-
);
|
|
3535
|
-
});
|
|
3536
|
-
var sizeMap2 = {
|
|
3537
|
-
xs: "text-xs",
|
|
3538
|
-
sm: "text-sm",
|
|
3539
|
-
md: "text-base",
|
|
3540
|
-
lg: "text-lg"
|
|
3541
|
-
};
|
|
3542
|
-
var colorMap = {
|
|
3543
|
-
default: "text-white/90",
|
|
3544
|
-
muted: "text-white/70",
|
|
3545
|
-
dimmed: "text-white/50",
|
|
3546
|
-
primary: "text-primary-light",
|
|
3547
|
-
success: "text-emerald-400",
|
|
3548
|
-
warning: "text-amber-400",
|
|
3549
|
-
danger: "text-rose-400"
|
|
3550
|
-
};
|
|
3551
|
-
var weightMap = {
|
|
3552
|
-
normal: "font-normal",
|
|
3553
|
-
medium: "font-medium",
|
|
3554
|
-
semibold: "font-semibold",
|
|
3555
|
-
bold: "font-bold"
|
|
3556
|
-
};
|
|
3557
|
-
var Text = forwardRef(function Text2({ size = "md", color = "default", weight = "normal", inline = false, truncate = false, className, ...props }, ref) {
|
|
3558
|
-
const Tag = inline ? "span" : "p";
|
|
3559
|
-
return /* @__PURE__ */ jsx(
|
|
3560
|
-
Tag,
|
|
3561
|
-
{
|
|
3562
|
-
ref,
|
|
3563
|
-
...props,
|
|
3564
|
-
className: cn(
|
|
3565
|
-
sizeMap2[size],
|
|
3566
|
-
colorMap[color],
|
|
3567
|
-
weightMap[weight],
|
|
3568
|
-
truncate && "truncate",
|
|
3569
|
-
className
|
|
3570
|
-
)
|
|
3571
|
-
}
|
|
3572
|
-
);
|
|
3573
|
-
});
|
|
3574
|
-
var gapClass = {
|
|
3575
|
-
0: "gap-0",
|
|
3576
|
-
1: "gap-1",
|
|
3577
|
-
2: "gap-2",
|
|
3578
|
-
3: "gap-3",
|
|
3579
|
-
4: "gap-4",
|
|
3580
|
-
5: "gap-5",
|
|
3581
|
-
6: "gap-6",
|
|
3582
|
-
8: "gap-8",
|
|
3583
|
-
10: "gap-10",
|
|
3584
|
-
12: "gap-12"
|
|
3585
|
-
};
|
|
3586
|
-
var alignClass2 = {
|
|
3587
|
-
start: "items-start",
|
|
3588
|
-
center: "items-center",
|
|
3589
|
-
end: "items-end",
|
|
3590
|
-
stretch: "items-stretch",
|
|
3591
|
-
baseline: "items-baseline"
|
|
3592
|
-
};
|
|
3593
|
-
var justifyClass = {
|
|
3594
|
-
start: "justify-start",
|
|
3595
|
-
center: "justify-center",
|
|
3596
|
-
end: "justify-end",
|
|
3597
|
-
between: "justify-between",
|
|
3598
|
-
around: "justify-around",
|
|
3599
|
-
evenly: "justify-evenly"
|
|
3600
|
-
};
|
|
3601
|
-
var Stack = forwardRef(function Stack2({ children, direction = "vertical", gap = 4, align = "stretch", justify = "start", wrap = false, className, ...props }, ref) {
|
|
3602
|
-
return /* @__PURE__ */ jsx(
|
|
3603
|
-
"div",
|
|
3604
|
-
{
|
|
3605
|
-
ref,
|
|
3606
|
-
...props,
|
|
3607
|
-
className: cn(
|
|
3608
|
-
"flex",
|
|
3609
|
-
direction === "vertical" ? "flex-col" : "flex-row",
|
|
3610
|
-
gapClass[gap],
|
|
3611
|
-
alignClass2[align],
|
|
3612
|
-
justifyClass[justify],
|
|
3613
|
-
wrap && "flex-wrap",
|
|
3614
|
-
className
|
|
3615
|
-
),
|
|
3616
|
-
children
|
|
3617
|
-
}
|
|
3618
|
-
);
|
|
3619
|
-
});
|
|
3620
|
-
var ScrollArea = forwardRef(function ScrollArea2({ children, maxHeight, hideScrollbar = false, orientation = "vertical", className, style, ...props }, ref) {
|
|
3621
|
-
const overflowClass = {
|
|
3622
|
-
vertical: "overflow-y-auto overflow-x-hidden",
|
|
3623
|
-
horizontal: "overflow-x-auto overflow-y-hidden",
|
|
3624
|
-
both: "overflow-auto"
|
|
3625
|
-
}[orientation];
|
|
3626
|
-
return /* @__PURE__ */ jsx(
|
|
3627
|
-
"div",
|
|
3628
|
-
{
|
|
3629
|
-
ref,
|
|
3630
|
-
...props,
|
|
3631
|
-
tabIndex: 0,
|
|
3632
|
-
className: cn(
|
|
3633
|
-
overflowClass,
|
|
3634
|
-
// Custom dark scrollbar styling
|
|
3635
|
-
"[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5",
|
|
3636
|
-
"[&::-webkit-scrollbar-track]:bg-transparent",
|
|
3637
|
-
"[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-white/15 hover:[&::-webkit-scrollbar-thumb]:bg-white/25",
|
|
3638
|
-
hideScrollbar && "no-scrollbar",
|
|
3639
|
-
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/30 focus-visible:ring-inset",
|
|
3640
|
-
className
|
|
3641
|
-
),
|
|
3642
|
-
style: {
|
|
3643
|
-
maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
|
|
3644
|
-
...style
|
|
3645
|
-
},
|
|
3646
|
-
children
|
|
3647
|
-
}
|
|
3648
|
-
);
|
|
3649
|
-
});
|
|
3650
|
-
var defaultSeparator = /* @__PURE__ */ jsx(
|
|
3651
|
-
"svg",
|
|
3652
|
-
{
|
|
3653
|
-
className: "w-3.5 h-3.5 text-white/30 flex-shrink-0",
|
|
3654
|
-
viewBox: "0 0 16 16",
|
|
5037
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5038
|
+
viewBox: "0 0 24 24",
|
|
3655
5039
|
fill: "none",
|
|
3656
5040
|
stroke: "currentColor",
|
|
3657
|
-
strokeWidth:
|
|
5041
|
+
strokeWidth: 2,
|
|
3658
5042
|
strokeLinecap: "round",
|
|
5043
|
+
strokeLinejoin: "round",
|
|
5044
|
+
className,
|
|
3659
5045
|
"aria-hidden": "true",
|
|
3660
|
-
children:
|
|
5046
|
+
children: [
|
|
5047
|
+
/* @__PURE__ */ jsx("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }),
|
|
5048
|
+
/* @__PURE__ */ jsx("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })
|
|
5049
|
+
]
|
|
3661
5050
|
}
|
|
3662
5051
|
);
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
const
|
|
3667
|
-
return /* @__PURE__ */ jsxs(
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
onOpenChange,
|
|
3697
|
-
offset = 8,
|
|
3698
|
-
className
|
|
3699
|
-
}) {
|
|
3700
|
-
const popoverId = useId();
|
|
3701
|
-
const anchorRef = useRef(null);
|
|
3702
|
-
const popoverRef = useRef(null);
|
|
3703
|
-
const [internalOpen, setInternalOpen] = useState(false);
|
|
3704
|
-
const [pos, setPos] = useState(null);
|
|
3705
|
-
const isControlled = controlledOpen !== void 0;
|
|
3706
|
-
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
3707
|
-
const setOpen = useCallback(
|
|
3708
|
-
(value) => {
|
|
3709
|
-
if (!isControlled) setInternalOpen(value);
|
|
3710
|
-
onOpenChange?.(value);
|
|
3711
|
-
},
|
|
3712
|
-
[isControlled, onOpenChange]
|
|
3713
|
-
);
|
|
3714
|
-
const toggle = useCallback(() => setOpen(!isOpen), [isOpen, setOpen]);
|
|
3715
|
-
const close = useCallback(() => setOpen(false), [setOpen]);
|
|
3716
|
-
const updatePosition = useCallback(() => {
|
|
3717
|
-
const el = anchorRef.current;
|
|
3718
|
-
if (!el) return;
|
|
3719
|
-
const r = el.getBoundingClientRect();
|
|
3720
|
-
let left;
|
|
3721
|
-
let top;
|
|
3722
|
-
let effPlacement = placement;
|
|
3723
|
-
if (placement === "bottom" || placement === "top") {
|
|
3724
|
-
left = r.left + r.width / 2;
|
|
3725
|
-
if (placement === "bottom") {
|
|
3726
|
-
top = r.bottom + offset;
|
|
3727
|
-
if (top + 200 > window.innerHeight && r.top - offset > 200) {
|
|
3728
|
-
effPlacement = "top";
|
|
3729
|
-
top = r.top - offset;
|
|
3730
|
-
}
|
|
3731
|
-
} else {
|
|
3732
|
-
top = r.top - offset;
|
|
3733
|
-
if (top < 8) {
|
|
3734
|
-
effPlacement = "bottom";
|
|
3735
|
-
top = r.bottom + offset;
|
|
3736
|
-
}
|
|
3737
|
-
}
|
|
3738
|
-
} else {
|
|
3739
|
-
top = r.top + r.height / 2;
|
|
3740
|
-
if (placement === "right") {
|
|
3741
|
-
left = r.right + offset;
|
|
3742
|
-
} else {
|
|
3743
|
-
left = r.left - offset;
|
|
3744
|
-
}
|
|
3745
|
-
}
|
|
3746
|
-
setPos({ left: Math.round(left), top: Math.round(top), placement: effPlacement });
|
|
3747
|
-
}, [placement, offset]);
|
|
3748
|
-
useEffect(() => {
|
|
3749
|
-
if (!isOpen) return;
|
|
3750
|
-
updatePosition();
|
|
3751
|
-
window.addEventListener("scroll", updatePosition, true);
|
|
3752
|
-
window.addEventListener("resize", updatePosition);
|
|
3753
|
-
return () => {
|
|
3754
|
-
window.removeEventListener("scroll", updatePosition, true);
|
|
3755
|
-
window.removeEventListener("resize", updatePosition);
|
|
3756
|
-
};
|
|
3757
|
-
}, [isOpen, updatePosition]);
|
|
3758
|
-
useEffect(() => {
|
|
3759
|
-
if (!isOpen || !closeOnClickOutside) return;
|
|
3760
|
-
const handleClick = (e) => {
|
|
3761
|
-
const target = e.target;
|
|
3762
|
-
if (anchorRef.current?.contains(target) || popoverRef.current?.contains(target)) {
|
|
3763
|
-
return;
|
|
3764
|
-
}
|
|
3765
|
-
close();
|
|
3766
|
-
};
|
|
3767
|
-
document.addEventListener("mousedown", handleClick);
|
|
3768
|
-
return () => document.removeEventListener("mousedown", handleClick);
|
|
3769
|
-
}, [isOpen, closeOnClickOutside, close]);
|
|
3770
|
-
useEffect(() => {
|
|
3771
|
-
if (!isOpen || !closeOnEsc) return;
|
|
3772
|
-
const handleKey = (e) => {
|
|
3773
|
-
if (e.key === "Escape") {
|
|
3774
|
-
e.preventDefault();
|
|
3775
|
-
close();
|
|
3776
|
-
anchorRef.current?.focus();
|
|
5052
|
+
var NotificationBell = forwardRef(
|
|
5053
|
+
function NotificationBell2({ icon, count, maxCount = 99, size = "md", ping, className, disabled, ...props }, ref) {
|
|
5054
|
+
const displayCount = count && count > maxCount ? `${maxCount}+` : count;
|
|
5055
|
+
const hasCount = count !== void 0 && count > 0;
|
|
5056
|
+
return /* @__PURE__ */ jsxs(
|
|
5057
|
+
"button",
|
|
5058
|
+
{
|
|
5059
|
+
ref,
|
|
5060
|
+
type: "button",
|
|
5061
|
+
...props,
|
|
5062
|
+
disabled,
|
|
5063
|
+
"aria-label": props["aria-label"] || `Notifications${hasCount ? ` (${count})` : ""}`,
|
|
5064
|
+
className: cn(
|
|
5065
|
+
"relative inline-flex items-center justify-center rounded-xl text-white/70 transition-colors hover:text-white hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent disabled:opacity-60 disabled:pointer-events-none",
|
|
5066
|
+
sizeClass7[size],
|
|
5067
|
+
className
|
|
5068
|
+
),
|
|
5069
|
+
children: [
|
|
5070
|
+
icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: icon }) : /* @__PURE__ */ jsx(DefaultBellIcon, { className: iconSizeClass[size] }),
|
|
5071
|
+
hasCount && /* @__PURE__ */ jsxs(
|
|
5072
|
+
"span",
|
|
5073
|
+
{
|
|
5074
|
+
className: cn(
|
|
5075
|
+
"absolute top-0 right-0 flex items-center justify-center rounded-full bg-rose-500 text-white font-semibold leading-none",
|
|
5076
|
+
badgeSizeClass[size]
|
|
5077
|
+
),
|
|
5078
|
+
children: [
|
|
5079
|
+
ping && /* @__PURE__ */ jsx("span", { className: "absolute inset-0 rounded-full bg-rose-500 animate-ping opacity-75" }),
|
|
5080
|
+
/* @__PURE__ */ jsx("span", { className: "relative", children: displayCount })
|
|
5081
|
+
]
|
|
5082
|
+
}
|
|
5083
|
+
)
|
|
5084
|
+
]
|
|
3777
5085
|
}
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
}, [isOpen, closeOnEsc, close]);
|
|
3782
|
-
if (!isValidElement(children)) return children;
|
|
3783
|
-
const child = cloneElement(children, {
|
|
3784
|
-
ref: (node) => {
|
|
3785
|
-
anchorRef.current = node;
|
|
3786
|
-
const childProps = children.props;
|
|
3787
|
-
const prevRef = childProps.ref;
|
|
3788
|
-
if (typeof prevRef === "function") prevRef(node);
|
|
3789
|
-
else if (prevRef && typeof prevRef === "object") prevRef.current = node;
|
|
3790
|
-
},
|
|
3791
|
-
onClick: (e) => {
|
|
3792
|
-
const childProps = children.props;
|
|
3793
|
-
if (typeof childProps.onClick === "function") childProps.onClick(e);
|
|
3794
|
-
toggle();
|
|
3795
|
-
},
|
|
3796
|
-
"aria-expanded": isOpen,
|
|
3797
|
-
"aria-haspopup": "dialog",
|
|
3798
|
-
"aria-controls": isOpen ? popoverId : void 0
|
|
3799
|
-
});
|
|
3800
|
-
const getTransform = () => {
|
|
3801
|
-
if (!pos) return "translate(-9999px, -9999px)";
|
|
3802
|
-
switch (pos.placement) {
|
|
3803
|
-
case "top":
|
|
3804
|
-
return "translate(-50%, -100%)";
|
|
3805
|
-
case "bottom":
|
|
3806
|
-
return "translate(-50%, 0%)";
|
|
3807
|
-
case "left":
|
|
3808
|
-
return "translate(-100%, -50%)";
|
|
3809
|
-
case "right":
|
|
3810
|
-
return "translate(0%, -50%)";
|
|
3811
|
-
}
|
|
3812
|
-
};
|
|
3813
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3814
|
-
child,
|
|
3815
|
-
isOpen && typeof document !== "undefined" ? createPortal(
|
|
3816
|
-
/* @__PURE__ */ jsx(
|
|
3817
|
-
"div",
|
|
3818
|
-
{
|
|
3819
|
-
ref: popoverRef,
|
|
3820
|
-
id: popoverId,
|
|
3821
|
-
role: "dialog",
|
|
3822
|
-
className: cn(
|
|
3823
|
-
"fixed z-[9999] rounded-xl shadow-xl ring-1 ring-white/10 bg-surface-50 backdrop-blur-md p-4",
|
|
3824
|
-
className
|
|
3825
|
-
),
|
|
3826
|
-
style: {
|
|
3827
|
-
left: pos?.left ?? 0,
|
|
3828
|
-
top: pos?.top ?? 0,
|
|
3829
|
-
transform: getTransform()
|
|
3830
|
-
},
|
|
3831
|
-
children: content
|
|
3832
|
-
}
|
|
3833
|
-
),
|
|
3834
|
-
document.body
|
|
3835
|
-
) : null
|
|
3836
|
-
] });
|
|
3837
|
-
}
|
|
5086
|
+
);
|
|
5087
|
+
}
|
|
5088
|
+
);
|
|
3838
5089
|
var sizeClass8 = {
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
5090
|
+
xs: "text-sm font-semibold",
|
|
5091
|
+
sm: "text-base font-semibold",
|
|
5092
|
+
md: "text-lg font-bold",
|
|
5093
|
+
lg: "text-xl font-bold",
|
|
5094
|
+
xl: "text-2xl font-bold tracking-tight",
|
|
5095
|
+
"2xl": "text-3xl font-bold tracking-tight sm:text-4xl"
|
|
5096
|
+
};
|
|
5097
|
+
var levelToSize = {
|
|
5098
|
+
1: "2xl",
|
|
5099
|
+
2: "xl",
|
|
5100
|
+
3: "lg",
|
|
5101
|
+
4: "md",
|
|
5102
|
+
5: "sm",
|
|
5103
|
+
6: "xs"
|
|
5104
|
+
};
|
|
5105
|
+
var colorClass = {
|
|
5106
|
+
default: "text-white",
|
|
5107
|
+
muted: "text-white/70",
|
|
5108
|
+
gradient: "text-gradient"
|
|
5109
|
+
};
|
|
5110
|
+
var Heading = forwardRef(function Heading2({ level = 2, size, color = "default", className, ...props }, ref) {
|
|
5111
|
+
const Tag = `h${level}`;
|
|
5112
|
+
const effectiveSize = size ?? levelToSize[level];
|
|
5113
|
+
return /* @__PURE__ */ jsx(
|
|
5114
|
+
Tag,
|
|
5115
|
+
{
|
|
5116
|
+
ref,
|
|
5117
|
+
...props,
|
|
5118
|
+
className: cn(sizeClass8[effectiveSize], colorClass[color], className)
|
|
5119
|
+
}
|
|
5120
|
+
);
|
|
5121
|
+
});
|
|
5122
|
+
var sizeMap2 = {
|
|
5123
|
+
xs: "text-xs",
|
|
5124
|
+
sm: "text-sm",
|
|
5125
|
+
md: "text-base",
|
|
5126
|
+
lg: "text-lg"
|
|
5127
|
+
};
|
|
5128
|
+
var colorMap = {
|
|
5129
|
+
default: "text-white/90",
|
|
5130
|
+
muted: "text-white/70",
|
|
5131
|
+
dimmed: "text-white/50",
|
|
5132
|
+
primary: "text-primary-light",
|
|
5133
|
+
success: "text-emerald-400",
|
|
5134
|
+
warning: "text-amber-400",
|
|
5135
|
+
danger: "text-rose-400"
|
|
3842
5136
|
};
|
|
3843
|
-
var
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
5137
|
+
var weightMap = {
|
|
5138
|
+
normal: "font-normal",
|
|
5139
|
+
medium: "font-medium",
|
|
5140
|
+
semibold: "font-semibold",
|
|
5141
|
+
bold: "font-bold"
|
|
3847
5142
|
};
|
|
3848
|
-
var
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
5143
|
+
var Text = forwardRef(function Text2({ size = "md", color = "default", weight = "normal", inline = false, truncate = false, className, ...props }, ref) {
|
|
5144
|
+
const Tag = inline ? "span" : "p";
|
|
5145
|
+
return /* @__PURE__ */ jsx(
|
|
5146
|
+
Tag,
|
|
5147
|
+
{
|
|
5148
|
+
ref,
|
|
5149
|
+
...props,
|
|
5150
|
+
className: cn(
|
|
5151
|
+
sizeMap2[size],
|
|
5152
|
+
colorMap[color],
|
|
5153
|
+
weightMap[weight],
|
|
5154
|
+
truncate && "truncate",
|
|
5155
|
+
className
|
|
5156
|
+
)
|
|
5157
|
+
}
|
|
5158
|
+
);
|
|
5159
|
+
});
|
|
5160
|
+
var gapClass = {
|
|
5161
|
+
0: "gap-0",
|
|
5162
|
+
1: "gap-1",
|
|
5163
|
+
2: "gap-2",
|
|
5164
|
+
3: "gap-3",
|
|
5165
|
+
4: "gap-4",
|
|
5166
|
+
5: "gap-5",
|
|
5167
|
+
6: "gap-6",
|
|
5168
|
+
8: "gap-8",
|
|
5169
|
+
10: "gap-10",
|
|
5170
|
+
12: "gap-12"
|
|
3852
5171
|
};
|
|
3853
|
-
var
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
5172
|
+
var alignClass2 = {
|
|
5173
|
+
start: "items-start",
|
|
5174
|
+
center: "items-center",
|
|
5175
|
+
end: "items-end",
|
|
5176
|
+
stretch: "items-stretch",
|
|
5177
|
+
baseline: "items-baseline"
|
|
3857
5178
|
};
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
5179
|
+
var justifyClass = {
|
|
5180
|
+
start: "justify-start",
|
|
5181
|
+
center: "justify-center",
|
|
5182
|
+
end: "justify-end",
|
|
5183
|
+
between: "justify-between",
|
|
5184
|
+
around: "justify-around",
|
|
5185
|
+
evenly: "justify-evenly"
|
|
5186
|
+
};
|
|
5187
|
+
var Stack = forwardRef(function Stack2({ children, direction = "vertical", gap = 4, align = "stretch", justify = "start", wrap = false, className, ...props }, ref) {
|
|
5188
|
+
return /* @__PURE__ */ jsx(
|
|
5189
|
+
"div",
|
|
5190
|
+
{
|
|
5191
|
+
ref,
|
|
5192
|
+
...props,
|
|
5193
|
+
className: cn(
|
|
5194
|
+
"flex",
|
|
5195
|
+
direction === "vertical" ? "flex-col" : "flex-row",
|
|
5196
|
+
gapClass[gap],
|
|
5197
|
+
alignClass2[align],
|
|
5198
|
+
justifyClass[justify],
|
|
5199
|
+
wrap && "flex-wrap",
|
|
5200
|
+
className
|
|
5201
|
+
),
|
|
5202
|
+
children
|
|
5203
|
+
}
|
|
5204
|
+
);
|
|
5205
|
+
});
|
|
5206
|
+
var ScrollArea = forwardRef(function ScrollArea2({ children, maxHeight, hideScrollbar = false, orientation = "vertical", className, style, ...props }, ref) {
|
|
5207
|
+
const overflowClass = {
|
|
5208
|
+
vertical: "overflow-y-auto overflow-x-hidden",
|
|
5209
|
+
horizontal: "overflow-x-auto overflow-y-hidden",
|
|
5210
|
+
both: "overflow-auto"
|
|
5211
|
+
}[orientation];
|
|
5212
|
+
return /* @__PURE__ */ jsx(
|
|
5213
|
+
"div",
|
|
5214
|
+
{
|
|
5215
|
+
ref,
|
|
5216
|
+
...props,
|
|
5217
|
+
tabIndex: 0,
|
|
5218
|
+
className: cn(
|
|
5219
|
+
overflowClass,
|
|
5220
|
+
// Custom dark scrollbar styling
|
|
5221
|
+
"[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5",
|
|
5222
|
+
"[&::-webkit-scrollbar-track]:bg-transparent",
|
|
5223
|
+
"[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-white/15 hover:[&::-webkit-scrollbar-thumb]:bg-white/25",
|
|
5224
|
+
hideScrollbar && "no-scrollbar",
|
|
5225
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/30 focus-visible:ring-inset",
|
|
5226
|
+
className
|
|
5227
|
+
),
|
|
5228
|
+
style: {
|
|
5229
|
+
maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
|
|
5230
|
+
...style
|
|
5231
|
+
},
|
|
5232
|
+
children
|
|
5233
|
+
}
|
|
5234
|
+
);
|
|
5235
|
+
});
|
|
5236
|
+
var defaultSeparator = /* @__PURE__ */ jsx(
|
|
5237
|
+
"svg",
|
|
5238
|
+
{
|
|
5239
|
+
className: "w-3.5 h-3.5 text-white/30 flex-shrink-0",
|
|
5240
|
+
viewBox: "0 0 16 16",
|
|
5241
|
+
fill: "none",
|
|
5242
|
+
stroke: "currentColor",
|
|
5243
|
+
strokeWidth: "2",
|
|
5244
|
+
strokeLinecap: "round",
|
|
5245
|
+
"aria-hidden": "true",
|
|
5246
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 4l4 4-4 4" })
|
|
5247
|
+
}
|
|
5248
|
+
);
|
|
5249
|
+
function DotsIcon() {
|
|
5250
|
+
return /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", className: "h-4 w-4", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
5251
|
+
/* @__PURE__ */ jsx("circle", { cx: "3", cy: "8", r: "1.25" }),
|
|
5252
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "1.25" }),
|
|
5253
|
+
/* @__PURE__ */ jsx("circle", { cx: "13", cy: "8", r: "1.25" })
|
|
5254
|
+
] });
|
|
5255
|
+
}
|
|
5256
|
+
function renderItemContent(item) {
|
|
5257
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-1.5", children: [
|
|
5258
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-white/45", children: item.icon }) : null,
|
|
5259
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
|
|
5260
|
+
] });
|
|
5261
|
+
}
|
|
5262
|
+
function getVisibleItems(items, maxItems, itemsBeforeCollapse = 1, itemsAfterCollapse = 1) {
|
|
5263
|
+
if (!maxItems || items.length <= maxItems) {
|
|
5264
|
+
return items.map((item, index) => ({ type: "item", item, originalIndex: index }));
|
|
5265
|
+
}
|
|
5266
|
+
const before = Math.max(1, itemsBeforeCollapse);
|
|
5267
|
+
const after = Math.max(1, itemsAfterCollapse);
|
|
5268
|
+
if (before + after >= items.length) {
|
|
5269
|
+
return items.map((item, index) => ({ type: "item", item, originalIndex: index }));
|
|
5270
|
+
}
|
|
5271
|
+
const collapsedItems = items.slice(before, items.length - after);
|
|
5272
|
+
const startItems = items.slice(0, before).map((item, index) => ({ type: "item", item, originalIndex: index }));
|
|
5273
|
+
const endItems = items.slice(items.length - after).map((item, index) => ({
|
|
5274
|
+
type: "item",
|
|
5275
|
+
item,
|
|
5276
|
+
originalIndex: items.length - after + index
|
|
5277
|
+
}));
|
|
5278
|
+
return [
|
|
5279
|
+
...startItems,
|
|
5280
|
+
{ type: "collapse", items: collapsedItems },
|
|
5281
|
+
...endItems
|
|
5282
|
+
];
|
|
5283
|
+
}
|
|
5284
|
+
function Breadcrumbs({
|
|
5285
|
+
items,
|
|
5286
|
+
separator = defaultSeparator,
|
|
5287
|
+
maxItems,
|
|
5288
|
+
itemsBeforeCollapse = 1,
|
|
5289
|
+
itemsAfterCollapse = 1,
|
|
5290
|
+
renderLink,
|
|
3867
5291
|
className
|
|
3868
5292
|
}) {
|
|
3869
|
-
|
|
3870
|
-
const
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
}
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
const active = document.activeElement;
|
|
3930
|
-
const first = focusables[0];
|
|
3931
|
-
const last = focusables[focusables.length - 1];
|
|
3932
|
-
if (e.shiftKey) {
|
|
3933
|
-
if (active === first) {
|
|
3934
|
-
e.preventDefault();
|
|
3935
|
-
focusSafely(last);
|
|
3936
|
-
}
|
|
3937
|
-
} else {
|
|
3938
|
-
if (active === last) {
|
|
3939
|
-
e.preventDefault();
|
|
3940
|
-
focusSafely(first);
|
|
3941
|
-
}
|
|
5293
|
+
if (items.length === 0) return null;
|
|
5294
|
+
const visibleItems = getVisibleItems(items, maxItems, itemsBeforeCollapse, itemsAfterCollapse);
|
|
5295
|
+
const lastItemIndex = items.length - 1;
|
|
5296
|
+
const renderLinkNode = (item, classNameValue) => {
|
|
5297
|
+
const content = renderItemContent(item);
|
|
5298
|
+
if (!item.href) {
|
|
5299
|
+
return content;
|
|
5300
|
+
}
|
|
5301
|
+
if (renderLink) {
|
|
5302
|
+
return renderLink({
|
|
5303
|
+
href: item.href,
|
|
5304
|
+
onClick: item.onClick,
|
|
5305
|
+
className: classNameValue,
|
|
5306
|
+
children: content,
|
|
5307
|
+
item
|
|
5308
|
+
});
|
|
5309
|
+
}
|
|
5310
|
+
return /* @__PURE__ */ jsx("a", { href: item.href, onClick: item.onClick, className: classNameValue, children: content });
|
|
5311
|
+
};
|
|
5312
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: cn("flex items-center", className), children: /* @__PURE__ */ jsx("ol", { className: "flex min-w-0 items-center gap-1.5 text-sm", children: visibleItems.map((entry, index) => {
|
|
5313
|
+
if (entry.type === "collapse") {
|
|
5314
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
5315
|
+
index > 0 ? /* @__PURE__ */ jsx("li", { className: "flex items-center", children: separator }) : null,
|
|
5316
|
+
/* @__PURE__ */ jsx("li", { className: "flex items-center", children: /* @__PURE__ */ jsx(
|
|
5317
|
+
Popover,
|
|
5318
|
+
{
|
|
5319
|
+
placement: "bottom",
|
|
5320
|
+
className: "min-w-[12rem] p-2",
|
|
5321
|
+
content: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: entry.items.map((item2, hiddenIndex) => /* @__PURE__ */ jsx("div", { children: item2.href ? renderLink ? renderLink({
|
|
5322
|
+
href: item2.href,
|
|
5323
|
+
onClick: item2.onClick,
|
|
5324
|
+
className: "flex w-full items-center rounded-lg px-3 py-2 text-sm text-white/75 transition-colors hover:bg-white/10 hover:text-white",
|
|
5325
|
+
children: renderItemContent(item2),
|
|
5326
|
+
item: item2
|
|
5327
|
+
}) : /* @__PURE__ */ jsx(
|
|
5328
|
+
"a",
|
|
5329
|
+
{
|
|
5330
|
+
href: item2.href,
|
|
5331
|
+
onClick: item2.onClick,
|
|
5332
|
+
className: "flex w-full items-center rounded-lg px-3 py-2 text-sm text-white/75 transition-colors hover:bg-white/10 hover:text-white",
|
|
5333
|
+
children: renderItemContent(item2)
|
|
5334
|
+
}
|
|
5335
|
+
) : item2.onClick ? /* @__PURE__ */ jsx(
|
|
5336
|
+
"button",
|
|
5337
|
+
{
|
|
5338
|
+
type: "button",
|
|
5339
|
+
onClick: item2.onClick,
|
|
5340
|
+
className: "flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-white/75 transition-colors hover:bg-white/10 hover:text-white",
|
|
5341
|
+
children: renderItemContent(item2)
|
|
5342
|
+
}
|
|
5343
|
+
) : /* @__PURE__ */ jsx("div", { className: "flex w-full items-center rounded-lg px-3 py-2 text-sm text-white/55", children: renderItemContent(item2) }) }, `${hiddenIndex}-${String(item2.href ?? item2.label)}`)) }),
|
|
5344
|
+
children: /* @__PURE__ */ jsx(
|
|
5345
|
+
"button",
|
|
5346
|
+
{
|
|
5347
|
+
type: "button",
|
|
5348
|
+
"aria-label": "Show hidden breadcrumbs",
|
|
5349
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded-lg text-white/45 transition-colors hover:bg-white/10 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
5350
|
+
children: /* @__PURE__ */ jsx(DotsIcon, {})
|
|
5351
|
+
}
|
|
5352
|
+
)
|
|
3942
5353
|
}
|
|
3943
|
-
}
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
5354
|
+
) })
|
|
5355
|
+
] }, `collapse-${index}`);
|
|
5356
|
+
}
|
|
5357
|
+
const isLast = entry.originalIndex === lastItemIndex;
|
|
5358
|
+
const item = entry.item;
|
|
5359
|
+
const interactiveClassName = "text-white/50 hover:text-white/80 transition-colors";
|
|
5360
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
5361
|
+
index > 0 ? /* @__PURE__ */ jsx("li", { className: "flex items-center", children: separator }) : null,
|
|
5362
|
+
/* @__PURE__ */ jsx("li", { className: "flex min-w-0 items-center", children: isLast ? /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-1.5 text-white font-medium", "aria-current": "page", children: [
|
|
5363
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-white/55", children: item.icon }) : null,
|
|
5364
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
|
|
5365
|
+
] }) : item.href ? renderLinkNode(item, interactiveClassName) : item.onClick ? /* @__PURE__ */ jsx(
|
|
5366
|
+
"button",
|
|
5367
|
+
{
|
|
5368
|
+
type: "button",
|
|
5369
|
+
onClick: item.onClick,
|
|
5370
|
+
className: cn("min-w-0", interactiveClassName),
|
|
5371
|
+
children: renderItemContent(item)
|
|
5372
|
+
}
|
|
5373
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-white/50", children: renderItemContent(item) }) })
|
|
5374
|
+
] }, `${entry.originalIndex}-${String(item.href ?? item.label)}`);
|
|
5375
|
+
}) }) });
|
|
3948
5376
|
}
|
|
3949
5377
|
var defaultFilter = (opt, q) => opt.label.toLowerCase().includes(q.toLowerCase());
|
|
3950
5378
|
var Combobox = forwardRef(function Combobox2({
|
|
@@ -4267,6 +5695,12 @@ function VisuallyHidden({ children, as: Tag = "span", style, ...props }) {
|
|
|
4267
5695
|
}
|
|
4268
5696
|
);
|
|
4269
5697
|
}
|
|
5698
|
+
function didResetKeysChange(previous, next) {
|
|
5699
|
+
if (!previous && !next) return false;
|
|
5700
|
+
if (!previous || !next) return true;
|
|
5701
|
+
if (previous.length !== next.length) return true;
|
|
5702
|
+
return previous.some((value, index) => !Object.is(value, next[index]));
|
|
5703
|
+
}
|
|
4270
5704
|
var ErrorBoundary = class extends Component {
|
|
4271
5705
|
constructor() {
|
|
4272
5706
|
super(...arguments);
|
|
@@ -4281,6 +5715,12 @@ var ErrorBoundary = class extends Component {
|
|
|
4281
5715
|
componentDidCatch(error, errorInfo) {
|
|
4282
5716
|
this.props.onError?.(error, errorInfo);
|
|
4283
5717
|
}
|
|
5718
|
+
componentDidUpdate(prevProps) {
|
|
5719
|
+
if (!this.state.error) return;
|
|
5720
|
+
if (!Object.is(prevProps.resetKey, this.props.resetKey) || didResetKeysChange(prevProps.resetKeys, this.props.resetKeys)) {
|
|
5721
|
+
this.reset();
|
|
5722
|
+
}
|
|
5723
|
+
}
|
|
4284
5724
|
render() {
|
|
4285
5725
|
const { error } = this.state;
|
|
4286
5726
|
if (!error) return this.props.children;
|
|
@@ -4291,19 +5731,40 @@ var ErrorBoundary = class extends Component {
|
|
|
4291
5731
|
if (fallback !== void 0) {
|
|
4292
5732
|
return fallback;
|
|
4293
5733
|
}
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
}
|
|
4305
|
-
|
|
4306
|
-
|
|
5734
|
+
const {
|
|
5735
|
+
actionLabel = "Try again",
|
|
5736
|
+
description,
|
|
5737
|
+
fullScreen = false,
|
|
5738
|
+
onAction,
|
|
5739
|
+
title = "Something went wrong"
|
|
5740
|
+
} = this.props;
|
|
5741
|
+
const descriptionContent = typeof description === "function" ? description(error) : description ?? error.message;
|
|
5742
|
+
const handleAction = () => {
|
|
5743
|
+
if (onAction) {
|
|
5744
|
+
onAction({ error, reset: this.reset });
|
|
5745
|
+
return;
|
|
5746
|
+
}
|
|
5747
|
+
this.reset();
|
|
5748
|
+
};
|
|
5749
|
+
const content = /* @__PURE__ */ jsxs(
|
|
5750
|
+
"div",
|
|
5751
|
+
{
|
|
5752
|
+
role: "alert",
|
|
5753
|
+
className: cn(
|
|
5754
|
+
"glass rounded-xl p-6 text-center",
|
|
5755
|
+
fullScreen && "w-full max-w-md rounded-2xl p-8 shadow-surface"
|
|
5756
|
+
),
|
|
5757
|
+
children: [
|
|
5758
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-white mb-2", children: title }),
|
|
5759
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-white/60 mb-4", children: descriptionContent }),
|
|
5760
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "primary", onClick: handleAction, children: actionLabel })
|
|
5761
|
+
]
|
|
5762
|
+
}
|
|
5763
|
+
);
|
|
5764
|
+
if (fullScreen) {
|
|
5765
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-surface flex items-center justify-center p-6", children: content });
|
|
5766
|
+
}
|
|
5767
|
+
return content;
|
|
4307
5768
|
}
|
|
4308
5769
|
};
|
|
4309
5770
|
function LoadingScreen({ message, size = "lg", className }) {
|
|
@@ -4323,4 +5784,4 @@ function LoadingScreen({ message, size = "lg", className }) {
|
|
|
4323
5784
|
);
|
|
4324
5785
|
}
|
|
4325
5786
|
|
|
4326
|
-
export { ActiveFilterPills, Alert, Avatar, Badge, Breadcrumbs, Button, Card, Checkbox, CollapsibleSection, ColorInput, Combobox, ConfirmDialog, CooldownRing, CopyField, DashboardLayout, Divider, DotIndicator, Drawer, DropZone, Dropdown, DropdownItem, DropdownMenu, DropdownSeparator, DropdownTrigger, EmptyState, ErrorBoundary, FormField, Heading, IconButton, Input, LoadingScreen, Modal, MutationOverlay, Navbar, NotificationBell, PageShell, Pagination, Pill, Popover, ProgressBar, ProgressButton, RadioGroup, RadioItem, ScrollArea, SearchInput, SectionCard, Select, Sidebar, Skeleton, Slider, Spinner, Stack, StageProgress, StatCard, Stepper, Tab, TabList, TabPanel, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TagInput, Text, Textarea, ToastProvider, Toggle, Tooltip, Transition, VisuallyHidden, cn, colors, focusSafely, getFocusableElements, useClipboard, useDebounce, useDisclosure, useHotkeys, useIntersectionObserver, useMediaQuery, useScrollLock, useSharedNow, useToast };
|
|
5787
|
+
export { ActiveFilterPills, Alert, Avatar, Badge, Breadcrumbs, Button, Card, Checkbox, CollapsibleSection, ColorInput, Combobox, ConfirmDialog, CooldownRing, CopyField, DashboardLayout, DataTable, DateRangePicker, Divider, DotIndicator, Drawer, DropZone, Dropdown, DropdownItem, DropdownMenu, DropdownSeparator, DropdownTrigger, EmptyState, ErrorBoundary, FormField, Heading, IconButton, Input, LoadingScreen, Modal, MutationOverlay, Navbar, NotificationBell, PageShell, Pagination, Pill, Popover, ProgressBar, ProgressButton, RadioGroup, RadioItem, ScrollArea, SearchInput, SectionCard, Select, Sidebar, Skeleton, Slider, Spinner, Stack, StageProgress, StatCard, Stepper, Tab, TabList, TabPanel, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TagInput, Text, Textarea, Timeline, ToastProvider, Toggle, Tooltip, Transition, VisuallyHidden, cn, colors, focusSafely, getFocusableElements, useClipboard, useDebounce, useDisclosure, useHotkeys, useIntersectionObserver, useMediaQuery, useScrollLock, useSharedNow, useToast };
|