@dimaan/ui 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +253 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +89 -14
- package/dist/index.d.ts +89 -14
- package/dist/index.js +238 -137
- package/dist/index.js.map +1 -1
- package/dist/preset.css +73 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -120,21 +120,21 @@ var AlertDialogDescription = react.forwardRef(function AlertDialogDescription2({
|
|
|
120
120
|
|
|
121
121
|
// src/components/button/buttonVariants.ts
|
|
122
122
|
var buttonVariantClass = {
|
|
123
|
-
primary: "bg-primary text-primary-foreground shadow-
|
|
123
|
+
primary: "bg-primary text-primary-foreground shadow-[var(--shadow-btn)] hover:bg-primary/95 hover:-translate-y-px hover:shadow-[var(--shadow-btn-hover)] active:translate-y-0 active:shadow-[var(--shadow-btn-active)] focus-visible:ring-primary/40",
|
|
124
124
|
secondary: "bg-muted text-foreground hover:bg-muted/80 focus-visible:ring-muted-foreground/30",
|
|
125
125
|
outline: "border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/40",
|
|
126
126
|
ghost: "bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/40",
|
|
127
|
-
destructive: "bg-destructive text-destructive-foreground shadow-
|
|
128
|
-
success: "bg-success text-success-foreground shadow-
|
|
129
|
-
warning: "bg-warning text-warning-foreground shadow-
|
|
127
|
+
destructive: "bg-destructive text-destructive-foreground shadow-[var(--shadow-solid)] hover:bg-destructive/95 hover:-translate-y-px hover:shadow-[var(--shadow-solid-hover)] active:translate-y-0 active:shadow-[var(--shadow-solid-active)] focus-visible:ring-destructive/40",
|
|
128
|
+
success: "bg-success text-success-foreground shadow-[var(--shadow-solid)] hover:bg-success/95 hover:-translate-y-px hover:shadow-[var(--shadow-solid-hover)] active:translate-y-0 active:shadow-[var(--shadow-solid-active)] focus-visible:ring-success/40",
|
|
129
|
+
warning: "bg-warning text-warning-foreground shadow-[var(--shadow-solid)] hover:bg-warning/95 hover:-translate-y-px hover:shadow-[var(--shadow-solid-hover)] active:translate-y-0 active:shadow-[var(--shadow-solid-active)] focus-visible:ring-warning/40",
|
|
130
130
|
link: "text-primary underline-offset-4 hover:underline focus-visible:ring-primary/40 px-0 shadow-none"
|
|
131
131
|
};
|
|
132
132
|
var buttonSizeClass = {
|
|
133
|
-
sm: "h-8 gap-1.5 rounded-
|
|
134
|
-
md: "h-9 gap-2 rounded-
|
|
135
|
-
lg: "h-11 gap-2.5 rounded-
|
|
136
|
-
icon: "
|
|
137
|
-
"icon-sm": "
|
|
133
|
+
sm: "h-8 gap-1.5 rounded-[10px] px-3 text-sm",
|
|
134
|
+
md: "h-9 gap-2 rounded-[10px] px-4 text-sm",
|
|
135
|
+
lg: "h-11 gap-2.5 rounded-[10px] px-6 text-base",
|
|
136
|
+
icon: "size-9 shrink-0 rounded-[10px] p-0",
|
|
137
|
+
"icon-sm": "size-8 shrink-0 rounded-[10px] p-0"
|
|
138
138
|
};
|
|
139
139
|
var buttonBaseClass = "group/button relative inline-flex items-center justify-center font-medium select-none whitespace-nowrap outline-none transition-[background-color,color,box-shadow,opacity,transform] active:scale-[0.98] focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 motion-reduce:transition-none motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:shrink-0";
|
|
140
140
|
var Button = react.forwardRef(function Button2({
|
|
@@ -197,10 +197,10 @@ var Button = react.forwardRef(function Button2({
|
|
|
197
197
|
);
|
|
198
198
|
});
|
|
199
199
|
function Slot({ children }) {
|
|
200
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "inline-flex
|
|
200
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "inline-flex size-4 items-center justify-center", children });
|
|
201
201
|
}
|
|
202
202
|
function Spinner() {
|
|
203
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "
|
|
203
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "size-4 animate-spin", "data-testid": "button-spinner" });
|
|
204
204
|
}
|
|
205
205
|
var ConfirmDialogContext = react.createContext(null);
|
|
206
206
|
function ConfirmDialogProvider({ labels, children }) {
|
|
@@ -372,7 +372,7 @@ function DashboardMain({ className, children, ...props }) {
|
|
|
372
372
|
// stretching the whole layout past 100%.
|
|
373
373
|
"flex min-h-screen min-w-0 flex-1 flex-col transition-[margin] duration-200 ease-out",
|
|
374
374
|
// On desktop, push the main column past the fixed sidebar using logical margin.
|
|
375
|
-
collapsed ? "lg:ms-
|
|
375
|
+
collapsed ? "lg:ms-0" : "lg:ms-(--sidebar-width)",
|
|
376
376
|
className
|
|
377
377
|
),
|
|
378
378
|
...props,
|
|
@@ -475,7 +475,7 @@ var HeaderSearch = react.forwardRef(
|
|
|
475
475
|
"span",
|
|
476
476
|
{
|
|
477
477
|
"aria-hidden": "true",
|
|
478
|
-
className: "pointer-events-none absolute start-3 flex
|
|
478
|
+
className: "pointer-events-none absolute start-3 flex size-4 items-center justify-center text-muted-foreground",
|
|
479
479
|
children: icon
|
|
480
480
|
}
|
|
481
481
|
) : null,
|
|
@@ -541,14 +541,16 @@ function Sidebar({ className, children, ...props }) {
|
|
|
541
541
|
"fixed inset-y-0 start-0 z-40 flex flex-col",
|
|
542
542
|
// Surface
|
|
543
543
|
"bg-sidebar text-sidebar-foreground border-e border-sidebar-border",
|
|
544
|
-
// Sizing — width
|
|
545
|
-
|
|
544
|
+
// Sizing — always full width; collapse hides it off-canvas (below).
|
|
545
|
+
"w-[var(--sidebar-width)]",
|
|
546
546
|
// Motion
|
|
547
|
-
"transition-
|
|
548
|
-
// Mobile slide
|
|
549
|
-
//
|
|
550
|
-
|
|
551
|
-
|
|
547
|
+
"transition-transform duration-200 ease-out",
|
|
548
|
+
// Mobile: slide in/out via mobileOpen. Logical translate (rtl variant)
|
|
549
|
+
// so it slides off the inline-start edge in both LTR and RTL.
|
|
550
|
+
mobileOpen ? "translate-x-0" : "-translate-x-full rtl:translate-x-full",
|
|
551
|
+
// Desktop: collapse fully hides the sidebar off-canvas; the header
|
|
552
|
+
// trigger slides it back in and the main content reclaims the width.
|
|
553
|
+
collapsed ? "lg:-translate-x-full lg:rtl:translate-x-full" : "lg:translate-x-0 lg:rtl:translate-x-0",
|
|
552
554
|
className
|
|
553
555
|
),
|
|
554
556
|
...props,
|
|
@@ -571,18 +573,8 @@ function SidebarFooter({ className, children, ...props }) {
|
|
|
571
573
|
);
|
|
572
574
|
}
|
|
573
575
|
function SidebarGroup({ label, className, children, ...props }) {
|
|
574
|
-
const { collapsed } = useDashboardLayout();
|
|
575
576
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1 py-2", className), ...props, children: [
|
|
576
|
-
label ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
577
|
-
"div",
|
|
578
|
-
{
|
|
579
|
-
className: cn(
|
|
580
|
-
"px-3 pb-1 text-xs font-medium uppercase tracking-wider text-muted-foreground transition-opacity",
|
|
581
|
-
collapsed && "pointer-events-none h-0 overflow-hidden opacity-0"
|
|
582
|
-
),
|
|
583
|
-
children: label
|
|
584
|
-
}
|
|
585
|
-
) : null,
|
|
577
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: label }) : null,
|
|
586
578
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children })
|
|
587
579
|
] });
|
|
588
580
|
}
|
|
@@ -616,7 +608,6 @@ function SidebarNavGroup({
|
|
|
616
608
|
onClick,
|
|
617
609
|
...props
|
|
618
610
|
}) {
|
|
619
|
-
const { collapsed } = useDashboardLayout();
|
|
620
611
|
const submenuId = react.useId();
|
|
621
612
|
const [internalOpen, setInternalOpen] = react.useState(defaultOpen);
|
|
622
613
|
const isControlled = openProp !== void 0;
|
|
@@ -643,27 +634,23 @@ function SidebarNavGroup({
|
|
|
643
634
|
const isActive = active || hasActiveChild;
|
|
644
635
|
const prevHasActiveChild = react.useRef(false);
|
|
645
636
|
react.useEffect(() => {
|
|
646
|
-
if (hasActiveChild && !prevHasActiveChild.current
|
|
637
|
+
if (hasActiveChild && !prevHasActiveChild.current) {
|
|
647
638
|
setOpen(true);
|
|
648
639
|
}
|
|
649
640
|
prevHasActiveChild.current = hasActiveChild;
|
|
650
|
-
}, [hasActiveChild,
|
|
651
|
-
|
|
652
|
-
if (collapsed && open) setOpen(false);
|
|
653
|
-
}, [collapsed, open, setOpen]);
|
|
654
|
-
const titleAttr = collapsed && typeof label === "string" ? label : props.title ?? void 0;
|
|
655
|
-
const showChildren = !collapsed;
|
|
641
|
+
}, [hasActiveChild, setOpen]);
|
|
642
|
+
const titleAttr = props.title ?? void 0;
|
|
656
643
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-col", children: [
|
|
657
644
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
658
645
|
"button",
|
|
659
646
|
{
|
|
660
647
|
type: "button",
|
|
661
|
-
"aria-expanded":
|
|
662
|
-
"aria-controls":
|
|
648
|
+
"aria-expanded": open,
|
|
649
|
+
"aria-controls": submenuId,
|
|
663
650
|
"data-active": isActive ? "true" : void 0,
|
|
664
651
|
title: titleAttr,
|
|
665
652
|
onClick: (e) => {
|
|
666
|
-
|
|
653
|
+
setOpen(!open);
|
|
667
654
|
onClick?.(e);
|
|
668
655
|
},
|
|
669
656
|
className: cn(
|
|
@@ -671,7 +658,6 @@ function SidebarNavGroup({
|
|
|
671
658
|
"text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
672
659
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
|
|
673
660
|
isActive && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
674
|
-
collapsed && "justify-center px-0",
|
|
675
661
|
className
|
|
676
662
|
),
|
|
677
663
|
...props,
|
|
@@ -683,19 +669,10 @@ function SidebarNavGroup({
|
|
|
683
669
|
className: "absolute inset-y-1.5 start-0 w-1 rounded-full bg-primary"
|
|
684
670
|
}
|
|
685
671
|
) : null,
|
|
686
|
-
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex
|
|
687
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
className: cn(
|
|
691
|
-
"flex-1 truncate text-start transition-[opacity,width]",
|
|
692
|
-
collapsed && "pointer-events-none w-0 opacity-0"
|
|
693
|
-
),
|
|
694
|
-
children: label
|
|
695
|
-
}
|
|
696
|
-
),
|
|
697
|
-
endSlot && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center", children: endSlot }) : null,
|
|
698
|
-
showChildren ? /* @__PURE__ */ jsxRuntime.jsx(ChevronCaret, { open }) : null
|
|
672
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex size-5 shrink-0 items-center justify-center", children: icon }) : null,
|
|
673
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-start", children: label }),
|
|
674
|
+
endSlot ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center", children: endSlot }) : null,
|
|
675
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronCaret, { open })
|
|
699
676
|
]
|
|
700
677
|
}
|
|
701
678
|
),
|
|
@@ -703,10 +680,10 @@ function SidebarNavGroup({
|
|
|
703
680
|
"div",
|
|
704
681
|
{
|
|
705
682
|
id: submenuId,
|
|
706
|
-
hidden: !
|
|
683
|
+
hidden: !open,
|
|
707
684
|
className: cn(
|
|
708
685
|
"grid transition-[grid-template-rows] duration-200 ease-out",
|
|
709
|
-
|
|
686
|
+
open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
|
|
710
687
|
),
|
|
711
688
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5 ps-7 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarNavGroupContext.Provider, { value: contextValue, children }) }) })
|
|
712
689
|
}
|
|
@@ -719,7 +696,7 @@ function ChevronCaret({ open }) {
|
|
|
719
696
|
{
|
|
720
697
|
"aria-hidden": "true",
|
|
721
698
|
className: cn(
|
|
722
|
-
"
|
|
699
|
+
"size-3.5 shrink-0 text-muted-foreground transition-transform duration-200",
|
|
723
700
|
open && "rotate-180"
|
|
724
701
|
)
|
|
725
702
|
}
|
|
@@ -737,7 +714,6 @@ function SidebarNavItem({
|
|
|
737
714
|
end,
|
|
738
715
|
...props
|
|
739
716
|
}) {
|
|
740
|
-
const { collapsed } = useDashboardLayout();
|
|
741
717
|
const resolved = reactRouterDom.useResolvedPath(to);
|
|
742
718
|
const group = react.useContext(SidebarNavGroupContext);
|
|
743
719
|
const itemId = react.useId();
|
|
@@ -749,13 +725,12 @@ function SidebarNavItem({
|
|
|
749
725
|
return () => group.reportActive(itemId, false);
|
|
750
726
|
}, [group, itemId, isActive]);
|
|
751
727
|
const labelContent = label ?? children;
|
|
752
|
-
const titleAttr =
|
|
728
|
+
const titleAttr = props.title;
|
|
753
729
|
const getClassName = (active) => cn(
|
|
754
730
|
"group relative flex h-9 shrink-0 items-center gap-3 rounded-md px-3 text-sm font-medium outline-none transition-colors",
|
|
755
731
|
"text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
756
732
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
|
|
757
733
|
active && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
758
|
-
collapsed && "justify-center px-0",
|
|
759
734
|
className
|
|
760
735
|
);
|
|
761
736
|
const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -766,18 +741,9 @@ function SidebarNavItem({
|
|
|
766
741
|
className: "absolute inset-y-1.5 start-0 w-1 rounded-full bg-primary"
|
|
767
742
|
}
|
|
768
743
|
) : null,
|
|
769
|
-
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex
|
|
770
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
771
|
-
|
|
772
|
-
{
|
|
773
|
-
className: cn(
|
|
774
|
-
"flex-1 truncate text-start transition-[opacity,width]",
|
|
775
|
-
collapsed && "pointer-events-none w-0 opacity-0"
|
|
776
|
-
),
|
|
777
|
-
children: labelContent
|
|
778
|
-
}
|
|
779
|
-
),
|
|
780
|
-
endSlot && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ms-auto flex shrink-0 items-center", children: endSlot }) : null
|
|
744
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex size-5 shrink-0 items-center justify-center", children: icon }) : null,
|
|
745
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-start", children: labelContent }),
|
|
746
|
+
endSlot ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ms-auto flex shrink-0 items-center", children: endSlot }) : null
|
|
781
747
|
] });
|
|
782
748
|
if (render) {
|
|
783
749
|
return render({
|
|
@@ -884,9 +850,9 @@ function AppShell({
|
|
|
884
850
|
) });
|
|
885
851
|
}
|
|
886
852
|
var sizeClass = {
|
|
887
|
-
sm: "
|
|
888
|
-
md: "
|
|
889
|
-
lg: "
|
|
853
|
+
sm: "size-7 text-xs",
|
|
854
|
+
md: "size-9 text-sm",
|
|
855
|
+
lg: "size-11 text-base"
|
|
890
856
|
};
|
|
891
857
|
function Avatar({ src, alt = "", fallback, size = "md", className, ...props }) {
|
|
892
858
|
const [errored, setErrored] = react.useState(false);
|
|
@@ -922,6 +888,14 @@ var badgeVariantClass = {
|
|
|
922
888
|
destructive: "bg-destructive text-destructive-foreground border-transparent",
|
|
923
889
|
outline: "border-border bg-transparent text-foreground"
|
|
924
890
|
};
|
|
891
|
+
var badgeSoftVariantClass = {
|
|
892
|
+
default: "bg-muted text-muted-foreground border-transparent",
|
|
893
|
+
primary: "bg-primary/15 text-primary-soft-foreground border-transparent",
|
|
894
|
+
success: "bg-success/15 text-success-soft-foreground border-transparent",
|
|
895
|
+
warning: "bg-warning/15 text-warning-soft-foreground border-transparent",
|
|
896
|
+
destructive: "bg-destructive/15 text-destructive-soft-foreground border-transparent",
|
|
897
|
+
outline: "border-border bg-transparent text-foreground"
|
|
898
|
+
};
|
|
925
899
|
var badgeSizeClass = {
|
|
926
900
|
sm: "h-5 gap-1 px-2 text-[11px]",
|
|
927
901
|
md: "h-6 gap-1.5 px-2.5 text-xs"
|
|
@@ -931,14 +905,16 @@ var badgeDotSizeClass = {
|
|
|
931
905
|
md: "size-2"
|
|
932
906
|
};
|
|
933
907
|
var badgeBaseClass = "inline-flex shrink-0 items-center rounded-full border font-medium leading-none whitespace-nowrap select-none transition-colors";
|
|
934
|
-
var Badge = react.forwardRef(function Badge2({ variant = "default", size = "md", dot = false, className, children, ...props }, ref) {
|
|
908
|
+
var Badge = react.forwardRef(function Badge2({ variant = "default", size = "md", tone = "solid", dot = false, className, children, ...props }, ref) {
|
|
909
|
+
const variantClass = tone === "soft" ? badgeSoftVariantClass[variant] : badgeVariantClass[variant];
|
|
935
910
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
936
911
|
"span",
|
|
937
912
|
{
|
|
938
913
|
ref,
|
|
939
914
|
"data-slot": "badge",
|
|
940
915
|
"data-variant": variant,
|
|
941
|
-
|
|
916
|
+
"data-tone": tone,
|
|
917
|
+
className: cn(badgeBaseClass, variantClass, badgeSizeClass[size], className),
|
|
942
918
|
...props,
|
|
943
919
|
children: [
|
|
944
920
|
dot ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -953,9 +929,75 @@ var Badge = react.forwardRef(function Badge2({ variant = "default", size = "md",
|
|
|
953
929
|
}
|
|
954
930
|
);
|
|
955
931
|
});
|
|
932
|
+
|
|
933
|
+
// src/components/card/cardVariants.ts
|
|
934
|
+
var cardBaseClass = "rounded-xl border border-border bg-card text-card-foreground shadow-[var(--shadow-card)]";
|
|
935
|
+
var cardHeaderClass = "flex flex-col gap-1.5 p-6";
|
|
936
|
+
var cardTitleClass = "text-lg font-semibold leading-none tracking-tight text-foreground";
|
|
937
|
+
var cardDescriptionClass = "text-sm text-muted-foreground";
|
|
938
|
+
var cardContentClass = "p-6 pt-0";
|
|
939
|
+
var cardFooterClass = "flex items-center gap-2 p-6 pt-0";
|
|
940
|
+
var Card = react.forwardRef(function Card2({ className, ...props }, ref) {
|
|
941
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, "data-slot": "card", className: cn(cardBaseClass, className), ...props });
|
|
942
|
+
});
|
|
943
|
+
var CardHeader = react.forwardRef(
|
|
944
|
+
function CardHeader2({ className, ...props }, ref) {
|
|
945
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
946
|
+
"div",
|
|
947
|
+
{
|
|
948
|
+
ref,
|
|
949
|
+
"data-slot": "card-header",
|
|
950
|
+
className: cn(cardHeaderClass, className),
|
|
951
|
+
...props
|
|
952
|
+
}
|
|
953
|
+
);
|
|
954
|
+
}
|
|
955
|
+
);
|
|
956
|
+
var CardTitle = react.forwardRef(
|
|
957
|
+
function CardTitle2({ className, ...props }, ref) {
|
|
958
|
+
return /* @__PURE__ */ jsxRuntime.jsx("h3", { ref, "data-slot": "card-title", className: cn(cardTitleClass, className), ...props });
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
var CardDescription = react.forwardRef(function CardDescription2({ className, ...props }, ref) {
|
|
962
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
963
|
+
"p",
|
|
964
|
+
{
|
|
965
|
+
ref,
|
|
966
|
+
"data-slot": "card-description",
|
|
967
|
+
className: cn(cardDescriptionClass, className),
|
|
968
|
+
...props
|
|
969
|
+
}
|
|
970
|
+
);
|
|
971
|
+
});
|
|
972
|
+
var CardContent = react.forwardRef(
|
|
973
|
+
function CardContent2({ className, ...props }, ref) {
|
|
974
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
975
|
+
"div",
|
|
976
|
+
{
|
|
977
|
+
ref,
|
|
978
|
+
"data-slot": "card-content",
|
|
979
|
+
className: cn(cardContentClass, className),
|
|
980
|
+
...props
|
|
981
|
+
}
|
|
982
|
+
);
|
|
983
|
+
}
|
|
984
|
+
);
|
|
985
|
+
var CardFooter = react.forwardRef(
|
|
986
|
+
function CardFooter2({ className, ...props }, ref) {
|
|
987
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
988
|
+
"div",
|
|
989
|
+
{
|
|
990
|
+
ref,
|
|
991
|
+
"data-slot": "card-footer",
|
|
992
|
+
className: cn(cardFooterClass, className),
|
|
993
|
+
...props
|
|
994
|
+
}
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
);
|
|
956
998
|
var sizeClass2 = {
|
|
957
|
-
sm: "
|
|
958
|
-
md: "
|
|
999
|
+
sm: "size-3.5",
|
|
1000
|
+
md: "size-4"
|
|
959
1001
|
};
|
|
960
1002
|
var Checkbox = react.forwardRef(function Checkbox2({
|
|
961
1003
|
checked,
|
|
@@ -998,7 +1040,7 @@ var Checkbox = react.forwardRef(function Checkbox2({
|
|
|
998
1040
|
"indeterminate:border-primary indeterminate:bg-primary",
|
|
999
1041
|
"hover:border-ring",
|
|
1000
1042
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1001
|
-
"focus-visible:outline-none focus-visible:ring-
|
|
1043
|
+
"focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-primary-glow"
|
|
1002
1044
|
),
|
|
1003
1045
|
...rest
|
|
1004
1046
|
}
|
|
@@ -1008,7 +1050,7 @@ var Checkbox = react.forwardRef(function Checkbox2({
|
|
|
1008
1050
|
{
|
|
1009
1051
|
"aria-hidden": "true",
|
|
1010
1052
|
strokeWidth: 3,
|
|
1011
|
-
className: "pointer-events-none absolute inset-0 m-auto
|
|
1053
|
+
className: "pointer-events-none absolute inset-0 m-auto size-3 text-primary-foreground opacity-0 peer-checked:opacity-100 peer-indeterminate:opacity-0"
|
|
1012
1054
|
}
|
|
1013
1055
|
),
|
|
1014
1056
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1016,7 +1058,7 @@ var Checkbox = react.forwardRef(function Checkbox2({
|
|
|
1016
1058
|
{
|
|
1017
1059
|
"aria-hidden": "true",
|
|
1018
1060
|
strokeWidth: 3,
|
|
1019
|
-
className: "pointer-events-none absolute inset-0 m-auto
|
|
1061
|
+
className: "pointer-events-none absolute inset-0 m-auto size-3 text-primary-foreground opacity-0 peer-indeterminate:opacity-100"
|
|
1020
1062
|
}
|
|
1021
1063
|
)
|
|
1022
1064
|
] });
|
|
@@ -1033,20 +1075,20 @@ var datePickerTriggerSizeClass = {
|
|
|
1033
1075
|
md: "h-9 rounded-md ps-3 pe-9 text-sm gap-2",
|
|
1034
1076
|
lg: "h-11 rounded-md ps-4 pe-10 text-base gap-2"
|
|
1035
1077
|
};
|
|
1036
|
-
var datePickerTriggerBaseClass = "group/datepicker relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-visible:ring-
|
|
1078
|
+
var datePickerTriggerBaseClass = "group/datepicker relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-visible:ring-[3px] focus-visible:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer";
|
|
1037
1079
|
var datePickerPlaceholderClass = "truncate text-muted-foreground";
|
|
1038
1080
|
var datePickerValueClass = "truncate text-foreground";
|
|
1039
1081
|
var datePickerContentClass = "z-50 overflow-hidden rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
1040
1082
|
var datePickerCalendarClass = "text-sm";
|
|
1041
1083
|
var datePickerCaptionClass = "flex items-center justify-between gap-2 pb-2 text-sm font-semibold";
|
|
1042
|
-
var datePickerNavButtonClass = "inline-flex
|
|
1084
|
+
var datePickerNavButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-input bg-background text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50";
|
|
1043
1085
|
var datePickerDayWrapperClass = "p-0 text-center";
|
|
1044
|
-
var datePickerDayBaseClass = "inline-flex
|
|
1086
|
+
var datePickerDayBaseClass = "inline-flex size-8 items-center justify-center rounded-md text-sm text-foreground font-normal transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40";
|
|
1045
1087
|
var datePickerSelectedClass = "[&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary [&_button]:hover:text-primary-foreground";
|
|
1046
1088
|
var datePickerTodayClass = "[&_button]:font-semibold [&_button]:ring-1 [&_button]:ring-inset [&_button]:ring-ring/40";
|
|
1047
1089
|
var datePickerOutsideClass = "[&_button]:text-muted-foreground [&_button]:opacity-60";
|
|
1048
1090
|
var datePickerDisabledClass = "[&_button]:pointer-events-none [&_button]:opacity-40";
|
|
1049
|
-
var datePickerWeekdayClass = "
|
|
1091
|
+
var datePickerWeekdayClass = "size-8 text-center text-xs font-medium text-muted-foreground";
|
|
1050
1092
|
var datePickerWeekClass = "flex w-full";
|
|
1051
1093
|
var datePickerWeekdaysClass = "flex w-full";
|
|
1052
1094
|
var datePickerMonthGridClass = "w-full border-collapse";
|
|
@@ -1357,6 +1399,9 @@ var pageHeaderBorderedClass = "border-b border-border pb-4";
|
|
|
1357
1399
|
var pageHeaderTitleRowClass = "flex flex-wrap items-start justify-between gap-3 sm:gap-4";
|
|
1358
1400
|
var pageHeaderTitleBlockClass = "min-w-0 flex-1 space-y-1";
|
|
1359
1401
|
var pageHeaderTitleClass = "text-2xl font-semibold tracking-tight text-foreground";
|
|
1402
|
+
var pageHeaderEyebrowClass = "text-xs font-semibold uppercase tracking-wide text-primary";
|
|
1403
|
+
var pageHeaderTitleLineClass = "flex flex-wrap items-center gap-x-2.5 gap-y-1";
|
|
1404
|
+
var pageHeaderTitleMetaClass = "shrink-0";
|
|
1360
1405
|
var pageHeaderDescriptionClass = "text-sm text-muted-foreground";
|
|
1361
1406
|
var pageHeaderActionsClass = "flex shrink-0 flex-wrap items-center gap-2";
|
|
1362
1407
|
var pageHeaderBackClass = "inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-md";
|
|
@@ -1365,6 +1410,8 @@ var pageHeaderBreadcrumbsClass = "text-xs text-muted-foreground";
|
|
|
1365
1410
|
var PageHeader = react.forwardRef(function PageHeader2({
|
|
1366
1411
|
title,
|
|
1367
1412
|
description,
|
|
1413
|
+
eyebrow,
|
|
1414
|
+
titleMeta,
|
|
1368
1415
|
breadcrumbs,
|
|
1369
1416
|
back,
|
|
1370
1417
|
actions,
|
|
@@ -1385,11 +1432,15 @@ var PageHeader = react.forwardRef(function PageHeader2({
|
|
|
1385
1432
|
back ? /* @__PURE__ */ jsxRuntime.jsx(PageHeaderBack, { ...back }) : null,
|
|
1386
1433
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "page-header-row", className: pageHeaderTitleRowClass, children: [
|
|
1387
1434
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: pageHeaderTitleBlockClass, children: [
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1435
|
+
eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-slot": "page-header-eyebrow", className: pageHeaderEyebrowClass, children: eyebrow }) : null,
|
|
1436
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: pageHeaderTitleLineClass, children: [
|
|
1437
|
+
react.createElement(
|
|
1438
|
+
as,
|
|
1439
|
+
{ "data-slot": "page-header-title", className: pageHeaderTitleClass },
|
|
1440
|
+
title
|
|
1441
|
+
),
|
|
1442
|
+
titleMeta ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-slot": "page-header-title-meta", className: pageHeaderTitleMetaClass, children: titleMeta }) : null
|
|
1443
|
+
] }),
|
|
1393
1444
|
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-slot": "page-header-description", className: pageHeaderDescriptionClass, children: description }) : null
|
|
1394
1445
|
] }),
|
|
1395
1446
|
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "page-header-actions", className: pageHeaderActionsClass, children: actions }) : null
|
|
@@ -1421,7 +1472,7 @@ function PageHeaderBack({ label = "Back", to, onClick, render }) {
|
|
|
1421
1472
|
var detailPageBaseClass = "flex w-full flex-col gap-6";
|
|
1422
1473
|
var detailPageBodyClass = "flex flex-col gap-6";
|
|
1423
1474
|
var detailPageSkeletonRowClass = "h-5 w-full animate-pulse rounded-md bg-muted";
|
|
1424
|
-
var detailPageEmptyClass = "rounded-
|
|
1475
|
+
var detailPageEmptyClass = "rounded-xl border border-border bg-card";
|
|
1425
1476
|
var DEFAULT_LABELS_LTR = {
|
|
1426
1477
|
back: "Back",
|
|
1427
1478
|
notFoundTitle: "Not found",
|
|
@@ -2088,7 +2139,7 @@ var inputSizeClass = {
|
|
|
2088
2139
|
md: "h-9 rounded-md px-3 text-sm gap-2",
|
|
2089
2140
|
lg: "h-11 rounded-md px-4 text-base gap-2.5"
|
|
2090
2141
|
};
|
|
2091
|
-
var inputBaseClass = "group/input relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-
|
|
2142
|
+
var inputBaseClass = "group/input relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-[3px] focus-within:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-within:ring-destructive/40 has-[input:disabled]:pointer-events-none has-[input:disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0";
|
|
2092
2143
|
var Input = react.forwardRef(function Input2({
|
|
2093
2144
|
variant = "default",
|
|
2094
2145
|
inputSize = "md",
|
|
@@ -2122,7 +2173,7 @@ var Input = react.forwardRef(function Input2({
|
|
|
2122
2173
|
"span",
|
|
2123
2174
|
{
|
|
2124
2175
|
"aria-hidden": "true",
|
|
2125
|
-
className: "inline-flex
|
|
2176
|
+
className: "inline-flex size-4 items-center justify-center text-muted-foreground",
|
|
2126
2177
|
children: leadingIcon
|
|
2127
2178
|
}
|
|
2128
2179
|
) : null,
|
|
@@ -2146,7 +2197,7 @@ var Input = react.forwardRef(function Input2({
|
|
|
2146
2197
|
"span",
|
|
2147
2198
|
{
|
|
2148
2199
|
"aria-hidden": "true",
|
|
2149
|
-
className: "inline-flex
|
|
2200
|
+
className: "inline-flex size-4 items-center justify-center text-muted-foreground",
|
|
2150
2201
|
children: trailingIcon
|
|
2151
2202
|
}
|
|
2152
2203
|
) : null
|
|
@@ -2267,7 +2318,7 @@ function Pagination({
|
|
|
2267
2318
|
disabled: isFirst,
|
|
2268
2319
|
onClick: goPrev,
|
|
2269
2320
|
"aria-label": labels.previousPage,
|
|
2270
|
-
children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "
|
|
2321
|
+
children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "size-3.5" })
|
|
2271
2322
|
}
|
|
2272
2323
|
),
|
|
2273
2324
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-1 text-foreground", children: [
|
|
@@ -2284,7 +2335,7 @@ function Pagination({
|
|
|
2284
2335
|
disabled: isLast,
|
|
2285
2336
|
onClick: goNext,
|
|
2286
2337
|
"aria-label": labels.nextPage,
|
|
2287
|
-
children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "
|
|
2338
|
+
children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "size-3.5" })
|
|
2288
2339
|
}
|
|
2289
2340
|
)
|
|
2290
2341
|
] })
|
|
@@ -2313,23 +2364,23 @@ function Toolbar({ count, onClear, renderLabel, clearLabel, children }) {
|
|
|
2313
2364
|
var tableSizeClass = {
|
|
2314
2365
|
sm: {
|
|
2315
2366
|
row: "",
|
|
2316
|
-
cell: "px-3 py-1.5 text-xs",
|
|
2367
|
+
cell: "px-3 py-1.5 text-xs tabular-nums",
|
|
2317
2368
|
head: "whitespace-nowrap px-3 py-2 text-xs font-medium"
|
|
2318
2369
|
},
|
|
2319
2370
|
md: {
|
|
2320
2371
|
row: "",
|
|
2321
|
-
cell: "px-4 py-2.5 text-sm",
|
|
2372
|
+
cell: "px-4 py-2.5 text-sm tabular-nums",
|
|
2322
2373
|
head: "whitespace-nowrap px-4 py-2.5 text-xs font-medium uppercase tracking-wide"
|
|
2323
2374
|
},
|
|
2324
2375
|
lg: {
|
|
2325
2376
|
row: "",
|
|
2326
|
-
cell: "px-5 py-3.5 text-sm",
|
|
2377
|
+
cell: "px-5 py-3.5 text-sm tabular-nums",
|
|
2327
2378
|
head: "whitespace-nowrap px-5 py-3 text-sm font-medium"
|
|
2328
2379
|
}
|
|
2329
2380
|
};
|
|
2330
2381
|
var tableBaseClass = "w-full caption-bottom border-collapse";
|
|
2331
|
-
var selectedRowClass = "bg-
|
|
2332
|
-
var sortIconClass = "inline-flex
|
|
2382
|
+
var selectedRowClass = "bg-primary/10";
|
|
2383
|
+
var sortIconClass = "inline-flex size-3 shrink-0 items-center justify-center";
|
|
2333
2384
|
var alignClass = {
|
|
2334
2385
|
start: "text-start",
|
|
2335
2386
|
center: "text-center",
|
|
@@ -2456,7 +2507,7 @@ function Table(props) {
|
|
|
2456
2507
|
"div",
|
|
2457
2508
|
{
|
|
2458
2509
|
className: cn(
|
|
2459
|
-
"overflow-x-auto rounded-
|
|
2510
|
+
"overflow-x-auto rounded-xl border border-border bg-card shadow-[var(--shadow-card)]",
|
|
2460
2511
|
maxHeight !== void 0 && "overflow-y-auto"
|
|
2461
2512
|
),
|
|
2462
2513
|
style: maxHeight !== void 0 ? { maxHeight } : void 0,
|
|
@@ -2474,9 +2525,11 @@ function Table(props) {
|
|
|
2474
2525
|
"thead",
|
|
2475
2526
|
{
|
|
2476
2527
|
className: cn(
|
|
2477
|
-
//
|
|
2478
|
-
// scrolling underneath it
|
|
2479
|
-
|
|
2528
|
+
// Clean opaque header (so a sticky header fully hides the rows
|
|
2529
|
+
// scrolling underneath it) with a hairline bottom rule drawn via an
|
|
2530
|
+
// inset shadow — it stays attached to the sticky header instead of
|
|
2531
|
+
// collapsing into the first row's border.
|
|
2532
|
+
"bg-card text-muted-foreground shadow-[inset_0_-1px_0_var(--color-border)]",
|
|
2480
2533
|
maxHeight !== void 0 && "sticky top-0 z-10"
|
|
2481
2534
|
),
|
|
2482
2535
|
children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -2553,8 +2606,8 @@ function Table(props) {
|
|
|
2553
2606
|
"data-selected": isSelected ? "true" : void 0,
|
|
2554
2607
|
"aria-selected": enableRowSelection ? isSelected : void 0,
|
|
2555
2608
|
className: cn(
|
|
2556
|
-
"border-t border-border transition-colors",
|
|
2557
|
-
"hover:bg-
|
|
2609
|
+
"border-t border-border/60 first:border-t-0 transition-colors",
|
|
2610
|
+
"hover:bg-primary/5",
|
|
2558
2611
|
striped && rowIndex % 2 === 1 && "bg-muted/20",
|
|
2559
2612
|
isSelected && selectedRowClass,
|
|
2560
2613
|
onRowClick && "cursor-pointer"
|
|
@@ -2637,10 +2690,7 @@ function SkeletonRows({ rowCount, columnCount, cellClassName }) {
|
|
|
2637
2690
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: rowKeys.map((rowKey) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "border-t border-border", "data-testid": "table-skeleton-row", children: colKeys.map((colKey) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: cellClassName, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block h-3 w-full animate-pulse rounded bg-muted" }) }, `${rowKey}-${colKey}`)) }, rowKey)) });
|
|
2638
2691
|
}
|
|
2639
2692
|
function SortIndicator({ active, direction }) {
|
|
2640
|
-
const className = cn(
|
|
2641
|
-
"h-3.5 w-3.5 shrink-0",
|
|
2642
|
-
active ? "text-foreground" : "text-muted-foreground"
|
|
2643
|
-
);
|
|
2693
|
+
const className = cn("size-3.5 shrink-0", active ? "text-foreground" : "text-muted-foreground");
|
|
2644
2694
|
if (!active) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { "aria-hidden": "true", className });
|
|
2645
2695
|
return direction === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { "aria-hidden": "true", className }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": "true", className });
|
|
2646
2696
|
}
|
|
@@ -2656,11 +2706,11 @@ var selectSizeClass = {
|
|
|
2656
2706
|
md: "h-9 rounded-md ps-3 pe-9 text-sm",
|
|
2657
2707
|
lg: "h-11 rounded-md ps-4 pe-10 text-base"
|
|
2658
2708
|
};
|
|
2659
|
-
var selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-
|
|
2709
|
+
var selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-[3px] focus:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
|
|
2660
2710
|
var selectContentClass = "z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
2661
2711
|
var selectViewportClass = "p-1";
|
|
2662
2712
|
var selectItemClass = "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 ps-8 pe-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
|
|
2663
|
-
var selectItemIndicatorClass = "absolute start-2 inline-flex
|
|
2713
|
+
var selectItemIndicatorClass = "absolute start-2 inline-flex size-3.5 items-center justify-center [&_svg]:h-3.5 [&_svg]:w-3.5";
|
|
2664
2714
|
var selectGroupLabelClass = "px-2 py-1.5 text-xs font-semibold text-muted-foreground";
|
|
2665
2715
|
var selectSeparatorClass = "-mx-1 my-1 h-px bg-border";
|
|
2666
2716
|
var selectStatusClass = "flex items-center justify-center gap-2 px-2 py-6 text-center text-sm text-muted-foreground";
|
|
@@ -3023,6 +3073,16 @@ function hasActiveFilters(filters, values) {
|
|
|
3023
3073
|
}
|
|
3024
3074
|
return false;
|
|
3025
3075
|
}
|
|
3076
|
+
function countActiveFilters(filters, values) {
|
|
3077
|
+
let count = 0;
|
|
3078
|
+
for (const filter of filters ?? []) {
|
|
3079
|
+
const current = values?.[filter.key];
|
|
3080
|
+
if (current === void 0) continue;
|
|
3081
|
+
const value = filter.type === "text" ? current.trim() : current;
|
|
3082
|
+
if (value !== filterDefaultValue(filter)) count += 1;
|
|
3083
|
+
}
|
|
3084
|
+
return count;
|
|
3085
|
+
}
|
|
3026
3086
|
function DebouncedFilterInput({
|
|
3027
3087
|
value,
|
|
3028
3088
|
onChange,
|
|
@@ -3087,7 +3147,6 @@ function ListPageFilterBar({
|
|
|
3087
3147
|
labels
|
|
3088
3148
|
}) {
|
|
3089
3149
|
const manual = mode === "manual";
|
|
3090
|
-
const active = hasActiveFilters(filters, values);
|
|
3091
3150
|
const appliedKey = JSON.stringify(values ?? {});
|
|
3092
3151
|
const [draft, setDraft] = react.useState(values ?? {});
|
|
3093
3152
|
react.useEffect(() => {
|
|
@@ -3118,8 +3177,11 @@ function ListPageFilterBar({
|
|
|
3118
3177
|
for (const filter of filters ?? []) {
|
|
3119
3178
|
onChange?.(filter.key, filterDefaultValue(filter));
|
|
3120
3179
|
}
|
|
3180
|
+
if (manual) setDraft({});
|
|
3121
3181
|
};
|
|
3122
|
-
|
|
3182
|
+
if (!filters || filters.length === 0) return null;
|
|
3183
|
+
const activeCount = countActiveFilters(filters, effectiveValues);
|
|
3184
|
+
const controls = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: filters.map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3123
3185
|
FilterControl,
|
|
3124
3186
|
{
|
|
3125
3187
|
filter,
|
|
@@ -3130,22 +3192,41 @@ function ListPageFilterBar({
|
|
|
3130
3192
|
},
|
|
3131
3193
|
filter.key
|
|
3132
3194
|
)) });
|
|
3133
|
-
const
|
|
3134
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3135
|
-
|
|
3136
|
-
|
|
3195
|
+
const header = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 border-b border-border bg-primary/5 px-4 py-3", children: [
|
|
3196
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-foreground", children: labels.title ?? "Filters" }),
|
|
3197
|
+
activeCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-xs font-semibold text-primary", children: [
|
|
3198
|
+
activeCount,
|
|
3199
|
+
" ",
|
|
3200
|
+
labels.activeLabel ?? "active"
|
|
3201
|
+
] }) : null,
|
|
3202
|
+
activeCount > 0 && !disabled ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "ms-auto", onClick: reset, children: [
|
|
3203
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
|
|
3204
|
+
labels.reset
|
|
3205
|
+
] }) : null
|
|
3206
|
+
] });
|
|
3207
|
+
const cardClass = "overflow-hidden rounded-xl border border-border bg-card";
|
|
3137
3208
|
if (manual) {
|
|
3138
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("form", { "data-slot": "list-page-filter-bar", className:
|
|
3139
|
-
|
|
3140
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
3141
|
-
|
|
3142
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3209
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("form", { "data-slot": "list-page-filter-bar", className: cardClass, onSubmit: apply, children: [
|
|
3210
|
+
header,
|
|
3211
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 p-4", children: [
|
|
3212
|
+
controls,
|
|
3213
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3214
|
+
Button,
|
|
3215
|
+
{
|
|
3216
|
+
type: "submit",
|
|
3217
|
+
size: "sm",
|
|
3218
|
+
leadingIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4" }),
|
|
3219
|
+
className: "min-w-32",
|
|
3220
|
+
disabled: disabled || !dirty,
|
|
3221
|
+
children: labels.apply ?? "Apply"
|
|
3222
|
+
}
|
|
3223
|
+
) })
|
|
3143
3224
|
] })
|
|
3144
3225
|
] });
|
|
3145
3226
|
}
|
|
3146
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page-filter-bar", className:
|
|
3147
|
-
|
|
3148
|
-
|
|
3227
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page-filter-bar", className: cardClass, children: [
|
|
3228
|
+
header,
|
|
3229
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: controls })
|
|
3149
3230
|
] });
|
|
3150
3231
|
}
|
|
3151
3232
|
function FilterControl({ filter, value, onChange, disabled, mode }) {
|
|
@@ -3213,6 +3294,8 @@ function renderFilterControl({
|
|
|
3213
3294
|
var EN_LABELS2 = {
|
|
3214
3295
|
reset: "Reset filters",
|
|
3215
3296
|
apply: "Apply",
|
|
3297
|
+
filtersTitle: "Filters",
|
|
3298
|
+
filtersActive: "active",
|
|
3216
3299
|
emptyTitle: "No results",
|
|
3217
3300
|
emptyDescription: "Try clearing the search or adjusting the filters.",
|
|
3218
3301
|
noDataTitle: "No data yet",
|
|
@@ -3220,7 +3303,9 @@ var EN_LABELS2 = {
|
|
|
3220
3303
|
};
|
|
3221
3304
|
var AR_LABELS2 = {
|
|
3222
3305
|
reset: "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646 \u0627\u0644\u0641\u0644\u0627\u062A\u0631",
|
|
3223
|
-
apply: "\u062A\
|
|
3306
|
+
apply: "\u0639\u0631\u0636 \u0627\u0644\u0646\u062A\u0627\u0626\u062C",
|
|
3307
|
+
filtersTitle: "\u0627\u0644\u062A\u0635\u0641\u064A\u0629",
|
|
3308
|
+
filtersActive: "\u0645\u0641\u0639\u0651\u0644",
|
|
3224
3309
|
emptyTitle: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C",
|
|
3225
3310
|
emptyDescription: "\u062C\u0631\u0651\u0628 \u0645\u0633\u062D \u0627\u0644\u0628\u062D\u062B \u0623\u0648 \u062A\u0639\u062F\u064A\u0644 \u0627\u0644\u0641\u0644\u0627\u062A\u0631.",
|
|
3226
3311
|
noDataTitle: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0628\u064A\u0627\u0646\u0627\u062A \u0628\u0639\u062F",
|
|
@@ -3245,6 +3330,7 @@ function ListPage({
|
|
|
3245
3330
|
pagination,
|
|
3246
3331
|
onPaginationChange,
|
|
3247
3332
|
totalCount,
|
|
3333
|
+
eyebrow,
|
|
3248
3334
|
pageSizeOptions,
|
|
3249
3335
|
emptyState,
|
|
3250
3336
|
noDataState,
|
|
@@ -3265,7 +3351,17 @@ function ListPage({
|
|
|
3265
3351
|
};
|
|
3266
3352
|
const tableMode = isLoading ? "loading" : data.length === 0 && !hasActiveQuery ? "no-data" : data.length === 0 && hasActiveQuery ? "no-results" : "rows";
|
|
3267
3353
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page", className: cn("space-y-6", className), children: [
|
|
3268
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3354
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3355
|
+
PageHeader,
|
|
3356
|
+
{
|
|
3357
|
+
title,
|
|
3358
|
+
description,
|
|
3359
|
+
eyebrow,
|
|
3360
|
+
titleMeta: typeof totalCount === "number" && totalCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "primary", tone: "soft", size: "sm", children: totalCount }) : void 0,
|
|
3361
|
+
bordered,
|
|
3362
|
+
actions
|
|
3363
|
+
}
|
|
3364
|
+
),
|
|
3269
3365
|
showFilterBar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3270
3366
|
ListPageFilterBar,
|
|
3271
3367
|
{
|
|
@@ -3273,7 +3369,12 @@ function ListPage({
|
|
|
3273
3369
|
values: filterValues,
|
|
3274
3370
|
onChange: onFilterChange,
|
|
3275
3371
|
mode: filterMode,
|
|
3276
|
-
labels: {
|
|
3372
|
+
labels: {
|
|
3373
|
+
reset: labels.reset,
|
|
3374
|
+
apply: labels.apply,
|
|
3375
|
+
title: labels.filtersTitle,
|
|
3376
|
+
activeLabel: labels.filtersActive
|
|
3377
|
+
}
|
|
3277
3378
|
}
|
|
3278
3379
|
) : null,
|
|
3279
3380
|
tableMode === "loading" || tableMode === "rows" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3350,7 +3451,7 @@ var radioLabelSizeClass = {
|
|
|
3350
3451
|
md: "text-sm",
|
|
3351
3452
|
lg: "text-base"
|
|
3352
3453
|
};
|
|
3353
|
-
var radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-
|
|
3454
|
+
var radioItemBaseClass = "aspect-square shrink-0 rounded-full border border-input bg-background text-primary outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-primary-glow hover:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:ring-destructive/40 data-[state=checked]:border-primary";
|
|
3354
3455
|
var radioIndicatorBaseClass = "flex h-full w-full items-center justify-center";
|
|
3355
3456
|
var radioIndicatorDotClass = "rounded-full bg-primary";
|
|
3356
3457
|
var radioOptionRowClass = "flex cursor-pointer items-start gap-2 has-[button:disabled]:cursor-not-allowed";
|
|
@@ -3521,7 +3622,7 @@ var switchThumbClass = {
|
|
|
3521
3622
|
md: "size-4 data-[state=checked]:translate-x-4 data-[state=checked]:rtl:-translate-x-4",
|
|
3522
3623
|
lg: "size-5 data-[state=checked]:translate-x-5 data-[state=checked]:rtl:-translate-x-5"
|
|
3523
3624
|
};
|
|
3524
|
-
var switchTrackBaseClass = "relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors focus-visible:outline-none focus-visible:ring-
|
|
3625
|
+
var switchTrackBaseClass = "relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-primary-glow disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary aria-[invalid=true]:ring-[3px] aria-[invalid=true]:ring-destructive/40";
|
|
3525
3626
|
var switchThumbBaseClass = "pointer-events-none block rounded-full bg-background shadow-sm ring-0 transition-transform";
|
|
3526
3627
|
var Switch = react.forwardRef(function Switch2({
|
|
3527
3628
|
switchSize = "md",
|
|
@@ -3602,7 +3703,7 @@ var textareaResizeClass = {
|
|
|
3602
3703
|
horizontal: "resize-x",
|
|
3603
3704
|
both: "resize"
|
|
3604
3705
|
};
|
|
3605
|
-
var textareaBaseClass = "group/textarea relative flex w-full text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-
|
|
3706
|
+
var textareaBaseClass = "group/textarea relative flex w-full text-foreground outline-none transition-[background-color,border-color,box-shadow] focus-within:ring-[3px] focus-within:ring-primary-glow aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-within:ring-destructive/40 has-[textarea:disabled]:pointer-events-none has-[textarea:disabled]:opacity-50";
|
|
3606
3707
|
var Textarea = react.forwardRef(function Textarea2({
|
|
3607
3708
|
variant = "default",
|
|
3608
3709
|
textareaSize = "md",
|
|
@@ -3765,6 +3866,12 @@ exports.AppShell = AppShell;
|
|
|
3765
3866
|
exports.Avatar = Avatar;
|
|
3766
3867
|
exports.Badge = Badge;
|
|
3767
3868
|
exports.Button = Button;
|
|
3869
|
+
exports.Card = Card;
|
|
3870
|
+
exports.CardContent = CardContent;
|
|
3871
|
+
exports.CardDescription = CardDescription;
|
|
3872
|
+
exports.CardFooter = CardFooter;
|
|
3873
|
+
exports.CardHeader = CardHeader;
|
|
3874
|
+
exports.CardTitle = CardTitle;
|
|
3768
3875
|
exports.Checkbox = Checkbox;
|
|
3769
3876
|
exports.ConfirmDialogProvider = ConfirmDialogProvider;
|
|
3770
3877
|
exports.DashboardContent = DashboardContent;
|
|
@@ -3826,10 +3933,17 @@ exports.TooltipProvider = TooltipProvider;
|
|
|
3826
3933
|
exports.badgeBaseClass = badgeBaseClass;
|
|
3827
3934
|
exports.badgeDotSizeClass = badgeDotSizeClass;
|
|
3828
3935
|
exports.badgeSizeClass = badgeSizeClass;
|
|
3936
|
+
exports.badgeSoftVariantClass = badgeSoftVariantClass;
|
|
3829
3937
|
exports.badgeVariantClass = badgeVariantClass;
|
|
3830
3938
|
exports.buttonBaseClass = buttonBaseClass;
|
|
3831
3939
|
exports.buttonSizeClass = buttonSizeClass;
|
|
3832
3940
|
exports.buttonVariantClass = buttonVariantClass;
|
|
3941
|
+
exports.cardBaseClass = cardBaseClass;
|
|
3942
|
+
exports.cardContentClass = cardContentClass;
|
|
3943
|
+
exports.cardDescriptionClass = cardDescriptionClass;
|
|
3944
|
+
exports.cardFooterClass = cardFooterClass;
|
|
3945
|
+
exports.cardHeaderClass = cardHeaderClass;
|
|
3946
|
+
exports.cardTitleClass = cardTitleClass;
|
|
3833
3947
|
exports.cn = cn;
|
|
3834
3948
|
exports.datePickerCalendarClass = datePickerCalendarClass;
|
|
3835
3949
|
exports.datePickerCaptionClass = datePickerCaptionClass;
|
|
@@ -3910,8 +4024,11 @@ exports.pageHeaderBaseClass = pageHeaderBaseClass;
|
|
|
3910
4024
|
exports.pageHeaderBorderedClass = pageHeaderBorderedClass;
|
|
3911
4025
|
exports.pageHeaderBreadcrumbsClass = pageHeaderBreadcrumbsClass;
|
|
3912
4026
|
exports.pageHeaderDescriptionClass = pageHeaderDescriptionClass;
|
|
4027
|
+
exports.pageHeaderEyebrowClass = pageHeaderEyebrowClass;
|
|
3913
4028
|
exports.pageHeaderTitleBlockClass = pageHeaderTitleBlockClass;
|
|
3914
4029
|
exports.pageHeaderTitleClass = pageHeaderTitleClass;
|
|
4030
|
+
exports.pageHeaderTitleLineClass = pageHeaderTitleLineClass;
|
|
4031
|
+
exports.pageHeaderTitleMetaClass = pageHeaderTitleMetaClass;
|
|
3915
4032
|
exports.pageHeaderTitleRowClass = pageHeaderTitleRowClass;
|
|
3916
4033
|
exports.radioGroupBaseClass = radioGroupBaseClass;
|
|
3917
4034
|
exports.radioGroupOrientationClass = radioGroupOrientationClass;
|