@misael703/ui 1.50.0 → 1.51.0

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.
Files changed (44) hide show
  1. package/dist/chunk-6D5UP23V.js +63 -0
  2. package/dist/chunk-6D5UP23V.js.map +1 -0
  3. package/dist/chunk-HT43MPKW.js +5 -0
  4. package/dist/{chunk-2KZ4NI3X.js.map → chunk-HT43MPKW.js.map} +1 -1
  5. package/dist/chunk-JT6OOSI2.mjs +4 -0
  6. package/dist/{chunk-QQE3XOEM.mjs.map → chunk-JT6OOSI2.mjs.map} +1 -1
  7. package/dist/{chunk-2IKGRN2O.js → chunk-UZX2SE42.js} +48 -34
  8. package/dist/chunk-UZX2SE42.js.map +1 -0
  9. package/dist/{chunk-LPKS5CM5.mjs → chunk-VNRZAYM7.mjs} +48 -34
  10. package/dist/chunk-VNRZAYM7.mjs.map +1 -0
  11. package/dist/chunk-YTKPENNW.mjs +41 -0
  12. package/dist/chunk-YTKPENNW.mjs.map +1 -0
  13. package/dist/components/AppShell.js +2 -1
  14. package/dist/components/AppShell.mjs +2 -1
  15. package/dist/components/Commerce.js +2 -1
  16. package/dist/components/Commerce.mjs +2 -1
  17. package/dist/components/DataTable.d.mts +19 -4
  18. package/dist/components/DataTable.d.ts +19 -4
  19. package/dist/components/DataTable.js +9 -8
  20. package/dist/components/DataTable.mjs +2 -1
  21. package/dist/components/Editing.js +2 -1
  22. package/dist/components/Editing.mjs +2 -1
  23. package/dist/components/Overlay.js +2 -1
  24. package/dist/components/Overlay.mjs +2 -1
  25. package/dist/hooks/index.d.mts +1 -0
  26. package/dist/hooks/index.d.ts +1 -0
  27. package/dist/hooks/index.js +6 -1
  28. package/dist/hooks/index.mjs +2 -1
  29. package/dist/hooks/useVirtualRows.d.mts +40 -0
  30. package/dist/hooks/useVirtualRows.d.ts +40 -0
  31. package/dist/hooks/useVirtualRows.js +13 -0
  32. package/dist/hooks/useVirtualRows.js.map +1 -0
  33. package/dist/hooks/useVirtualRows.mjs +4 -0
  34. package/dist/hooks/useVirtualRows.mjs.map +1 -0
  35. package/dist/index.d.mts +1 -0
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +14 -9
  38. package/dist/index.mjs +3 -2
  39. package/dist/styles.css +1 -1
  40. package/package.json +1 -1
  41. package/dist/chunk-2IKGRN2O.js.map +0 -1
  42. package/dist/chunk-2KZ4NI3X.js +0 -5
  43. package/dist/chunk-LPKS5CM5.mjs.map +0 -1
  44. package/dist/chunk-QQE3XOEM.mjs +0 -4
