@underverse-ui/underverse 0.2.68 → 0.2.70
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 +224 -178
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +224 -178
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1702,6 +1702,10 @@ interface DataTableProps<T> {
|
|
|
1702
1702
|
className?: string;
|
|
1703
1703
|
/** Key để lưu pageSize vào localStorage. Nếu không cung cấp, pageSize sẽ không được persist */
|
|
1704
1704
|
storageKey?: string;
|
|
1705
|
+
/** Bật sticky header khi cuộn. Mặc định là false */
|
|
1706
|
+
stickyHeader?: boolean;
|
|
1707
|
+
/** Chiều cao tối đa của bảng khi bật stickyHeader (mặc định: 500px) */
|
|
1708
|
+
maxHeight?: number | string;
|
|
1705
1709
|
labels?: {
|
|
1706
1710
|
density?: string;
|
|
1707
1711
|
columns?: string;
|
|
@@ -1715,7 +1719,7 @@ interface DataTableProps<T> {
|
|
|
1715
1719
|
};
|
|
1716
1720
|
}
|
|
1717
1721
|
declare function DataTable<T extends Record<string, any>>({ columns, data, rowKey, loading, total, page, pageSize, pageSizeOptions, onQueryChange, caption, toolbar, enableColumnVisibilityToggle, enableDensityToggle, enableHeaderAlignToggle, striped, // Mặc định bật màu nền sẽn kẽ cho các dòng
|
|
1718
|
-
columnDividers, className, storageKey, labels, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1722
|
+
columnDividers, className, storageKey, stickyHeader, maxHeight, labels, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1719
1723
|
|
|
1720
1724
|
interface TableProps extends React__default.HTMLAttributes<HTMLTableElement> {
|
|
1721
1725
|
containerClassName?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1702,6 +1702,10 @@ interface DataTableProps<T> {
|
|
|
1702
1702
|
className?: string;
|
|
1703
1703
|
/** Key để lưu pageSize vào localStorage. Nếu không cung cấp, pageSize sẽ không được persist */
|
|
1704
1704
|
storageKey?: string;
|
|
1705
|
+
/** Bật sticky header khi cuộn. Mặc định là false */
|
|
1706
|
+
stickyHeader?: boolean;
|
|
1707
|
+
/** Chiều cao tối đa của bảng khi bật stickyHeader (mặc định: 500px) */
|
|
1708
|
+
maxHeight?: number | string;
|
|
1705
1709
|
labels?: {
|
|
1706
1710
|
density?: string;
|
|
1707
1711
|
columns?: string;
|
|
@@ -1715,7 +1719,7 @@ interface DataTableProps<T> {
|
|
|
1715
1719
|
};
|
|
1716
1720
|
}
|
|
1717
1721
|
declare function DataTable<T extends Record<string, any>>({ columns, data, rowKey, loading, total, page, pageSize, pageSizeOptions, onQueryChange, caption, toolbar, enableColumnVisibilityToggle, enableDensityToggle, enableHeaderAlignToggle, striped, // Mặc định bật màu nền sẽn kẽ cho các dòng
|
|
1718
|
-
columnDividers, className, storageKey, labels, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1722
|
+
columnDividers, className, storageKey, stickyHeader, maxHeight, labels, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1719
1723
|
|
|
1720
1724
|
interface TableProps extends React__default.HTMLAttributes<HTMLTableElement> {
|
|
1721
1725
|
containerClassName?: string;
|
package/dist/index.js
CHANGED
|
@@ -12838,7 +12838,7 @@ var Table = React47.forwardRef(({ className, containerClassName, ...props }, ref
|
|
|
12838
12838
|
}
|
|
12839
12839
|
));
|
|
12840
12840
|
Table.displayName = "Table";
|
|
12841
|
-
var TableHeader = React47.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ jsxs50("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border", "bg-muted
|
|
12841
|
+
var TableHeader = React47.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ jsxs50("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border", "bg-muted", className), ...props, children: [
|
|
12842
12842
|
children,
|
|
12843
12843
|
filterRow
|
|
12844
12844
|
] }));
|
|
@@ -12907,6 +12907,8 @@ function DataTable({
|
|
|
12907
12907
|
columnDividers = false,
|
|
12908
12908
|
className,
|
|
12909
12909
|
storageKey,
|
|
12910
|
+
stickyHeader = true,
|
|
12911
|
+
maxHeight = 500,
|
|
12910
12912
|
labels
|
|
12911
12913
|
}) {
|
|
12912
12914
|
const t = useTranslations("Common");
|
|
@@ -12970,6 +12972,12 @@ function DataTable({
|
|
|
12970
12972
|
const cellPadding = density === "compact" ? "py-1.5 px-3" : density === "comfortable" ? "py-3 px-4" : "py-2.5 px-4";
|
|
12971
12973
|
const visibleColsSet = React48.useMemo(() => new Set(visibleCols), [visibleCols]);
|
|
12972
12974
|
const visibleColumns = columns.filter((c) => visibleColsSet.has(c.key));
|
|
12975
|
+
const totalColumnsWidth = React48.useMemo(() => {
|
|
12976
|
+
return visibleColumns.reduce((sum, col) => {
|
|
12977
|
+
const colWidth = typeof col.width === "number" ? col.width : parseInt(String(col.width) || "150", 10);
|
|
12978
|
+
return sum + colWidth;
|
|
12979
|
+
}, 0);
|
|
12980
|
+
}, [visibleColumns]);
|
|
12973
12981
|
const stickyPositions = React48.useMemo(() => {
|
|
12974
12982
|
const positions = {};
|
|
12975
12983
|
let leftOffset = 0;
|
|
@@ -12994,11 +13002,11 @@ function DataTable({
|
|
|
12994
13002
|
const getStickyColumnClass = (col, isHeader = false) => {
|
|
12995
13003
|
if (!col.fixed) return "";
|
|
12996
13004
|
return cn(
|
|
12997
|
-
"sticky
|
|
12998
|
-
col.fixed === "left" && "shadow-[2px_0_5px_-2px_rgba(0,0,0,0.
|
|
12999
|
-
col.fixed === "right" && "shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.
|
|
13000
|
-
|
|
13001
|
-
|
|
13005
|
+
"sticky",
|
|
13006
|
+
col.fixed === "left" && "left-0 shadow-[2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13007
|
+
col.fixed === "right" && "right-0 shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13008
|
+
// Header fixed column cần z-index cao hơn thead (z-30) để không bị che
|
|
13009
|
+
isHeader ? "z-50 bg-muted!" : "z-10 bg-card!"
|
|
13002
13010
|
);
|
|
13003
13011
|
};
|
|
13004
13012
|
const getStickyColumnStyle = (col) => {
|
|
@@ -13066,129 +13074,144 @@ function DataTable({
|
|
|
13066
13074
|
}
|
|
13067
13075
|
return null;
|
|
13068
13076
|
};
|
|
13069
|
-
const renderHeader = /* @__PURE__ */ jsx57(TableRow, { children: visibleColumns.map((col, colIdx) =>
|
|
13070
|
-
|
|
13071
|
-
|
|
13072
|
-
|
|
13073
|
-
|
|
13074
|
-
|
|
13075
|
-
|
|
13076
|
-
|
|
13077
|
-
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
col.
|
|
13086
|
-
|
|
13077
|
+
const renderHeader = /* @__PURE__ */ jsx57(TableRow, { children: visibleColumns.map((col, colIdx) => {
|
|
13078
|
+
const prevCol = colIdx > 0 ? visibleColumns[colIdx - 1] : null;
|
|
13079
|
+
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
13080
|
+
const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
|
|
13081
|
+
return /* @__PURE__ */ jsx57(
|
|
13082
|
+
TableHead,
|
|
13083
|
+
{
|
|
13084
|
+
style: { width: col.width, ...getStickyColumnStyle(col) },
|
|
13085
|
+
className: cn(
|
|
13086
|
+
// Use column-specific align if defined, otherwise use global headerAlign
|
|
13087
|
+
(col.align === "right" || !col.align && headerAlign === "right") && "text-right",
|
|
13088
|
+
(col.align === "center" || !col.align && headerAlign === "center") && "text-center",
|
|
13089
|
+
showBorderLeft && "border-l border-border/60",
|
|
13090
|
+
getStickyColumnClass(col, true)
|
|
13091
|
+
),
|
|
13092
|
+
children: (() => {
|
|
13093
|
+
const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
|
|
13094
|
+
const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
|
|
13095
|
+
const titleContent = /* @__PURE__ */ jsxs51(
|
|
13096
|
+
"div",
|
|
13087
13097
|
{
|
|
13088
13098
|
className: cn(
|
|
13089
|
-
"
|
|
13090
|
-
|
|
13099
|
+
"flex items-center gap-1",
|
|
13100
|
+
// Cột fixed không cần shrink vì đã có width cố định
|
|
13101
|
+
!col.fixed && "min-w-0 shrink"
|
|
13091
13102
|
),
|
|
13092
|
-
|
|
13093
|
-
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
if (s.order === "asc") return { key: col.key, order: "desc" };
|
|
13097
|
-
return null;
|
|
13098
|
-
});
|
|
13099
|
-
},
|
|
13100
|
-
"aria-label": "Sort",
|
|
13101
|
-
title: `Sort by ${String(col.title)}`,
|
|
13102
|
-
children: /* @__PURE__ */ jsxs51("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
|
|
13103
|
-
/* @__PURE__ */ jsx57(
|
|
13104
|
-
"path",
|
|
13105
|
-
{
|
|
13106
|
-
d: "M7 8l3-3 3 3",
|
|
13107
|
-
stroke: "currentColor",
|
|
13108
|
-
strokeWidth: "1.5",
|
|
13109
|
-
strokeLinecap: "round",
|
|
13110
|
-
strokeLinejoin: "round",
|
|
13111
|
-
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
13112
|
-
}
|
|
13113
|
-
),
|
|
13114
|
-
/* @__PURE__ */ jsx57(
|
|
13115
|
-
"path",
|
|
13103
|
+
children: [
|
|
13104
|
+
/* @__PURE__ */ jsx57("span", { className: cn("font-medium text-sm", !col.fixed && "truncate"), children: col.title }),
|
|
13105
|
+
col.sortable && /* @__PURE__ */ jsx57(
|
|
13106
|
+
"button",
|
|
13116
13107
|
{
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13108
|
+
className: cn(
|
|
13109
|
+
"p-1 rounded-lg transition-all duration-200 hover:bg-accent",
|
|
13110
|
+
sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
|
|
13111
|
+
),
|
|
13112
|
+
onClick: () => {
|
|
13113
|
+
setCurPage(1);
|
|
13114
|
+
setSort((s) => {
|
|
13115
|
+
if (!s || s.key !== col.key) return { key: col.key, order: "asc" };
|
|
13116
|
+
if (s.order === "asc") return { key: col.key, order: "desc" };
|
|
13117
|
+
return null;
|
|
13118
|
+
});
|
|
13119
|
+
},
|
|
13120
|
+
"aria-label": "Sort",
|
|
13121
|
+
title: `Sort by ${String(col.title)}`,
|
|
13122
|
+
children: /* @__PURE__ */ jsxs51("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
|
|
13123
|
+
/* @__PURE__ */ jsx57(
|
|
13124
|
+
"path",
|
|
13125
|
+
{
|
|
13126
|
+
d: "M7 8l3-3 3 3",
|
|
13127
|
+
stroke: "currentColor",
|
|
13128
|
+
strokeWidth: "1.5",
|
|
13129
|
+
strokeLinecap: "round",
|
|
13130
|
+
strokeLinejoin: "round",
|
|
13131
|
+
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
13132
|
+
}
|
|
13133
|
+
),
|
|
13134
|
+
/* @__PURE__ */ jsx57(
|
|
13135
|
+
"path",
|
|
13136
|
+
{
|
|
13137
|
+
d: "M7 12l3 3 3-3",
|
|
13138
|
+
stroke: "currentColor",
|
|
13139
|
+
strokeWidth: "1.5",
|
|
13140
|
+
strokeLinecap: "round",
|
|
13141
|
+
strokeLinejoin: "round",
|
|
13142
|
+
opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
|
|
13143
|
+
}
|
|
13144
|
+
)
|
|
13145
|
+
] })
|
|
13123
13146
|
}
|
|
13124
13147
|
)
|
|
13125
|
-
]
|
|
13148
|
+
]
|
|
13126
13149
|
}
|
|
13127
|
-
)
|
|
13128
|
-
|
|
13129
|
-
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
trigger: /* @__PURE__ */ jsx57(
|
|
13134
|
-
"button",
|
|
13135
|
-
{
|
|
13136
|
-
className: cn(
|
|
13137
|
-
"p-1.5 rounded-lg hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
13138
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
13139
|
-
filters[col.key] && "bg-accent text-foreground"
|
|
13140
|
-
),
|
|
13141
|
-
"aria-label": "Filter",
|
|
13142
|
-
title: "Filter",
|
|
13143
|
-
children: /* @__PURE__ */ jsx57(FilterIcon, { className: "h-4 w-4" })
|
|
13144
|
-
}
|
|
13145
|
-
),
|
|
13146
|
-
children: /* @__PURE__ */ jsxs51("div", { className: "w-48 p-2 space-y-2", children: [
|
|
13147
|
-
/* @__PURE__ */ jsxs51("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
|
|
13148
|
-
"Filter ",
|
|
13149
|
-
col.title
|
|
13150
|
-
] }),
|
|
13151
|
-
renderFilterControl(col),
|
|
13152
|
-
filters[col.key] && /* @__PURE__ */ jsx57(
|
|
13150
|
+
);
|
|
13151
|
+
const filterContent = col.filter && /* @__PURE__ */ jsx57(
|
|
13152
|
+
Popover,
|
|
13153
|
+
{
|
|
13154
|
+
placement: isRightAlign ? "bottom-end" : "bottom-start",
|
|
13155
|
+
trigger: /* @__PURE__ */ jsx57(
|
|
13153
13156
|
"button",
|
|
13154
13157
|
{
|
|
13155
|
-
|
|
13156
|
-
|
|
13157
|
-
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
|
|
13161
|
-
|
|
13162
|
-
}
|
|
13163
|
-
className: "text-xs text-destructive hover:underline",
|
|
13164
|
-
children: t("clearFilter")
|
|
13158
|
+
className: cn(
|
|
13159
|
+
"p-1.5 rounded-lg hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
13160
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
13161
|
+
filters[col.key] && "bg-accent text-foreground"
|
|
13162
|
+
),
|
|
13163
|
+
"aria-label": "Filter",
|
|
13164
|
+
title: "Filter",
|
|
13165
|
+
children: /* @__PURE__ */ jsx57(FilterIcon, { className: "h-4 w-4" })
|
|
13165
13166
|
}
|
|
13166
|
-
)
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13167
|
+
),
|
|
13168
|
+
children: /* @__PURE__ */ jsxs51("div", { className: "w-48 p-2 space-y-2", children: [
|
|
13169
|
+
/* @__PURE__ */ jsxs51("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
|
|
13170
|
+
"Filter ",
|
|
13171
|
+
col.title
|
|
13172
|
+
] }),
|
|
13173
|
+
renderFilterControl(col),
|
|
13174
|
+
filters[col.key] && /* @__PURE__ */ jsx57(
|
|
13175
|
+
"button",
|
|
13176
|
+
{
|
|
13177
|
+
onClick: () => {
|
|
13178
|
+
setCurPage(1);
|
|
13179
|
+
setFilters((f) => {
|
|
13180
|
+
const newFilters = { ...f };
|
|
13181
|
+
delete newFilters[col.key];
|
|
13182
|
+
return newFilters;
|
|
13183
|
+
});
|
|
13184
|
+
},
|
|
13185
|
+
className: "text-xs text-destructive hover:underline",
|
|
13186
|
+
children: t("clearFilter")
|
|
13187
|
+
}
|
|
13188
|
+
)
|
|
13189
|
+
] })
|
|
13190
|
+
}
|
|
13191
|
+
);
|
|
13192
|
+
return /* @__PURE__ */ jsx57(
|
|
13193
|
+
"div",
|
|
13194
|
+
{
|
|
13195
|
+
className: cn(
|
|
13196
|
+
"flex items-center gap-2 select-none min-h-10",
|
|
13197
|
+
isRightAlign && "justify-end",
|
|
13198
|
+
isCenterAlign && "justify-center",
|
|
13199
|
+
!isRightAlign && !isCenterAlign && "justify-start"
|
|
13200
|
+
),
|
|
13201
|
+
children: isRightAlign ? /* @__PURE__ */ jsxs51(Fragment22, { children: [
|
|
13202
|
+
filterContent,
|
|
13203
|
+
titleContent
|
|
13204
|
+
] }) : /* @__PURE__ */ jsxs51(Fragment22, { children: [
|
|
13205
|
+
titleContent,
|
|
13206
|
+
filterContent
|
|
13207
|
+
] })
|
|
13208
|
+
}
|
|
13209
|
+
);
|
|
13210
|
+
})()
|
|
13211
|
+
},
|
|
13212
|
+
col.key
|
|
13213
|
+
);
|
|
13214
|
+
}) });
|
|
13192
13215
|
const isServerMode = Boolean(onQueryChange);
|
|
13193
13216
|
const processedData = React48.useMemo(() => {
|
|
13194
13217
|
if (isServerMode) return data;
|
|
@@ -13293,69 +13316,92 @@ function DataTable({
|
|
|
13293
13316
|
toolbar
|
|
13294
13317
|
] })
|
|
13295
13318
|
] }),
|
|
13296
|
-
/* @__PURE__ */ jsx57(
|
|
13297
|
-
|
|
13319
|
+
/* @__PURE__ */ jsx57(
|
|
13320
|
+
"div",
|
|
13298
13321
|
{
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
|
|
13306
|
-
|
|
13307
|
-
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
return /* @__PURE__ */ jsx57(
|
|
13322
|
-
TableRow,
|
|
13323
|
-
{
|
|
13324
|
-
className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/50"),
|
|
13325
|
-
style: {
|
|
13326
|
-
// content-visibility: auto for rendering performance (skip off-screen rows)
|
|
13327
|
-
contentVisibility: "auto",
|
|
13328
|
-
containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
|
|
13329
|
-
},
|
|
13330
|
-
children: visibleColumns.map((col, colIdx) => {
|
|
13331
|
-
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
13332
|
-
return /* @__PURE__ */ jsx57(
|
|
13333
|
-
TableCell,
|
|
13322
|
+
className: cn("relative rounded-2xl md:rounded-3xl border border-border/50", loading2 && "opacity-60 pointer-events-none"),
|
|
13323
|
+
style: stickyHeader ? {
|
|
13324
|
+
maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
|
|
13325
|
+
overflowY: "auto",
|
|
13326
|
+
overflowX: "auto"
|
|
13327
|
+
} : { overflowX: "auto" },
|
|
13328
|
+
children: /* @__PURE__ */ jsxs51(
|
|
13329
|
+
Table,
|
|
13330
|
+
{
|
|
13331
|
+
containerClassName: cn("border-0 md:border-0 rounded-none md:rounded-none shadow-none bg-transparent", "overflow-visible"),
|
|
13332
|
+
className: cn(
|
|
13333
|
+
"table-fixed",
|
|
13334
|
+
stickyHeader && ["[&_thead]:sticky", "[&_thead]:top-0", "[&_thead]:z-20", "[&_thead]:shadow-[0_1px_3px_rgba(0,0,0,0.1)]"]
|
|
13335
|
+
),
|
|
13336
|
+
style: { minWidth: totalColumnsWidth > 0 ? `${totalColumnsWidth}px` : void 0 },
|
|
13337
|
+
children: [
|
|
13338
|
+
/* @__PURE__ */ jsx57(TableHeader, { children: renderHeader }),
|
|
13339
|
+
/* @__PURE__ */ jsx57(TableBody, { children: loading2 ? /* @__PURE__ */ jsx57(TableRow, { children: /* @__PURE__ */ jsx57(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ jsxs51("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
|
|
13340
|
+
/* @__PURE__ */ jsxs51("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
13341
|
+
/* @__PURE__ */ jsx57("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
13342
|
+
/* @__PURE__ */ jsx57(
|
|
13343
|
+
"path",
|
|
13334
13344
|
{
|
|
13335
|
-
|
|
13336
|
-
|
|
13337
|
-
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13345
|
+
className: "opacity-75",
|
|
13346
|
+
fill: "currentColor",
|
|
13347
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
13348
|
+
}
|
|
13349
|
+
)
|
|
13350
|
+
] }),
|
|
13351
|
+
/* @__PURE__ */ jsxs51("span", { className: "text-sm", children: [
|
|
13352
|
+
t("loading"),
|
|
13353
|
+
"\u2026"
|
|
13354
|
+
] })
|
|
13355
|
+
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ jsx57(TableRow, { children: /* @__PURE__ */ jsx57(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: t("noData") }) }) : displayedData.map((row, idx) => {
|
|
13356
|
+
const isLastRow = idx === displayedData.length - 1;
|
|
13357
|
+
return /* @__PURE__ */ jsx57(
|
|
13358
|
+
TableRow,
|
|
13359
|
+
{
|
|
13360
|
+
className: cn(densityRowClass),
|
|
13361
|
+
style: {
|
|
13362
|
+
// content-visibility: auto for rendering performance (skip off-screen rows)
|
|
13363
|
+
contentVisibility: "auto",
|
|
13364
|
+
containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
|
|
13348
13365
|
},
|
|
13349
|
-
col
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
|
|
13366
|
+
children: visibleColumns.map((col, colIdx) => {
|
|
13367
|
+
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
13368
|
+
const isStripedRow = striped && idx % 2 === 0;
|
|
13369
|
+
const prevCol = colIdx > 0 ? visibleColumns[colIdx - 1] : null;
|
|
13370
|
+
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
13371
|
+
const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
|
|
13372
|
+
return /* @__PURE__ */ jsx57(
|
|
13373
|
+
TableCell,
|
|
13374
|
+
{
|
|
13375
|
+
style: getStickyColumnStyle(col),
|
|
13376
|
+
className: cn(
|
|
13377
|
+
cellPadding,
|
|
13378
|
+
col.align === "right" && "text-right",
|
|
13379
|
+
col.align === "center" && "text-center",
|
|
13380
|
+
showBorderLeft && "border-l border-border/60",
|
|
13381
|
+
isLastRow && col === visibleColumns[0] && "rounded-bl-2xl md:rounded-bl-3xl",
|
|
13382
|
+
isLastRow && col === visibleColumns[visibleColumns.length - 1] && "rounded-br-2xl md:rounded-br-3xl",
|
|
13383
|
+
// Cột cố định cần solid background
|
|
13384
|
+
col.fixed ? cn(
|
|
13385
|
+
"sticky z-10",
|
|
13386
|
+
col.fixed === "left" && "left-0 shadow-[2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13387
|
+
col.fixed === "right" && "right-0 shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13388
|
+
isStripedRow ? "bg-muted!" : "bg-card!"
|
|
13389
|
+
) : isStripedRow && "bg-muted/50"
|
|
13390
|
+
),
|
|
13391
|
+
children: col.render ? col.render(value, row, idx) : String(value ?? "")
|
|
13392
|
+
},
|
|
13393
|
+
col.key
|
|
13394
|
+
);
|
|
13395
|
+
})
|
|
13396
|
+
},
|
|
13397
|
+
getRowKey(row, idx)
|
|
13398
|
+
);
|
|
13399
|
+
}) })
|
|
13400
|
+
]
|
|
13401
|
+
}
|
|
13402
|
+
)
|
|
13357
13403
|
}
|
|
13358
|
-
)
|
|
13404
|
+
),
|
|
13359
13405
|
totalItems > 0 && Math.ceil(totalItems / curPageSize) > 1 && /* @__PURE__ */ jsxs51("div", { className: "flex items-center justify-between gap-2 px-1 pt-3 text-xs text-muted-foreground", children: [
|
|
13360
13406
|
/* @__PURE__ */ jsxs51("div", { className: "tabular-nums", children: [
|
|
13361
13407
|
(curPage - 1) * curPageSize + 1,
|