@zvndev/yable-react 0.4.0 → 0.5.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.
package/dist/index.cjs CHANGED
@@ -3,6 +3,7 @@
3
3
  var yableCore = require('@zvndev/yable-core');
4
4
  var React3 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var reactDom = require('react-dom');
6
7
  var rowDragging = require('@zvndev/yable-core/features/rowDragging');
7
8
 
8
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -16,6 +17,8 @@ function useYableDefaults() {
16
17
  }
17
18
  function YableProvider({
18
19
  children,
20
+ config,
21
+ tableProfile,
19
22
  defaultColumnDef,
20
23
  striped,
21
24
  stickyHeader,
@@ -34,12 +37,86 @@ function YableProvider({
34
37
  if (direction !== void 0) tableProps.direction = direction;
35
38
  if (ariaLabel !== void 0) tableProps.ariaLabel = ariaLabel;
36
39
  const value = {
40
+ config,
41
+ tableProfile,
37
42
  tableProps: Object.keys(tableProps).length > 0 ? tableProps : void 0,
38
43
  defaultColumnDef
39
44
  };
40
45
  return /* @__PURE__ */ jsxRuntime.jsx(YableContext.Provider, { value, children });
41
46
  }
42
47
 
48
+ // src/config.ts
49
+ function createYableConfig(config) {
50
+ return config;
51
+ }
52
+ function resolveYableProfile(config, profileName = "default") {
53
+ const base = pickProfileFields(config);
54
+ const named = profileName === "default" ? void 0 : config?.profiles?.[profileName];
55
+ return {
56
+ name: profileName,
57
+ table: { ...base.table, ...named?.table },
58
+ columns: {
59
+ default: { ...base.columns?.default, ...named?.columns?.default },
60
+ byId: { ...base.columns?.byId, ...named?.columns?.byId }
61
+ },
62
+ rows: { ...base.rows, ...named?.rows },
63
+ cells: {
64
+ default: { ...base.cells?.default, ...named?.cells?.default },
65
+ named: { ...base.cells?.named, ...named?.cells?.named },
66
+ byColumn: { ...base.cells?.byColumn, ...named?.cells?.byColumn }
67
+ }
68
+ };
69
+ }
70
+ function getYableDefaultColumnDef(profile) {
71
+ const next = {
72
+ ...profile?.columns?.default
73
+ };
74
+ return Object.keys(next).length > 0 ? next : void 0;
75
+ }
76
+ function applyYableConfigToColumns(columns, profile) {
77
+ if (!profile) return columns;
78
+ return columns.map((columnDef) => applyColumnConfig(columnDef, profile));
79
+ }
80
+ function applyColumnConfig(columnDef, profile) {
81
+ const columnId = getColumnId(columnDef);
82
+ const explicit = columnDef;
83
+ const cellNames = normalizeCellConfigNames(explicit.cellConfig);
84
+ const namedCellConfig = cellNames.reduce(
85
+ (acc, name) => ({ ...acc, ...profile.cells?.named?.[name] }),
86
+ {}
87
+ );
88
+ const defaultCell = profile.cells?.default;
89
+ const columnCell = columnId ? profile.cells?.byColumn?.[columnId] : void 0;
90
+ const columnConfig = columnId ? profile.columns?.byId?.[columnId] : void 0;
91
+ const children = "columns" in columnDef && columnDef.columns ? { columns: columnDef.columns.map((child) => applyColumnConfig(child, profile)) } : void 0;
92
+ return {
93
+ ...defaultCell,
94
+ ...namedCellConfig,
95
+ ...columnCell,
96
+ ...columnConfig,
97
+ ...columnDef,
98
+ ...children
99
+ };
100
+ }
101
+ function pickProfileFields(config) {
102
+ if (!config) return {};
103
+ return {
104
+ table: config.table,
105
+ columns: config.columns,
106
+ rows: config.rows,
107
+ cells: config.cells
108
+ };
109
+ }
110
+ function getColumnId(columnDef) {
111
+ if ("id" in columnDef && columnDef.id) return String(columnDef.id);
112
+ if ("accessorKey" in columnDef && columnDef.accessorKey) return String(columnDef.accessorKey);
113
+ return void 0;
114
+ }
115
+ function normalizeCellConfigNames(value) {
116
+ if (!value) return [];
117
+ return Array.isArray(value) ? value : [value];
118
+ }
119
+
43
120
  // src/useTable.ts
44
121
  function shallowEqual(a, b) {
45
122
  if (a === b) return true;
@@ -55,15 +132,30 @@ function shallowEqual(a, b) {
55
132
  function useTable(options) {
56
133
  const providerDefaults = useYableDefaults();
57
134
  const optionsWithDefaults = React3.useMemo(() => {
58
- if (!providerDefaults.defaultColumnDef) return options;
135
+ const profile = resolveYableProfile(
136
+ options.config ?? providerDefaults.config,
137
+ options.configProfile ?? providerDefaults.tableProfile
138
+ );
139
+ const profileDefaultColumnDef = getYableDefaultColumnDef(profile);
140
+ const configuredColumns = applyYableConfigToColumns(options.columns, profile);
141
+ const defaultColumnDef = {
142
+ ...profileDefaultColumnDef,
143
+ ...providerDefaults.defaultColumnDef,
144
+ ...options.defaultColumnDef
145
+ };
59
146
  return {
60
147
  ...options,
61
- defaultColumnDef: {
62
- ...providerDefaults.defaultColumnDef,
63
- ...options.defaultColumnDef
64
- }
148
+ columns: configuredColumns,
149
+ rowClassName: options.rowClassName ?? profile.rows?.className,
150
+ rowStyle: options.rowStyle ?? profile.rows?.style,
151
+ defaultColumnDef: Object.keys(defaultColumnDef).length > 0 ? defaultColumnDef : void 0
65
152
  };
66
- }, [options, providerDefaults.defaultColumnDef]);
153
+ }, [
154
+ options,
155
+ providerDefaults.config,
156
+ providerDefaults.defaultColumnDef,
157
+ providerDefaults.tableProfile
158
+ ]);
67
159
  const [state, setState] = React3.useState(() => ({
68
160
  sorting: [],
69
161
  columnFilters: [],
@@ -149,6 +241,32 @@ function useTable(options) {
149
241
  })
150
242
  );
151
243
  }
244
+ React3.useEffect(() => {
245
+ const table = tableRef.current;
246
+ if (!table) return;
247
+ const unsubscribers = [
248
+ options.onCellClick && table.events.on("cell:click", options.onCellClick),
249
+ options.onCellDoubleClick && table.events.on("cell:dblclick", options.onCellDoubleClick),
250
+ options.onCellContextMenu && table.events.on("cell:contextmenu", options.onCellContextMenu),
251
+ options.onRowClick && table.events.on("row:click", options.onRowClick),
252
+ options.onRowDoubleClick && table.events.on("row:dblclick", options.onRowDoubleClick),
253
+ options.onRowContextMenu && table.events.on("row:contextmenu", options.onRowContextMenu),
254
+ options.onHeaderClick && table.events.on("header:click", options.onHeaderClick),
255
+ options.onHeaderContextMenu && table.events.on("header:contextmenu", options.onHeaderContextMenu)
256
+ ].filter((unsubscribe) => Boolean(unsubscribe));
257
+ return () => {
258
+ unsubscribers.forEach((unsubscribe) => unsubscribe());
259
+ };
260
+ }, [
261
+ options.onCellClick,
262
+ options.onCellContextMenu,
263
+ options.onCellDoubleClick,
264
+ options.onHeaderClick,
265
+ options.onHeaderContextMenu,
266
+ options.onRowClick,
267
+ options.onRowContextMenu,
268
+ options.onRowDoubleClick
269
+ ]);
152
270
  React3.useEffect(() => {
153
271
  return () => {
154
272
  if (tableRef.current) {
@@ -158,6 +276,195 @@ function useTable(options) {
158
276
  }, []);
159
277
  return tableRef.current;
160
278
  }
279
+ function useServerTable({
280
+ fetchData,
281
+ updateRow,
282
+ initialRows = [],
283
+ initialCursor = null,
284
+ initialHasMore = true,
285
+ initialRowCount,
286
+ initialPageCount,
287
+ initialSorting = [],
288
+ initialColumnFilters = [],
289
+ initialGlobalFilter = "",
290
+ initialPagination = { pageIndex: 0, pageSize: 50 },
291
+ autoLoad = true,
292
+ getRowId,
293
+ ...tableOptions
294
+ }) {
295
+ const [rows, setRows] = React3.useState(initialRows);
296
+ const [cursor, setCursor] = React3.useState(initialCursor);
297
+ const [hasMore, setHasMore] = React3.useState(initialHasMore);
298
+ const [rowCount, setRowCount] = React3.useState(initialRowCount);
299
+ const [pageCount, setPageCount] = React3.useState(initialPageCount);
300
+ const [sorting, setSorting] = React3.useState(initialSorting);
301
+ const [columnFilters, setColumnFilters] = React3.useState(initialColumnFilters);
302
+ const [globalFilter, setGlobalFilter] = React3.useState(initialGlobalFilter);
303
+ const [pagination, setPagination] = React3.useState(initialPagination);
304
+ const [loading, setLoading] = React3.useState(false);
305
+ const [error, setError] = React3.useState(null);
306
+ const abortRef = React3.useRef(null);
307
+ const cursorRef = React3.useRef(cursor);
308
+ const fetchDataRef = React3.useRef(fetchData);
309
+ const updateRowRef = React3.useRef(updateRow);
310
+ const resolveRowId = React3.useCallback(
311
+ (row, index) => getRowId?.(row, index) ?? String(row.id ?? index),
312
+ [getRowId]
313
+ );
314
+ const runFetch = React3.useCallback(
315
+ async (mode) => {
316
+ abortRef.current?.abort();
317
+ const abort = new AbortController();
318
+ abortRef.current = abort;
319
+ setLoading(true);
320
+ setError(null);
321
+ try {
322
+ const result = await fetchDataRef.current({
323
+ sorting,
324
+ columnFilters,
325
+ globalFilter,
326
+ pagination,
327
+ cursor: mode === "append" ? cursorRef.current : null,
328
+ signal: abort.signal
329
+ });
330
+ if (abort.signal.aborted) return;
331
+ setRows((prev) => mode === "append" ? [...prev, ...result.rows] : result.rows);
332
+ setCursor(result.cursor ?? null);
333
+ setHasMore((prev) => result.hasMore ?? prev);
334
+ setRowCount((prev) => result.rowCount ?? prev);
335
+ setPageCount((prev) => result.pageCount ?? prev);
336
+ } catch (nextError) {
337
+ if (!abort.signal.aborted) setError(nextError);
338
+ } finally {
339
+ if (!abort.signal.aborted) setLoading(false);
340
+ }
341
+ },
342
+ [columnFilters, globalFilter, pagination, sorting]
343
+ );
344
+ const refresh = React3.useCallback(() => runFetch("replace"), [runFetch]);
345
+ const loadMore = React3.useCallback(async () => {
346
+ if (!hasMore || loading) return;
347
+ await runFetch("append");
348
+ }, [hasMore, loading, runFetch]);
349
+ const patchRow = React3.useCallback(
350
+ async (rowId, patch) => {
351
+ const previousRow = rows.find((row, index) => resolveRowId(row, index) === rowId);
352
+ setRows(
353
+ (prev) => prev.map((row, index) => resolveRowId(row, index) === rowId ? { ...row, ...patch } : row)
354
+ );
355
+ if (!updateRowRef.current) return;
356
+ const abort = new AbortController();
357
+ try {
358
+ const result = await updateRowRef.current({
359
+ rowId,
360
+ patch,
361
+ previousRow,
362
+ signal: abort.signal
363
+ });
364
+ if (!result) return;
365
+ setRows(
366
+ (prev) => prev.map(
367
+ (row, index) => resolveRowId(row, index) === rowId ? { ...row, ...result } : row
368
+ )
369
+ );
370
+ } catch (nextError) {
371
+ setError(nextError);
372
+ if (previousRow) {
373
+ setRows(
374
+ (prev) => prev.map((row, index) => resolveRowId(row, index) === rowId ? previousRow : row)
375
+ );
376
+ }
377
+ }
378
+ },
379
+ [resolveRowId, rows]
380
+ );
381
+ React3.useEffect(() => {
382
+ fetchDataRef.current = fetchData;
383
+ }, [fetchData]);
384
+ React3.useEffect(() => {
385
+ updateRowRef.current = updateRow;
386
+ }, [updateRow]);
387
+ React3.useEffect(() => {
388
+ if (!autoLoad) return;
389
+ void refresh();
390
+ }, [autoLoad, refresh]);
391
+ React3.useEffect(() => {
392
+ cursorRef.current = cursor;
393
+ }, [cursor]);
394
+ React3.useEffect(() => () => abortRef.current?.abort(), []);
395
+ const table = useTable({
396
+ ...tableOptions,
397
+ data: rows,
398
+ getRowId: resolveRowId,
399
+ manualSorting: true,
400
+ manualFiltering: true,
401
+ manualPagination: true,
402
+ rowCount,
403
+ pageCount,
404
+ state: {
405
+ sorting,
406
+ columnFilters,
407
+ globalFilter,
408
+ pagination
409
+ },
410
+ onSortingChange: (updater) => {
411
+ setSorting((prev) => yableCore.functionalUpdate(updater, prev));
412
+ setCursor(null);
413
+ setHasMore(true);
414
+ },
415
+ onColumnFiltersChange: (updater) => {
416
+ setColumnFilters((prev) => yableCore.functionalUpdate(updater, prev));
417
+ setCursor(null);
418
+ setHasMore(true);
419
+ },
420
+ onGlobalFilterChange: (updater) => {
421
+ setGlobalFilter((prev) => yableCore.functionalUpdate(updater, prev));
422
+ setCursor(null);
423
+ setHasMore(true);
424
+ },
425
+ onPaginationChange: (updater) => {
426
+ setPagination((prev) => yableCore.functionalUpdate(updater, prev));
427
+ setCursor(null);
428
+ setHasMore(true);
429
+ }
430
+ });
431
+ return React3.useMemo(
432
+ () => ({
433
+ table,
434
+ rows,
435
+ loading,
436
+ error,
437
+ cursor,
438
+ hasMore,
439
+ rowCount,
440
+ pageCount,
441
+ sorting,
442
+ columnFilters,
443
+ globalFilter,
444
+ pagination,
445
+ refresh,
446
+ loadMore,
447
+ updateRow: patchRow
448
+ }),
449
+ [
450
+ table,
451
+ rows,
452
+ loading,
453
+ error,
454
+ cursor,
455
+ hasMore,
456
+ rowCount,
457
+ pageCount,
458
+ sorting,
459
+ columnFilters,
460
+ globalFilter,
461
+ pagination,
462
+ refresh,
463
+ loadMore,
464
+ patchRow
465
+ ]
466
+ );
467
+ }
161
468
  var DEFAULT_PERSISTED_KEYS = [
162
469
  "columnVisibility",
163
470
  "columnOrder",
@@ -354,7 +661,7 @@ function useVirtualization({
354
661
  resizeObserver.disconnect();
355
662
  }
356
663
  };
357
- }, [containerRef]);
664
+ }, [containerRef, totalRows]);
358
665
  React3.useEffect(() => {
359
666
  if (!isFixedHeight) {
360
667
  heightCacheRef.current.clear();
@@ -545,14 +852,20 @@ function useColumnVirtualization({
545
852
  containerRef,
546
853
  columns,
547
854
  overscan = 2,
548
- enabled = true
855
+ enabled = true,
856
+ sizingKey
549
857
  }) {
550
858
  const [scrollState, setScrollState] = React3.useState({
551
859
  scrollLeft: 0,
552
860
  containerWidth: 0
553
861
  });
554
862
  const rafRef = React3.useRef(null);
555
- const sizes = React3.useMemo(() => columns.map((column) => column.getSize()), [columns]);
863
+ const sizes = React3.useMemo(
864
+ () => columns.map((column) => column.getSize()),
865
+ // `sizingKey` is an explicit invalidation hook for stable Column objects whose getSize value changed.
866
+ // eslint-disable-next-line react-hooks/exhaustive-deps
867
+ [columns, sizingKey]
868
+ );
556
869
  const offsets = React3.useMemo(() => {
557
870
  const next = new Array(columns.length + 1);
558
871
  next[0] = 0;
@@ -1130,12 +1443,12 @@ function getRegisteredCellTypes() {
1130
1443
 
1131
1444
  // src/hooks/useAutoMeasurements.ts
1132
1445
  var NON_DATA_COLUMN_IDS = /* @__PURE__ */ new Set(["select", "expand", "drag", "actions"]);
1133
- function getColumnId(col) {
1446
+ function getColumnId2(col) {
1134
1447
  const id = col.id ?? col.accessorKey;
1135
1448
  return typeof id === "string" ? id : void 0;
1136
1449
  }
1137
1450
  function defaultShouldMeasure(col) {
1138
- const id = getColumnId(col);
1451
+ const id = getColumnId2(col);
1139
1452
  if (!id) return false;
1140
1453
  if (id.startsWith("_")) return false;
1141
1454
  if (NON_DATA_COLUMN_IDS.has(id)) return false;
@@ -1160,11 +1473,11 @@ function useAutoMeasurements({
1160
1473
  getColumnWidth = defaultGetColumnWidth,
1161
1474
  shouldMeasureColumn = defaultShouldMeasure
1162
1475
  }) {
1163
- const widthKey = columns.map((c) => `${getColumnId(c) ?? "?"}:${getColumnWidth(c)}`).join("|");
1476
+ const widthKey = columns.map((c) => `${getColumnId2(c) ?? "?"}:${getColumnWidth(c)}`).join("|");
1164
1477
  return React3.useMemo(() => {
1165
1478
  const result = [];
1166
1479
  for (const col of columns) {
1167
- const id = getColumnId(col);
1480
+ const id = getColumnId2(col);
1168
1481
  if (!id) continue;
1169
1482
  if (!shouldMeasureColumn(col)) continue;
1170
1483
  const recipe = resolveMeasureRecipe(col, defaultRecipe);
@@ -1483,16 +1796,170 @@ function FloatingFilter({ column }) {
1483
1796
  }
1484
1797
  ) });
1485
1798
  }
1486
- var DRAG_MIME = "application/yable-column";
1799
+ var REORDER_TRANSITION = "transform 180ms cubic-bezier(0.2, 0, 0, 1)";
1800
+ function transformAt(i, d) {
1801
+ if (i === d.fromIndex) return 0;
1802
+ if (d.toIndex > d.fromIndex) return i > d.fromIndex && i < d.toIndex ? -d.width : 0;
1803
+ return i >= d.toIndex && i < d.fromIndex ? d.width : 0;
1804
+ }
1487
1805
  function TableHeader({
1488
1806
  table,
1489
1807
  floatingFilters = false
1490
1808
  }) {
1491
1809
  const headerGroups = table.getHeaderGroups();
1492
1810
  const visibleColumns = table.getVisibleLeafColumns();
1493
- return /* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "yable-thead", children: [
1494
- headerGroups.map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row", children: headerGroup.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(HeaderCell, { header, table }, header.id)) }, headerGroup.id)),
1495
- floatingFilters && visibleColumns.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row yable-header-row--filters", children: visibleColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(FloatingFilterCell, { column }, `${column.id}-filter`)) })
1811
+ const theadRef = React3.useRef(null);
1812
+ const reorderEndRef = React3.useRef(0);
1813
+ const [drag, setDrag] = React3.useState(null);
1814
+ const commitReorder = React3.useCallback(
1815
+ (d) => {
1816
+ if (d.toIndex === d.fromIndex || d.toIndex === d.fromIndex + 1) return;
1817
+ const order = table.getState().columnOrder;
1818
+ const base = order && order.length > 0 ? [...order] : d.layout.map((l) => l.id);
1819
+ const targetId = d.toIndex < d.layout.length ? d.layout[d.toIndex].id : null;
1820
+ const next = base.filter((id) => id !== d.columnId);
1821
+ let insertAt = targetId ? next.indexOf(targetId) : next.length;
1822
+ if (insertAt === -1) insertAt = next.length;
1823
+ next.splice(insertAt, 0, d.columnId);
1824
+ table.setColumnOrder(next);
1825
+ },
1826
+ [table]
1827
+ );
1828
+ const beginReorder = React3.useCallback(
1829
+ (e, columnId) => {
1830
+ if (e.button !== 0) return;
1831
+ const thead = theadRef.current;
1832
+ if (!thead) return;
1833
+ const startX = e.clientX;
1834
+ const startY = e.clientY;
1835
+ const layout = [];
1836
+ let top = 0;
1837
+ let height = 0;
1838
+ for (const c of visibleColumns) {
1839
+ const th = thead.querySelector(`th[data-column-id="${CSS.escape(c.id)}"]`);
1840
+ if (!th) return;
1841
+ const r = th.getBoundingClientRect();
1842
+ layout.push({ id: c.id, left: r.left, width: r.width });
1843
+ if (c.id === columnId) {
1844
+ top = r.top;
1845
+ height = r.height;
1846
+ }
1847
+ }
1848
+ const fromIndex = layout.findIndex((l) => l.id === columnId);
1849
+ if (fromIndex < 0) return;
1850
+ const src = layout[fromIndex];
1851
+ const bodyRoot = thead.closest("table");
1852
+ const applyBody = (d) => {
1853
+ if (!bodyRoot) return;
1854
+ visibleColumns.forEach((col, i) => {
1855
+ if (col.getIsPinned()) return;
1856
+ const tx = transformAt(i, d);
1857
+ bodyRoot.querySelectorAll(`td[data-column-id="${CSS.escape(col.id)}"]`).forEach((td) => {
1858
+ td.style.transition = REORDER_TRANSITION;
1859
+ td.style.opacity = i === d.fromIndex ? "0" : "";
1860
+ td.style.transform = i !== d.fromIndex && tx ? `translateX(${tx}px)` : "";
1861
+ });
1862
+ });
1863
+ };
1864
+ const clearBody = () => {
1865
+ bodyRoot?.querySelectorAll("td[data-column-id]").forEach((td) => {
1866
+ td.style.transform = "";
1867
+ td.style.transition = "";
1868
+ td.style.opacity = "";
1869
+ });
1870
+ };
1871
+ let started = false;
1872
+ let latest = {
1873
+ columnId,
1874
+ fromIndex,
1875
+ toIndex: fromIndex,
1876
+ pointerX: startX,
1877
+ grabOffsetX: startX - src.left,
1878
+ width: src.width,
1879
+ top,
1880
+ height,
1881
+ layout
1882
+ };
1883
+ const computeToIndex = (x) => {
1884
+ let t = layout.findIndex((l) => x < l.left + l.width / 2);
1885
+ if (t === -1) t = layout.length;
1886
+ return t;
1887
+ };
1888
+ const onMove = (ev) => {
1889
+ if (!started) {
1890
+ if (Math.abs(ev.clientX - startX) < 4 && Math.abs(ev.clientY - startY) < 4) return;
1891
+ started = true;
1892
+ table.setColumnDragActive(true);
1893
+ document.body.style.userSelect = "none";
1894
+ document.body.style.cursor = "grabbing";
1895
+ }
1896
+ latest = { ...latest, pointerX: ev.clientX, toIndex: computeToIndex(ev.clientX) };
1897
+ setDrag(latest);
1898
+ applyBody(latest);
1899
+ };
1900
+ const finish = () => {
1901
+ window.removeEventListener("pointermove", onMove);
1902
+ window.removeEventListener("pointerup", finish);
1903
+ window.removeEventListener("pointercancel", finish);
1904
+ if (started) {
1905
+ commitReorder(latest);
1906
+ reorderEndRef.current = Date.now();
1907
+ table.setColumnDragActive(false);
1908
+ document.body.style.userSelect = "";
1909
+ document.body.style.cursor = "";
1910
+ clearBody();
1911
+ }
1912
+ setDrag(null);
1913
+ };
1914
+ window.addEventListener("pointermove", onMove);
1915
+ window.addEventListener("pointerup", finish);
1916
+ window.addEventListener("pointercancel", finish);
1917
+ },
1918
+ [visibleColumns, table, commitReorder]
1919
+ );
1920
+ const transformFor = React3.useCallback(
1921
+ (columnId) => {
1922
+ if (!drag) return 0;
1923
+ const i = visibleColumns.findIndex((c) => c.id === columnId);
1924
+ if (i < 0) return 0;
1925
+ return transformAt(i, drag);
1926
+ },
1927
+ [drag, visibleColumns]
1928
+ );
1929
+ const dragColumn = drag ? visibleColumns.find((c) => c.id === drag.columnId) : null;
1930
+ return /* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "yable-thead", ref: theadRef, children: [
1931
+ headerGroups.map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row", children: headerGroup.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(
1932
+ HeaderCell,
1933
+ {
1934
+ header,
1935
+ table,
1936
+ onReorderPointerDown: beginReorder,
1937
+ dragTransform: transformFor(header.column.id),
1938
+ isDragSource: drag?.columnId === header.column.id,
1939
+ dragActive: drag !== null,
1940
+ reorderEndRef
1941
+ },
1942
+ header.id
1943
+ )) }, headerGroup.id)),
1944
+ floatingFilters && visibleColumns.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-header-row yable-header-row--filters", children: visibleColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(FloatingFilterCell, { column }, `${column.id}-filter`)) }),
1945
+ drag && dragColumn && typeof document !== "undefined" && reactDom.createPortal(
1946
+ /* @__PURE__ */ jsxRuntime.jsx(
1947
+ "div",
1948
+ {
1949
+ className: "yable-col-drag-ghost",
1950
+ "aria-hidden": "true",
1951
+ style: {
1952
+ position: "fixed",
1953
+ top: drag.top,
1954
+ left: drag.pointerX - drag.grabOffsetX,
1955
+ width: drag.width,
1956
+ height: drag.height
1957
+ },
1958
+ children: typeof dragColumn.columnDef.header === "string" ? dragColumn.columnDef.header : dragColumn.id
1959
+ }
1960
+ ),
1961
+ document.body
1962
+ )
1496
1963
  ] });
1497
1964
  }
1498
1965
  function FloatingFilterCell({
@@ -1521,7 +1988,12 @@ function FloatingFilterCell({
1521
1988
  }
1522
1989
  function HeaderCell({
1523
1990
  header,
1524
- table
1991
+ table,
1992
+ onReorderPointerDown,
1993
+ dragTransform,
1994
+ isDragSource,
1995
+ dragActive,
1996
+ reorderEndRef
1525
1997
  }) {
1526
1998
  const column = header.column;
1527
1999
  const canSort = column.getCanSort();
@@ -1529,6 +2001,7 @@ function HeaderCell({
1529
2001
  const sortIndex = column.getSortIndex();
1530
2002
  const canResize = column.getCanResize();
1531
2003
  const canReorder = column.getCanReorder() && !header.isPlaceholder;
2004
+ const pinned = column.getIsPinned();
1532
2005
  const headerContent = header.isPlaceholder ? null : typeof column.columnDef.header === "function" ? column.columnDef.header(header.getContext()) : column.columnDef.header ?? header.id;
1533
2006
  const style = React3.useMemo(() => {
1534
2007
  const s = {
@@ -1536,18 +2009,19 @@ function HeaderCell({
1536
2009
  minWidth: column.columnDef.minSize,
1537
2010
  maxWidth: column.columnDef.maxSize
1538
2011
  };
1539
- const pinned2 = column.getIsPinned();
1540
- if (pinned2) {
2012
+ if (pinned) {
1541
2013
  s.position = "sticky";
1542
- if (pinned2 === "left") {
2014
+ if (pinned === "left") {
1543
2015
  s.left = header.getStart("left");
1544
2016
  } else {
1545
2017
  s.right = header.getStart("right");
1546
2018
  }
1547
2019
  }
2020
+ if (!pinned && !isDragSource && dragTransform !== 0) {
2021
+ s.transform = `translateX(${dragTransform}px)`;
2022
+ }
1548
2023
  return s;
1549
- }, [header, column]);
1550
- const pinned = column.getIsPinned();
2024
+ }, [header, column, pinned, isDragSource, dragTransform]);
1551
2025
  const lastResizeEndRef = React3.useRef(0);
1552
2026
  const startResize = React3.useCallback(
1553
2027
  (e) => {
@@ -1567,122 +2041,60 @@ function HeaderCell({
1567
2041
  const handleResizeClick = React3.useCallback((e) => {
1568
2042
  e.stopPropagation();
1569
2043
  }, []);
1570
- const [dragOver, setDragOver] = React3.useState(null);
1571
- const handleDragStart = React3.useCallback(
1572
- (e) => {
1573
- if (!canReorder) return;
1574
- e.stopPropagation();
1575
- e.dataTransfer.effectAllowed = "move";
1576
- try {
1577
- e.dataTransfer.setData(DRAG_MIME, column.id);
1578
- e.dataTransfer.setData("text/plain", column.id);
1579
- } catch {
1580
- }
1581
- table.setColumnDragActive(true);
1582
- },
1583
- [canReorder, column.id, table]
1584
- );
1585
- const handleDragOver = React3.useCallback(
1586
- (e) => {
1587
- if (!canReorder) return;
1588
- const types = e.dataTransfer.types;
1589
- let isYableDrag = false;
1590
- for (let i = 0; i < types.length; i++) {
1591
- if (types[i] === DRAG_MIME) {
1592
- isYableDrag = true;
1593
- break;
1594
- }
1595
- }
1596
- if (!isYableDrag) return;
1597
- e.preventDefault();
1598
- e.dataTransfer.dropEffect = "move";
1599
- const rect = e.currentTarget.getBoundingClientRect();
1600
- const midpoint = rect.left + rect.width / 2;
1601
- setDragOver(e.clientX < midpoint ? "left" : "right");
1602
- },
1603
- [canReorder]
1604
- );
1605
- const handleDragLeave = React3.useCallback((e) => {
1606
- const next = e.relatedTarget;
1607
- if (next && e.currentTarget.contains(next)) return;
1608
- setDragOver(null);
1609
- }, []);
1610
- const handleDragEnd = React3.useCallback(() => {
1611
- setDragOver(null);
1612
- table.setColumnDragActive(false);
1613
- }, [table]);
1614
- const handleDrop = React3.useCallback(
2044
+ const handleContentPointerDown = React3.useCallback(
1615
2045
  (e) => {
1616
- if (!canReorder) return;
1617
- e.preventDefault();
1618
- e.stopPropagation();
1619
- const sourceId = e.dataTransfer.getData(DRAG_MIME);
1620
- const rect = e.currentTarget.getBoundingClientRect();
1621
- const insertAfter = e.clientX >= rect.left + rect.width / 2;
1622
- setDragOver(null);
1623
- table.setColumnDragActive(false);
1624
- if (!sourceId || sourceId === column.id) return;
1625
- const state = table.getState();
1626
- const allLeafs = table.getAllLeafColumns();
1627
- const baseOrder = state.columnOrder && state.columnOrder.length > 0 ? state.columnOrder : allLeafs.map((c) => c.id);
1628
- const next = [];
1629
- const seen = /* @__PURE__ */ new Set();
1630
- for (const id of baseOrder) {
1631
- if (allLeafs.some((c) => c.id === id)) {
1632
- next.push(id);
1633
- seen.add(id);
1634
- }
1635
- }
1636
- for (const c of allLeafs) {
1637
- if (!seen.has(c.id)) {
1638
- next.push(c.id);
1639
- seen.add(c.id);
1640
- }
1641
- }
1642
- const fromIdx = next.indexOf(sourceId);
1643
- if (fromIdx === -1) return;
1644
- next.splice(fromIdx, 1);
1645
- let toIdx = next.indexOf(column.id);
1646
- if (toIdx === -1) return;
1647
- if (insertAfter) toIdx += 1;
1648
- next.splice(toIdx, 0, sourceId);
1649
- table.setColumnOrder(next);
2046
+ if (!canReorder || pinned) return;
2047
+ onReorderPointerDown(e, column.id);
1650
2048
  },
1651
- [canReorder, column.id, table]
2049
+ [canReorder, pinned, onReorderPointerDown, column.id]
1652
2050
  );
1653
2051
  const handleHeaderClick = React3.useCallback(
1654
2052
  (e) => {
2053
+ table.events.emit("header:click", {
2054
+ column,
2055
+ header,
2056
+ originalEvent: e
2057
+ });
1655
2058
  if (!canSort) return;
1656
2059
  if (Date.now() - lastResizeEndRef.current < 250) return;
2060
+ if (Date.now() - reorderEndRef.current < 250) return;
1657
2061
  const handler = column.getToggleSortingHandler();
1658
2062
  if (handler) handler(e);
1659
2063
  },
1660
- [canSort, column]
2064
+ [canSort, column, header, table.events, reorderEndRef]
2065
+ );
2066
+ const handleHeaderContextMenu = React3.useCallback(
2067
+ (e) => {
2068
+ table.events.emit("header:contextmenu", {
2069
+ column,
2070
+ header,
2071
+ originalEvent: e
2072
+ });
2073
+ },
2074
+ [column, header, table.events]
1661
2075
  );
1662
2076
  return /* @__PURE__ */ jsxRuntime.jsxs(
1663
2077
  "th",
1664
2078
  {
1665
2079
  className: "yable-th",
1666
2080
  style,
2081
+ "data-column-id": column.id,
1667
2082
  "data-sortable": canSort || void 0,
1668
2083
  "data-pinned": pinned || void 0,
1669
- "data-reorderable": canReorder || void 0,
1670
- "data-drag-over": dragOver || void 0,
2084
+ "data-reorderable": canReorder && !pinned || void 0,
2085
+ "data-reordering": dragActive && !pinned || void 0,
2086
+ "data-drag-source": isDragSource || void 0,
1671
2087
  "aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : canSort ? "none" : void 0,
1672
2088
  role: "columnheader",
1673
2089
  colSpan: header.colSpan,
1674
2090
  onClick: handleHeaderClick,
1675
- onDragOver: canReorder ? handleDragOver : void 0,
1676
- onDragLeave: canReorder ? handleDragLeave : void 0,
1677
- onDrop: canReorder ? handleDrop : void 0,
2091
+ onContextMenu: handleHeaderContextMenu,
1678
2092
  children: [
1679
2093
  /* @__PURE__ */ jsxRuntime.jsxs(
1680
2094
  "div",
1681
2095
  {
1682
2096
  className: "yable-th-content",
1683
- draggable: canReorder || void 0,
1684
- onDragStart: canReorder ? handleDragStart : void 0,
1685
- onDragEnd: canReorder ? handleDragEnd : void 0,
2097
+ onPointerDown: canReorder && !pinned ? handleContentPointerDown : void 0,
1686
2098
  children: [
1687
2099
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: headerContent }),
1688
2100
  canSort && /* @__PURE__ */ jsxRuntime.jsx(SortIndicator, { direction: sortDirection, index: sortIndex > 0 ? sortIndex : void 0 })
@@ -1794,6 +2206,7 @@ function TableCell({
1794
2206
  const isAlwaysEditable = cell.getIsAlwaysEditable();
1795
2207
  const pinned = column.getIsPinned();
1796
2208
  const keyboardNavigationEnabled = table.options.enableKeyboardNavigation !== false;
2209
+ const cellSelectionEnabled = table.options.enableCellSelection !== false && column.columnDef.enableCellSelection !== false;
1797
2210
  const style = {
1798
2211
  width: column.getSize(),
1799
2212
  minWidth: column.columnDef.minSize,
@@ -1878,6 +2291,7 @@ function TableCell({
1878
2291
  const handleMouseDown = React3.useCallback(
1879
2292
  (e) => {
1880
2293
  if (e.button !== 0) return;
2294
+ if (!cellSelectionEnabled) return;
1881
2295
  const clickTarget = e.target;
1882
2296
  if (isInteractiveClickTarget(clickTarget)) return;
1883
2297
  e.preventDefault();
@@ -1885,12 +2299,13 @@ function TableCell({
1885
2299
  table.startCellRangeSelection({ rowIndex, columnIndex }, { extend: e.shiftKey });
1886
2300
  e.currentTarget.focus({ preventScroll: true });
1887
2301
  },
1888
- [columnIndex, rowIndex, table]
2302
+ [cellSelectionEnabled, columnIndex, rowIndex, table]
1889
2303
  );
1890
2304
  const handleMouseEnter = React3.useCallback(() => {
2305
+ if (!cellSelectionEnabled) return;
1891
2306
  if (!table.getState().cellSelection?.isDragging) return;
1892
2307
  table.updateCellRangeSelection({ rowIndex, columnIndex });
1893
- }, [columnIndex, rowIndex, table]);
2308
+ }, [cellSelectionEnabled, columnIndex, rowIndex, table]);
1894
2309
  const handleMouseUp = React3.useCallback(() => {
1895
2310
  if (!table.getState().cellSelection?.isDragging) return;
1896
2311
  table.endCellRangeSelection();
@@ -2054,6 +2469,33 @@ var CellErrorBoundary = class extends React3__default.default.Component {
2054
2469
  return this.props.children;
2055
2470
  }
2056
2471
  };
2472
+ function MasterDetail({
2473
+ row,
2474
+ table,
2475
+ colSpan,
2476
+ renderDetailPanel,
2477
+ animationClass
2478
+ }) {
2479
+ const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
2480
+ if (!renderer) return null;
2481
+ const content = renderer(row);
2482
+ if (content == null) return null;
2483
+ const classes = [
2484
+ "yable-detail-row",
2485
+ "yable-detail-row--animated",
2486
+ animationClass
2487
+ ].filter(Boolean).join(" ");
2488
+ return /* @__PURE__ */ jsxRuntime.jsx(
2489
+ "tr",
2490
+ {
2491
+ className: classes,
2492
+ "data-detail-for": row.id,
2493
+ role: "row",
2494
+ "aria-label": `Details for row ${row.id}`,
2495
+ children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: "yable-detail-cell", colSpan, role: "cell", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel-inner", children: content }) }) })
2496
+ }
2497
+ );
2498
+ }
2057
2499
  function TableBody({
2058
2500
  table,
2059
2501
  clickableRows,
@@ -2067,6 +2509,7 @@ function TableBody({
2067
2509
  range: null,
2068
2510
  isDragging: false
2069
2511
  };
2512
+ const pendingValues = table.getState().editing.pendingValues ?? {};
2070
2513
  const options = table.options;
2071
2514
  const enableVirtualization = options.enableVirtualization ?? false;
2072
2515
  const scrollContainerRef = React3.useRef(null);
@@ -2110,24 +2553,40 @@ function TableBody({
2110
2553
  window.removeEventListener("mouseup", handleWindowMouseUp);
2111
2554
  };
2112
2555
  }, [table]);
2556
+ const renderRow = (row, rowIndex, pinnedPosition) => /* @__PURE__ */ jsxRuntime.jsx(
2557
+ MemoizedTableRow,
2558
+ {
2559
+ row,
2560
+ table,
2561
+ rowIndex,
2562
+ visibleColumns,
2563
+ isSelected: row.getIsSelected(),
2564
+ isExpanded: row.getIsExpanded(),
2565
+ activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
2566
+ focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
2567
+ hasFocusedCell: focusedCell !== null,
2568
+ cellSelectionKey,
2569
+ pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
2570
+ clickable: clickableRows,
2571
+ pinnedPosition
2572
+ },
2573
+ row.id
2574
+ );
2113
2575
  if (!enableVirtualization) {
2114
- return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2115
- MemoizedTableRow,
2116
- {
2117
- row,
2118
- table,
2119
- rowIndex,
2120
- visibleColumns,
2121
- isSelected: row.getIsSelected(),
2122
- isExpanded: row.getIsExpanded(),
2123
- activeColumnId: activeCell?.rowId === row.id ? activeCell.columnId : void 0,
2124
- focusedColumnIndex: focusedCell?.rowIndex === rowIndex ? focusedCell.columnIndex : null,
2125
- hasFocusedCell: focusedCell !== null,
2126
- cellSelectionKey,
2127
- clickable: clickableRows
2128
- },
2129
- row.id
2130
- )) });
2576
+ const rowPinning = table.getState().rowPinning;
2577
+ const hasPinnedRows = (rowPinning.top?.length ?? 0) > 0 || (rowPinning.bottom?.length ?? 0) > 0;
2578
+ if (hasPinnedRows) {
2579
+ const topRows = table.getTopRows();
2580
+ const centerRows = table.getCenterRows();
2581
+ const bottomRows = table.getBottomRows();
2582
+ let visualIndex = 0;
2583
+ return /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "yable-tbody", children: [
2584
+ topRows.map((row) => renderRow(row, visualIndex++, "top")),
2585
+ centerRows.map((row) => renderRow(row, visualIndex++)),
2586
+ bottomRows.map((row) => renderRow(row, visualIndex++, "bottom"))
2587
+ ] });
2588
+ }
2589
+ return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "yable-tbody", children: rows.map((row, rowIndex) => renderRow(row, rowIndex)) });
2131
2590
  }
2132
2591
  const hasPretextData = !!(pretextHeights && pretextPrefixSums);
2133
2592
  const fixedRowHeight = typeof rowHeight === "number" && !hasPretextData ? rowHeight : void 0;
@@ -2176,6 +2635,7 @@ function TableBody({
2176
2635
  focusedColumnIndex: focusedCell?.rowIndex === vRow.index ? focusedCell.columnIndex : null,
2177
2636
  hasFocusedCell: focusedCell !== null,
2178
2637
  cellSelectionKey,
2638
+ pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
2179
2639
  clickable: clickableRows,
2180
2640
  virtualStyle: {
2181
2641
  position: "absolute",
@@ -2208,13 +2668,18 @@ function TableRowInner({
2208
2668
  focusedColumnIndex,
2209
2669
  hasFocusedCell,
2210
2670
  cellSelectionKey: _cellSelectionKey,
2671
+ pendingValuesKey: _pendingValuesKey,
2211
2672
  clickable,
2673
+ pinnedPosition,
2212
2674
  virtualStyle
2213
2675
  }) {
2214
2676
  const allCells = row.getAllCells();
2215
2677
  const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
2216
2678
  const handleClick = React3.useCallback(
2217
2679
  (e) => {
2680
+ if (table.options.enableRowClickSelection && row.getCanSelect() && !isInteractiveClickTarget2(e.target)) {
2681
+ row.toggleSelected();
2682
+ }
2218
2683
  if (clickable) {
2219
2684
  table.events.emit("row:click", {
2220
2685
  row,
@@ -2222,7 +2687,7 @@ function TableRowInner({
2222
2687
  });
2223
2688
  }
2224
2689
  },
2225
- [clickable, table.events, row]
2690
+ [clickable, table, row]
2226
2691
  );
2227
2692
  const handleDoubleClick = React3.useCallback(
2228
2693
  (e) => {
@@ -2244,15 +2709,26 @@ function TableRowInner({
2244
2709
  );
2245
2710
  const selectionEnabled = Boolean(table.options.enableRowSelection);
2246
2711
  const expansionEnabled = Boolean(table.options.enableExpanding);
2712
+ const rowClassNameDef = table.options.rowClassName;
2713
+ const userRowClassName = typeof rowClassNameDef === "function" ? rowClassNameDef(row) : rowClassNameDef;
2714
+ const rowStyleDef = table.options.rowStyle;
2715
+ const userRowStyle = typeof rowStyleDef === "function" ? rowStyleDef(row) : rowStyleDef;
2716
+ const mergedRowStyle = userRowStyle ? { ...virtualStyle, ...userRowStyle } : virtualStyle;
2717
+ const rowClassName = [
2718
+ "yable-tr",
2719
+ pinnedPosition && `yable-tr--pinned-${pinnedPosition}`,
2720
+ userRowClassName
2721
+ ].filter(Boolean).join(" ");
2247
2722
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2248
2723
  /* @__PURE__ */ jsxRuntime.jsx(
2249
2724
  "tr",
2250
2725
  {
2251
- className: "yable-tr",
2252
- style: virtualStyle,
2726
+ className: rowClassName,
2727
+ style: mergedRowStyle,
2253
2728
  "data-selected": isSelected || void 0,
2254
2729
  "data-expanded": isExpanded || void 0,
2255
2730
  "data-clickable": clickable || void 0,
2731
+ "data-pinned-row": pinnedPosition,
2256
2732
  "data-row-id": row.id,
2257
2733
  "data-row-index": rowIndex,
2258
2734
  "aria-selected": selectionEnabled ? isSelected : void 0,
@@ -2284,7 +2760,7 @@ function TableRowInner({
2284
2760
  })
2285
2761
  }
2286
2762
  ),
2287
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "yable-expand-row", children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: "yable-td", colSpan: visibleColumns.length, children: typeof row._renderExpanded === "function" ? row._renderExpanded() : null }) })
2763
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx(MasterDetail, { row, table, colSpan: visibleColumns.length })
2288
2764
  ] });
2289
2765
  }
2290
2766
  function areRowPropsEqual(prev, next) {
@@ -2295,10 +2771,12 @@ function areRowPropsEqual(prev, next) {
2295
2771
  if (prev.isSelected !== next.isSelected) return false;
2296
2772
  if (prev.isExpanded !== next.isExpanded) return false;
2297
2773
  if (prev.clickable !== next.clickable) return false;
2774
+ if (prev.pinnedPosition !== next.pinnedPosition) return false;
2298
2775
  if (prev.activeColumnId !== next.activeColumnId) return false;
2299
2776
  if (prev.focusedColumnIndex !== next.focusedColumnIndex) return false;
2300
2777
  if (prev.hasFocusedCell !== next.hasFocusedCell) return false;
2301
2778
  if (prev.cellSelectionKey !== next.cellSelectionKey) return false;
2779
+ if (prev.pendingValuesKey !== next.pendingValuesKey) return false;
2302
2780
  if (prev.virtualStyle !== next.virtualStyle) {
2303
2781
  if (!prev.virtualStyle || !next.virtualStyle) return false;
2304
2782
  if (prev.virtualStyle.transform !== next.virtualStyle.transform) return false;
@@ -2308,6 +2786,16 @@ function areRowPropsEqual(prev, next) {
2308
2786
  return true;
2309
2787
  }
2310
2788
  var MemoizedTableRow = React3__default.default.memo(TableRowInner, areRowPropsEqual);
2789
+ function getPendingValuesKey(values) {
2790
+ if (!values) return "";
2791
+ return Object.keys(values).sort().map((key) => `${key}:${String(values[key])}`).join("|");
2792
+ }
2793
+ function isInteractiveClickTarget2(target) {
2794
+ if (!(target instanceof HTMLElement)) return false;
2795
+ return Boolean(
2796
+ target.closest('input, textarea, select, button, a[href], [contenteditable="true"]')
2797
+ );
2798
+ }
2311
2799
  function TableFooter({ table }) {
2312
2800
  const footerGroups = table.getFooterGroups();
2313
2801
  if (!footerGroups.length) return null;
@@ -2595,29 +3083,73 @@ function StatusBar({
2595
3083
  ] });
2596
3084
  }
2597
3085
  function SearchIcon() {
2598
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "yable-sidebar-search-icon", width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
2599
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6.25", cy: "6.25", r: "4.25", stroke: "currentColor", strokeWidth: "1.5" }),
2600
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9.5 9.5L12.5 12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
2601
- ] });
3086
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3087
+ "svg",
3088
+ {
3089
+ className: "yable-sidebar-search-icon",
3090
+ width: "13",
3091
+ height: "13",
3092
+ viewBox: "0 0 14 14",
3093
+ fill: "none",
3094
+ "aria-hidden": "true",
3095
+ children: [
3096
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "6.25", cy: "6.25", r: "4.25", stroke: "currentColor", strokeWidth: "1.5" }),
3097
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9.5 9.5L12.5 12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
3098
+ ]
3099
+ }
3100
+ );
2602
3101
  }
2603
3102
  function VisibilityIcon({ visible }) {
2604
3103
  if (visible) {
2605
3104
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
2606
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z", stroke: "currentColor", strokeWidth: "1.2", strokeLinejoin: "round" }),
3105
+ /* @__PURE__ */ jsxRuntime.jsx(
3106
+ "path",
3107
+ {
3108
+ d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
3109
+ stroke: "currentColor",
3110
+ strokeWidth: "1.2",
3111
+ strokeLinejoin: "round"
3112
+ }
3113
+ ),
2607
3114
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "2", stroke: "currentColor", strokeWidth: "1.2" })
2608
3115
  ] });
2609
3116
  }
2610
3117
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: [
2611
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z", stroke: "currentColor", strokeWidth: "1.2", strokeLinejoin: "round", opacity: "0.3" }),
2612
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "2", y1: "2", x2: "12", y2: "12", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", opacity: "0.5" })
3118
+ /* @__PURE__ */ jsxRuntime.jsx(
3119
+ "path",
3120
+ {
3121
+ d: "M1 7s2.5-4 6-4 6 4 6 4-2.5 4-6 4-6-4-6-4z",
3122
+ stroke: "currentColor",
3123
+ strokeWidth: "1.2",
3124
+ strokeLinejoin: "round",
3125
+ opacity: "0.3"
3126
+ }
3127
+ ),
3128
+ /* @__PURE__ */ jsxRuntime.jsx(
3129
+ "line",
3130
+ {
3131
+ x1: "2",
3132
+ y1: "2",
3133
+ x2: "12",
3134
+ y2: "12",
3135
+ stroke: "currentColor",
3136
+ strokeWidth: "1.2",
3137
+ strokeLinecap: "round",
3138
+ opacity: "0.5"
3139
+ }
3140
+ )
2613
3141
  ] });
2614
3142
  }
2615
- function ColumnsPanel({
2616
- table
2617
- }) {
3143
+ function ColumnsPanel({ table }) {
2618
3144
  const [search, setSearch] = React3.useState("");
2619
3145
  const [draggedId, setDraggedId] = React3.useState(null);
2620
- const columns = table.getAllLeafColumns();
3146
+ const allColumns = table.getAllLeafColumns();
3147
+ const columnOrder = table.getState().columnOrder;
3148
+ const columns = columnOrder && columnOrder.length > 0 ? [...allColumns].sort((a, b) => {
3149
+ const ia = columnOrder.indexOf(a.id);
3150
+ const ib = columnOrder.indexOf(b.id);
3151
+ return (ia === -1 ? Number.MAX_SAFE_INTEGER : ia) - (ib === -1 ? Number.MAX_SAFE_INTEGER : ib);
3152
+ }) : allColumns;
2621
3153
  const visibleCount = columns.filter((c) => c.getIsVisible()).length;
2622
3154
  const filteredColumns = search ? columns.filter((col) => {
2623
3155
  const header = typeof col.columnDef.header === "string" ? col.columnDef.header : col.id;
@@ -3044,6 +3576,7 @@ function ContextMenu({
3044
3576
  y,
3045
3577
  onClose,
3046
3578
  table,
3579
+ targetColumnId,
3047
3580
  customItems
3048
3581
  }) {
3049
3582
  const menuRef = React3.useRef(null);
@@ -3087,6 +3620,17 @@ function ContextMenu({
3087
3620
  },
3088
3621
  [onClose]
3089
3622
  );
3623
+ const resolveSortColumn = () => {
3624
+ if (targetColumnId) {
3625
+ const column = table.getColumn(targetColumnId);
3626
+ if (column) return column;
3627
+ }
3628
+ const focused = table.getFocusedCell();
3629
+ if (focused) {
3630
+ return table.getVisibleLeafColumns()[focused.columnIndex];
3631
+ }
3632
+ return void 0;
3633
+ };
3090
3634
  const defaultItems = [
3091
3635
  {
3092
3636
  id: "copy",
@@ -3135,14 +3679,14 @@ function ContextMenu({
3135
3679
  id: "sort-asc",
3136
3680
  label: "Sort Ascending",
3137
3681
  action: () => {
3138
- table.setSorting([]);
3682
+ resolveSortColumn()?.toggleSorting(false);
3139
3683
  }
3140
3684
  },
3141
3685
  {
3142
3686
  id: "sort-desc",
3143
3687
  label: "Sort Descending",
3144
3688
  action: () => {
3145
- table.setSorting([]);
3689
+ resolveSortColumn()?.toggleSorting(true);
3146
3690
  }
3147
3691
  },
3148
3692
  {
@@ -3234,11 +3778,13 @@ function useContextMenu() {
3234
3778
  const [x, setX] = React3.useState(0);
3235
3779
  const [y, setY] = React3.useState(0);
3236
3780
  const [targetTable, setTargetTable] = React3.useState(null);
3781
+ const [targetColumnId, setTargetColumnId] = React3.useState(void 0);
3237
3782
  const open = React3.useCallback(
3238
- (clientX, clientY, table) => {
3783
+ (clientX, clientY, table, columnId) => {
3239
3784
  setX(clientX);
3240
3785
  setY(clientY);
3241
3786
  setTargetTable(table);
3787
+ setTargetColumnId(columnId);
3242
3788
  setIsOpen(true);
3243
3789
  },
3244
3790
  []
@@ -3246,6 +3792,7 @@ function useContextMenu() {
3246
3792
  const close = React3.useCallback(() => {
3247
3793
  setIsOpen(false);
3248
3794
  setTargetTable(null);
3795
+ setTargetColumnId(void 0);
3249
3796
  }, []);
3250
3797
  React3.useEffect(() => {
3251
3798
  if (!isOpen) return;
@@ -3260,7 +3807,7 @@ function useContextMenu() {
3260
3807
  document.removeEventListener("click", handleClick);
3261
3808
  };
3262
3809
  }, [isOpen, close]);
3263
- return { isOpen, x, y, targetTable, open, close };
3810
+ return { isOpen, x, y, targetTable, targetColumnId, open, close };
3264
3811
  }
3265
3812
  function useKeyboardNavigation(table, options = {}) {
3266
3813
  const {
@@ -3473,6 +4020,8 @@ function Table({
3473
4020
  bordered: borderedProp,
3474
4021
  compact: compactProp,
3475
4022
  theme: themeProp,
4023
+ config,
4024
+ configProfile,
3476
4025
  clickableRows,
3477
4026
  footer,
3478
4027
  loading,
@@ -3490,7 +4039,7 @@ function Table({
3490
4039
  statusBar,
3491
4040
  statusBarPanels,
3492
4041
  sidebar,
3493
- sidebarPanels = ["columns", "filters"],
4042
+ sidebarPanels,
3494
4043
  defaultSidebarPanel,
3495
4044
  floatingFilters,
3496
4045
  columnVirtualization,
@@ -3498,17 +4047,31 @@ function Table({
3498
4047
  ariaLabel: ariaLabelProp,
3499
4048
  ...rest
3500
4049
  }) {
3501
- const { tableProps: providerTableProps } = useYableDefaults();
3502
- const stickyHeader = stickyHeaderProp ?? providerTableProps?.stickyHeader;
3503
- const striped = stripedProp ?? providerTableProps?.striped;
3504
- const bordered = borderedProp ?? providerTableProps?.bordered;
3505
- const compact = compactProp ?? providerTableProps?.compact;
3506
- const theme = themeProp ?? providerTableProps?.theme;
3507
- const direction = directionProp ?? providerTableProps?.direction;
3508
- const ariaLabel = ariaLabelProp ?? providerTableProps?.ariaLabel;
4050
+ const providerDefaults = useYableDefaults();
4051
+ const { tableProps: providerTableProps } = providerDefaults;
4052
+ const profile = resolveYableProfile(
4053
+ config ?? providerDefaults.config,
4054
+ configProfile ?? providerDefaults.tableProfile
4055
+ );
4056
+ const profileTableProps = profile.table;
4057
+ const stickyHeader = stickyHeaderProp ?? profileTableProps?.stickyHeader ?? providerTableProps?.stickyHeader;
4058
+ const striped = stripedProp ?? profileTableProps?.striped ?? providerTableProps?.striped;
4059
+ const bordered = borderedProp ?? profileTableProps?.bordered ?? providerTableProps?.bordered;
4060
+ const compact = compactProp ?? profileTableProps?.compact ?? providerTableProps?.compact;
4061
+ const theme = themeProp ?? profileTableProps?.theme ?? providerTableProps?.theme;
4062
+ const direction = directionProp ?? profileTableProps?.direction ?? providerTableProps?.direction;
4063
+ const ariaLabel = ariaLabelProp ?? profileTableProps?.ariaLabel ?? providerTableProps?.ariaLabel;
4064
+ const resolvedClickableRows = clickableRows ?? profileTableProps?.clickableRows;
4065
+ const resolvedStatusBar = statusBar ?? profileTableProps?.statusBar;
4066
+ const resolvedSidebar = sidebar ?? profileTableProps?.sidebar;
4067
+ const resolvedSidebarPanels = sidebarPanels ?? profileTableProps?.sidebarPanels ?? ["columns", "filters"];
4068
+ const resolvedDefaultSidebarPanel = defaultSidebarPanel ?? profileTableProps?.defaultSidebarPanel;
4069
+ const resolvedFloatingFilters = floatingFilters ?? profileTableProps?.floatingFilters;
4070
+ const resolvedColumnVirtualization = columnVirtualization ?? profileTableProps?.columnVirtualization;
4071
+ const resolvedColumnVirtualizationOverscan = columnVirtualizationOverscan ?? profileTableProps?.columnVirtualizationOverscan;
3509
4072
  const [sidebarOpen, setSidebarOpen] = React3.useState(false);
3510
4073
  const [sidebarPanel, setSidebarPanel] = React3.useState(
3511
- defaultSidebarPanel ?? "columns"
4074
+ resolvedDefaultSidebarPanel ?? "columns"
3512
4075
  );
3513
4076
  const containerRef = React3.useRef(null);
3514
4077
  const horizontalScrollRef = React3.useRef(null);
@@ -3532,12 +4095,14 @@ function Table({
3532
4095
  const allVisibleColumns = table.getVisibleLeafColumns();
3533
4096
  const hasPinnedColumns = table.getLeftVisibleLeafColumns().length > 0 || table.getRightVisibleLeafColumns().length > 0;
3534
4097
  const hasGroupedHeaders = table.getHeaderGroups().length > 1;
3535
- const canVirtualizeColumns = Boolean(columnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
4098
+ const canVirtualizeColumns = Boolean(resolvedColumnVirtualization) && !hasPinnedColumns && !hasGroupedHeaders && allVisibleColumns.length > 0;
4099
+ const allVisibleColumnSizeSignature = allVisibleColumns.map((column) => `${column.id}:${column.getSize()}`).join("|");
3536
4100
  const columnVirtualState = useColumnVirtualization({
3537
4101
  containerRef: horizontalScrollRef,
3538
4102
  columns: allVisibleColumns,
3539
- overscan: columnVirtualizationOverscan ?? 2,
3540
- enabled: canVirtualizeColumns
4103
+ overscan: resolvedColumnVirtualizationOverscan ?? 2,
4104
+ enabled: canVirtualizeColumns,
4105
+ sizingKey: allVisibleColumnSizeSignature
3541
4106
  });
3542
4107
  const renderTable = React3.useMemo(() => {
3543
4108
  if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
@@ -3612,17 +4177,18 @@ function Table({
3612
4177
  const handleContextMenu = React3.useCallback(
3613
4178
  (e) => {
3614
4179
  e.preventDefault();
3615
- contextMenu.open(e.clientX, e.clientY, table);
4180
+ const targetEl = e.target?.closest?.("[data-column-id]");
4181
+ const targetColumnId = targetEl?.getAttribute("data-column-id") ?? void 0;
4182
+ contextMenu.open(e.clientX, e.clientY, table, targetColumnId);
3616
4183
  },
3617
4184
  [contextMenu, table]
3618
4185
  );
3619
- const enableRowVirtualization = renderTable.options.enableVirtualization ?? false;
3620
4186
  const visibleLeafColumns = renderTable.getVisibleLeafColumns();
3621
- const columnSizing = renderTable.getState().columnSizing;
3622
- const colgroup = React3.useMemo(() => {
3623
- if (visibleLeafColumns.length === 0) return null;
3624
- return /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: visibleLeafColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: col.getSize() } }, col.id)) });
3625
- }, [visibleLeafColumns, columnSizing]);
4187
+ const visibleColumnTotalSize = visibleLeafColumns.reduce(
4188
+ (sum, column) => sum + column.getSize(),
4189
+ 0
4190
+ );
4191
+ const colgroup = visibleLeafColumns.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: visibleLeafColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: col.getSize() } }, col.id)) });
3626
4192
  const outerTableStyle = React3.useMemo(() => {
3627
4193
  if (columnVirtualState.isVirtualized) {
3628
4194
  return {
@@ -3632,15 +4198,15 @@ function Table({
3632
4198
  tableLayout: "fixed"
3633
4199
  };
3634
4200
  }
3635
- if (enableRowVirtualization) {
3636
- return { tableLayout: "fixed" };
3637
- }
3638
- return void 0;
4201
+ return {
4202
+ minWidth: visibleColumnTotalSize || void 0,
4203
+ tableLayout: "fixed"
4204
+ };
3639
4205
  }, [
3640
4206
  columnVirtualState.isVirtualized,
3641
4207
  columnVirtualState.visibleWidth,
3642
4208
  columnVirtualState.startOffset,
3643
- enableRowVirtualization
4209
+ visibleColumnTotalSize
3644
4210
  ]);
3645
4211
  const tableNode = /* @__PURE__ */ jsxRuntime.jsxs(
3646
4212
  "table",
@@ -3649,9 +4215,9 @@ function Table({
3649
4215
  style: outerTableStyle,
3650
4216
  "data-column-virtualized": columnVirtualState.isVirtualized || void 0,
3651
4217
  children: [
3652
- enableRowVirtualization && colgroup,
3653
- /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters }),
3654
- /* @__PURE__ */ jsxRuntime.jsx(TableBody, { table: renderTable, clickableRows, colgroup }),
4218
+ colgroup,
4219
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters: resolvedFloatingFilters }),
4220
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { table: renderTable, clickableRows: resolvedClickableRows, colgroup }),
3655
4221
  footer && /* @__PURE__ */ jsxRuntime.jsx(TableFooter, { table: renderTable })
3656
4222
  ]
3657
4223
  }
@@ -3717,18 +4283,43 @@ function Table({
3717
4283
  }
3718
4284
  ))
3719
4285
  ] }),
3720
- sidebar && /* @__PURE__ */ jsxRuntime.jsx(
4286
+ resolvedSidebar && !sidebarOpen && /* @__PURE__ */ jsxRuntime.jsx(
4287
+ "button",
4288
+ {
4289
+ type: "button",
4290
+ className: "yable-sidebar-trigger",
4291
+ "aria-label": "Open tool panel",
4292
+ title: "Open tool panel",
4293
+ onClick: () => setSidebarOpen(true),
4294
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
4295
+ /* @__PURE__ */ jsxRuntime.jsx(
4296
+ "rect",
4297
+ {
4298
+ x: "3",
4299
+ y: "4",
4300
+ width: "18",
4301
+ height: "16",
4302
+ rx: "2",
4303
+ stroke: "currentColor",
4304
+ strokeWidth: "2"
4305
+ }
4306
+ ),
4307
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "14", y1: "4", x2: "14", y2: "20", stroke: "currentColor", strokeWidth: "2" })
4308
+ ] })
4309
+ }
4310
+ ),
4311
+ resolvedSidebar && /* @__PURE__ */ jsxRuntime.jsx(
3721
4312
  Sidebar,
3722
4313
  {
3723
4314
  table,
3724
4315
  open: sidebarOpen,
3725
4316
  onClose: () => setSidebarOpen(false),
3726
- panels: sidebarPanels,
4317
+ panels: resolvedSidebarPanels,
3727
4318
  activePanel: sidebarPanel,
3728
4319
  onPanelChange: setSidebarPanel
3729
4320
  }
3730
4321
  ),
3731
- statusBar && /* @__PURE__ */ jsxRuntime.jsx(StatusBar, { table, panels: statusBarPanels }),
4322
+ resolvedStatusBar && /* @__PURE__ */ jsxRuntime.jsx(StatusBar, { table, panels: statusBarPanels }),
3732
4323
  children,
3733
4324
  contextMenu.isOpen && /* @__PURE__ */ jsxRuntime.jsx(
3734
4325
  ContextMenu,
@@ -3736,7 +4327,8 @@ function Table({
3736
4327
  x: contextMenu.x,
3737
4328
  y: contextMenu.y,
3738
4329
  onClose: contextMenu.close,
3739
- table
4330
+ table,
4331
+ targetColumnId: contextMenu.targetColumnId
3740
4332
  }
3741
4333
  ),
3742
4334
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4664,33 +5256,6 @@ function TreeToggle({
4664
5256
  }
4665
5257
  );
4666
5258
  }
4667
- function MasterDetail({
4668
- row,
4669
- table,
4670
- colSpan,
4671
- renderDetailPanel,
4672
- animationClass
4673
- }) {
4674
- const renderer = renderDetailPanel ?? table.options.renderDetailPanel;
4675
- if (!renderer) return null;
4676
- const content = renderer(row);
4677
- if (content == null) return null;
4678
- const classes = [
4679
- "yable-detail-row",
4680
- "yable-detail-row--animated",
4681
- animationClass
4682
- ].filter(Boolean).join(" ");
4683
- return /* @__PURE__ */ jsxRuntime.jsx(
4684
- "tr",
4685
- {
4686
- className: classes,
4687
- "data-detail-for": row.id,
4688
- role: "row",
4689
- "aria-label": `Details for row ${row.id}`,
4690
- children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: "yable-detail-cell", colSpan, role: "cell", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-detail-panel-inner", children: content }) }) })
4691
- }
4692
- );
4693
- }
4694
5259
  function ExpandIcon({
4695
5260
  isExpanded,
4696
5261
  onClick,
@@ -5663,10 +6228,11 @@ function selectColumn(options = {}) {
5663
6228
  const { id = "_select", size = 40, headerAriaLabel = "Select all rows" } = options;
5664
6229
  return {
5665
6230
  id,
5666
- header: ({ table }) => /* @__PURE__ */ jsxRuntime.jsx(
6231
+ header: ({ table }) => /* @__PURE__ */ jsxRuntime.jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
5667
6232
  "input",
5668
6233
  {
5669
6234
  type: "checkbox",
6235
+ className: "yable-checkbox",
5670
6236
  checked: table.getIsAllPageRowsSelected(),
5671
6237
  ref: (el) => {
5672
6238
  if (el)
@@ -5675,19 +6241,21 @@ function selectColumn(options = {}) {
5675
6241
  onChange: () => table.toggleAllPageRowsSelected(),
5676
6242
  "aria-label": headerAriaLabel
5677
6243
  }
5678
- ),
5679
- cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx(
6244
+ ) }),
6245
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx("label", { className: "yable-checkbox-hitbox", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
5680
6246
  "input",
5681
6247
  {
5682
6248
  type: "checkbox",
6249
+ className: "yable-checkbox",
5683
6250
  checked: row.getIsSelected(),
5684
6251
  disabled: !row.getCanSelect(),
5685
6252
  onChange: row.getToggleSelectedHandler(),
5686
- "aria-label": `Select row`
6253
+ "aria-label": "Select row"
5687
6254
  }
5688
- ),
6255
+ ) }),
5689
6256
  size,
5690
- enableSorting: false,
6257
+ enableSorting: true,
6258
+ sortingFn: (rowA, rowB) => Number(rowA.getIsSelected()) - Number(rowB.getIsSelected()),
5691
6259
  enableColumnFilter: false,
5692
6260
  enableResizing: false,
5693
6261
  enableReorder: false,
@@ -6020,11 +6588,15 @@ exports.Tooltip = Tooltip;
6020
6588
  exports.TreeToggle = TreeToggle;
6021
6589
  exports.YableProvider = YableProvider;
6022
6590
  exports.actionsColumn = actionsColumn;
6591
+ exports.applyYableConfigToColumns = applyYableConfigToColumns;
6592
+ exports.createYableConfig = createYableConfig;
6023
6593
  exports.expandColumn = expandColumn;
6024
6594
  exports.getMeasureRecipeForCellType = getMeasureRecipeForCellType;
6025
6595
  exports.getRegisteredCellTypes = getRegisteredCellTypes;
6596
+ exports.getYableDefaultColumnDef = getYableDefaultColumnDef;
6026
6597
  exports.mergeEditChanges = mergeEditChanges;
6027
6598
  exports.resolveMeasureRecipe = resolveMeasureRecipe;
6599
+ exports.resolveYableProfile = resolveYableProfile;
6028
6600
  exports.rowNumberColumn = rowNumberColumn;
6029
6601
  exports.selectColumn = selectColumn;
6030
6602
  exports.useAutoMeasurements = useAutoMeasurements;
@@ -6038,6 +6610,7 @@ exports.usePretextMeasurement = usePretextMeasurement;
6038
6610
  exports.usePrintLayout = usePrintLayout;
6039
6611
  exports.useRowAnimation = useRowAnimation;
6040
6612
  exports.useRowDrag = useRowDrag;
6613
+ exports.useServerTable = useServerTable;
6041
6614
  exports.useTable = useTable;
6042
6615
  exports.useTableContext = useTableContext;
6043
6616
  exports.useTablePersistence = useTablePersistence;