@@ -0,0 +1,63 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+
6
+ function _interopNamespace(e) {
7
+ if (e && e.__esModule) return e;
8
+ var n = Object.create(null);
9
+ if (e) {
10
+ Object.keys(e).forEach(function (k) {
11
+ if (k !== 'default') {
12
+ var d = Object.getOwnPropertyDescriptor(e, k);
13
+ Object.defineProperty(n, k, d.get ? d : {
14
+ enumerable: true,
15
+ get: function () { return e[k]; }
16
+ });
17
+ }
18
+ });
19
+ }
20
+ n.default = e;
21
+ return Object.freeze(n);
22
+ }
23
+
24
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
25
+
26
+ // src/hooks/useVirtualRows.ts
27
+ var INITIAL_WINDOW = 40;
28
+ function useVirtualRows(scrollRef, { count, rowHeight, overscan = 6, enabled = true }) {
29
+ const [range, setRange] = React__namespace.useState({ start: 0, end: Math.min(count, INITIAL_WINDOW) });
30
+ React__namespace.useEffect(() => {
31
+ if (!enabled) return;
32
+ const el = scrollRef.current;
33
+ if (!el) return;
34
+ const compute = () => {
35
+ const visible = Math.ceil((el.clientHeight || 0) / rowHeight);
36
+ const first = Math.floor(el.scrollTop / rowHeight);
37
+ const start2 = Math.max(0, first - overscan);
38
+ const end2 = Math.min(count, first + visible + overscan);
39
+ setRange((prev) => prev.start === start2 && prev.end === end2 ? prev : { start: start2, end: end2 });
40
+ };
41
+ compute();
42
+ el.addEventListener("scroll", compute, { passive: true });
43
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(compute) : null;
44
+ ro?.observe(el);
45
+ return () => {
46
+ el.removeEventListener("scroll", compute);
47
+ ro?.disconnect();
48
+ };
49
+ }, [enabled, scrollRef, count, rowHeight, overscan]);
50
+ if (!enabled) return { start: 0, end: count, padTop: 0, padBottom: 0 };
51
+ const start = Math.min(range.start, count);
52
+ const end = Math.min(range.end, count);
53
+ return {
54
+ start,
55
+ end,
56
+ padTop: start * rowHeight,
57
+ padBottom: (count - end) * rowHeight
58
+ };
59
+ }
60
+
61
+ exports.useVirtualRows = useVirtualRows;
62
+ //# sourceMappingURL=chunk-6D5UP23V.js.map
63
+ //# sourceMappingURL=chunk-6D5UP23V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useVirtualRows.ts"],"names":["React","start","end"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAM,cAAA,GAAiB,EAAA;AAEhB,SAAS,cAAA,CACd,WACA,EAAE,KAAA,EAAO,WAAW,QAAA,GAAW,CAAA,EAAG,OAAA,GAAU,IAAA,EAAK,EAC/B;AAClB,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,0BAAS,EAAE,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,cAAc,GAAG,CAAA;AAE3F,EAAMA,2BAAU,MAAM;AACpB,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,KAAK,SAAA,CAAU,OAAA;AACrB,IAAA,IAAI,CAAC,EAAA,EAAI;AAET,IAAA,MAAM,UAAU,MAAM;AAGpB,MAAA,MAAM,UAAU,IAAA,CAAK,IAAA,CAAA,CAAM,EAAA,CAAG,YAAA,IAAgB,KAAK,SAAS,CAAA;AAC5D,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,YAAY,SAAS,CAAA;AACjD,MAAA,MAAMC,MAAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,QAAQ,CAAA;AAC1C,MAAA,MAAMC,OAAM,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,KAAA,GAAQ,UAAU,QAAQ,CAAA;AACtD,MAAA,QAAA,CAAS,CAAC,IAAA,KAAU,IAAA,CAAK,KAAA,KAAUD,UAAS,IAAA,CAAK,GAAA,KAAQC,IAAAA,GAAM,IAAA,GAAO,EAAE,KAAA,EAAAD,MAAAA,EAAO,GAAA,EAAAC,MAAM,CAAA;AAAA,IACvF,CAAA;AAEA,IAAA,OAAA,EAAQ;AACR,IAAA,EAAA,CAAG,iBAAiB,QAAA,EAAU,OAAA,EAAS,EAAE,OAAA,EAAS,MAAM,CAAA;AACxD,IAAA,MAAM,KAAK,OAAO,cAAA,KAAmB,cAAc,IAAI,cAAA,CAAe,OAAO,CAAA,GAAI,IAAA;AACjF,IAAA,EAAA,EAAI,QAAQ,EAAE,CAAA;AACd,IAAA,OAAO,MAAM;AACX,MAAA,EAAA,CAAG,mBAAA,CAAoB,UAAU,OAAO,CAAA;AACxC,MAAA,EAAA,EAAI,UAAA,EAAW;AAAA,IACjB,CAAA;AAAA,EACF,GAAG,CAAC,OAAA,EAAS,WAAW,KAAA,EAAO,SAAA,EAAW,QAAQ,CAAC,CAAA;AAEnD,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,KAAA,EAAO,MAAA,EAAQ,CAAA,EAAG,SAAA,EAAW,CAAA,EAAE;AACrE,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,OAAO,KAAK,CAAA;AACzC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,KAAK,KAAK,CAAA;AACrC,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,GAAA;AAAA,IACA,QAAQ,KAAA,GAAQ,SAAA;AAAA,IAChB,SAAA,EAAA,CAAY,QAAQ,GAAA,IAAO;AAAA,GAC7B;AACF","file":"chunk-6D5UP23V.js","sourcesContent":["'use client';\nimport * as React from 'react';\n\n/**\n * Fixed-height row windowing, zero dependencies. Renders only the rows\n * inside (viewport + overscan) and replaces the rest with two pixel-exact\n * spacers, so a 10k-row table costs ~40 DOM rows.\n *\n * Deliberately FIXED-height only: variable heights need a measurement\n * cache (tanstack-virtual territory) and the kit's dense table rows are\n * uniform by design. Anything that breaks uniformity (row expansion,\n * mobile cards, wrapping `comfortable` cells) must not be combined with\n * this — `DataTable` gates those combinations off automatically.\n */\nexport interface UseVirtualRowsOptions {\n /** Total row count (the full dataset length, not the rendered window). */\n count: number;\n /** Fixed pixel height of every row. The math trusts it: measure once in devtools. */\n rowHeight: number;\n /** Extra rows rendered above/below the viewport. Default 6. */\n overscan?: number;\n /**\n * When `false` the hook is inert and returns the full range with zero\n * padding — callers keep one uniform render path instead of forking on\n * \"virtual or not\" (hooks can't be called conditionally).\n */\n enabled?: boolean;\n}\n\nexport interface VirtualRowsRange {\n /** First rendered index (inclusive). */\n start: number;\n /** Last rendered index (exclusive). */\n end: number;\n /** Pixel height of the spacer above the window. */\n padTop: number;\n /** Pixel height of the spacer below the window. */\n padBottom: number;\n}\n\n/**\n * Rows visible before the first measurement (SSR / first paint, where the\n * scroller's clientHeight is unknown). Tall enough to fill any reasonable\n * bounded table once, without rendering thousands server-side.\n */\nconst INITIAL_WINDOW = 40;\n\nexport function useVirtualRows(\n scrollRef: React.RefObject<HTMLElement | null>,\n { count, rowHeight, overscan = 6, enabled = true }: UseVirtualRowsOptions\n): VirtualRowsRange {\n const [range, setRange] = React.useState({ start: 0, end: Math.min(count, INITIAL_WINDOW) });\n\n React.useEffect(() => {\n if (!enabled) return;\n const el = scrollRef.current;\n if (!el) return;\n\n const compute = () => {\n // Quantized by row: setRange bails on identical ranges, so scrolling\n // inside the same row window costs zero re-renders.\n const visible = Math.ceil((el.clientHeight || 0) / rowHeight);\n const first = Math.floor(el.scrollTop / rowHeight);\n const start = Math.max(0, first - overscan);\n const end = Math.min(count, first + visible + overscan);\n setRange((prev) => (prev.start === start && prev.end === end ? prev : { start, end }));\n };\n\n compute();\n el.addEventListener('scroll', compute, { passive: true });\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(compute) : null;\n ro?.observe(el);\n return () => {\n el.removeEventListener('scroll', compute);\n ro?.disconnect();\n };\n }, [enabled, scrollRef, count, rowHeight, overscan]);\n\n if (!enabled) return { start: 0, end: count, padTop: 0, padBottom: 0 };\n const start = Math.min(range.start, count);\n const end = Math.min(range.end, count);\n return {\n start,\n end,\n padTop: start * rowHeight,\n padBottom: (count - end) * rowHeight,\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ //# sourceMappingURL=chunk-HT43MPKW.js.map
5
+ //# sourceMappingURL=chunk-HT43MPKW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-2KZ4NI3X.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-HT43MPKW.js"}
@@ -0,0 +1,4 @@
1
+ 'use client';
2
+
3
+ //# sourceMappingURL=chunk-JT6OOSI2.mjs.map
4
+ //# sourceMappingURL=chunk-JT6OOSI2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-QQE3XOEM.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-JT6OOSI2.mjs"}
@@ -5,6 +5,7 @@ var chunkMW7HQCFC_js = require('./chunk-MW7HQCFC.js');
5
5
  var chunkAKUGR3AX_js = require('./chunk-AKUGR3AX.js');
6
6
  var chunk6SSTTJV4_js = require('./chunk-6SSTTJV4.js');
7
7
  var chunkJDK4GEME_js = require('./chunk-JDK4GEME.js');
8
+ var chunk6D5UP23V_js = require('./chunk-6D5UP23V.js');
8
9
  var chunkMJMLNETS_js = require('./chunk-MJMLNETS.js');
9
10
  var chunkAJ22SXI2_js = require('./chunk-AJ22SXI2.js');
10
11
  var chunkC4AKMVDZ_js = require('./chunk-C4AKMVDZ.js');
@@ -141,6 +142,7 @@ function DataTable({
141
142
  expandedKeys,
142
143
  onExpandedChange,
143
144
  hiddenColumnKeys,
145
+ virtualizeRows,
144
146
  surface = "card"
145
147
  }) {
146
148
  const t = chunkMJMLNETS_js.useLocale();
@@ -203,6 +205,13 @@ function DataTable({
203
205
  const expandable = renderExpanded != null;
204
206
  const tableId = React__namespace.useId();
205
207
  const totalCols = columns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0);
208
+ const virtual = virtualizeRows != null && maxHeight != null && !expandable && mobileLayout !== "cards";
209
+ const vrange = chunk6D5UP23V_js.useVirtualRows(scrollRef, {
210
+ count: rows.length,
211
+ rowHeight: virtualizeRows?.rowHeight ?? 1,
212
+ overscan: virtualizeRows?.overscan,
213
+ enabled: virtual
214
+ });
206
215
  const onSort = (col) => {
207
216
  if (!col.sortable || !onSortChange) return;
208
217
  if (!sort || sort.key !== col.key) onSortChange({ key: col.key, dir: "asc" });
@@ -217,6 +226,7 @@ function DataTable({
217
226
  density === "comfortable" && "table--comfortable"
218
227
  ),
219
228
  "aria-label": ariaLabel,
229
+ "aria-rowcount": virtual ? rows.length + 1 : void 0,
220
230
  children: [
221
231
  /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
222
232
  selectable && /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", style: { width: 40 }, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -270,38 +280,42 @@ function DataTable({
270
280
  selectable && /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "skel", style: { height: 14 } }) }),
271
281
  expandable && /* @__PURE__ */ jsxRuntime.jsx("td", { "aria-hidden": "true" }),
272
282
  columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "skel", style: { height: 12, width: "70%" } }) }, c.key))
