@dimaan/ui 0.0.29 → 0.0.31
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 +227 -220
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +227 -220
- package/dist/index.js.map +1 -1
- package/dist/preset.css +23 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -344,7 +344,7 @@ function DashboardMain({ className, children, ...props }) {
|
|
|
344
344
|
// stretching the whole layout past 100%.
|
|
345
345
|
"flex min-h-screen min-w-0 flex-1 flex-col transition-[margin] duration-200 ease-out",
|
|
346
346
|
// On desktop, push the main column past the fixed sidebar using logical margin.
|
|
347
|
-
collapsed ? "lg:ms-
|
|
347
|
+
collapsed ? "lg:ms-0" : "lg:ms-(--sidebar-width)",
|
|
348
348
|
className
|
|
349
349
|
),
|
|
350
350
|
...props,
|
|
@@ -513,14 +513,16 @@ function Sidebar({ className, children, ...props }) {
|
|
|
513
513
|
"fixed inset-y-0 start-0 z-40 flex flex-col",
|
|
514
514
|
// Surface
|
|
515
515
|
"bg-sidebar text-sidebar-foreground border-e border-sidebar-border",
|
|
516
|
-
// Sizing — width
|
|
517
|
-
|
|
516
|
+
// Sizing — always full width; collapse hides it off-canvas (below).
|
|
517
|
+
"w-[var(--sidebar-width)]",
|
|
518
518
|
// Motion
|
|
519
|
-
"transition-
|
|
520
|
-
// Mobile slide
|
|
521
|
-
//
|
|
522
|
-
|
|
523
|
-
|
|
519
|
+
"transition-transform duration-200 ease-out",
|
|
520
|
+
// Mobile: slide in/out via mobileOpen. Logical translate (rtl variant)
|
|
521
|
+
// so it slides off the inline-start edge in both LTR and RTL.
|
|
522
|
+
mobileOpen ? "translate-x-0" : "-translate-x-full rtl:translate-x-full",
|
|
523
|
+
// Desktop: collapse fully hides the sidebar off-canvas; the header
|
|
524
|
+
// trigger slides it back in and the main content reclaims the width.
|
|
525
|
+
collapsed ? "lg:-translate-x-full lg:rtl:translate-x-full" : "lg:translate-x-0 lg:rtl:translate-x-0",
|
|
524
526
|
className
|
|
525
527
|
),
|
|
526
528
|
...props,
|
|
@@ -543,18 +545,8 @@ function SidebarFooter({ className, children, ...props }) {
|
|
|
543
545
|
);
|
|
544
546
|
}
|
|
545
547
|
function SidebarGroup({ label, className, children, ...props }) {
|
|
546
|
-
const { collapsed } = useDashboardLayout();
|
|
547
548
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 py-2", className), ...props, children: [
|
|
548
|
-
label ? /* @__PURE__ */ jsx(
|
|
549
|
-
"div",
|
|
550
|
-
{
|
|
551
|
-
className: cn(
|
|
552
|
-
"px-3 pb-1 text-xs font-medium uppercase tracking-wider text-muted-foreground transition-opacity",
|
|
553
|
-
collapsed && "pointer-events-none h-0 overflow-hidden opacity-0"
|
|
554
|
-
),
|
|
555
|
-
children: label
|
|
556
|
-
}
|
|
557
|
-
) : null,
|
|
549
|
+
label ? /* @__PURE__ */ jsx("div", { className: "px-3 pb-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: label }) : null,
|
|
558
550
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children })
|
|
559
551
|
] });
|
|
560
552
|
}
|
|
@@ -588,7 +580,6 @@ function SidebarNavGroup({
|
|
|
588
580
|
onClick,
|
|
589
581
|
...props
|
|
590
582
|
}) {
|
|
591
|
-
const { collapsed } = useDashboardLayout();
|
|
592
583
|
const submenuId = useId();
|
|
593
584
|
const [internalOpen, setInternalOpen] = useState(defaultOpen);
|
|
594
585
|
const isControlled = openProp !== void 0;
|
|
@@ -615,27 +606,23 @@ function SidebarNavGroup({
|
|
|
615
606
|
const isActive = active || hasActiveChild;
|
|
616
607
|
const prevHasActiveChild = useRef(false);
|
|
617
608
|
useEffect(() => {
|
|
618
|
-
if (hasActiveChild && !prevHasActiveChild.current
|
|
609
|
+
if (hasActiveChild && !prevHasActiveChild.current) {
|
|
619
610
|
setOpen(true);
|
|
620
611
|
}
|
|
621
612
|
prevHasActiveChild.current = hasActiveChild;
|
|
622
|
-
}, [hasActiveChild,
|
|
623
|
-
|
|
624
|
-
if (collapsed && open) setOpen(false);
|
|
625
|
-
}, [collapsed, open, setOpen]);
|
|
626
|
-
const titleAttr = collapsed && typeof label === "string" ? label : props.title ?? void 0;
|
|
627
|
-
const showChildren = !collapsed;
|
|
613
|
+
}, [hasActiveChild, setOpen]);
|
|
614
|
+
const titleAttr = props.title ?? void 0;
|
|
628
615
|
return /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col", children: [
|
|
629
616
|
/* @__PURE__ */ jsxs(
|
|
630
617
|
"button",
|
|
631
618
|
{
|
|
632
619
|
type: "button",
|
|
633
|
-
"aria-expanded":
|
|
634
|
-
"aria-controls":
|
|
620
|
+
"aria-expanded": open,
|
|
621
|
+
"aria-controls": submenuId,
|
|
635
622
|
"data-active": isActive ? "true" : void 0,
|
|
636
623
|
title: titleAttr,
|
|
637
624
|
onClick: (e) => {
|
|
638
|
-
|
|
625
|
+
setOpen(!open);
|
|
639
626
|
onClick?.(e);
|
|
640
627
|
},
|
|
641
628
|
className: cn(
|
|
@@ -643,7 +630,6 @@ function SidebarNavGroup({
|
|
|
643
630
|
"text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
644
631
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
|
|
645
632
|
isActive && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
646
|
-
collapsed && "justify-center px-0",
|
|
647
633
|
className
|
|
648
634
|
),
|
|
649
635
|
...props,
|
|
@@ -656,18 +642,9 @@ function SidebarNavGroup({
|
|
|
656
642
|
}
|
|
657
643
|
) : null,
|
|
658
644
|
icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "flex size-5 shrink-0 items-center justify-center", children: icon }) : null,
|
|
659
|
-
/* @__PURE__ */ jsx(
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
className: cn(
|
|
663
|
-
"flex-1 truncate text-start transition-[opacity,width]",
|
|
664
|
-
collapsed && "pointer-events-none w-0 opacity-0"
|
|
665
|
-
),
|
|
666
|
-
children: label
|
|
667
|
-
}
|
|
668
|
-
),
|
|
669
|
-
endSlot && !collapsed ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center", children: endSlot }) : null,
|
|
670
|
-
showChildren ? /* @__PURE__ */ jsx(ChevronCaret, { open }) : null
|
|
645
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-start", children: label }),
|
|
646
|
+
endSlot ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center", children: endSlot }) : null,
|
|
647
|
+
/* @__PURE__ */ jsx(ChevronCaret, { open })
|
|
671
648
|
]
|
|
672
649
|
}
|
|
673
650
|
),
|
|
@@ -675,10 +652,10 @@ function SidebarNavGroup({
|
|
|
675
652
|
"div",
|
|
676
653
|
{
|
|
677
654
|
id: submenuId,
|
|
678
|
-
hidden: !
|
|
655
|
+
hidden: !open,
|
|
679
656
|
className: cn(
|
|
680
657
|
"grid transition-[grid-template-rows] duration-200 ease-out",
|
|
681
|
-
|
|
658
|
+
open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
|
|
682
659
|
),
|
|
683
660
|
children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5 ps-7 pt-1", children: /* @__PURE__ */ jsx(SidebarNavGroupContext.Provider, { value: contextValue, children }) }) })
|
|
684
661
|
}
|
|
@@ -709,7 +686,6 @@ function SidebarNavItem({
|
|
|
709
686
|
end,
|
|
710
687
|
...props
|
|
711
688
|
}) {
|
|
712
|
-
const { collapsed } = useDashboardLayout();
|
|
713
689
|
const resolved = useResolvedPath(to);
|
|
714
690
|
const group = useContext(SidebarNavGroupContext);
|
|
715
691
|
const itemId = useId();
|
|
@@ -721,13 +697,12 @@ function SidebarNavItem({
|
|
|
721
697
|
return () => group.reportActive(itemId, false);
|
|
722
698
|
}, [group, itemId, isActive]);
|
|
723
699
|
const labelContent = label ?? children;
|
|
724
|
-
const titleAttr =
|
|
700
|
+
const titleAttr = props.title;
|
|
725
701
|
const getClassName = (active) => cn(
|
|
726
702
|
"group relative flex h-9 shrink-0 items-center gap-3 rounded-md px-3 text-sm font-medium outline-none transition-colors",
|
|
727
703
|
"text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
728
704
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
|
|
729
705
|
active && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
730
|
-
collapsed && "justify-center px-0",
|
|
731
706
|
className
|
|
732
707
|
);
|
|
733
708
|
const innerContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -739,17 +714,8 @@ function SidebarNavItem({
|
|
|
739
714
|
}
|
|
740
715
|
) : null,
|
|
741
716
|
icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "flex size-5 shrink-0 items-center justify-center", children: icon }) : null,
|
|
742
|
-
/* @__PURE__ */ jsx(
|
|
743
|
-
|
|
744
|
-
{
|
|
745
|
-
className: cn(
|
|
746
|
-
"flex-1 truncate text-start transition-[opacity,width]",
|
|
747
|
-
collapsed && "pointer-events-none w-0 opacity-0"
|
|
748
|
-
),
|
|
749
|
-
children: labelContent
|
|
750
|
-
}
|
|
751
|
-
),
|
|
752
|
-
endSlot && !collapsed ? /* @__PURE__ */ jsx("span", { className: "ms-auto flex shrink-0 items-center", children: endSlot }) : null
|
|
717
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-start", children: labelContent }),
|
|
718
|
+
endSlot ? /* @__PURE__ */ jsx("span", { className: "ms-auto flex shrink-0 items-center", children: endSlot }) : null
|
|
753
719
|
] });
|
|
754
720
|
if (render) {
|
|
755
721
|
return render({
|
|
@@ -911,7 +877,7 @@ var badgeDotSizeClass = {
|
|
|
911
877
|
md: "size-2"
|
|
912
878
|
};
|
|
913
879
|
var badgeBaseClass = "inline-flex shrink-0 items-center rounded-full border font-medium leading-none whitespace-nowrap select-none transition-colors";
|
|
914
|
-
var Badge = forwardRef(function Badge2({ variant = "default", size = "md", tone = "
|
|
880
|
+
var Badge = forwardRef(function Badge2({ variant = "default", size = "md", tone = "soft", dot = false, className, children, ...props }, ref) {
|
|
915
881
|
const variantClass = tone === "soft" ? badgeSoftVariantClass[variant] : badgeVariantClass[variant];
|
|
916
882
|
return /* @__PURE__ */ jsxs(
|
|
917
883
|
"span",
|
|
@@ -2327,9 +2293,9 @@ function Pagination({
|
|
|
2327
2293
|
children: isRtl ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true", className: "size-3.5" })
|
|
2328
2294
|
}
|
|
2329
2295
|
),
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
|
|
2332
|
-
"
|
|
2296
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex min-w-7 items-center justify-center rounded-lg bg-gradient-table px-2.5 py-0.5 text-xs font-semibold text-white", children: pageIndex + 1 }),
|
|
2297
|
+
/* @__PURE__ */ jsxs("span", { className: "px-0.5 text-muted-foreground", children: [
|
|
2298
|
+
"/ ",
|
|
2333
2299
|
pageCount
|
|
2334
2300
|
] }),
|
|
2335
2301
|
/* @__PURE__ */ jsx(
|
|
@@ -2354,7 +2320,7 @@ function Toolbar({ count, onClear, renderLabel, clearLabel, children }) {
|
|
|
2354
2320
|
{
|
|
2355
2321
|
role: "toolbar",
|
|
2356
2322
|
"aria-label": "Bulk actions",
|
|
2357
|
-
className: "flex flex-wrap items-center gap-3 rounded-
|
|
2323
|
+
className: "flex flex-wrap items-center gap-3 rounded-xl border border-border bg-muted/50 px-3.5 py-2.5 text-sm shadow-[var(--shadow-xs)]",
|
|
2358
2324
|
children: [
|
|
2359
2325
|
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: renderLabel ? renderLabel(count) : `${count} selected` }),
|
|
2360
2326
|
/* @__PURE__ */ jsxs("div", { className: "ms-auto flex flex-wrap items-center gap-2", children: [
|
|
@@ -2370,18 +2336,18 @@ function Toolbar({ count, onClear, renderLabel, clearLabel, children }) {
|
|
|
2370
2336
|
var tableSizeClass = {
|
|
2371
2337
|
sm: {
|
|
2372
2338
|
row: "",
|
|
2373
|
-
cell: "px-3 py-
|
|
2374
|
-
head: "whitespace-nowrap px-3 py-
|
|
2339
|
+
cell: "px-3 py-2 text-xs tabular-nums",
|
|
2340
|
+
head: "whitespace-nowrap px-3 py-3 text-[11px] font-semibold uppercase tracking-wider"
|
|
2375
2341
|
},
|
|
2376
2342
|
md: {
|
|
2377
2343
|
row: "",
|
|
2378
|
-
cell: "px-4 py-
|
|
2379
|
-
head: "whitespace-nowrap px-4 py-
|
|
2344
|
+
cell: "px-4 py-3.5 text-sm tabular-nums",
|
|
2345
|
+
head: "whitespace-nowrap px-4 py-4 text-xs font-semibold uppercase tracking-wider"
|
|
2380
2346
|
},
|
|
2381
2347
|
lg: {
|
|
2382
2348
|
row: "",
|
|
2383
|
-
cell: "px-
|
|
2384
|
-
head: "whitespace-nowrap px-
|
|
2349
|
+
cell: "px-6 py-4 text-sm tabular-nums",
|
|
2350
|
+
head: "whitespace-nowrap px-6 py-5 text-[13px] font-semibold uppercase tracking-wider"
|
|
2385
2351
|
}
|
|
2386
2352
|
};
|
|
2387
2353
|
var tableBaseClass = "w-full caption-bottom border-collapse";
|
|
@@ -2438,6 +2404,7 @@ function Table(props) {
|
|
|
2438
2404
|
maxHeight,
|
|
2439
2405
|
striped = false,
|
|
2440
2406
|
onRowClick,
|
|
2407
|
+
getRowAccent,
|
|
2441
2408
|
tableRef,
|
|
2442
2409
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
2443
2410
|
showPagination,
|
|
@@ -2509,166 +2476,198 @@ function Table(props) {
|
|
|
2509
2476
|
children: bulkActions(selectedRowsInData)
|
|
2510
2477
|
}
|
|
2511
2478
|
),
|
|
2512
|
-
/* @__PURE__ */
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
"
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
"bg-card text-muted-foreground shadow-[inset_0_-1px_0_var(--color-border)]",
|
|
2539
|
-
maxHeight !== void 0 && "sticky top-0 z-10"
|
|
2540
|
-
),
|
|
2541
|
-
children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2542
|
-
enableRowSelection ? /* @__PURE__ */ jsx("th", { scope: "col", className: cn("w-10", sizeClasses.head), children: /* @__PURE__ */ jsx(
|
|
2543
|
-
Checkbox,
|
|
2544
|
-
{
|
|
2545
|
-
"aria-label": "Select all rows on this page",
|
|
2546
|
-
checked: allOnPageSelected,
|
|
2547
|
-
indeterminate: someOnPageSelected,
|
|
2548
|
-
disabled: selectableRowIds.length === 0,
|
|
2549
|
-
onCheckedChange: toggleHeader
|
|
2550
|
-
}
|
|
2551
|
-
) }) : null,
|
|
2552
|
-
columns.map((column) => {
|
|
2553
|
-
const isSorted = effectiveSort.columnId === column.id;
|
|
2554
|
-
const ariaSort = isSorted ? effectiveSort.direction === "asc" ? "ascending" : "descending" : "none";
|
|
2555
|
-
return /* @__PURE__ */ jsx(
|
|
2556
|
-
"th",
|
|
2557
|
-
{
|
|
2558
|
-
scope: "col",
|
|
2559
|
-
"aria-sort": column.sortable ? ariaSort : void 0,
|
|
2560
|
-
className: cn(
|
|
2561
|
-
sizeClasses.head,
|
|
2562
|
-
alignClass[column.align ?? "start"],
|
|
2563
|
-
column.className
|
|
2564
|
-
),
|
|
2565
|
-
children: column.sortable ? /* @__PURE__ */ jsxs(
|
|
2566
|
-
"button",
|
|
2567
|
-
{
|
|
2568
|
-
type: "button",
|
|
2569
|
-
onClick: () => handleSortClick(column.id),
|
|
2570
|
-
className: "inline-flex items-center gap-1.5 font-inherit uppercase tracking-inherit text-inherit hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
2571
|
-
"aria-label": sortAriaLabel(column, effectiveSort),
|
|
2572
|
-
children: [
|
|
2573
|
-
/* @__PURE__ */ jsx("span", { children: renderHeader(column.header) }),
|
|
2574
|
-
/* @__PURE__ */ jsx(
|
|
2575
|
-
SortIndicator,
|
|
2576
|
-
{
|
|
2577
|
-
active: isSorted,
|
|
2578
|
-
direction: isSorted ? effectiveSort.direction : null
|
|
2579
|
-
}
|
|
2580
|
-
)
|
|
2581
|
-
]
|
|
2582
|
-
}
|
|
2583
|
-
) : renderHeader(column.header)
|
|
2584
|
-
},
|
|
2585
|
-
column.id
|
|
2586
|
-
);
|
|
2587
|
-
})
|
|
2588
|
-
] })
|
|
2589
|
-
}
|
|
2590
|
-
),
|
|
2591
|
-
/* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx(
|
|
2592
|
-
SkeletonRows,
|
|
2593
|
-
{
|
|
2594
|
-
rowCount: skeletonCount,
|
|
2595
|
-
columnCount: totalColumnCount,
|
|
2596
|
-
cellClassName: sizeClasses.cell
|
|
2597
|
-
}
|
|
2598
|
-
) : data.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
2599
|
-
"td",
|
|
2600
|
-
{
|
|
2601
|
-
colSpan: totalColumnCount,
|
|
2602
|
-
className: cn(sizeClasses.cell, "py-10 text-center text-muted-foreground"),
|
|
2603
|
-
children: emptyState ?? "No data"
|
|
2604
|
-
}
|
|
2605
|
-
) }) : data.map((row, rowIndex) => {
|
|
2606
|
-
const id = getRowId(row, rowIndex);
|
|
2607
|
-
const isSelected = selected.has(id);
|
|
2608
|
-
const rowSelectable = isRowSelectable ? isRowSelectable(row) : true;
|
|
2609
|
-
return /* @__PURE__ */ jsxs(
|
|
2610
|
-
"tr",
|
|
2479
|
+
/* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-xl border border-border bg-card shadow-[var(--shadow-card)]", children: [
|
|
2480
|
+
/* @__PURE__ */ jsx(
|
|
2481
|
+
"span",
|
|
2482
|
+
{
|
|
2483
|
+
"aria-hidden": "true",
|
|
2484
|
+
"data-testid": "table-accent",
|
|
2485
|
+
className: "pointer-events-none absolute inset-x-0 top-0 z-20 h-[3px] bg-gradient-table"
|
|
2486
|
+
}
|
|
2487
|
+
),
|
|
2488
|
+
/* @__PURE__ */ jsx(
|
|
2489
|
+
"div",
|
|
2490
|
+
{
|
|
2491
|
+
className: cn("overflow-x-auto", maxHeight !== void 0 && "overflow-y-auto"),
|
|
2492
|
+
style: maxHeight !== void 0 ? { maxHeight } : void 0,
|
|
2493
|
+
children: /* @__PURE__ */ jsxs(
|
|
2494
|
+
"table",
|
|
2495
|
+
{
|
|
2496
|
+
ref: tableRef,
|
|
2497
|
+
"aria-label": ariaLabel,
|
|
2498
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2499
|
+
"aria-rowcount": totalRowCount,
|
|
2500
|
+
className: cn(tableBaseClass, "text-sm text-foreground", tableClassName),
|
|
2501
|
+
children: [
|
|
2502
|
+
caption ? /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }) : null,
|
|
2503
|
+
/* @__PURE__ */ jsx(
|
|
2504
|
+
"thead",
|
|
2611
2505
|
{
|
|
2612
|
-
"data-selected": isSelected ? "true" : void 0,
|
|
2613
|
-
"aria-selected": enableRowSelection ? isSelected : void 0,
|
|
2614
2506
|
className: cn(
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2507
|
+
// Clean opaque header (so a sticky header fully hides the rows
|
|
2508
|
+
// scrolling underneath it) with a hairline bottom rule drawn via an
|
|
2509
|
+
// inset shadow — it stays attached to the sticky header instead of
|
|
2510
|
+
// collapsing into the first row's border.
|
|
2511
|
+
// Opaque header background so a sticky header fully hides the rows
|
|
2512
|
+
// scrolling underneath it (a translucent tint would let them bleed through).
|
|
2513
|
+
"bg-muted text-muted-foreground shadow-[inset_0_-1px_0_var(--color-border)]",
|
|
2514
|
+
maxHeight !== void 0 && "sticky top-0 z-10"
|
|
2620
2515
|
),
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
enableRowSelection ? /* @__PURE__ */ jsx("td", { className: cn(sizeClasses.cell, "w-10"), children: /* @__PURE__ */ jsx(
|
|
2516
|
+
children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2517
|
+
enableRowSelection ? /* @__PURE__ */ jsx("th", { scope: "col", className: cn("w-10", sizeClasses.head), children: /* @__PURE__ */ jsx(
|
|
2624
2518
|
Checkbox,
|
|
2625
2519
|
{
|
|
2626
|
-
"aria-label":
|
|
2627
|
-
checked:
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2520
|
+
"aria-label": "Select all rows on this page",
|
|
2521
|
+
checked: allOnPageSelected,
|
|
2522
|
+
indeterminate: someOnPageSelected,
|
|
2523
|
+
disabled: selectableRowIds.length === 0,
|
|
2524
|
+
onCheckedChange: toggleHeader
|
|
2631
2525
|
}
|
|
2632
2526
|
) }) : null,
|
|
2633
|
-
columns.map((column) =>
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2527
|
+
columns.map((column) => {
|
|
2528
|
+
const isSorted = effectiveSort.columnId === column.id;
|
|
2529
|
+
const ariaSort = isSorted ? effectiveSort.direction === "asc" ? "ascending" : "descending" : "none";
|
|
2530
|
+
return /* @__PURE__ */ jsx(
|
|
2531
|
+
"th",
|
|
2532
|
+
{
|
|
2533
|
+
scope: "col",
|
|
2534
|
+
"aria-sort": column.sortable ? ariaSort : void 0,
|
|
2535
|
+
className: cn(
|
|
2536
|
+
sizeClasses.head,
|
|
2537
|
+
alignClass[column.align ?? "start"],
|
|
2538
|
+
column.className,
|
|
2539
|
+
isSorted && "text-primary"
|
|
2540
|
+
),
|
|
2541
|
+
children: column.sortable ? /* @__PURE__ */ jsxs(
|
|
2542
|
+
"button",
|
|
2543
|
+
{
|
|
2544
|
+
type: "button",
|
|
2545
|
+
onClick: () => handleSortClick(column.id),
|
|
2546
|
+
className: "inline-flex items-center gap-1.5 font-inherit uppercase tracking-inherit text-inherit hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
2547
|
+
"aria-label": sortAriaLabel(column, effectiveSort),
|
|
2548
|
+
children: [
|
|
2549
|
+
/* @__PURE__ */ jsx("span", { children: renderHeader(column.header) }),
|
|
2550
|
+
/* @__PURE__ */ jsx(
|
|
2551
|
+
SortIndicator,
|
|
2552
|
+
{
|
|
2553
|
+
active: isSorted,
|
|
2554
|
+
direction: isSorted ? effectiveSort.direction : null
|
|
2555
|
+
}
|
|
2556
|
+
)
|
|
2557
|
+
]
|
|
2558
|
+
}
|
|
2559
|
+
) : renderHeader(column.header)
|
|
2560
|
+
},
|
|
2561
|
+
column.id
|
|
2562
|
+
);
|
|
2563
|
+
})
|
|
2564
|
+
] })
|
|
2565
|
+
}
|
|
2566
|
+
),
|
|
2567
|
+
/* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx(
|
|
2568
|
+
SkeletonRows,
|
|
2569
|
+
{
|
|
2570
|
+
rowCount: skeletonCount,
|
|
2571
|
+
columnCount: totalColumnCount,
|
|
2572
|
+
cellClassName: sizeClasses.cell
|
|
2573
|
+
}
|
|
2574
|
+
) : data.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
2575
|
+
"td",
|
|
2576
|
+
{
|
|
2577
|
+
colSpan: totalColumnCount,
|
|
2578
|
+
className: cn(sizeClasses.cell, "py-10 text-center text-muted-foreground"),
|
|
2579
|
+
children: emptyState ?? "No data"
|
|
2580
|
+
}
|
|
2581
|
+
) }) : data.map((row, rowIndex) => {
|
|
2582
|
+
const id = getRowId(row, rowIndex);
|
|
2583
|
+
const isSelected = selected.has(id);
|
|
2584
|
+
const rowSelectable = isRowSelectable ? isRowSelectable(row) : true;
|
|
2585
|
+
const accent = getRowAccent?.(row, rowIndex);
|
|
2586
|
+
return /* @__PURE__ */ jsxs(
|
|
2587
|
+
"tr",
|
|
2588
|
+
{
|
|
2589
|
+
"data-selected": isSelected ? "true" : void 0,
|
|
2590
|
+
"aria-selected": enableRowSelection ? isSelected : void 0,
|
|
2591
|
+
className: cn(
|
|
2592
|
+
"border-b border-border/60 last:border-b-0 transition-colors",
|
|
2593
|
+
"hover:bg-muted/60",
|
|
2594
|
+
striped && rowIndex % 2 === 1 && "bg-muted/20",
|
|
2595
|
+
isSelected && selectedRowClass,
|
|
2596
|
+
onRowClick && "cursor-pointer"
|
|
2597
|
+
),
|
|
2598
|
+
onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
|
|
2599
|
+
children: [
|
|
2600
|
+
enableRowSelection ? /* @__PURE__ */ jsxs("td", { className: cn(sizeClasses.cell, "relative w-10"), children: [
|
|
2601
|
+
accent ? /* @__PURE__ */ jsx(RowAccent, { color: accent }) : null,
|
|
2602
|
+
/* @__PURE__ */ jsx(
|
|
2603
|
+
Checkbox,
|
|
2604
|
+
{
|
|
2605
|
+
"aria-label": `Select row ${rowIndex + 1}`,
|
|
2606
|
+
checked: isSelected,
|
|
2607
|
+
disabled: !rowSelectable,
|
|
2608
|
+
onCheckedChange: (next) => toggleRow(id, next),
|
|
2609
|
+
onClick: stopRowClickPropagation
|
|
2610
|
+
}
|
|
2611
|
+
)
|
|
2612
|
+
] }) : null,
|
|
2613
|
+
columns.map((column, colIndex) => {
|
|
2614
|
+
const isFirst = colIndex === 0 && !enableRowSelection;
|
|
2615
|
+
return /* @__PURE__ */ jsxs(
|
|
2616
|
+
"td",
|
|
2617
|
+
{
|
|
2618
|
+
className: cn(
|
|
2619
|
+
sizeClasses.cell,
|
|
2620
|
+
alignClass[column.align ?? "start"],
|
|
2621
|
+
column.className,
|
|
2622
|
+
isFirst && "relative"
|
|
2623
|
+
),
|
|
2624
|
+
children: [
|
|
2625
|
+
isFirst && accent ? /* @__PURE__ */ jsx(RowAccent, { color: accent }) : null,
|
|
2626
|
+
renderCell(column, row, rowIndex)
|
|
2627
|
+
]
|
|
2628
|
+
},
|
|
2629
|
+
column.id
|
|
2630
|
+
);
|
|
2631
|
+
})
|
|
2632
|
+
]
|
|
2633
|
+
},
|
|
2634
|
+
id
|
|
2635
|
+
);
|
|
2636
|
+
}) })
|
|
2637
|
+
]
|
|
2638
|
+
}
|
|
2639
|
+
)
|
|
2640
|
+
}
|
|
2641
|
+
),
|
|
2642
|
+
paginationVisible ? /* @__PURE__ */ jsx("div", { className: "border-t border-border px-4 py-3", children: /* @__PURE__ */ jsx(
|
|
2643
|
+
Pagination,
|
|
2644
|
+
{
|
|
2645
|
+
pageIndex,
|
|
2646
|
+
pageSize,
|
|
2647
|
+
pageCount,
|
|
2648
|
+
totalRowCount,
|
|
2649
|
+
pageSizeOptions,
|
|
2650
|
+
onChange: handlePaginationChange,
|
|
2651
|
+
labels
|
|
2652
|
+
}
|
|
2653
|
+
) }) : null
|
|
2654
|
+
] })
|
|
2667
2655
|
] });
|
|
2668
2656
|
}
|
|
2669
2657
|
function renderHeader(header) {
|
|
2670
2658
|
return typeof header === "function" ? header() : header;
|
|
2671
2659
|
}
|
|
2660
|
+
function RowAccent({ color }) {
|
|
2661
|
+
return /* @__PURE__ */ jsx(
|
|
2662
|
+
"span",
|
|
2663
|
+
{
|
|
2664
|
+
"aria-hidden": "true",
|
|
2665
|
+
"data-testid": "row-accent",
|
|
2666
|
+
className: "pointer-events-none absolute inset-y-1 start-0 w-[3px] rounded-full",
|
|
2667
|
+
style: { background: color }
|
|
2668
|
+
}
|
|
2669
|
+
);
|
|
2670
|
+
}
|
|
2672
2671
|
function renderCell(column, row, rowIndex) {
|
|
2673
2672
|
if (column.render) return column.render(row, rowIndex);
|
|
2674
2673
|
if (column.accessor !== void 0) {
|
|
@@ -2693,10 +2692,18 @@ function stopRowClickPropagation(event) {
|
|
|
2693
2692
|
function SkeletonRows({ rowCount, columnCount, cellClassName }) {
|
|
2694
2693
|
const rowKeys = Array.from({ length: Math.max(0, rowCount) }, (_, i) => `skeleton-row-${i}`);
|
|
2695
2694
|
const colKeys = Array.from({ length: Math.max(1, columnCount) }, (_, i) => `skeleton-col-${i}`);
|
|
2696
|
-
return /* @__PURE__ */ jsx(Fragment, { children: rowKeys.map((rowKey) => /* @__PURE__ */ jsx(
|
|
2695
|
+
return /* @__PURE__ */ jsx(Fragment, { children: rowKeys.map((rowKey) => /* @__PURE__ */ jsx(
|
|
2696
|
+
"tr",
|
|
2697
|
+
{
|
|
2698
|
+
className: "border-b border-border/60 last:border-b-0",
|
|
2699
|
+
"data-testid": "table-skeleton-row",
|
|
2700
|
+
children: colKeys.map((colKey) => /* @__PURE__ */ jsx("td", { className: cellClassName, children: /* @__PURE__ */ jsx("span", { className: "block h-3 w-full animate-pulse rounded bg-muted" }) }, `${rowKey}-${colKey}`))
|
|
2701
|
+
},
|
|
2702
|
+
rowKey
|
|
2703
|
+
)) });
|
|
2697
2704
|
}
|
|
2698
2705
|
function SortIndicator({ active, direction }) {
|
|
2699
|
-
const className = cn("size-3.5 shrink-0", active ? "text-
|
|
2706
|
+
const className = cn("size-3.5 shrink-0", active ? "text-primary" : "text-muted-foreground");
|
|
2700
2707
|
if (!active) return /* @__PURE__ */ jsx(ChevronsUpDown, { "aria-hidden": "true", className });
|
|
2701
2708
|
return direction === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { "aria-hidden": "true", className }) : /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true", className });
|
|
2702
2709
|
}
|