@payglocal_ui/flux-ui 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +43 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +43 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/data-table.tsx +92 -34
package/dist/index.d.cts
CHANGED
|
@@ -777,10 +777,31 @@ interface DataTableProps<T> {
|
|
|
777
777
|
label: string;
|
|
778
778
|
onClick?: (row: T) => void;
|
|
779
779
|
};
|
|
780
|
+
/**
|
|
781
|
+
* Custom action revealed on row hover — typically a `<Button>` or
|
|
782
|
+
* `<ButtonGroup>`, but any `ReactNode` is accepted. Pass a **function** to
|
|
783
|
+
* render per-row: it receives `(row, index)`, so the action always has the
|
|
784
|
+
* record for its row (e.g. to navigate or open a drawer for that row).
|
|
785
|
+
*
|
|
786
|
+
* It is not a real column: it floats as an overlay **pinned to the right edge
|
|
787
|
+
* of the viewport**, so it stays in view as the table scrolls horizontally
|
|
788
|
+
* (no scrolling to the end to reach it) while the last data column stays
|
|
789
|
+
* flush with nothing trailing it. Takes precedence over `rowCta`.
|
|
790
|
+
*/
|
|
791
|
+
rowAction?: ReactNode | ((row: T, index: number) => ReactNode);
|
|
780
792
|
/** Row / cell vertical rhythm and horizontal gutters */
|
|
781
793
|
density?: DataTableDensity;
|
|
782
|
-
/**
|
|
783
|
-
|
|
794
|
+
/**
|
|
795
|
+
* Column-sizing strategy:
|
|
796
|
+
* - `fixed` — widths come only from `colgroup` hints (`width`/`minWidth`/
|
|
797
|
+
* `maxWidth`); content is ignored and overflow is clipped. Table fills 100%.
|
|
798
|
+
* - `auto` — columns size to content but the table still fills 100%, so any
|
|
799
|
+
* leftover space is distributed into the columns (they stretch).
|
|
800
|
+
* - `content` — columns size to their content's intrinsic width and the table
|
|
801
|
+
* shrinks to fit. Leftover space stays empty to the right of the last
|
|
802
|
+
* column; it scrolls horizontally only once content exceeds the container.
|
|
803
|
+
*/
|
|
804
|
+
tableLayout?: "auto" | "fixed" | "content";
|
|
784
805
|
theadClassName?: string;
|
|
785
806
|
headerStyle?: DataTableHeaderStyle;
|
|
786
807
|
/** Footer: paginated range vs simple `n items` */
|
|
@@ -793,7 +814,7 @@ interface DataTableProps<T> {
|
|
|
793
814
|
/** With `density="compact"`, use tighter cell gutters (`pl-1.5 pr-2.5` vs `px-3`). Footer keeps normal horizontal padding. */
|
|
794
815
|
snug?: boolean;
|
|
795
816
|
}
|
|
796
|
-
declare function DataTable<T>({ columns, data, isLoading, skeletonRows, emptyTitle, emptyDescription, pageSize, page: controlledPage, onPageChange, totalRows, className, rowKey, rowCta, density, tableLayout, theadClassName, headerStyle, footerSummary, footerCountLabels, snug, }: DataTableProps<T>): React$1.JSX.Element;
|
|
817
|
+
declare function DataTable<T>({ columns, data, isLoading, skeletonRows, emptyTitle, emptyDescription, pageSize, page: controlledPage, onPageChange, totalRows, className, rowKey, rowCta, rowAction, density, tableLayout, theadClassName, headerStyle, footerSummary, footerCountLabels, snug, }: DataTableProps<T>): React$1.JSX.Element;
|
|
797
818
|
|
|
798
819
|
interface EmptyStateProps {
|
|
799
820
|
icon?: LucideIcon;
|
package/dist/index.d.ts
CHANGED
|
@@ -777,10 +777,31 @@ interface DataTableProps<T> {
|
|
|
777
777
|
label: string;
|
|
778
778
|
onClick?: (row: T) => void;
|
|
779
779
|
};
|
|
780
|
+
/**
|
|
781
|
+
* Custom action revealed on row hover — typically a `<Button>` or
|
|
782
|
+
* `<ButtonGroup>`, but any `ReactNode` is accepted. Pass a **function** to
|
|
783
|
+
* render per-row: it receives `(row, index)`, so the action always has the
|
|
784
|
+
* record for its row (e.g. to navigate or open a drawer for that row).
|
|
785
|
+
*
|
|
786
|
+
* It is not a real column: it floats as an overlay **pinned to the right edge
|
|
787
|
+
* of the viewport**, so it stays in view as the table scrolls horizontally
|
|
788
|
+
* (no scrolling to the end to reach it) while the last data column stays
|
|
789
|
+
* flush with nothing trailing it. Takes precedence over `rowCta`.
|
|
790
|
+
*/
|
|
791
|
+
rowAction?: ReactNode | ((row: T, index: number) => ReactNode);
|
|
780
792
|
/** Row / cell vertical rhythm and horizontal gutters */
|
|
781
793
|
density?: DataTableDensity;
|
|
782
|
-
/**
|
|
783
|
-
|
|
794
|
+
/**
|
|
795
|
+
* Column-sizing strategy:
|
|
796
|
+
* - `fixed` — widths come only from `colgroup` hints (`width`/`minWidth`/
|
|
797
|
+
* `maxWidth`); content is ignored and overflow is clipped. Table fills 100%.
|
|
798
|
+
* - `auto` — columns size to content but the table still fills 100%, so any
|
|
799
|
+
* leftover space is distributed into the columns (they stretch).
|
|
800
|
+
* - `content` — columns size to their content's intrinsic width and the table
|
|
801
|
+
* shrinks to fit. Leftover space stays empty to the right of the last
|
|
802
|
+
* column; it scrolls horizontally only once content exceeds the container.
|
|
803
|
+
*/
|
|
804
|
+
tableLayout?: "auto" | "fixed" | "content";
|
|
784
805
|
theadClassName?: string;
|
|
785
806
|
headerStyle?: DataTableHeaderStyle;
|
|
786
807
|
/** Footer: paginated range vs simple `n items` */
|
|
@@ -793,7 +814,7 @@ interface DataTableProps<T> {
|
|
|
793
814
|
/** With `density="compact"`, use tighter cell gutters (`pl-1.5 pr-2.5` vs `px-3`). Footer keeps normal horizontal padding. */
|
|
794
815
|
snug?: boolean;
|
|
795
816
|
}
|
|
796
|
-
declare function DataTable<T>({ columns, data, isLoading, skeletonRows, emptyTitle, emptyDescription, pageSize, page: controlledPage, onPageChange, totalRows, className, rowKey, rowCta, density, tableLayout, theadClassName, headerStyle, footerSummary, footerCountLabels, snug, }: DataTableProps<T>): React$1.JSX.Element;
|
|
817
|
+
declare function DataTable<T>({ columns, data, isLoading, skeletonRows, emptyTitle, emptyDescription, pageSize, page: controlledPage, onPageChange, totalRows, className, rowKey, rowCta, rowAction, density, tableLayout, theadClassName, headerStyle, footerSummary, footerCountLabels, snug, }: DataTableProps<T>): React$1.JSX.Element;
|
|
797
818
|
|
|
798
819
|
interface EmptyStateProps {
|
|
799
820
|
icon?: LucideIcon;
|
package/dist/index.js
CHANGED
|
@@ -3605,6 +3605,7 @@ function DataTable({
|
|
|
3605
3605
|
className,
|
|
3606
3606
|
rowKey,
|
|
3607
3607
|
rowCta,
|
|
3608
|
+
rowAction,
|
|
3608
3609
|
density = "default",
|
|
3609
3610
|
tableLayout = "fixed",
|
|
3610
3611
|
theadClassName,
|
|
@@ -3617,6 +3618,8 @@ function DataTable({
|
|
|
3617
3618
|
const [internalPage, setInternalPage] = useState6(1);
|
|
3618
3619
|
const page = isControlled ? controlledPage : internalPage;
|
|
3619
3620
|
const setPage = isControlled ? (p) => onPageChange?.(p) : (p) => setInternalPage(p);
|
|
3621
|
+
const hasAction = rowAction != null || rowCta != null;
|
|
3622
|
+
const hasSpacer = tableLayout === "content";
|
|
3620
3623
|
const total = totalRows ?? data.length;
|
|
3621
3624
|
const totalPages = Math.ceil(total / pageSize);
|
|
3622
3625
|
const paginated = isControlled ? data : data.slice((page - 1) * pageSize, page * pageSize);
|
|
@@ -3634,7 +3637,7 @@ function DataTable({
|
|
|
3634
3637
|
const headPad = comfortable ? "px-5 py-4" : compactCellPad;
|
|
3635
3638
|
const footerPad = comfortable ? "px-5 py-4" : compact ? "px-4 py-2.5" : "px-4 py-3.5";
|
|
3636
3639
|
const headText = comfortable ? "text-[12px] font-medium text-muted-foreground tracking-normal" : compact ? "text-[11px] font-semibold text-muted-foreground" : "text-[11px] font-semibold text-foreground/75 dark:text-foreground/85";
|
|
3637
|
-
const
|
|
3640
|
+
const actionGutter = comfortable ? 20 : compact ? 12 : 16;
|
|
3638
3641
|
return /* @__PURE__ */ jsxs30(
|
|
3639
3642
|
"div",
|
|
3640
3643
|
{
|
|
@@ -3657,7 +3660,13 @@ function DataTable({
|
|
|
3657
3660
|
"table",
|
|
3658
3661
|
{
|
|
3659
3662
|
className: cn(tableLayout === "auto" && "min-w-[920px]"),
|
|
3660
|
-
style: {
|
|
3663
|
+
style: {
|
|
3664
|
+
// `content` uses the automatic algorithm but stays 100% wide; a
|
|
3665
|
+
// greedy spacer column (below) soaks up the slack so the data
|
|
3666
|
+
// columns collapse to their content width while the table fills.
|
|
3667
|
+
tableLayout: tableLayout === "fixed" ? "fixed" : "auto",
|
|
3668
|
+
width: "100%"
|
|
3669
|
+
},
|
|
3661
3670
|
children: [
|
|
3662
3671
|
tableLayout === "fixed" && /* @__PURE__ */ jsxs30("colgroup", { children: [
|
|
3663
3672
|
columns.map((col) => /* @__PURE__ */ jsx49(
|
|
@@ -3671,7 +3680,7 @@ function DataTable({
|
|
|
3671
3680
|
},
|
|
3672
3681
|
col.key
|
|
3673
3682
|
)),
|
|
3674
|
-
|
|
3683
|
+
hasAction ? /* @__PURE__ */ jsx49("col", { style: { width: 0 } }) : null
|
|
3675
3684
|
] }),
|
|
3676
3685
|
/* @__PURE__ */ jsx49(
|
|
3677
3686
|
"thead",
|
|
@@ -3703,7 +3712,8 @@ function DataTable({
|
|
|
3703
3712
|
},
|
|
3704
3713
|
col.key
|
|
3705
3714
|
)),
|
|
3706
|
-
|
|
3715
|
+
hasSpacer ? /* @__PURE__ */ jsx49("th", { className: "w-full p-0", "aria-hidden": true }) : null,
|
|
3716
|
+
hasAction ? /* @__PURE__ */ jsx49("th", { className: "sticky right-0 z-[1] w-0 p-0", "aria-hidden": true }) : null
|
|
3707
3717
|
]
|
|
3708
3718
|
}
|
|
3709
3719
|
)
|
|
@@ -3712,12 +3722,12 @@ function DataTable({
|
|
|
3712
3722
|
/* @__PURE__ */ jsx49("tbody", { children: isLoading ? Array.from({ length: skeletonRows }).map((_, i) => /* @__PURE__ */ jsx49(
|
|
3713
3723
|
TableRowSkeleton,
|
|
3714
3724
|
{
|
|
3715
|
-
cols: columns.length
|
|
3725
|
+
cols: columns.length,
|
|
3716
3726
|
density,
|
|
3717
3727
|
snug
|
|
3718
3728
|
},
|
|
3719
3729
|
i
|
|
3720
|
-
)) : paginated.length === 0 ? /* @__PURE__ */ jsx49("tr", { children: /* @__PURE__ */ jsx49("td", { colSpan: columns.length + (
|
|
3730
|
+
)) : paginated.length === 0 ? /* @__PURE__ */ jsx49("tr", { children: /* @__PURE__ */ jsx49("td", { colSpan: columns.length + (hasSpacer ? 1 : 0) + (hasAction ? 1 : 0), children: /* @__PURE__ */ jsx49(EmptyState, { title: emptyTitle, description: emptyDescription }) }) }) : paginated.map((row, i) => /* @__PURE__ */ jsxs30(
|
|
3721
3731
|
"tr",
|
|
3722
3732
|
{
|
|
3723
3733
|
className: cn(
|
|
@@ -3725,7 +3735,7 @@ function DataTable({
|
|
|
3725
3735
|
comfortable && "min-h-[56px]",
|
|
3726
3736
|
compact && "min-h-[44px]",
|
|
3727
3737
|
"hover:bg-muted/40 dark:hover:bg-muted/25",
|
|
3728
|
-
|
|
3738
|
+
hasAction && "hover:shadow-[0_1px_0_rgba(0,0,0,0.04)] dark:hover:shadow-none"
|
|
3729
3739
|
),
|
|
3730
3740
|
children: [
|
|
3731
3741
|
columns.map((col) => /* @__PURE__ */ jsx49(
|
|
@@ -3749,27 +3759,32 @@ function DataTable({
|
|
|
3749
3759
|
},
|
|
3750
3760
|
col.key
|
|
3751
3761
|
)),
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3762
|
+
hasSpacer ? /* @__PURE__ */ jsx49("td", { className: "p-0", "aria-hidden": true }) : null,
|
|
3763
|
+
hasAction ? (
|
|
3764
|
+
// Zero-width sticky cell pinned to the right edge of the
|
|
3765
|
+
// viewport. Its children are positioned absolutely so they
|
|
3766
|
+
// float over the row (out of the 0-width cell) — the action
|
|
3767
|
+
// stays in view while scrolling and nothing trails the last
|
|
3768
|
+
// data column. Everything is revealed on hover only.
|
|
3769
|
+
/* @__PURE__ */ jsx49("td", { className: "sticky right-0 z-[1] w-0 p-0 align-middle", children: /* @__PURE__ */ jsx49(
|
|
3770
|
+
"span",
|
|
3771
|
+
{
|
|
3772
|
+
className: "absolute top-1/2 -translate-y-1/2 z-[1] inline-flex items-center opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100",
|
|
3773
|
+
style: { right: actionGutter },
|
|
3774
|
+
children: rowAction != null ? typeof rowAction === "function" ? rowAction(row, i) : rowAction : /* @__PURE__ */ jsx49(
|
|
3775
|
+
"button",
|
|
3776
|
+
{
|
|
3777
|
+
type: "button",
|
|
3778
|
+
onClick: () => rowCta?.onClick?.(row),
|
|
3779
|
+
className: cn(
|
|
3780
|
+
"inline-flex items-center font-medium text-foreground bg-card rounded-lg border border-border hover:border-muted-foreground/50 whitespace-nowrap shadow-sm",
|
|
3781
|
+
compact ? "px-2.5 py-1 text-[11px]" : "px-3 py-1.5 text-[12px]"
|
|
3782
|
+
),
|
|
3783
|
+
children: rowCta?.label
|
|
3784
|
+
}
|
|
3785
|
+
)
|
|
3786
|
+
}
|
|
3787
|
+
) })
|
|
3773
3788
|
) : null
|
|
3774
3789
|
]
|
|
3775
3790
|
},
|