273
- ] }, `s${i}`)) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalCols, style: { padding: 32 }, children: empty ?? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", color: "var(--fg-muted)" }, children: t["table.empty"] }) }) }) : rows.map((r) => {
274
- const k = rowKey(r);
275
- const label = rowLabel ? rowLabel(r) : k;
276
- const href = rowHref?.(r);
277
- const onActivate = onRowClick ? () => onRowClick(r) : void 0;
278
- const expanded = expandable && !!expandedKeys?.has(k);
279
- const detailId = `${tableId}-detail-${k}`;
280
- return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
281
- /* @__PURE__ */ jsxRuntime.jsx(
282
- DataTableRow,
283
- {
284
- row: r,
285
- rowK: k,
286
- selected: !!selectedKeys?.has(k),
287
- selectable: !!selectable,
288
- selectAriaLabel: chunkJDK4GEME_js.format(t["table.selectRow"], { label }),
289
- columns,
290
- onToggle: toggleRow,
291
- href,
292
- onActivate,
293
- actionLabel: chunkJDK4GEME_js.format(t["table.rowAction"], { label }),
294
- renderRow,
295
- expandable,
296
- expanded,
297
- onToggleExpand: toggleExpand,
298
- expandLabel: chunkJDK4GEME_js.format(t["table.expandRow"], { label }),
299
- detailId
300
- }
301
- ),
302
- expanded && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "data-table__detail", children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalCols, id: detailId, children: renderExpanded(r) }) })
303
- ] }, k);
304
- }) }),
283
+ ] }, `s${i}`)) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalCols, style: { padding: 32 }, children: empty ?? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", color: "var(--fg-muted)" }, children: t["table.empty"] }) }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
284
+ virtual && vrange.padTop > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "data-table__spacer", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalCols, style: { height: vrange.padTop } }) }),
285
+ (virtual ? rows.slice(vrange.start, vrange.end) : rows).map((r) => {
286
+ const k = rowKey(r);
287
+ const label = rowLabel ? rowLabel(r) : k;
288
+ const href = rowHref?.(r);
289
+ const onActivate = onRowClick ? () => onRowClick(r) : void 0;
290
+ const expanded = expandable && !!expandedKeys?.has(k);
291
+ const detailId = `${tableId}-detail-${k}`;
292
+ return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
293
+ /* @__PURE__ */ jsxRuntime.jsx(
294
+ DataTableRow,
295
+ {
296
+ row: r,
297
+ rowK: k,
298
+ selected: !!selectedKeys?.has(k),
299
+ selectable: !!selectable,
300
+ selectAriaLabel: chunkJDK4GEME_js.format(t["table.selectRow"], { label }),
301
+ columns,
302
+ onToggle: toggleRow,
303
+ href,
304
+ onActivate,
305
+ actionLabel: chunkJDK4GEME_js.format(t["table.rowAction"], { label }),
306
+ renderRow,
307
+ expandable,
308
+ expanded,
309
+ onToggleExpand: toggleExpand,
310
+ expandLabel: chunkJDK4GEME_js.format(t["table.expandRow"], { label }),
311
+ detailId
312
+ }
313
+ ),
314
+ expanded && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "data-table__detail", children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalCols, id: detailId, children: renderExpanded(r) }) })
315
+ ] }, k);
316
+ }),
317
+ virtual && vrange.padBottom > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "data-table__spacer", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalCols, style: { height: vrange.padBottom } }) })
318
+ ] }) }),
305
319
  columns.some((c) => c.footer != null) && !error && !loading && rows.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("tfoot", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
306
320
  selectable && /* @__PURE__ */ jsxRuntime.jsx("td", {}),
307
321
  expandable && /* @__PURE__ */ jsxRuntime.jsx("td", { "aria-hidden": "true" }),
@@ -497,5 +511,5 @@ exports.ColumnToggle = ColumnToggle;
497
511
  exports.DataTable = DataTable;
498
512
  exports.TablePagination = TablePagination;
499
513
  exports.TableToolbar = TableToolbar;
500
- //# sourceMappingURL=chunk-2IKGRN2O.js.map
501
- //# sourceMappingURL=chunk-2IKGRN2O.js.map
514
+ //# sourceMappingURL=chunk-UZX2SE42.js.map
515
+ //# sourceMappingURL=chunk-UZX2SE42.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/DataTable.tsx"],"names":["jsxs","Fragment","cx","jsx","Checkbox","ChevronRight","React","useLocale","rows","rowKey","selectedKeys","onSelectionChange","expandedKeys","onExpandedChange","useVirtualRows","ChevronUp","ChevronDown","MoreVertical","format","Pagination","TableToolbar","Popover","Button"],"mappings":"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","file":"chunk-UZX2SE42.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { ChevronUp, ChevronDown, ChevronRight, MoreVertical } from './Icons';\nimport { Checkbox } from './Form';\nimport { Popover } from './Popover';\nimport { Button } from './Button';\nimport { useVirtualRows } from '../hooks/useVirtualRows';\nimport { useLocale } from '../locale/LocaleProvider';\nimport { format } from '../locale/messages';\n\n// ---------- DataTableRow (memoized) -------------------------------------\n// Extracted as React.memo so unrelated parent re-renders don't churn through\n// every row in the table. Combined with a ref-stable `onToggle`, only the\n// row whose `selected` prop actually changed re-renders on toggle.\ninterface DataTableRowProps<T> {\n row: T;\n rowK: string;\n selected: boolean;\n selectable: boolean;\n selectAriaLabel: string;\n columns: Column<T>[];\n onToggle: (k: string) => void;\n /** Resolved from `rowHref(row)` — makes the row a navigable link. */\n href?: string;\n /** Resolved from `onRowClick(row)` — makes the row activate a callback. */\n onActivate?: () => void;\n /** Accessible name for the stretched row control (e.g. \"Ver Taladro\"). */\n actionLabel?: string;\n /** Full-control escape hatch (see `DataTableProps.renderRow`). */\n renderRow?: (args: {\n row: T;\n cells: React.ReactNode;\n rowKey: string;\n }) => React.ReactNode;\n /** Row expansion (resolved from `DataTableProps.renderExpanded`). */\n expandable?: boolean;\n expanded?: boolean;\n onToggleExpand?: (k: string) => void;\n expandLabel?: string;\n detailId?: string;\n}\n\nfunction DataTableRowImpl<T>({\n row, rowK, selected, selectable, selectAriaLabel, columns, onToggle,\n href, onActivate, actionLabel, renderRow,\n expandable, expanded, onToggleExpand, expandLabel, detailId,\n}: DataTableRowProps<T>) {\n const interactive = !renderRow && (!!href || !!onActivate);\n\n const cells = (\n <>\n {selectable && (\n <td className={cx(interactive && 'data-table__cell--above')}>\n <Checkbox\n checked={selected}\n onChange={() => onToggle(rowK)}\n aria-label={selectAriaLabel}\n />\n </td>\n )}\n {expandable && (\n <td className={cx(interactive && 'data-table__cell--above')}>\n <button\n type=\"button\"\n className=\"data-table__expand-btn\"\n aria-expanded={expanded}\n // Only reference the panel while it exists in the DOM — a\n // collapsed row's aria-controls would point at a missing id.\n aria-controls={expanded ? detailId : undefined}\n aria-label={expandLabel}\n onClick={() => onToggleExpand?.(rowK)}\n >\n <ChevronRight size={16} />\n </button>\n </td>\n )}\n {columns.map((c, ci) => {\n const align = c.align ?? (c.numeric ? 'right' : 'left');\n const value = c.accessor\n ? c.accessor(row)\n : (row as Record<string, unknown>)[c.key] as React.ReactNode;\n // data-label is consumed by the .data-table--cards CSS to surface\n // the column header as an inline label on each row when the table\n // collapses to a card layout on narrow viewports. Non-string\n // headers (e.g. JSX) can't be projected through `attr()` so we\n // omit the attribute and the cell renders without a visible label.\n const label = typeof c.header === 'string' ? c.header : undefined;\n return (\n <td\n key={c.key}\n // `table__align-*` makes alignment authoritative for ANY cell\n // content. `text-align` alone silently fails for a block/flex\n // child (e.g. an action column of buttons → floated left); the\n // class adds the matching `margin` auto so element children\n // honor `align` too. Left cells emit no extra class → byte-\n // identical to pre-1.10.0 (zero regression for the default).\n className={cx(\n c.numeric && 'table__num',\n align !== 'left' && `table__align-${align}`,\n )}\n style={{ textAlign: align }}\n data-label={label}\n >\n {/* Stretched row control: a real <a>/<button> in the first\n data cell, overlaying the whole row (the <tr> is the\n positioned ancestor). Keyboard-operable + SR-labelled +\n valid table markup — no role hacks, no onClick-only div.\n Visually empty; the cells stay the visible content. Other\n interactive cell content opts above it via\n `data-table__cell--above` (stretched-link pattern). */}\n {interactive && ci === 0 && (\n href ? (\n <a\n href={href}\n className=\"data-table__rowlink\"\n aria-label={actionLabel}\n onClick={onActivate}\n />\n ) : (\n <button\n type=\"button\"\n className=\"data-table__rowlink\"\n aria-label={actionLabel}\n onClick={onActivate}\n />\n )\n )}\n {value as React.ReactNode}\n </td>\n );\n })}\n </>\n );\n\n if (renderRow) return <>{renderRow({ row, cells, rowKey: rowK })}</>;\n\n return (\n <tr className={cx(selected && 'is-selected', interactive && 'is-clickable')}>\n {cells}\n </tr>\n );\n}\n\n// Cast preserves the generic signature through React.memo.\nconst DataTableRow = React.memo(DataTableRowImpl) as typeof DataTableRowImpl;\n\n// ---------- DataTable ----------------------------------------------------\nexport interface Column<T> {\n key: string;\n header: React.ReactNode;\n accessor?: (row: T) => React.ReactNode;\n sortable?: boolean;\n align?: 'left' | 'right' | 'center';\n width?: number | string;\n /**\n * Marks the column as numeric: cells get the `.table__num` class\n * (monospace + tabular alignment) and right-align by default.\n */\n numeric?: boolean;\n /**\n * Aggregate cell for this column (a total, a count, a \"Total\" label).\n * When ANY column sets it, the table renders a `<tfoot>` row styled like\n * the header band; in bounded (`maxHeight`) mode it stays pinned to the\n * bottom of the scroll box, so totals remain visible while rows scroll.\n * Aggregating is the consumer's job (the kit never sums for you — rows\n * may be a server page, and the page total ≠ the dataset total).\n * Only rendered with actual rows: the error / loading / empty states\n * have nothing meaningful to total. Hidden in `mobileLayout=\"cards\"`\n * (cells lose their column geometry there, like the header does).\n */\n footer?: React.ReactNode;\n}\n\nexport interface DataTableProps<T> {\n columns: Column<T>[];\n rows: T[];\n rowKey: (row: T) => string;\n sort?: { key: string; dir: 'asc' | 'desc' } | null;\n /**\n * Sorting is uncontrolled inside the table — consumers re-order `rows`\n * in response to `onSortChange`. Stability of equal-keyed rows is the\n * caller's responsibility (use a stable sort like `Array.prototype.sort`\n * in V8/Node ≥ 12, or a tiebreaker on rowKey).\n */\n onSortChange?: (s: { key: string; dir: 'asc' | 'desc' } | null) => void;\n selectable?: boolean;\n selectedKeys?: Set<string>;\n /**\n * \"Select all\" toggles only the rows currently passed to the component.\n * If the consumer paginates externally and only passes the visible page,\n * this selects the page — not the dataset across all pages.\n */\n onSelectionChange?: (keys: Set<string>) => void;\n empty?: React.ReactNode;\n /**\n * Renders an error state in place of the body. Takes precedence over\n * `loading`, `empty`, and rows. Use it when a fetch fails.\n */\n error?: React.ReactNode;\n loading?: boolean;\n /**\n * Keep the table header pinned while rows scroll past it\n * (`position: sticky`). The header sticks to the nearest scrolling\n * ancestor: pair it with `maxHeight` to scroll inside a bounded box, or\n * leave `maxHeight` unset to let the header stick to an outer scroller\n * (a `Modal` body, the page) — one scroll, no nested scrollbar.\n *\n * NOTE: a wide table needs its own horizontal scroll, which only exists in\n * the bounded (`maxHeight`) mode. Without `maxHeight` the wrap is not a\n * scroll container, so a wider-than-container table overflows its parent —\n * use `maxHeight` for wide tables, or keep the table within its width.\n */\n stickyHeader?: boolean;\n /**\n * Cap the table's height and scroll its body inside a bounded box (the\n * wrap becomes the vertical scroll container). Accepts any CSS length\n * (`'70vh'`, `480`, `'30rem'`). Combine with `stickyHeader` for a\n * scroll-region table whose header stays pinned to the box. Leaving this\n * unset (with `stickyHeader`) makes the header stick to an outer scroller\n * instead — see `stickyHeader`.\n */\n maxHeight?: string | number;\n /**\n * Layout for narrow viewports (`<600px`):\n * - `'table'` (default): the table scrolls horizontally inside its wrapper.\n * - `'cards'`: each row collapses to a stacked card with the column\n * header as an inline label per cell. Requires string `header` values\n * for the labels to appear; non-string headers render without a label.\n */\n mobileLayout?: 'table' | 'cards';\n /** Accessible name announced by screen readers (e.g. \"Pedidos abiertos\"). */\n ariaLabel?: string;\n /**\n * Builds the accessible label for the per-row checkbox so screen-reader\n * users can tell rows apart. Defaults to the row's key. Provide this\n * when the key isn't human-readable (e.g. a UUID).\n */\n rowLabel?: (row: T) => string;\n /**\n * Body density. Default `'compact'` (v1.10.0): a readable-dense register\n * (~30px rows, `--text-xs`, single-line cells) — the right default for\n * the data-heavy screens this kit serves (\"default = product\"). Pass\n * `'comfortable'` to opt back into the pre-1.10.0 airy 14px/16px rows\n * (which wrap to two lines).\n */\n density?: 'comfortable' | 'compact';\n /**\n * Makes every row a navigable link. The kit renders a real, keyboard-\n * operable, screen-reader-labelled `<a>` stretched over the row — valid\n * table markup (no `role` hacks, no `asChild` on `<tr>`, never an\n * onClick-only div). One Tab stop per row; Enter activates; the focus\n * ring shows on the row. Additive; combinable with `onRowClick`.\n */\n rowHref?: (row: T) => string;\n /**\n * Makes every row activate a callback (pointer **and** keyboard).\n * Renders a real stretched `<button>` with the same a11y guarantees as\n * `rowHref`. Prefer `rowHref` when the action is navigation.\n */\n onRowClick?: (row: T) => void;\n /**\n * Full-control escape hatch — the render-prop polymorphism the kit uses\n * for data/array-driven components (cf. `AppShell.linkAs`; deliberately\n * NOT `asChild`, which would emit invalid markup on `<tr>`). Receives the\n * row, the kit-rendered `cells`, and the row key; return your own row\n * element (e.g. a framework `<Link>` wrapping a `<tr>`). When set,\n * `rowHref`/`onRowClick` are ignored (you own row interactivity & a11y).\n */\n renderRow?: (args: {\n row: T;\n cells: React.ReactNode;\n rowKey: string;\n }) => React.ReactNode;\n /**\n * Row expansion: renders a detail panel under the row (an order's line\n * items, an audit trail). Setting it adds a chevron toggle column; the\n * open panel is an extra `<tr>` spanning every column, recessed on the\n * header's grey band. Controlled like selection: pair with\n * `expandedKeys`/`onExpandedChange`. The toggle is a real `<button>`\n * (`aria-expanded` + `aria-controls` while open) and stays clickable on\n * interactive rows (above the stretched row link). In\n * `mobileLayout=\"cards\"` the detail renders as its own card under the\n * row's card.\n */\n renderExpanded?: (row: T) => React.ReactNode;\n expandedKeys?: Set<string>;\n onExpandedChange?: (keys: Set<string>) => void;\n /**\n * Hides columns by key without mutating the canonical `columns` array —\n * the consumer keeps ONE column definition and toggles a `Set`. Header,\n * cells, totals footer, colSpans and mobile cards all follow. Pair with\n * `<ColumnToggle>` in the toolbar for the ready-made visibility menu.\n * Hiding every column is the consumer's foot-gun to avoid\n * (`ColumnToggle` already prevents it by disabling the last one).\n */\n hiddenColumnKeys?: Set<string>;\n /**\n * Fixed-height row windowing for large client-side datasets (1k-50k\n * rows): only the rows around the viewport hit the DOM; the rest become\n * two pixel-exact spacers. Requires `maxHeight` (the bounded scroller is\n * the measuring viewport) and UNIFORM row heights — it silently disables\n * itself when combined with `renderExpanded` (detail panels change row\n * heights) or `mobileLayout=\"cards\"` (cards re-flow every row), because\n * a correct full render beats a broken windowed one. Selection,\n * select-all and sorting keep operating on the FULL `rows` array — only\n * the DOM is windowed. Prefer server pagination when you have it; this\n * is for the genuinely client-side big list.\n */\n virtualizeRows?: { rowHeight: number; overscan?: number };\n /**\n * Toolbar / filter zone that shares the table's rounded surface. When\n * set, the DataTable renders it INSIDE its own border+radius+overflow\n * surface (`.table-surface`): the toolbar is clipped to the radius,\n * there is exactly one divider between it and the header, and the\n * header band's corner-rounding is dropped so the strip is clean in the\n * corner — no card-border + filter-border + header-top stack, no seam.\n * Accepts any node (`<TableToolbar>`, `<FilterBar>`, a custom row). The\n * legacy sibling pattern (`<TableToolbar/><DataTable/>`) still works.\n */\n toolbar?: React.ReactNode;\n /**\n * Surface chrome mode. Default `'card'`: the table draws its own\n * border + radius (and `--table-elevation` if set), the standalone\n * surface. `'flush'`: drops that chrome so the table sits clean inside\n * a parent that already owns the surface (a `<Card>`) without doubling\n * the border or nesting a radius. Use `'flush'` for the embedded-in-Card\n * case; leave the default for standalone tables.\n */\n surface?: 'card' | 'flush';\n className?: string;\n}\n\n/**\n * Tabular data renderer with optional sorting, selection, error/empty/\n * loading states.\n *\n * State priority (only one body state renders at a time):\n * error > loading > empty > rows\n *\n * Large datasets: prefer server pagination; for genuinely client-side big\n * lists use `virtualizeRows` (fixed-height windowing, v1.51.0).\n */\nexport function DataTable<T>({\n columns: allColumns, rows, rowKey,\n sort, onSortChange,\n selectable, selectedKeys, onSelectionChange,\n empty, error, loading, stickyHeader, maxHeight, mobileLayout = 'table',\n ariaLabel, rowLabel, className,\n density = 'compact', rowHref, onRowClick, renderRow, toolbar,\n renderExpanded, expandedKeys, onExpandedChange,\n hiddenColumnKeys, virtualizeRows,\n surface = 'card',\n}: DataTableProps<T>) {\n const t = useLocale();\n // Everything below sees only the visible columns; hiding is a pure\n // pre-filter so header/cells/footer/colSpans stay in sync for free.\n const columns = React.useMemo(\n () => (hiddenColumnKeys?.size ? allColumns.filter((c) => !hiddenColumnKeys.has(c.key)) : allColumns),\n [allColumns, hiddenColumnKeys]\n );\n const allSelected = selectable && rows.length > 0 && rows.every((r) => selectedKeys?.has(rowKey(r)));\n const someSelected = selectable && !allSelected && rows.some((r) => selectedKeys?.has(rowKey(r)));\n const headerCbRef = React.useRef<HTMLInputElement>(null);\n React.useEffect(() => {\n if (headerCbRef.current) headerCbRef.current.indeterminate = !!someSelected;\n }, [someSelected]);\n\n // On-scroll header elevation (bounded `maxHeight` + `stickyHeader` only).\n // A zero-height sentinel sits at the top of the inner scroll container; an\n // IntersectionObserver flips `stuck` when it leaves the scroller's top, so\n // the sticky header gains a soft drop shadow once content scrolls beneath\n // it. IO (not a scroll listener) → no per-frame work; SSR/jsdom-safe via\n // the `typeof` guard. Ancestor-stick mode keeps the flush header (the\n // outer scroller isn't ours to observe).\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const sentinelRef = React.useRef<HTMLDivElement>(null);\n const [stuck, setStuck] = React.useState(false);\n const elevatable = stickyHeader && maxHeight != null;\n React.useEffect(() => {\n if (!elevatable) { setStuck(false); return; }\n const root = scrollRef.current;\n const sentinel = sentinelRef.current;\n if (!root || !sentinel || typeof IntersectionObserver === 'undefined') return;\n const io = new IntersectionObserver(\n ([entry]) => setStuck(!entry.isIntersecting),\n { root, threshold: 0 },\n );\n io.observe(sentinel);\n return () => io.disconnect();\n }, [elevatable]);\n\n // Latest-props ref so toggleRow stays referentially stable across selection\n // changes. Without this, every selection update would create a new\n // toggleRow, defeating React.memo on DataTableRow.\n const propsRef = React.useRef({ rows, rowKey, selectedKeys, onSelectionChange, expandedKeys, onExpandedChange });\n propsRef.current = { rows, rowKey, selectedKeys, onSelectionChange, expandedKeys, onExpandedChange };\n\n const toggleAll = React.useCallback(() => {\n const { rows, rowKey, selectedKeys, onSelectionChange } = propsRef.current;\n if (!onSelectionChange) return;\n const allSel = rows.length > 0 && rows.every((r) => selectedKeys?.has(rowKey(r)));\n const next = new Set(selectedKeys);\n if (allSel) rows.forEach((r) => next.delete(rowKey(r)));\n else rows.forEach((r) => next.add(rowKey(r)));\n onSelectionChange(next);\n }, []);\n\n const toggleRow = React.useCallback((k: string) => {\n const { selectedKeys, onSelectionChange } = propsRef.current;\n if (!onSelectionChange) return;\n const next = new Set(selectedKeys);\n if (next.has(k)) next.delete(k); else next.add(k);\n onSelectionChange(next);\n }, []);\n\n const toggleExpand = React.useCallback((k: string) => {\n const { expandedKeys, onExpandedChange } = propsRef.current;\n if (!onExpandedChange) return;\n const next = new Set(expandedKeys);\n if (next.has(k)) next.delete(k); else next.add(k);\n onExpandedChange(next);\n }, []);\n\n const expandable = renderExpanded != null;\n // Stable per-table id base for the detail panels' aria-controls wiring.\n const tableId = React.useId();\n const totalCols = columns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0);\n\n // Row windowing — gated to the combinations where fixed-height math is\n // actually true (see the prop's JSDoc). When the gate is off the hook is\n // inert and returns the full range, so there is ONE render path below.\n const virtual =\n virtualizeRows != null && maxHeight != null && !expandable && mobileLayout !== 'cards';\n const vrange = useVirtualRows(scrollRef, {\n count: rows.length,\n rowHeight: virtualizeRows?.rowHeight ?? 1,\n overscan: virtualizeRows?.overscan,\n enabled: virtual,\n });\n\n const onSort = (col: Column<T>) => {\n if (!col.sortable || !onSortChange) return;\n if (!sort || sort.key !== col.key) onSortChange({ key: col.key, dir: 'asc' });\n else if (sort.dir === 'asc') onSortChange({ key: col.key, dir: 'desc' });\n else onSortChange(null);\n };\n\n const tableEl = (\n <table\n className={cx(\n 'table data-table',\n density === 'comfortable' && 'table--comfortable',\n )}\n aria-label={ariaLabel}\n // With windowing the DOM row count lies to assistive tech; declare\n // the real dataset size (+1 = the header row, per the ARIA spec).\n aria-rowcount={virtual ? rows.length + 1 : undefined}\n >\n <thead>\n <tr>\n {selectable && (\n <th scope=\"col\" style={{ width: 40 }}>\n <Checkbox\n ref={headerCbRef}\n checked={!!allSelected}\n onChange={toggleAll}\n aria-label={t['table.selectAll']}\n />\n </th>\n )}\n {/* Visually empty but properly named: it IS the column header\n of the toggle column (a `td` here would lose the thead band\n and sticky CSS, which target `thead th`). */}\n {expandable && <th scope=\"col\" style={{ width: 36 }} aria-label={t['table.expandColumn']} />}\n {columns.map((c) => {\n const active = sort?.key === c.key;\n const align = c.align ?? (c.numeric ? 'right' : 'left');\n const sortValue = c.sortable\n ? (active ? (sort!.dir === 'asc' ? 'ascending' : 'descending') : 'none')\n : undefined;\n const headerInner = (\n <span className=\"data-table__th\">\n {c.header}\n {c.sortable && (\n <span className=\"data-table__sort\" aria-hidden=\"true\">\n {active ? (sort!.dir === 'asc' ? <ChevronUp size={12} /> : <ChevronDown size={12} />) : <MoreVertical size={12} />}\n </span>\n )}\n </span>\n );\n return (\n <th\n key={c.key}\n scope=\"col\"\n style={{ width: c.width, textAlign: align }}\n aria-sort={sortValue}\n >\n {c.sortable ? (\n <button\n type=\"button\"\n className=\"data-table__sort-btn\"\n onClick={() => onSort(c)}\n >\n {headerInner}\n </button>\n ) : headerInner}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {error ? (\n <tr>\n <td\n colSpan={totalCols}\n className=\"data-table__error\"\n role=\"alert\"\n style={{ padding: 32, textAlign: 'center' }}\n >\n {error}\n </td>\n </tr>\n ) : loading ? (\n Array.from({ length: 5 }).map((_, i) => (\n <tr key={`s${i}`}>\n {selectable && <td><div className=\"skel\" style={{ height: 14 }} /></td>}\n {expandable && <td aria-hidden=\"true\" />}\n {columns.map((c) => <td key={c.key}><div className=\"skel\" style={{ height: 12, width: '70%' }} /></td>)}\n </tr>\n ))\n ) : rows.length === 0 ? (\n <tr>\n <td colSpan={totalCols} style={{ padding: 32 }}>\n {empty ?? <div style={{ textAlign: 'center', color: 'var(--fg-muted)' }}>{t['table.empty']}</div>}\n </td>\n </tr>\n ) : (\n <>\n {virtual && vrange.padTop > 0 && (\n <tr className=\"data-table__spacer\" aria-hidden=\"true\">\n <td colSpan={totalCols} style={{ height: vrange.padTop }} />\n </tr>\n )}\n {(virtual ? rows.slice(vrange.start, vrange.end) : rows).map((r) => {\n const k = rowKey(r);\n const label = rowLabel ? rowLabel(r) : k;\n const href = rowHref?.(r);\n const onActivate = onRowClick ? () => onRowClick(r) : undefined;\n const expanded = expandable && !!expandedKeys?.has(k);\n const detailId = `${tableId}-detail-${k}`;\n return (\n <React.Fragment key={k}>\n <DataTableRow\n row={r}\n rowK={k}\n selected={!!selectedKeys?.has(k)}\n selectable={!!selectable}\n selectAriaLabel={format(t['table.selectRow'], { label })}\n columns={columns}\n onToggle={toggleRow}\n href={href}\n onActivate={onActivate}\n actionLabel={format(t['table.rowAction'], { label })}\n renderRow={renderRow}\n expandable={expandable}\n expanded={expanded}\n onToggleExpand={toggleExpand}\n expandLabel={format(t['table.expandRow'], { label })}\n detailId={detailId}\n />\n {expanded && (\n <tr className=\"data-table__detail\">\n <td colSpan={totalCols} id={detailId}>\n {renderExpanded(r)}\n </td>\n </tr>\n )}\n </React.Fragment>\n );\n })}\n {virtual && vrange.padBottom > 0 && (\n <tr className=\"data-table__spacer\" aria-hidden=\"true\">\n <td colSpan={totalCols} style={{ height: vrange.padBottom }} />\n </tr>\n )}\n </>\n )}\n </tbody>\n {columns.some((c) => c.footer != null) && !error && !loading && rows.length > 0 && (\n <tfoot>\n <tr>\n {selectable && <td />}\n {expandable && <td aria-hidden=\"true\" />}\n {columns.map((c) => {\n const align = c.align ?? (c.numeric ? 'right' : 'left');\n return (\n <td\n key={c.key}\n className={cx(\n c.numeric && 'table__num',\n align !== 'left' && `table__align-${align}`,\n )}\n style={{ textAlign: align }}\n >\n {c.footer}\n </td>\n );\n })}\n </tr>\n </tfoot>\n )}\n </table>\n );\n // Bounded mode (`maxHeight`): the table lives in an inner scroll\n // container, while the outer `.table-wrap` keeps the border/radius and\n // `overflow: hidden` clips it cleanly — including the sticky header's\n // paint and the scrollbar corners. (A single element that is BOTH the\n // rounded box AND the sticky scroll container can't clip the sticky paint\n // to its radius in Chrome; splitting the two does, because the outer\n // clipping element is no longer the sticky's scroll container.)\n const wrap = (\n <div\n className={cx(\n 'table-wrap',\n stickyHeader && 'table-wrap--sticky',\n maxHeight != null && 'table-wrap--scroll',\n mobileLayout === 'cards' && 'table-wrap--cards',\n surface === 'flush' && toolbar == null && 'table-wrap--flush',\n className,\n )}\n >\n {maxHeight != null\n ? (\n <div\n ref={scrollRef}\n className={cx('table-wrap__scroll', stuck && 'is-stuck')}\n style={{ maxHeight }}\n >\n {elevatable && <div ref={sentinelRef} className=\"table-wrap__sentinel\" aria-hidden=\"true\" />}\n {tableEl}\n </div>\n )\n : tableEl}\n </div>\n );\n // No toolbar → byte-identical legacy output. With a toolbar, the\n // DataTable owns the single rounded+clipped+bordered surface; the inner\n // .table-wrap defers its border/radius (CSS) and stays the scroll/sticky\n // context, so existing behaviour is untouched.\n return toolbar == null ? wrap : (\n <div className={cx('table-surface', surface === 'flush' && 'table-surface--flush')}>\n <div className=\"table-surface__bar\">{toolbar}</div>\n {wrap}\n </div>\n );\n}\n\n// ---------- Accordion ----------------------------------------------------\ninterface AccordionContextValue {\n open: Set<string>;\n toggle: (id: string) => void;\n multiple: boolean;\n}\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\nexport interface AccordionProps {\n multiple?: boolean;\n defaultOpen?: string[];\n children: React.ReactNode;\n className?: string;\n}\n\nexport function Accordion({ multiple = false, defaultOpen = [], children, className }: AccordionProps) {\n const [open, setOpen] = React.useState<Set<string>>(new Set(defaultOpen));\n const toggle = (id: string) => {\n setOpen((curr) => {\n const next = new Set(curr);\n if (next.has(id)) next.delete(id);\n else {\n if (!multiple) next.clear();\n next.add(id);\n }\n return next;\n });\n };\n return (\n <AccordionContext.Provider value={{ open, toggle, multiple }}>\n <div className={cx('accordion', className)}>{children}</div>\n </AccordionContext.Provider>\n );\n}\n\nexport function AccordionItem({ id, title, children }: { id: string; title: React.ReactNode; children: React.ReactNode }) {\n const ctx = React.useContext(AccordionContext);\n if (!ctx) throw new Error('<AccordionItem> must be used inside <Accordion>');\n const isOpen = ctx.open.has(id);\n const reactId = React.useId();\n const triggerId = `accordion-trigger-${reactId}`;\n const panelId = `accordion-panel-${reactId}`;\n return (\n <div className={cx('accordion__item', isOpen && 'is-open')}>\n <button\n type=\"button\"\n id={triggerId}\n className=\"accordion__trigger\"\n aria-expanded={isOpen}\n aria-controls={panelId}\n onClick={() => ctx.toggle(id)}\n >\n <span>{title}</span>\n <span className=\"accordion__chev\" aria-hidden=\"true\"><ChevronDown size={14} /></span>\n </button>\n {isOpen && (\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={triggerId}\n className=\"accordion__panel\"\n >\n {children}\n </div>\n )}\n </div>\n );\n}\n\n// ---------- Breadcrumbs --------------------------------------------------\nexport interface BreadcrumbItem {\n label: React.ReactNode;\n href?: string;\n}\n\nexport function Breadcrumbs({ items, className }: { items: BreadcrumbItem[]; className?: string }) {\n return (\n <nav aria-label=\"Breadcrumb\" className={cx('breadcrumbs', className)}>\n <ol>\n {items.map((it, i) => {\n const last = i === items.length - 1;\n return (\n <li key={i}>\n {it.href && !last ? <a href={it.href}>{it.label}</a> : <span aria-current={last ? 'page' : undefined}>{it.label}</span>}\n {!last && <span aria-hidden=\"true\" className=\"breadcrumbs__sep\">/</span>}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n}\n\n// ---------- TablePagination ---------------------------------------------\n// Convenience wrapper that pairs a page-size selector with a Pagination\n// row. Use it under a DataTable when the table is paginated externally.\nimport { Pagination } from './Inputs';\n\nexport interface TablePaginationProps {\n page: number;\n pageSize: number;\n total: number;\n onPageChange: (page: number) => void;\n /** If set, renders a page-size selector. Omit for fixed-size pagination. */\n onPageSizeChange?: (size: number) => void;\n /** Options shown in the page-size selector. Default `[10, 25, 50, 100]`. */\n pageSizeOptions?: readonly number[];\n className?: string;\n}\n\nexport function TablePagination({\n page, pageSize, total, onPageChange,\n onPageSizeChange, pageSizeOptions = [10, 25, 50, 100],\n className,\n}: TablePaginationProps) {\n const t = useLocale();\n const selectId = React.useId();\n return (\n <div className={cx('table-pagination', className)}>\n {onPageSizeChange && (\n <label className=\"table-pagination__size\" htmlFor={selectId}>\n <span>{t['pagination.rowsPerPage']}</span>\n <select\n id={selectId}\n className=\"select\"\n value={pageSize}\n onChange={(e) => onPageSizeChange(Number(e.target.value))}\n >\n {pageSizeOptions.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n )}\n <Pagination\n page={page}\n pageSize={pageSize}\n total={total}\n onPageChange={onPageChange}\n />\n </div>\n );\n}\n\n// ---------- TableToolbar -------------------------------------------------\n// Barra superior que se compone arriba (o dentro de un wrapper) de un DataTable.\n// Cualquier hijo con className \"grow\" se expande para empujar las acciones al lado.\nexport const TableToolbar = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n function TableToolbar({ className, ...rest }, ref) {\n return <div ref={ref} className={cx('table-toolbar', className)} {...rest} />;\n }\n);\n\n// ---------- ColumnToggle ---------------------------------------------------\nexport interface ColumnToggleProps {\n /**\n * The CANONICAL column list (pass the same array the table gets, or a\n * `{key, header}` subset) — the menu lists every column regardless of\n * current visibility. Non-string headers render as-is in the menu.\n */\n columns: Array<{ key: string; header: React.ReactNode }>;\n hiddenKeys: Set<string>;\n onChange: (keys: Set<string>) => void;\n /** Trigger label. Defaults to the `table.columns` locale string. */\n label?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Ready-made column-visibility menu for the table toolbar: a button that\n * opens a checkbox list, driving `DataTable.hiddenColumnKeys`. The popover\n * stays open across toggles (multi-adjust without reopening). The last\n * visible column's checkbox is disabled — a table with zero columns is a\n * broken state no menu should be able to reach.\n */\nexport function ColumnToggle({ columns, hiddenKeys, onChange, label, className }: ColumnToggleProps) {\n const t = useLocale();\n const visibleCount = columns.length - columns.filter((c) => hiddenKeys.has(c.key)).length;\n const toggle = (key: string) => {\n const next = new Set(hiddenKeys);\n if (next.has(key)) next.delete(key); else next.add(key);\n onChange(next);\n };\n return (\n <Popover\n className={className}\n placement=\"bottom\"\n align=\"end\"\n ariaLabel={t['table.columns']}\n trigger={<Button type=\"button\" variant=\"secondary\" size=\"sm\">{label ?? t['table.columns']}</Button>}\n >\n <div className=\"column-toggle\" role=\"group\" aria-label={t['table.columns']}>\n {columns.map((c) => {\n const visible = !hiddenKeys.has(c.key);\n // Checkbox already renders a <label> wrapper with `children` as\n // the label text — wrapping it in another label would nest labels\n // (invalid HTML). Compose via children instead.\n return (\n <Checkbox\n key={c.key}\n className=\"column-toggle__item\"\n checked={visible}\n disabled={visible && visibleCount === 1}\n onChange={() => toggle(c.key)}\n >\n {c.header}\n </Checkbox>\n );\n })}\n </div>\n </Popover>\n );\n}\n"]}
@@ -3,6 +3,7 @@ import { Popover } from './chunk-FR4JV3JA.mjs';
3
3
  import { Pagination } from './chunk-YEIU5W7E.mjs';
4
4
  import { Checkbox } from './chunk-SUQLII3F.mjs';
5
5
  import { format } from './chunk-SDR7JKDF.mjs';
6
+ import { useVirtualRows } from './chunk-YTKPENNW.mjs';
6
7
  import { useLocale } from './chunk-H6ZT2DJ2.mjs';
7
8
  import { Button } from './chunk-NAL457NQ.mjs';
8
9
  import { ChevronRight, ChevronUp, ChevronDown, MoreVertical } from './chunk-BJGMROKL.mjs';
@@ -119,6 +120,7 @@ function DataTable({
119
120
  expandedKeys,
120
121
  onExpandedChange,
121
122
  hiddenColumnKeys,
123
+ virtualizeRows,
122
124
  surface = "card"
123
125
  }) {
124
126
  const t = useLocale();
@@ -181,6 +183,13 @@ function DataTable({
181
183
  const expandable = renderExpanded != null;
182
184
  const tableId = React.useId();
183
185
  const totalCols = columns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0);
186
+ const virtual = virtualizeRows != null && maxHeight != null && !expandable && mobileLayout !== "cards";
187
+ const vrange = useVirtualRows(scrollRef, {
188
+ count: rows.length,
189
+ rowHeight: virtualizeRows?.rowHeight ?? 1,
190
+ overscan: virtualizeRows?.overscan,
191
+ enabled: virtual
192
+ });
184
193
  const onSort = (col) => {
185
194
  if (!col.sortable || !onSortChange) return;
186
195
  if (!sort || sort.key !== col.key) onSortChange({ key: col.key, dir: "asc" });
@@ -195,6 +204,7 @@ function DataTable({
195
204
  density === "comfortable" && "table--comfortable"
196
205
  ),
197
206
  "aria-label": ariaLabel,
207
+ "aria-rowcount": virtual ? rows.length + 1 : void 0,
198
208
  children: [
199
209
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
200
210
  selectable && /* @__PURE__ */ jsx("th", { scope: "col", style: { width: 40 }, children: /* @__PURE__ */ jsx(
@@ -248,38 +258,42 @@ function DataTable({
248
258
  selectable && /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("div", { className: "skel", style: { height: 14 } }) }),
249
259
  expandable && /* @__PURE__ */ jsx("td", { "aria-hidden": "true" }),
250
260
  columns.map((c) => /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("div", { className: "skel", style: { height: 12, width: "70%" } }) }, c.key))
251
- ] }, `s${i}`)) : rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: totalCols, style: { padding: 32 }, children: empty ?? /* @__PURE__ */ jsx("div", { style: { textAlign: "center", color: "var(--fg-muted)" }, children: t["table.empty"] }) }) }) : rows.map((r) => {
252
- const k = rowKey(r);
253
- const label = rowLabel ? rowLabel(r) : k;
254
- const href = rowHref?.(r);
255
- const onActivate = onRowClick ? () => onRowClick(r) : void 0;
256
- const expanded = expandable && !!expandedKeys?.has(k);
257
- const detailId = `${tableId}-detail-${k}`;
258
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
259
- /* @__PURE__ */ jsx(
260
- DataTableRow,
261
- {
262
- row: r,
263
- rowK: k,
264
- selected: !!selectedKeys?.has(k),
265
- selectable: !!selectable,
266
- selectAriaLabel: format(t["table.selectRow"], { label }),
267
- columns,
268
- onToggle: toggleRow,
269
- href,
270
- onActivate,
271
- actionLabel: format(t["table.rowAction"], { label }),
272
- renderRow,
273
- expandable,
274
- expanded,
275
- onToggleExpand: toggleExpand,
276
- expandLabel: format(t["table.expandRow"], { label }),
277
- detailId
278
- }
279
- ),
280
- expanded && /* @__PURE__ */ jsx("tr", { className: "data-table__detail", children: /* @__PURE__ */ jsx("td", { colSpan: totalCols, id: detailId, children: renderExpanded(r) }) })
281
- ] }, k);
282
- }) }),
261
+ ] }, `s${i}`)) : rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: totalCols, style: { padding: 32 }, children: empty ?? /* @__PURE__ */ jsx("div", { style: { textAlign: "center", color: "var(--fg-muted)" }, children: t["table.empty"] }) }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
262
+ virtual && vrange.padTop > 0 && /* @__PURE__ */ jsx("tr", { className: "data-table__spacer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("td", { colSpan: totalCols, style: { height: vrange.padTop } }) }),
263
+ (virtual ? rows.slice(vrange.start, vrange.end) : rows).map((r) => {
264
+ const k = rowKey(r);
265
+ const label = rowLabel ? rowLabel(r) : k;
266
+ const href = rowHref?.(r);
267
+ const onActivate = onRowClick ? () => onRowClick(r) : void 0;
268
+ const expanded = expandable && !!expandedKeys?.has(k);
269
+ const detailId = `${tableId}-detail-${k}`;
270
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
271
+ /* @__PURE__ */ jsx(
272
+ DataTableRow,
273
+ {
274
+ row: r,
275
+ rowK: k,
276
+ selected: !!selectedKeys?.has(k),
277
+ selectable: !!selectable,
278
+ selectAriaLabel: format(t["table.selectRow"], { label }),
279
+ columns,
280
+ onToggle: toggleRow,
281
+ href,
282
+ onActivate,
283
+ actionLabel: format(t["table.rowAction"], { label }),
284
+ renderRow,
285
+ expandable,
286
+ expanded,
287
+ onToggleExpand: toggleExpand,
288
+ expandLabel: format(t["table.expandRow"], { label }),
289
+ detailId
290
+ }
291
+ ),
292
+ expanded && /* @__PURE__ */ jsx("tr", { className: "data-table__detail", children: /* @__PURE__ */ jsx("td", { colSpan: totalCols, id: detailId, children: renderExpanded(r) }) })
293
+ ] }, k);
294
+ }),
295
+ virtual && vrange.padBottom > 0 && /* @__PURE__ */ jsx("tr", { className: "data-table__spacer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("td", { colSpan: totalCols, style: { height: vrange.padBottom } }) })
296
+ ] }) }),
283
297
  columns.some((c) => c.footer != null) && !error && !loading && rows.length > 0 && /* @__PURE__ */ jsx("tfoot", { children: /* @__PURE__ */ jsxs("tr", { children: [
284
298
  selectable && /* @__PURE__ */ jsx("td", {}),
285
299
  expandable && /* @__PURE__ */ jsx("td", { "aria-hidden": "true" }),
@@ -469,5 +483,5 @@ function ColumnToggle({ columns, hiddenKeys, onChange, label, className }) {
469
483
  }
470
484
 
471
485
  export { Accordion, AccordionItem, Breadcrumbs, ColumnToggle, DataTable, TablePagination, TableToolbar };
472
- //# sourceMappingURL=chunk-LPKS5CM5.mjs.map
473
- //# sourceMappingURL=chunk-LPKS5CM5.mjs.map
486
+ //# sourceMappingURL=chunk-VNRZAYM7.mjs.map
487
+ //# sourceMappingURL=chunk-VNRZAYM7.mjs.map