@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.cjs
CHANGED
|
@@ -13011,7 +13011,7 @@ var Table = import_react31.default.forwardRef(({ className, containerClassName,
|
|
|
13011
13011
|
}
|
|
13012
13012
|
));
|
|
13013
13013
|
Table.displayName = "Table";
|
|
13014
|
-
var TableHeader = import_react31.default.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border", "bg-muted
|
|
13014
|
+
var TableHeader = import_react31.default.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border", "bg-muted", className), ...props, children: [
|
|
13015
13015
|
children,
|
|
13016
13016
|
filterRow
|
|
13017
13017
|
] }));
|
|
@@ -13080,6 +13080,8 @@ function DataTable({
|
|
|
13080
13080
|
columnDividers = false,
|
|
13081
13081
|
className,
|
|
13082
13082
|
storageKey,
|
|
13083
|
+
stickyHeader = true,
|
|
13084
|
+
maxHeight = 500,
|
|
13083
13085
|
labels
|
|
13084
13086
|
}) {
|
|
13085
13087
|
const t = useTranslations("Common");
|
|
@@ -13143,6 +13145,12 @@ function DataTable({
|
|
|
13143
13145
|
const cellPadding = density === "compact" ? "py-1.5 px-3" : density === "comfortable" ? "py-3 px-4" : "py-2.5 px-4";
|
|
13144
13146
|
const visibleColsSet = import_react32.default.useMemo(() => new Set(visibleCols), [visibleCols]);
|
|
13145
13147
|
const visibleColumns = columns.filter((c) => visibleColsSet.has(c.key));
|
|
13148
|
+
const totalColumnsWidth = import_react32.default.useMemo(() => {
|
|
13149
|
+
return visibleColumns.reduce((sum, col) => {
|
|
13150
|
+
const colWidth = typeof col.width === "number" ? col.width : parseInt(String(col.width) || "150", 10);
|
|
13151
|
+
return sum + colWidth;
|
|
13152
|
+
}, 0);
|
|
13153
|
+
}, [visibleColumns]);
|
|
13146
13154
|
const stickyPositions = import_react32.default.useMemo(() => {
|
|
13147
13155
|
const positions = {};
|
|
13148
13156
|
let leftOffset = 0;
|
|
@@ -13167,11 +13175,11 @@ function DataTable({
|
|
|
13167
13175
|
const getStickyColumnClass = (col, isHeader = false) => {
|
|
13168
13176
|
if (!col.fixed) return "";
|
|
13169
13177
|
return cn(
|
|
13170
|
-
"sticky
|
|
13171
|
-
col.fixed === "left" && "shadow-[2px_0_5px_-2px_rgba(0,0,0,0.
|
|
13172
|
-
col.fixed === "right" && "shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.
|
|
13173
|
-
|
|
13174
|
-
|
|
13178
|
+
"sticky",
|
|
13179
|
+
col.fixed === "left" && "left-0 shadow-[2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13180
|
+
col.fixed === "right" && "right-0 shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13181
|
+
// Header fixed column cần z-index cao hơn thead (z-30) để không bị che
|
|
13182
|
+
isHeader ? "z-50 bg-muted!" : "z-10 bg-card!"
|
|
13175
13183
|
);
|
|
13176
13184
|
};
|
|
13177
13185
|
const getStickyColumnStyle = (col) => {
|
|
@@ -13239,129 +13247,144 @@ function DataTable({
|
|
|
13239
13247
|
}
|
|
13240
13248
|
return null;
|
|
13241
13249
|
};
|
|
13242
|
-
const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableRow, { children: visibleColumns.map((col, colIdx) =>
|
|
13243
|
-
|
|
13244
|
-
|
|
13245
|
-
|
|
13246
|
-
|
|
13247
|
-
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13251
|
-
|
|
13252
|
-
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
col.
|
|
13259
|
-
|
|
13250
|
+
const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableRow, { children: visibleColumns.map((col, colIdx) => {
|
|
13251
|
+
const prevCol = colIdx > 0 ? visibleColumns[colIdx - 1] : null;
|
|
13252
|
+
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
13253
|
+
const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
|
|
13254
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13255
|
+
TableHead,
|
|
13256
|
+
{
|
|
13257
|
+
style: { width: col.width, ...getStickyColumnStyle(col) },
|
|
13258
|
+
className: cn(
|
|
13259
|
+
// Use column-specific align if defined, otherwise use global headerAlign
|
|
13260
|
+
(col.align === "right" || !col.align && headerAlign === "right") && "text-right",
|
|
13261
|
+
(col.align === "center" || !col.align && headerAlign === "center") && "text-center",
|
|
13262
|
+
showBorderLeft && "border-l border-border/60",
|
|
13263
|
+
getStickyColumnClass(col, true)
|
|
13264
|
+
),
|
|
13265
|
+
children: (() => {
|
|
13266
|
+
const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
|
|
13267
|
+
const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
|
|
13268
|
+
const titleContent = /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
13269
|
+
"div",
|
|
13260
13270
|
{
|
|
13261
13271
|
className: cn(
|
|
13262
|
-
"
|
|
13263
|
-
|
|
13272
|
+
"flex items-center gap-1",
|
|
13273
|
+
// Cột fixed không cần shrink vì đã có width cố định
|
|
13274
|
+
!col.fixed && "min-w-0 shrink"
|
|
13264
13275
|
),
|
|
13265
|
-
|
|
13266
|
-
|
|
13267
|
-
|
|
13268
|
-
|
|
13269
|
-
if (s.order === "asc") return { key: col.key, order: "desc" };
|
|
13270
|
-
return null;
|
|
13271
|
-
});
|
|
13272
|
-
},
|
|
13273
|
-
"aria-label": "Sort",
|
|
13274
|
-
title: `Sort by ${String(col.title)}`,
|
|
13275
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
|
|
13276
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13277
|
-
"path",
|
|
13278
|
-
{
|
|
13279
|
-
d: "M7 8l3-3 3 3",
|
|
13280
|
-
stroke: "currentColor",
|
|
13281
|
-
strokeWidth: "1.5",
|
|
13282
|
-
strokeLinecap: "round",
|
|
13283
|
-
strokeLinejoin: "round",
|
|
13284
|
-
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
13285
|
-
}
|
|
13286
|
-
),
|
|
13287
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13288
|
-
"path",
|
|
13276
|
+
children: [
|
|
13277
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: cn("font-medium text-sm", !col.fixed && "truncate"), children: col.title }),
|
|
13278
|
+
col.sortable && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13279
|
+
"button",
|
|
13289
13280
|
{
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
|
|
13281
|
+
className: cn(
|
|
13282
|
+
"p-1 rounded-lg transition-all duration-200 hover:bg-accent",
|
|
13283
|
+
sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
|
|
13284
|
+
),
|
|
13285
|
+
onClick: () => {
|
|
13286
|
+
setCurPage(1);
|
|
13287
|
+
setSort((s) => {
|
|
13288
|
+
if (!s || s.key !== col.key) return { key: col.key, order: "asc" };
|
|
13289
|
+
if (s.order === "asc") return { key: col.key, order: "desc" };
|
|
13290
|
+
return null;
|
|
13291
|
+
});
|
|
13292
|
+
},
|
|
13293
|
+
"aria-label": "Sort",
|
|
13294
|
+
title: `Sort by ${String(col.title)}`,
|
|
13295
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
|
|
13296
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13297
|
+
"path",
|
|
13298
|
+
{
|
|
13299
|
+
d: "M7 8l3-3 3 3",
|
|
13300
|
+
stroke: "currentColor",
|
|
13301
|
+
strokeWidth: "1.5",
|
|
13302
|
+
strokeLinecap: "round",
|
|
13303
|
+
strokeLinejoin: "round",
|
|
13304
|
+
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
13305
|
+
}
|
|
13306
|
+
),
|
|
13307
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13308
|
+
"path",
|
|
13309
|
+
{
|
|
13310
|
+
d: "M7 12l3 3 3-3",
|
|
13311
|
+
stroke: "currentColor",
|
|
13312
|
+
strokeWidth: "1.5",
|
|
13313
|
+
strokeLinecap: "round",
|
|
13314
|
+
strokeLinejoin: "round",
|
|
13315
|
+
opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
|
|
13316
|
+
}
|
|
13317
|
+
)
|
|
13318
|
+
] })
|
|
13296
13319
|
}
|
|
13297
13320
|
)
|
|
13298
|
-
]
|
|
13321
|
+
]
|
|
13299
13322
|
}
|
|
13300
|
-
)
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
|
|
13306
|
-
trigger: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13307
|
-
"button",
|
|
13308
|
-
{
|
|
13309
|
-
className: cn(
|
|
13310
|
-
"p-1.5 rounded-lg hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
13311
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
13312
|
-
filters[col.key] && "bg-accent text-foreground"
|
|
13313
|
-
),
|
|
13314
|
-
"aria-label": "Filter",
|
|
13315
|
-
title: "Filter",
|
|
13316
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react27.Filter, { className: "h-4 w-4" })
|
|
13317
|
-
}
|
|
13318
|
-
),
|
|
13319
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "w-48 p-2 space-y-2", children: [
|
|
13320
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
|
|
13321
|
-
"Filter ",
|
|
13322
|
-
col.title
|
|
13323
|
-
] }),
|
|
13324
|
-
renderFilterControl(col),
|
|
13325
|
-
filters[col.key] && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13323
|
+
);
|
|
13324
|
+
const filterContent = col.filter && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13325
|
+
Popover,
|
|
13326
|
+
{
|
|
13327
|
+
placement: isRightAlign ? "bottom-end" : "bottom-start",
|
|
13328
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13326
13329
|
"button",
|
|
13327
13330
|
{
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
}
|
|
13336
|
-
className: "text-xs text-destructive hover:underline",
|
|
13337
|
-
children: t("clearFilter")
|
|
13331
|
+
className: cn(
|
|
13332
|
+
"p-1.5 rounded-lg hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
13333
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
13334
|
+
filters[col.key] && "bg-accent text-foreground"
|
|
13335
|
+
),
|
|
13336
|
+
"aria-label": "Filter",
|
|
13337
|
+
title: "Filter",
|
|
13338
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react27.Filter, { className: "h-4 w-4" })
|
|
13338
13339
|
}
|
|
13339
|
-
)
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
|
|
13364
|
-
|
|
13340
|
+
),
|
|
13341
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "w-48 p-2 space-y-2", children: [
|
|
13342
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
|
|
13343
|
+
"Filter ",
|
|
13344
|
+
col.title
|
|
13345
|
+
] }),
|
|
13346
|
+
renderFilterControl(col),
|
|
13347
|
+
filters[col.key] && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13348
|
+
"button",
|
|
13349
|
+
{
|
|
13350
|
+
onClick: () => {
|
|
13351
|
+
setCurPage(1);
|
|
13352
|
+
setFilters((f) => {
|
|
13353
|
+
const newFilters = { ...f };
|
|
13354
|
+
delete newFilters[col.key];
|
|
13355
|
+
return newFilters;
|
|
13356
|
+
});
|
|
13357
|
+
},
|
|
13358
|
+
className: "text-xs text-destructive hover:underline",
|
|
13359
|
+
children: t("clearFilter")
|
|
13360
|
+
}
|
|
13361
|
+
)
|
|
13362
|
+
] })
|
|
13363
|
+
}
|
|
13364
|
+
);
|
|
13365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13366
|
+
"div",
|
|
13367
|
+
{
|
|
13368
|
+
className: cn(
|
|
13369
|
+
"flex items-center gap-2 select-none min-h-10",
|
|
13370
|
+
isRightAlign && "justify-end",
|
|
13371
|
+
isCenterAlign && "justify-center",
|
|
13372
|
+
!isRightAlign && !isCenterAlign && "justify-start"
|
|
13373
|
+
),
|
|
13374
|
+
children: isRightAlign ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
13375
|
+
filterContent,
|
|
13376
|
+
titleContent
|
|
13377
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
13378
|
+
titleContent,
|
|
13379
|
+
filterContent
|
|
13380
|
+
] })
|
|
13381
|
+
}
|
|
13382
|
+
);
|
|
13383
|
+
})()
|
|
13384
|
+
},
|
|
13385
|
+
col.key
|
|
13386
|
+
);
|
|
13387
|
+
}) });
|
|
13365
13388
|
const isServerMode = Boolean(onQueryChange);
|
|
13366
13389
|
const processedData = import_react32.default.useMemo(() => {
|
|
13367
13390
|
if (isServerMode) return data;
|
|
@@ -13466,69 +13489,92 @@ function DataTable({
|
|
|
13466
13489
|
toolbar
|
|
13467
13490
|
] })
|
|
13468
13491
|
] }),
|
|
13469
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13470
|
-
|
|
13492
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13493
|
+
"div",
|
|
13471
13494
|
{
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13495
|
-
TableRow,
|
|
13496
|
-
{
|
|
13497
|
-
className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/50"),
|
|
13498
|
-
style: {
|
|
13499
|
-
// content-visibility: auto for rendering performance (skip off-screen rows)
|
|
13500
|
-
contentVisibility: "auto",
|
|
13501
|
-
containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
|
|
13502
|
-
},
|
|
13503
|
-
children: visibleColumns.map((col, colIdx) => {
|
|
13504
|
-
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
13505
|
-
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13506
|
-
TableCell,
|
|
13495
|
+
className: cn("relative rounded-2xl md:rounded-3xl border border-border/50", loading2 && "opacity-60 pointer-events-none"),
|
|
13496
|
+
style: stickyHeader ? {
|
|
13497
|
+
maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
|
|
13498
|
+
overflowY: "auto",
|
|
13499
|
+
overflowX: "auto"
|
|
13500
|
+
} : { overflowX: "auto" },
|
|
13501
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
13502
|
+
Table,
|
|
13503
|
+
{
|
|
13504
|
+
containerClassName: cn("border-0 md:border-0 rounded-none md:rounded-none shadow-none bg-transparent", "overflow-visible"),
|
|
13505
|
+
className: cn(
|
|
13506
|
+
"table-fixed",
|
|
13507
|
+
stickyHeader && ["[&_thead]:sticky", "[&_thead]:top-0", "[&_thead]:z-20", "[&_thead]:shadow-[0_1px_3px_rgba(0,0,0,0.1)]"]
|
|
13508
|
+
),
|
|
13509
|
+
style: { minWidth: totalColumnsWidth > 0 ? `${totalColumnsWidth}px` : void 0 },
|
|
13510
|
+
children: [
|
|
13511
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableHeader, { children: renderHeader }),
|
|
13512
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
|
|
13513
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
13514
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
13515
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13516
|
+
"path",
|
|
13507
13517
|
{
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13518
|
+
className: "opacity-75",
|
|
13519
|
+
fill: "currentColor",
|
|
13520
|
+
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"
|
|
13521
|
+
}
|
|
13522
|
+
)
|
|
13523
|
+
] }),
|
|
13524
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "text-sm", children: [
|
|
13525
|
+
t("loading"),
|
|
13526
|
+
"\u2026"
|
|
13527
|
+
] })
|
|
13528
|
+
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: t("noData") }) }) : displayedData.map((row, idx) => {
|
|
13529
|
+
const isLastRow = idx === displayedData.length - 1;
|
|
13530
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13531
|
+
TableRow,
|
|
13532
|
+
{
|
|
13533
|
+
className: cn(densityRowClass),
|
|
13534
|
+
style: {
|
|
13535
|
+
// content-visibility: auto for rendering performance (skip off-screen rows)
|
|
13536
|
+
contentVisibility: "auto",
|
|
13537
|
+
containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
|
|
13521
13538
|
},
|
|
13522
|
-
col
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13539
|
+
children: visibleColumns.map((col, colIdx) => {
|
|
13540
|
+
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
13541
|
+
const isStripedRow = striped && idx % 2 === 0;
|
|
13542
|
+
const prevCol = colIdx > 0 ? visibleColumns[colIdx - 1] : null;
|
|
13543
|
+
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
13544
|
+
const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
|
|
13545
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
13546
|
+
TableCell,
|
|
13547
|
+
{
|
|
13548
|
+
style: getStickyColumnStyle(col),
|
|
13549
|
+
className: cn(
|
|
13550
|
+
cellPadding,
|
|
13551
|
+
col.align === "right" && "text-right",
|
|
13552
|
+
col.align === "center" && "text-center",
|
|
13553
|
+
showBorderLeft && "border-l border-border/60",
|
|
13554
|
+
isLastRow && col === visibleColumns[0] && "rounded-bl-2xl md:rounded-bl-3xl",
|
|
13555
|
+
isLastRow && col === visibleColumns[visibleColumns.length - 1] && "rounded-br-2xl md:rounded-br-3xl",
|
|
13556
|
+
// Cột cố định cần solid background
|
|
13557
|
+
col.fixed ? cn(
|
|
13558
|
+
"sticky z-10",
|
|
13559
|
+
col.fixed === "left" && "left-0 shadow-[2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13560
|
+
col.fixed === "right" && "right-0 shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.15)]",
|
|
13561
|
+
isStripedRow ? "bg-muted!" : "bg-card!"
|
|
13562
|
+
) : isStripedRow && "bg-muted/50"
|
|
13563
|
+
),
|
|
13564
|
+
children: col.render ? col.render(value, row, idx) : String(value ?? "")
|
|
13565
|
+
},
|
|
13566
|
+
col.key
|
|
13567
|
+
);
|
|
13568
|
+
})
|
|
13569
|
+
},
|
|
13570
|
+
getRowKey(row, idx)
|
|
13571
|
+
);
|
|
13572
|
+
}) })
|
|
13573
|
+
]
|
|
13574
|
+
}
|
|
13575
|
+
)
|
|
13530
13576
|
}
|
|
13531
|
-
)
|
|
13577
|
+
),
|
|
13532
13578
|
totalItems > 0 && Math.ceil(totalItems / curPageSize) > 1 && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center justify-between gap-2 px-1 pt-3 text-xs text-muted-foreground", children: [
|
|
13533
13579
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "tabular-nums", children: [
|
|
13534
13580
|
(curPage - 1) * curPageSize + 1,
|