@zvndev/yable-react 0.5.0 → 0.6.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
@@ -1,19 +1,19 @@
1
1
  'use strict';
2
2
 
3
3
  var yableCore = require('@zvndev/yable-core');
4
- var React3 = require('react');
4
+ var React4 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var reactDom = require('react-dom');
7
7
  var rowDragging = require('@zvndev/yable-core/features/rowDragging');
8
8
 
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
- var React3__default = /*#__PURE__*/_interopDefault(React3);
11
+ var React4__default = /*#__PURE__*/_interopDefault(React4);
12
12
 
13
13
  // src/index.ts
14
- var YableContext = React3.createContext({});
14
+ var YableContext = React4.createContext({});
15
15
  function useYableDefaults() {
16
- return React3.useContext(YableContext);
16
+ return React4.useContext(YableContext);
17
17
  }
18
18
  function YableProvider({
19
19
  children,
@@ -131,7 +131,7 @@ function shallowEqual(a, b) {
131
131
  }
132
132
  function useTable(options) {
133
133
  const providerDefaults = useYableDefaults();
134
- const optionsWithDefaults = React3.useMemo(() => {
134
+ const optionsWithDefaults = React4.useMemo(() => {
135
135
  const profile = resolveYableProfile(
136
136
  options.config ?? providerDefaults.config,
137
137
  options.configProfile ?? providerDefaults.tableProfile
@@ -156,7 +156,7 @@ function useTable(options) {
156
156
  providerDefaults.defaultColumnDef,
157
157
  providerDefaults.tableProfile
158
158
  ]);
159
- const [state, setState] = React3.useState(() => ({
159
+ const [state, setState] = React4.useState(() => ({
160
160
  sorting: [],
161
161
  columnFilters: [],
162
162
  globalFilter: "",
@@ -193,26 +193,26 @@ function useTable(options) {
193
193
  ...options.initialState,
194
194
  ...options.state
195
195
  }));
196
- const stateRef = React3.useRef(state);
196
+ const stateRef = React4.useRef(state);
197
197
  stateRef.current = state;
198
- const prevOptionsRef = React3.useRef(optionsWithDefaults);
199
- const stableOptions = React3.useMemo(() => {
198
+ const prevOptionsRef = React4.useRef(optionsWithDefaults);
199
+ const stableOptions = React4.useMemo(() => {
200
200
  if (shallowEqual(prevOptionsRef.current, optionsWithDefaults)) {
201
201
  return prevOptionsRef.current;
202
202
  }
203
203
  prevOptionsRef.current = optionsWithDefaults;
204
204
  return optionsWithDefaults;
205
205
  }, [optionsWithDefaults]);
206
- const onStateChangeRef = React3.useRef(options.onStateChange);
206
+ const onStateChangeRef = React4.useRef(options.onStateChange);
207
207
  onStateChangeRef.current = options.onStateChange;
208
- const resolvedState = React3.useMemo(
208
+ const resolvedState = React4.useMemo(
209
209
  () => ({
210
210
  ...state,
211
211
  ...stableOptions.state
212
212
  }),
213
213
  [state, stableOptions.state]
214
214
  );
215
- const onStateChange = React3.useCallback((updater) => {
215
+ const onStateChange = React4.useCallback((updater) => {
216
216
  const latest = onStateChangeRef.current;
217
217
  if (latest) {
218
218
  latest(updater);
@@ -220,7 +220,7 @@ function useTable(options) {
220
220
  setState((prev) => yableCore.functionalUpdate(updater, prev));
221
221
  }
222
222
  }, []);
223
- const resolvedOptions = React3.useMemo(
223
+ const resolvedOptions = React4.useMemo(
224
224
  () => ({
225
225
  ...stableOptions,
226
226
  state: resolvedState,
@@ -228,7 +228,7 @@ function useTable(options) {
228
228
  }),
229
229
  [stableOptions, resolvedState, onStateChange]
230
230
  );
231
- const tableRef = React3.useRef(null);
231
+ const tableRef = React4.useRef(null);
232
232
  if (!tableRef.current) {
233
233
  tableRef.current = yableCore.createTable(resolvedOptions);
234
234
  } else {
@@ -241,7 +241,7 @@ function useTable(options) {
241
241
  })
242
242
  );
243
243
  }
244
- React3.useEffect(() => {
244
+ React4.useEffect(() => {
245
245
  const table = tableRef.current;
246
246
  if (!table) return;
247
247
  const unsubscribers = [
@@ -267,7 +267,7 @@ function useTable(options) {
267
267
  options.onRowContextMenu,
268
268
  options.onRowDoubleClick
269
269
  ]);
270
- React3.useEffect(() => {
270
+ React4.useEffect(() => {
271
271
  return () => {
272
272
  if (tableRef.current) {
273
273
  tableRef.current.events.removeAllListeners();
@@ -292,26 +292,26 @@ function useServerTable({
292
292
  getRowId,
293
293
  ...tableOptions
294
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(
295
+ const [rows, setRows] = React4.useState(initialRows);
296
+ const [cursor, setCursor] = React4.useState(initialCursor);
297
+ const [hasMore, setHasMore] = React4.useState(initialHasMore);
298
+ const [rowCount, setRowCount] = React4.useState(initialRowCount);
299
+ const [pageCount, setPageCount] = React4.useState(initialPageCount);
300
+ const [sorting, setSorting] = React4.useState(initialSorting);
301
+ const [columnFilters, setColumnFilters] = React4.useState(initialColumnFilters);
302
+ const [globalFilter, setGlobalFilter] = React4.useState(initialGlobalFilter);
303
+ const [pagination, setPagination] = React4.useState(initialPagination);
304
+ const [loading, setLoading] = React4.useState(false);
305
+ const [error, setError] = React4.useState(null);
306
+ const abortRef = React4.useRef(null);
307
+ const cursorRef = React4.useRef(cursor);
308
+ const fetchDataRef = React4.useRef(fetchData);
309
+ const updateRowRef = React4.useRef(updateRow);
310
+ const resolveRowId = React4.useCallback(
311
311
  (row, index) => getRowId?.(row, index) ?? String(row.id ?? index),
312
312
  [getRowId]
313
313
  );
314
- const runFetch = React3.useCallback(
314
+ const runFetch = React4.useCallback(
315
315
  async (mode) => {
316
316
  abortRef.current?.abort();
317
317
  const abort = new AbortController();
@@ -341,12 +341,12 @@ function useServerTable({
341
341
  },
342
342
  [columnFilters, globalFilter, pagination, sorting]
343
343
  );
344
- const refresh = React3.useCallback(() => runFetch("replace"), [runFetch]);
345
- const loadMore = React3.useCallback(async () => {
344
+ const refresh = React4.useCallback(() => runFetch("replace"), [runFetch]);
345
+ const loadMore = React4.useCallback(async () => {
346
346
  if (!hasMore || loading) return;
347
347
  await runFetch("append");
348
348
  }, [hasMore, loading, runFetch]);
349
- const patchRow = React3.useCallback(
349
+ const patchRow = React4.useCallback(
350
350
  async (rowId, patch) => {
351
351
  const previousRow = rows.find((row, index) => resolveRowId(row, index) === rowId);
352
352
  setRows(
@@ -378,20 +378,20 @@ function useServerTable({
378
378
  },
379
379
  [resolveRowId, rows]
380
380
  );
381
- React3.useEffect(() => {
381
+ React4.useEffect(() => {
382
382
  fetchDataRef.current = fetchData;
383
383
  }, [fetchData]);
384
- React3.useEffect(() => {
384
+ React4.useEffect(() => {
385
385
  updateRowRef.current = updateRow;
386
386
  }, [updateRow]);
387
- React3.useEffect(() => {
387
+ React4.useEffect(() => {
388
388
  if (!autoLoad) return;
389
389
  void refresh();
390
390
  }, [autoLoad, refresh]);
391
- React3.useEffect(() => {
391
+ React4.useEffect(() => {
392
392
  cursorRef.current = cursor;
393
393
  }, [cursor]);
394
- React3.useEffect(() => () => abortRef.current?.abort(), []);
394
+ React4.useEffect(() => () => abortRef.current?.abort(), []);
395
395
  const table = useTable({
396
396
  ...tableOptions,
397
397
  data: rows,
@@ -428,7 +428,7 @@ function useServerTable({
428
428
  setHasMore(true);
429
429
  }
430
430
  });
431
- return React3.useMemo(
431
+ return React4.useMemo(
432
432
  () => ({
433
433
  table,
434
434
  rows,
@@ -528,25 +528,25 @@ function useTablePersistence(options) {
528
528
  version = 0,
529
529
  storage: customStorage
530
530
  } = options;
531
- const storage = React3.useMemo(() => resolveStorage(customStorage), [customStorage]);
532
- const initialState = React3.useMemo(
531
+ const storage = React4.useMemo(() => resolveStorage(customStorage), [customStorage]);
532
+ const initialState = React4.useMemo(
533
533
  () => readState(storage, key, version, persistedKeys),
534
534
  // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally read only on mount
535
535
  []
536
536
  );
537
- const [state, setState] = React3.useState(initialState);
538
- const timerRef = React3.useRef(null);
539
- const keyRef = React3.useRef(key);
537
+ const [state, setState] = React4.useState(initialState);
538
+ const timerRef = React4.useRef(null);
539
+ const keyRef = React4.useRef(key);
540
540
  keyRef.current = key;
541
- const versionRef = React3.useRef(version);
541
+ const versionRef = React4.useRef(version);
542
542
  versionRef.current = version;
543
- const persistedKeysRef = React3.useRef(persistedKeys);
543
+ const persistedKeysRef = React4.useRef(persistedKeys);
544
544
  persistedKeysRef.current = persistedKeys;
545
- const debounceRef = React3.useRef(debounceMs);
545
+ const debounceRef = React4.useRef(debounceMs);
546
546
  debounceRef.current = debounceMs;
547
- const storageRef = React3.useRef(storage);
547
+ const storageRef = React4.useRef(storage);
548
548
  storageRef.current = storage;
549
- const onStateChange = React3.useCallback((updater) => {
549
+ const onStateChange = React4.useCallback((updater) => {
550
550
  setState((prev) => {
551
551
  const next = yableCore.functionalUpdate(updater, prev);
552
552
  if (timerRef.current !== null) {
@@ -563,14 +563,14 @@ function useTablePersistence(options) {
563
563
  return next;
564
564
  });
565
565
  }, []);
566
- React3.useEffect(() => {
566
+ React4.useEffect(() => {
567
567
  return () => {
568
568
  if (timerRef.current !== null) {
569
569
  clearTimeout(timerRef.current);
570
570
  }
571
571
  };
572
572
  }, []);
573
- const clearPersistedState = React3.useCallback(() => {
573
+ const clearPersistedState = React4.useCallback(() => {
574
574
  const s = storageRef.current;
575
575
  if (s) {
576
576
  try {
@@ -599,10 +599,10 @@ function useVirtualization({
599
599
  }) {
600
600
  const hasPretextHeights = !!(pretextHeights && pretextPrefixSums && pretextHeights.length >= totalRows);
601
601
  const isFixedHeight = typeof rowHeight === "number" && !hasPretextHeights;
602
- const heightCacheRef = React3.useRef(/* @__PURE__ */ new Map());
603
- const heightCacheVersionRef = React3.useRef(0);
604
- const [heightCacheVersion, setHeightCacheVersion] = React3.useState(0);
605
- const getRowHeight = React3.useCallback(
602
+ const heightCacheRef = React4.useRef(/* @__PURE__ */ new Map());
603
+ const heightCacheVersionRef = React4.useRef(0);
604
+ const [heightCacheVersion, setHeightCacheVersion] = React4.useState(0);
605
+ const getRowHeight = React4.useCallback(
606
606
  (index) => {
607
607
  if (hasPretextHeights) return pretextHeights[index];
608
608
  if (isFixedHeight) return rowHeight;
@@ -616,9 +616,9 @@ function useVirtualization({
616
616
  // eslint-disable-next-line react-hooks/exhaustive-deps
617
617
  [rowHeight, isFixedHeight, hasPretextHeights, pretextHeights, heightCacheVersion]
618
618
  );
619
- const [scrollState, setScrollState] = React3.useState({ scrollTop: 0, containerHeight: 0 });
620
- const rafRef = React3.useRef(null);
621
- React3.useEffect(() => {
619
+ const [scrollState, setScrollState] = React4.useState({ scrollTop: 0, containerHeight: 0 });
620
+ const rafRef = React4.useRef(null);
621
+ React4.useEffect(() => {
622
622
  const container = containerRef.current;
623
623
  if (!container) return;
624
624
  setScrollState({
@@ -662,24 +662,24 @@ function useVirtualization({
662
662
  }
663
663
  };
664
664
  }, [containerRef, totalRows]);
665
- React3.useEffect(() => {
665
+ React4.useEffect(() => {
666
666
  if (!isFixedHeight) {
667
667
  heightCacheRef.current.clear();
668
668
  }
669
669
  }, [totalRows, isFixedHeight]);
670
- React3.useEffect(() => {
670
+ React4.useEffect(() => {
671
671
  if (!isFixedHeight && columnSizingHash !== void 0) {
672
672
  heightCacheRef.current.clear();
673
673
  heightCacheVersionRef.current += 1;
674
674
  setHeightCacheVersion(heightCacheVersionRef.current);
675
675
  }
676
676
  }, [columnSizingHash]);
677
- const invalidateRowHeights = React3.useCallback(() => {
677
+ const invalidateRowHeights = React4.useCallback(() => {
678
678
  heightCacheRef.current.clear();
679
679
  heightCacheVersionRef.current += 1;
680
680
  setHeightCacheVersion(heightCacheVersionRef.current);
681
681
  }, []);
682
- const scrollTo = React3.useCallback(
682
+ const scrollTo = React4.useCallback(
683
683
  (index) => {
684
684
  const container = containerRef.current;
685
685
  if (!container || totalRows === 0) return;
@@ -706,7 +706,7 @@ function useVirtualization({
706
706
  pretextPrefixSums
707
707
  ]
708
708
  );
709
- const totalHeight = React3.useMemo(() => {
709
+ const totalHeight = React4.useMemo(() => {
710
710
  if (totalRows === 0) return 0;
711
711
  if (hasPretextHeights && pretextPrefixSums) return pretextPrefixSums[totalRows];
712
712
  if (isFixedHeight) return totalRows * rowHeight;
@@ -855,18 +855,18 @@ function useColumnVirtualization({
855
855
  enabled = true,
856
856
  sizingKey
857
857
  }) {
858
- const [scrollState, setScrollState] = React3.useState({
858
+ const [scrollState, setScrollState] = React4.useState({
859
859
  scrollLeft: 0,
860
860
  containerWidth: 0
861
861
  });
862
- const rafRef = React3.useRef(null);
863
- const sizes = React3.useMemo(
862
+ const rafRef = React4.useRef(null);
863
+ const sizes = React4.useMemo(
864
864
  () => columns.map((column) => column.getSize()),
865
865
  // `sizingKey` is an explicit invalidation hook for stable Column objects whose getSize value changed.
866
866
  // eslint-disable-next-line react-hooks/exhaustive-deps
867
867
  [columns, sizingKey]
868
868
  );
869
- const offsets = React3.useMemo(() => {
869
+ const offsets = React4.useMemo(() => {
870
870
  const next = new Array(columns.length + 1);
871
871
  next[0] = 0;
872
872
  for (let i = 0; i < columns.length; i++) {
@@ -875,7 +875,7 @@ function useColumnVirtualization({
875
875
  return next;
876
876
  }, [columns.length, sizes]);
877
877
  const totalWidth = offsets[offsets.length - 1] ?? 0;
878
- React3.useEffect(() => {
878
+ React4.useEffect(() => {
879
879
  const container = containerRef.current;
880
880
  if (!container) return;
881
881
  setScrollState({
@@ -922,7 +922,7 @@ function useColumnVirtualization({
922
922
  resizeObserver?.disconnect();
923
923
  };
924
924
  }, [containerRef]);
925
- const scrollToIndex = React3.useCallback(
925
+ const scrollToIndex = React4.useCallback(
926
926
  (index) => {
927
927
  const container = containerRef.current;
928
928
  if (!container || columns.length === 0) return;
@@ -1010,12 +1010,12 @@ function usePretextMeasurement({
1010
1010
  minRowHeight = 32,
1011
1011
  enabled = true
1012
1012
  }) {
1013
- const [pretext, setPretext] = React3.useState(null);
1014
- const [ready, setReady] = React3.useState(false);
1015
- const prepareTimeRef = React3.useRef(0);
1016
- const layoutTimeRef = React3.useRef(0);
1013
+ const [pretext, setPretext] = React4.useState(null);
1014
+ const [ready, setReady] = React4.useState(false);
1015
+ const prepareTimeRef = React4.useRef(0);
1016
+ const layoutTimeRef = React4.useRef(0);
1017
1017
  const columnWidthsKey = columns.map((c) => `${c.columnId}:${c.width}`).join("|");
1018
- React3.useEffect(() => {
1018
+ React4.useEffect(() => {
1019
1019
  if (!enabled) return;
1020
1020
  let cancelled = false;
1021
1021
  loadPretext().then((mod) => {
@@ -1025,8 +1025,8 @@ function usePretextMeasurement({
1025
1025
  cancelled = true;
1026
1026
  };
1027
1027
  }, [enabled]);
1028
- const preparedCacheRef = React3.useRef(/* @__PURE__ */ new Map());
1029
- const preparedCells = React3.useMemo(() => {
1028
+ const preparedCacheRef = React4.useRef(/* @__PURE__ */ new Map());
1029
+ const preparedCells = React4.useMemo(() => {
1030
1030
  if (!pretext || !enabled || data.length === 0 || columns.length === 0) return null;
1031
1031
  const cache = preparedCacheRef.current;
1032
1032
  const start = performance.now();
@@ -1053,7 +1053,7 @@ function usePretextMeasurement({
1053
1053
  data,
1054
1054
  columns.map((c) => `${c.columnId}:${c.font}:${c.fixedHeight ? "F" : "T"}`).join("|")
1055
1055
  ]);
1056
- const measurement = React3.useMemo(() => {
1056
+ const measurement = React4.useMemo(() => {
1057
1057
  if (!pretext || !preparedCells) {
1058
1058
  return { rowHeights: null, prefixSums: null, totalHeight: 0 };
1059
1059
  }
@@ -1094,7 +1094,7 @@ function usePretextMeasurement({
1094
1094
  totalHeight: prefixSums[data.length]
1095
1095
  };
1096
1096
  }, [pretext, preparedCells, columnWidthsKey, minRowHeight, data.length]);
1097
- React3.useEffect(() => {
1097
+ React4.useEffect(() => {
1098
1098
  if (measurement.rowHeights) setReady(true);
1099
1099
  }, [measurement.rowHeights]);
1100
1100
  return {
@@ -1143,7 +1143,7 @@ function CellCurrency({
1143
1143
  }) {
1144
1144
  const raw = context.getValue();
1145
1145
  const num = typeof raw === "number" ? raw : Number(raw);
1146
- const formatter = React3.useMemo(
1146
+ const formatter = React4.useMemo(
1147
1147
  () => new Intl.NumberFormat(locale, {
1148
1148
  style: "currency",
1149
1149
  currency,
@@ -1220,7 +1220,7 @@ function CellNumeric({
1220
1220
  }) {
1221
1221
  const raw = context.getValue();
1222
1222
  const num = typeof raw === "number" ? raw : Number(raw);
1223
- const formatter = React3.useMemo(
1223
+ const formatter = React4.useMemo(
1224
1224
  () => new Intl.NumberFormat(locale, {
1225
1225
  minimumFractionDigits: decimals,
1226
1226
  maximumFractionDigits: decimals
@@ -1474,7 +1474,7 @@ function useAutoMeasurements({
1474
1474
  shouldMeasureColumn = defaultShouldMeasure
1475
1475
  }) {
1476
1476
  const widthKey = columns.map((c) => `${getColumnId2(c) ?? "?"}:${getColumnWidth(c)}`).join("|");
1477
- return React3.useMemo(() => {
1477
+ return React4.useMemo(() => {
1478
1478
  const result = [];
1479
1479
  for (const col of columns) {
1480
1480
  const id = getColumnId2(col);
@@ -1511,7 +1511,7 @@ function useTableRowHeights({
1511
1511
  defaultRecipe,
1512
1512
  getColumnWidth
1513
1513
  });
1514
- const accessorMap = React3.useMemo(() => {
1514
+ const accessorMap = React4.useMemo(() => {
1515
1515
  const map = /* @__PURE__ */ new Map();
1516
1516
  for (const col of columns) {
1517
1517
  const id = col.id ?? col.accessorKey;
@@ -1528,7 +1528,7 @@ function useTableRowHeights({
1528
1528
  }
1529
1529
  return map;
1530
1530
  }, [columns]);
1531
- const getCellText = React3.useMemo(
1531
+ const getCellText = React4.useMemo(
1532
1532
  () => (row, columnId) => {
1533
1533
  const get = accessorMap.get(columnId);
1534
1534
  if (!get) return "";
@@ -1547,10 +1547,10 @@ function useTableRowHeights({
1547
1547
  });
1548
1548
  return { ...result, measurements };
1549
1549
  }
1550
- var TableContext = React3.createContext(null);
1550
+ var TableContext = React4.createContext(null);
1551
1551
  var TableProvider = TableContext.Provider;
1552
1552
  function useTableContext() {
1553
- const ctx = React3.useContext(TableContext);
1553
+ const ctx = React4.useContext(TableContext);
1554
1554
  if (!ctx) {
1555
1555
  throw new Error(
1556
1556
  "[yable E001] useTableContext must be used within a <Table> component. Did you forget to pass the `table` prop?"
@@ -1611,7 +1611,7 @@ function formatValue(value) {
1611
1611
  return JSON.stringify(value);
1612
1612
  }
1613
1613
  function SetFilter({ column, className }) {
1614
- const [open, setOpen] = React3.useState(false);
1614
+ const [open, setOpen] = React4.useState(false);
1615
1615
  const filterValue = column.getFilterValue();
1616
1616
  const selectedValues = Array.isArray(filterValue) ? filterValue : filterValue == null || filterValue === "" ? [] : [filterValue];
1617
1617
  const facetedUniqueValues = column.getFacetedUniqueValues();
@@ -1808,10 +1808,10 @@ function TableHeader({
1808
1808
  }) {
1809
1809
  const headerGroups = table.getHeaderGroups();
1810
1810
  const visibleColumns = table.getVisibleLeafColumns();
1811
- const theadRef = React3.useRef(null);
1812
- const reorderEndRef = React3.useRef(0);
1813
- const [drag, setDrag] = React3.useState(null);
1814
- const commitReorder = React3.useCallback(
1811
+ const theadRef = React4.useRef(null);
1812
+ const reorderEndRef = React4.useRef(0);
1813
+ const [drag, setDrag] = React4.useState(null);
1814
+ const commitReorder = React4.useCallback(
1815
1815
  (d) => {
1816
1816
  if (d.toIndex === d.fromIndex || d.toIndex === d.fromIndex + 1) return;
1817
1817
  const order = table.getState().columnOrder;
@@ -1825,7 +1825,7 @@ function TableHeader({
1825
1825
  },
1826
1826
  [table]
1827
1827
  );
1828
- const beginReorder = React3.useCallback(
1828
+ const beginReorder = React4.useCallback(
1829
1829
  (e, columnId) => {
1830
1830
  if (e.button !== 0) return;
1831
1831
  const thead = theadRef.current;
@@ -1917,7 +1917,7 @@ function TableHeader({
1917
1917
  },
1918
1918
  [visibleColumns, table, commitReorder]
1919
1919
  );
1920
- const transformFor = React3.useCallback(
1920
+ const transformFor = React4.useCallback(
1921
1921
  (columnId) => {
1922
1922
  if (!drag) return 0;
1923
1923
  const i = visibleColumns.findIndex((c) => c.id === columnId);
@@ -1965,7 +1965,7 @@ function TableHeader({
1965
1965
  function FloatingFilterCell({
1966
1966
  column
1967
1967
  }) {
1968
- const style = React3.useMemo(() => {
1968
+ const style = React4.useMemo(() => {
1969
1969
  const next = {
1970
1970
  width: column.getSize(),
1971
1971
  minWidth: column.columnDef.minSize,
@@ -2003,7 +2003,7 @@ function HeaderCell({
2003
2003
  const canReorder = column.getCanReorder() && !header.isPlaceholder;
2004
2004
  const pinned = column.getIsPinned();
2005
2005
  const headerContent = header.isPlaceholder ? null : typeof column.columnDef.header === "function" ? column.columnDef.header(header.getContext()) : column.columnDef.header ?? header.id;
2006
- const style = React3.useMemo(() => {
2006
+ const style = React4.useMemo(() => {
2007
2007
  const s = {
2008
2008
  width: header.getSize(),
2009
2009
  minWidth: column.columnDef.minSize,
@@ -2022,8 +2022,8 @@ function HeaderCell({
2022
2022
  }
2023
2023
  return s;
2024
2024
  }, [header, column, pinned, isDragSource, dragTransform]);
2025
- const lastResizeEndRef = React3.useRef(0);
2026
- const startResize = React3.useCallback(
2025
+ const lastResizeEndRef = React4.useRef(0);
2026
+ const startResize = React4.useCallback(
2027
2027
  (e) => {
2028
2028
  e.stopPropagation();
2029
2029
  const onEnd = () => {
@@ -2038,17 +2038,17 @@ function HeaderCell({
2038
2038
  },
2039
2039
  [header]
2040
2040
  );
2041
- const handleResizeClick = React3.useCallback((e) => {
2041
+ const handleResizeClick = React4.useCallback((e) => {
2042
2042
  e.stopPropagation();
2043
2043
  }, []);
2044
- const handleContentPointerDown = React3.useCallback(
2044
+ const handleContentPointerDown = React4.useCallback(
2045
2045
  (e) => {
2046
2046
  if (!canReorder || pinned) return;
2047
2047
  onReorderPointerDown(e, column.id);
2048
2048
  },
2049
2049
  [canReorder, pinned, onReorderPointerDown, column.id]
2050
2050
  );
2051
- const handleHeaderClick = React3.useCallback(
2051
+ const handleHeaderClick = React4.useCallback(
2052
2052
  (e) => {
2053
2053
  table.events.emit("header:click", {
2054
2054
  column,
@@ -2063,7 +2063,7 @@ function HeaderCell({
2063
2063
  },
2064
2064
  [canSort, column, header, table.events, reorderEndRef]
2065
2065
  );
2066
- const handleHeaderContextMenu = React3.useCallback(
2066
+ const handleHeaderContextMenu = React4.useCallback(
2067
2067
  (e) => {
2068
2068
  table.events.emit("header:contextmenu", {
2069
2069
  column,
@@ -2193,13 +2193,39 @@ function CellStatusBadge(props) {
2193
2193
  }
2194
2194
  );
2195
2195
  }
2196
+ function FillHandle({
2197
+ rowIndex,
2198
+ columnIndex,
2199
+ onMouseDown
2200
+ }) {
2201
+ const handleMouseDown = React4.useCallback(
2202
+ (e) => {
2203
+ e.preventDefault();
2204
+ e.stopPropagation();
2205
+ onMouseDown(rowIndex, columnIndex, e);
2206
+ },
2207
+ [rowIndex, columnIndex, onMouseDown]
2208
+ );
2209
+ return /* @__PURE__ */ jsxRuntime.jsx(
2210
+ "div",
2211
+ {
2212
+ className: "yable-fill-handle",
2213
+ onMouseDown: handleMouseDown,
2214
+ role: "presentation",
2215
+ "aria-hidden": "true",
2216
+ title: "Drag to fill",
2217
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-fill-handle-dot" })
2218
+ }
2219
+ );
2220
+ }
2196
2221
  function TableCell({
2197
2222
  cell,
2198
2223
  table,
2199
2224
  rowIndex,
2200
2225
  columnIndex,
2201
2226
  isFocused,
2202
- isTabStop
2227
+ isTabStop,
2228
+ onFillHandleMouseDown
2203
2229
  }) {
2204
2230
  const column = cell.column;
2205
2231
  const isEditing = cell.getIsEditing();
@@ -2248,8 +2274,42 @@ function TableCell({
2248
2274
  } else {
2249
2275
  content = overrideValue !== void 0 ? overrideValue : cell.renderValue();
2250
2276
  }
2251
- const handleClick = React3.useCallback(
2277
+ const isGroupRow = cell.row.getIsGrouped();
2278
+ if (isGroupRow) {
2279
+ if (column.id === cell.row.groupingColumnId) {
2280
+ const expanded = cell.row.getIsExpanded();
2281
+ content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "yable-group-cell", style: { paddingLeft: cell.row.depth * 16 }, children: [
2282
+ /* @__PURE__ */ jsxRuntime.jsx(
2283
+ "button",
2284
+ {
2285
+ type: "button",
2286
+ className: "yable-group-toggle",
2287
+ "aria-label": expanded ? "Collapse group" : "Expand group",
2288
+ "aria-expanded": expanded,
2289
+ onClick: cell.row.getToggleExpandedHandler(),
2290
+ children: expanded ? "\u25BE" : "\u25B8"
2291
+ }
2292
+ ),
2293
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-group-value", children: String(cell.row.groupingValue ?? "") }),
2294
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "yable-group-count", children: [
2295
+ "(",
2296
+ cell.row.getLeafRows().length,
2297
+ ")"
2298
+ ] })
2299
+ ] });
2300
+ } else {
2301
+ const aggDef = column.columnDef.aggregatedCell;
2302
+ if (typeof aggDef === "function") {
2303
+ content = aggDef(cell.getContext());
2304
+ } else {
2305
+ const aggVal = cell.getValue();
2306
+ content = aggVal == null ? null : aggVal;
2307
+ }
2308
+ }
2309
+ }
2310
+ const handleClick = React4.useCallback(
2252
2311
  (e) => {
2312
+ if (cell.row.getIsGrouped()) return;
2253
2313
  table.events.emit("cell:click", {
2254
2314
  cell,
2255
2315
  row: cell.row,
@@ -2262,7 +2322,7 @@ function TableCell({
2262
2322
  },
2263
2323
  [cell, column, isAlwaysEditable, isEditing, isMultiCellSelection, table]
2264
2324
  );
2265
- const handleDoubleClick = React3.useCallback(
2325
+ const handleDoubleClick = React4.useCallback(
2266
2326
  (e) => {
2267
2327
  table.events.emit("cell:dblclick", {
2268
2328
  cell,
@@ -2273,7 +2333,7 @@ function TableCell({
2273
2333
  },
2274
2334
  [table, cell]
2275
2335
  );
2276
- const handleContextMenu = React3.useCallback(
2336
+ const handleContextMenu = React4.useCallback(
2277
2337
  (e) => {
2278
2338
  table.events.emit("cell:contextmenu", {
2279
2339
  cell,
@@ -2284,11 +2344,11 @@ function TableCell({
2284
2344
  },
2285
2345
  [table, cell]
2286
2346
  );
2287
- const handleFocus = React3.useCallback(() => {
2347
+ const handleFocus = React4.useCallback(() => {
2288
2348
  if (!keyboardNavigationEnabled) return;
2289
2349
  table.setFocusedCell({ rowIndex, columnIndex });
2290
2350
  }, [columnIndex, keyboardNavigationEnabled, rowIndex, table]);
2291
- const handleMouseDown = React3.useCallback(
2351
+ const handleMouseDown = React4.useCallback(
2292
2352
  (e) => {
2293
2353
  if (e.button !== 0) return;
2294
2354
  if (!cellSelectionEnabled) return;
@@ -2301,12 +2361,12 @@ function TableCell({
2301
2361
  },
2302
2362
  [cellSelectionEnabled, columnIndex, rowIndex, table]
2303
2363
  );
2304
- const handleMouseEnter = React3.useCallback(() => {
2364
+ const handleMouseEnter = React4.useCallback(() => {
2305
2365
  if (!cellSelectionEnabled) return;
2306
2366
  if (!table.getState().cellSelection?.isDragging) return;
2307
2367
  table.updateCellRangeSelection({ rowIndex, columnIndex });
2308
2368
  }, [cellSelectionEnabled, columnIndex, rowIndex, table]);
2309
- const handleMouseUp = React3.useCallback(() => {
2369
+ const handleMouseUp = React4.useCallback(() => {
2310
2370
  if (!table.getState().cellSelection?.isDragging) return;
2311
2371
  table.endCellRangeSelection();
2312
2372
  }, [table]);
@@ -2315,6 +2375,7 @@ function TableCell({
2315
2375
  const cellStyleDef = column.columnDef.cellStyle;
2316
2376
  const userStyle = typeof cellStyleDef === "function" ? cellStyleDef(cell.getContext()) : cellStyleDef;
2317
2377
  const mergedStyle = userStyle ? { ...style, ...userStyle } : style;
2378
+ const showFillHandle = isFocused && Boolean(table.options.enableFillHandle) && onFillHandleMouseDown != null && !isGroupRow;
2318
2379
  const classNames = [
2319
2380
  "yable-td",
2320
2381
  isFocused && "yable-cell--focused",
@@ -2335,6 +2396,7 @@ function TableCell({
2335
2396
  "data-pinned": pinned || void 0,
2336
2397
  "data-cell-status": cellStatus !== "idle" ? cellStatus : void 0,
2337
2398
  "data-column-id": column.id,
2399
+ "data-grouped": isGroupRow || void 0,
2338
2400
  "data-row-index": rowIndex,
2339
2401
  "data-column-index": columnIndex,
2340
2402
  "data-cell-selected": isCellSelected || void 0,
@@ -2368,6 +2430,14 @@ function TableCell({
2368
2430
  onRetry: () => void table.retryCommit(cell.row.id, column.id),
2369
2431
  onDismiss: () => table.dismissCommit(cell.row.id, column.id)
2370
2432
  }
2433
+ ),
2434
+ showFillHandle && onFillHandleMouseDown && /* @__PURE__ */ jsxRuntime.jsx(
2435
+ FillHandle,
2436
+ {
2437
+ rowIndex,
2438
+ columnIndex,
2439
+ onMouseDown: onFillHandleMouseDown
2440
+ }
2371
2441
  )
2372
2442
  ]
2373
2443
  }
@@ -2380,7 +2450,7 @@ function isInteractiveClickTarget(element) {
2380
2450
  );
2381
2451
  return interactive !== null;
2382
2452
  }
2383
- var ErrorBoundary = class extends React3__default.default.Component {
2453
+ var ErrorBoundary = class extends React4__default.default.Component {
2384
2454
  constructor(props) {
2385
2455
  super(props);
2386
2456
  this.state = { hasError: false, error: null };
@@ -2426,7 +2496,7 @@ var ErrorBoundary = class extends React3__default.default.Component {
2426
2496
  return this.props.children;
2427
2497
  }
2428
2498
  };
2429
- var CellErrorBoundary = class extends React3__default.default.Component {
2499
+ var CellErrorBoundary = class extends React4__default.default.Component {
2430
2500
  constructor(props) {
2431
2501
  super(props);
2432
2502
  this.state = { hasError: false, error: null };
@@ -2499,7 +2569,8 @@ function MasterDetail({
2499
2569
  function TableBody({
2500
2570
  table,
2501
2571
  clickableRows,
2502
- colgroup
2572
+ colgroup,
2573
+ onFillHandleMouseDown
2503
2574
  }) {
2504
2575
  const rows = table.getRowModel().rows;
2505
2576
  const visibleColumns = table.getVisibleLeafColumns();
@@ -2512,14 +2583,14 @@ function TableBody({
2512
2583
  const pendingValues = table.getState().editing.pendingValues ?? {};
2513
2584
  const options = table.options;
2514
2585
  const enableVirtualization = options.enableVirtualization ?? false;
2515
- const scrollContainerRef = React3.useRef(null);
2586
+ const scrollContainerRef = React4.useRef(null);
2516
2587
  const rowHeight = options.rowHeight ?? 40;
2517
2588
  const overscan = options.overscan ?? 5;
2518
2589
  const estimateRowHeight = options.estimateRowHeight;
2519
2590
  const pretextHeights = options.pretextHeights ?? null;
2520
2591
  const pretextPrefixSums = options.pretextPrefixSums ?? null;
2521
2592
  const columnSizing = table.getState().columnSizing;
2522
- const columnSizingHash = React3.useMemo(() => {
2593
+ const columnSizingHash = React4.useMemo(() => {
2523
2594
  const entries = Object.entries(columnSizing);
2524
2595
  if (entries.length === 0) return 0;
2525
2596
  let h = 0;
@@ -2542,7 +2613,7 @@ function TableBody({
2542
2613
  columnSizingHash
2543
2614
  });
2544
2615
  const cellSelectionKey = cellSelection.range ? `${cellSelection.range.start.rowIndex}:${cellSelection.range.start.columnIndex}:${cellSelection.range.end.rowIndex}:${cellSelection.range.end.columnIndex}:${cellSelection.isDragging ? "dragging" : "idle"}` : `none:${cellSelection.isDragging ? "dragging" : "idle"}`;
2545
- React3.useEffect(() => {
2616
+ React4.useEffect(() => {
2546
2617
  const handleWindowMouseUp = () => {
2547
2618
  if (table.getState().cellSelection?.isDragging) {
2548
2619
  table.endCellRangeSelection();
@@ -2568,7 +2639,8 @@ function TableBody({
2568
2639
  cellSelectionKey,
2569
2640
  pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
2570
2641
  clickable: clickableRows,
2571
- pinnedPosition
2642
+ pinnedPosition,
2643
+ onFillHandleMouseDown
2572
2644
  },
2573
2645
  row.id
2574
2646
  );
@@ -2637,6 +2709,7 @@ function TableBody({
2637
2709
  cellSelectionKey,
2638
2710
  pendingValuesKey: getPendingValuesKey(pendingValues[row.id]),
2639
2711
  clickable: clickableRows,
2712
+ onFillHandleMouseDown,
2640
2713
  virtualStyle: {
2641
2714
  position: "absolute",
2642
2715
  top: 0,
@@ -2671,11 +2744,12 @@ function TableRowInner({
2671
2744
  pendingValuesKey: _pendingValuesKey,
2672
2745
  clickable,
2673
2746
  pinnedPosition,
2674
- virtualStyle
2747
+ virtualStyle,
2748
+ onFillHandleMouseDown
2675
2749
  }) {
2676
2750
  const allCells = row.getAllCells();
2677
2751
  const visibleCells = visibleColumns.map((column) => allCells.find((cell) => cell.column.id === column.id)).filter((cell) => cell != null);
2678
- const handleClick = React3.useCallback(
2752
+ const handleClick = React4.useCallback(
2679
2753
  (e) => {
2680
2754
  if (table.options.enableRowClickSelection && row.getCanSelect() && !isInteractiveClickTarget2(e.target)) {
2681
2755
  row.toggleSelected();
@@ -2689,7 +2763,7 @@ function TableRowInner({
2689
2763
  },
2690
2764
  [clickable, table, row]
2691
2765
  );
2692
- const handleDoubleClick = React3.useCallback(
2766
+ const handleDoubleClick = React4.useCallback(
2693
2767
  (e) => {
2694
2768
  table.events.emit("row:dblclick", {
2695
2769
  row,
@@ -2698,7 +2772,7 @@ function TableRowInner({
2698
2772
  },
2699
2773
  [table.events, row]
2700
2774
  );
2701
- const handleContextMenu = React3.useCallback(
2775
+ const handleContextMenu = React4.useCallback(
2702
2776
  (e) => {
2703
2777
  table.events.emit("row:contextmenu", {
2704
2778
  row,
@@ -2751,7 +2825,8 @@ function TableRowInner({
2751
2825
  rowIndex,
2752
2826
  columnIndex,
2753
2827
  isFocused,
2754
- isTabStop
2828
+ isTabStop,
2829
+ onFillHandleMouseDown
2755
2830
  }
2756
2831
  )
2757
2832
  },
@@ -2785,7 +2860,7 @@ function areRowPropsEqual(prev, next) {
2785
2860
  if (prev.table !== next.table) return false;
2786
2861
  return true;
2787
2862
  }
2788
- var MemoizedTableRow = React3__default.default.memo(TableRowInner, areRowPropsEqual);
2863
+ var MemoizedTableRow = React4__default.default.memo(TableRowInner, areRowPropsEqual);
2789
2864
  function getPendingValuesKey(values) {
2790
2865
  if (!values) return "";
2791
2866
  return Object.keys(values).sort().map((key) => `${key}:${String(values[key])}`).join("|");
@@ -3003,8 +3078,8 @@ function StatusDivider() {
3003
3078
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "yable-status-bar-divider", "aria-hidden": "true" });
3004
3079
  }
3005
3080
  function PanelGroup({ children }) {
3006
- const items = React3__default.default.Children.toArray(children).filter(Boolean);
3007
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: items.map((child, i) => /* @__PURE__ */ jsxRuntime.jsxs(React3__default.default.Fragment, { children: [
3081
+ const items = React4__default.default.Children.toArray(children).filter(Boolean);
3082
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: items.map((child, i) => /* @__PURE__ */ jsxRuntime.jsxs(React4__default.default.Fragment, { children: [
3008
3083
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(StatusDivider, {}),
3009
3084
  child
3010
3085
  ] }, i)) });
@@ -3141,8 +3216,8 @@ function VisibilityIcon({ visible }) {
3141
3216
  ] });
3142
3217
  }
3143
3218
  function ColumnsPanel({ table }) {
3144
- const [search, setSearch] = React3.useState("");
3145
- const [draggedId, setDraggedId] = React3.useState(null);
3219
+ const [search, setSearch] = React4.useState("");
3220
+ const [draggedId, setDraggedId] = React4.useState(null);
3146
3221
  const allColumns = table.getAllLeafColumns();
3147
3222
  const columnOrder = table.getState().columnOrder;
3148
3223
  const columns = columnOrder && columnOrder.length > 0 ? [...allColumns].sort((a, b) => {
@@ -3155,25 +3230,25 @@ function ColumnsPanel({ table }) {
3155
3230
  const header = typeof col.columnDef.header === "string" ? col.columnDef.header : col.id;
3156
3231
  return header.toLowerCase().includes(search.toLowerCase());
3157
3232
  }) : columns;
3158
- const handleToggleAll = React3.useCallback(
3233
+ const handleToggleAll = React4.useCallback(
3159
3234
  (visible) => {
3160
3235
  table.toggleAllColumnsVisible(visible);
3161
3236
  },
3162
3237
  [table]
3163
3238
  );
3164
- const handleDragStart = React3.useCallback((e, columnId) => {
3239
+ const handleDragStart = React4.useCallback((e, columnId) => {
3165
3240
  setDraggedId(columnId);
3166
3241
  e.dataTransfer.effectAllowed = "move";
3167
3242
  e.dataTransfer.setData("text/plain", columnId);
3168
3243
  }, []);
3169
- const handleDragOver = React3.useCallback((e) => {
3244
+ const handleDragOver = React4.useCallback((e) => {
3170
3245
  e.preventDefault();
3171
3246
  e.dataTransfer.dropEffect = "move";
3172
3247
  }, []);
3173
- const handleDragEnd = React3.useCallback(() => {
3248
+ const handleDragEnd = React4.useCallback(() => {
3174
3249
  setDraggedId(null);
3175
3250
  }, []);
3176
- const handleDrop = React3.useCallback(
3251
+ const handleDrop = React4.useCallback(
3177
3252
  (e, targetId) => {
3178
3253
  e.preventDefault();
3179
3254
  if (!draggedId || draggedId === targetId) return;
@@ -3298,7 +3373,7 @@ function FiltersPanel({
3298
3373
  const globalFilter = table.getState().globalFilter;
3299
3374
  const hasFilters = columnFilters.length > 0 || Boolean(globalFilter);
3300
3375
  const filterCount = columnFilters.length + (globalFilter ? 1 : 0);
3301
- const handleRemoveColumnFilter = React3.useCallback(
3376
+ const handleRemoveColumnFilter = React4.useCallback(
3302
3377
  (columnId) => {
3303
3378
  table.setColumnFilters(
3304
3379
  (prev) => prev.filter((f) => f.id !== columnId)
@@ -3306,7 +3381,7 @@ function FiltersPanel({
3306
3381
  },
3307
3382
  [table]
3308
3383
  );
3309
- const handleClearAll = React3.useCallback(() => {
3384
+ const handleClearAll = React4.useCallback(() => {
3310
3385
  table.resetColumnFilters(true);
3311
3386
  table.resetGlobalFilter(true);
3312
3387
  }, [table]);
@@ -3400,8 +3475,8 @@ function Sidebar({
3400
3475
  activePanel,
3401
3476
  onPanelChange
3402
3477
  }) {
3403
- const sidebarRef = React3.useRef(null);
3404
- const handleKeyDown = React3.useCallback(
3478
+ const sidebarRef = React4.useRef(null);
3479
+ const handleKeyDown = React4.useCallback(
3405
3480
  (e) => {
3406
3481
  if (e.key === "Escape" && open) {
3407
3482
  onClose();
@@ -3409,7 +3484,7 @@ function Sidebar({
3409
3484
  },
3410
3485
  [open, onClose]
3411
3486
  );
3412
- React3.useEffect(() => {
3487
+ React4.useEffect(() => {
3413
3488
  document.addEventListener("keydown", handleKeyDown);
3414
3489
  return () => document.removeEventListener("keydown", handleKeyDown);
3415
3490
  }, [handleKeyDown]);
@@ -3491,11 +3566,11 @@ function Sidebar({
3491
3566
  );
3492
3567
  }
3493
3568
  function ContextMenuItem({ item, onClose }) {
3494
- const [submenuOpen, setSubmenuOpen] = React3.useState(false);
3495
- const itemRef = React3.useRef(null);
3496
- const submenuRef = React3.useRef(null);
3497
- const timerRef = React3.useRef(void 0);
3498
- React3.useEffect(() => {
3569
+ const [submenuOpen, setSubmenuOpen] = React4.useState(false);
3570
+ const itemRef = React4.useRef(null);
3571
+ const submenuRef = React4.useRef(null);
3572
+ const timerRef = React4.useRef(void 0);
3573
+ React4.useEffect(() => {
3499
3574
  return () => clearTimeout(timerRef.current);
3500
3575
  }, []);
3501
3576
  if (item.separator) {
@@ -3579,8 +3654,8 @@ function ContextMenu({
3579
3654
  targetColumnId,
3580
3655
  customItems
3581
3656
  }) {
3582
- const menuRef = React3.useRef(null);
3583
- React3.useEffect(() => {
3657
+ const menuRef = React4.useRef(null);
3658
+ React4.useEffect(() => {
3584
3659
  if (!menuRef.current) return;
3585
3660
  const rect = menuRef.current.getBoundingClientRect();
3586
3661
  const vw = window.innerWidth;
@@ -3592,11 +3667,11 @@ function ContextMenu({
3592
3667
  menuRef.current.style.top = `${y - rect.height}px`;
3593
3668
  }
3594
3669
  }, [x, y]);
3595
- React3.useEffect(() => {
3670
+ React4.useEffect(() => {
3596
3671
  const firstItem = menuRef.current?.querySelector('[role="menuitem"]');
3597
3672
  firstItem?.focus();
3598
3673
  }, []);
3599
- const handleKeyDown = React3.useCallback(
3674
+ const handleKeyDown = React4.useCallback(
3600
3675
  (e) => {
3601
3676
  if (e.key === "Escape") {
3602
3677
  onClose();
@@ -3774,12 +3849,12 @@ function ContextMenu({
3774
3849
  ] });
3775
3850
  }
3776
3851
  function useContextMenu() {
3777
- const [isOpen, setIsOpen] = React3.useState(false);
3778
- const [x, setX] = React3.useState(0);
3779
- const [y, setY] = React3.useState(0);
3780
- const [targetTable, setTargetTable] = React3.useState(null);
3781
- const [targetColumnId, setTargetColumnId] = React3.useState(void 0);
3782
- const open = React3.useCallback(
3852
+ const [isOpen, setIsOpen] = React4.useState(false);
3853
+ const [x, setX] = React4.useState(0);
3854
+ const [y, setY] = React4.useState(0);
3855
+ const [targetTable, setTargetTable] = React4.useState(null);
3856
+ const [targetColumnId, setTargetColumnId] = React4.useState(void 0);
3857
+ const open = React4.useCallback(
3783
3858
  (clientX, clientY, table, columnId) => {
3784
3859
  setX(clientX);
3785
3860
  setY(clientY);
@@ -3789,12 +3864,12 @@ function useContextMenu() {
3789
3864
  },
3790
3865
  []
3791
3866
  );
3792
- const close = React3.useCallback(() => {
3867
+ const close = React4.useCallback(() => {
3793
3868
  setIsOpen(false);
3794
3869
  setTargetTable(null);
3795
3870
  setTargetColumnId(void 0);
3796
3871
  }, []);
3797
- React3.useEffect(() => {
3872
+ React4.useEffect(() => {
3798
3873
  if (!isOpen) return;
3799
3874
  const handleKeyDown = (e) => {
3800
3875
  if (e.key === "Escape") close();
@@ -3818,7 +3893,7 @@ function useKeyboardNavigation(table, options = {}) {
3818
3893
  const activeCell = table.getState().editing.activeCell;
3819
3894
  const focusedRowIndex = focusedCell?.rowIndex ?? null;
3820
3895
  const focusedColumnIndex = focusedCell?.columnIndex ?? null;
3821
- const focusCellElement = React3.useCallback(
3896
+ const focusCellElement = React4.useCallback(
3822
3897
  (container, cell) => {
3823
3898
  const element = getCellElement(container, cell);
3824
3899
  if (!element) return false;
@@ -3833,7 +3908,7 @@ function useKeyboardNavigation(table, options = {}) {
3833
3908
  },
3834
3909
  []
3835
3910
  );
3836
- const handleKeyDown = React3.useCallback(
3911
+ const handleKeyDown = React4.useCallback(
3837
3912
  (event) => {
3838
3913
  if (!enabled || table.options.enableKeyboardNavigation === false) return;
3839
3914
  const target = event.target;
@@ -3907,7 +3982,7 @@ function useKeyboardNavigation(table, options = {}) {
3907
3982
  },
3908
3983
  [activeCell, containerRef, enabled, table]
3909
3984
  );
3910
- React3.useEffect(() => {
3985
+ React4.useEffect(() => {
3911
3986
  if (!enabled || table.options.enableKeyboardNavigation === false) return;
3912
3987
  const container = containerRef?.current;
3913
3988
  if (!container) return;
@@ -3916,7 +3991,7 @@ function useKeyboardNavigation(table, options = {}) {
3916
3991
  container.removeEventListener("keydown", handleKeyDown);
3917
3992
  };
3918
3993
  }, [containerRef, enabled, handleKeyDown, table.options.enableKeyboardNavigation]);
3919
- React3.useEffect(() => {
3994
+ React4.useEffect(() => {
3920
3995
  if (!enabled || table.options.enableKeyboardNavigation === false) return;
3921
3996
  if (focusedRowIndex === null || focusedColumnIndex === null) return;
3922
3997
  if (activeCell) return;
@@ -4007,6 +4082,85 @@ function isEditableTarget(element) {
4007
4082
  }
4008
4083
  return element.isContentEditable;
4009
4084
  }
4085
+ function useFillHandle(table, options = {}) {
4086
+ const { enabled = true } = options;
4087
+ const [dragState, setDragState] = React4.useState({
4088
+ isDragging: false,
4089
+ sourceCell: null,
4090
+ currentCell: null
4091
+ });
4092
+ const dragRef = React4.useRef(dragState);
4093
+ dragRef.current = dragState;
4094
+ const onFillHandleMouseDown = React4.useCallback(
4095
+ (rowIndex, columnIndex, e) => {
4096
+ if (!enabled) return;
4097
+ e.preventDefault();
4098
+ e.stopPropagation();
4099
+ setDragState({
4100
+ isDragging: true,
4101
+ sourceCell: { rowIndex, columnIndex },
4102
+ currentCell: { rowIndex, columnIndex }
4103
+ });
4104
+ },
4105
+ [enabled]
4106
+ );
4107
+ React4.useEffect(() => {
4108
+ if (!dragState.isDragging) return;
4109
+ const handleMouseMove = (e) => {
4110
+ const target = document.elementFromPoint(e.clientX, e.clientY);
4111
+ if (!target) return;
4112
+ const td = target.closest("td[data-column-id]");
4113
+ const tr = target.closest("tr[data-row-id]");
4114
+ if (!td || !tr) return;
4115
+ const columnId = td.getAttribute("data-column-id");
4116
+ const rowId = tr.getAttribute("data-row-id");
4117
+ if (!columnId || !rowId) return;
4118
+ const rows = table.getRowModel().rows;
4119
+ const columns = table.getVisibleLeafColumns();
4120
+ const rowIndex = rows.findIndex((r) => r.id === rowId);
4121
+ const columnIndex = columns.findIndex((c) => c.id === columnId);
4122
+ if (rowIndex === -1 || columnIndex === -1) return;
4123
+ setDragState((prev) => ({
4124
+ ...prev,
4125
+ currentCell: { rowIndex, columnIndex }
4126
+ }));
4127
+ };
4128
+ const handleMouseUp = () => {
4129
+ const current = dragRef.current;
4130
+ if (current.sourceCell && current.currentCell) {
4131
+ const source = current.sourceCell;
4132
+ const target = current.currentCell;
4133
+ if (source.rowIndex !== target.rowIndex || source.columnIndex !== target.columnIndex) {
4134
+ const sourceRange = {
4135
+ startRow: source.rowIndex,
4136
+ startCol: source.columnIndex,
4137
+ endRow: source.rowIndex,
4138
+ endCol: source.columnIndex
4139
+ };
4140
+ const targetRange = {
4141
+ startRow: Math.min(source.rowIndex, target.rowIndex),
4142
+ startCol: Math.min(source.columnIndex, target.columnIndex),
4143
+ endRow: Math.max(source.rowIndex, target.rowIndex),
4144
+ endCol: Math.max(source.columnIndex, target.columnIndex)
4145
+ };
4146
+ table.fillRange(sourceRange, targetRange);
4147
+ }
4148
+ }
4149
+ setDragState({
4150
+ isDragging: false,
4151
+ sourceCell: null,
4152
+ currentCell: null
4153
+ });
4154
+ };
4155
+ document.addEventListener("mousemove", handleMouseMove);
4156
+ document.addEventListener("mouseup", handleMouseUp);
4157
+ return () => {
4158
+ document.removeEventListener("mousemove", handleMouseMove);
4159
+ document.removeEventListener("mouseup", handleMouseUp);
4160
+ };
4161
+ }, [dragState.isDragging, table]);
4162
+ return { dragState, onFillHandleMouseDown };
4163
+ }
4010
4164
  function filterHeaderGroups(groups, visibleColumnIds) {
4011
4165
  return groups.map((group) => ({
4012
4166
  ...group,
@@ -4069,12 +4223,12 @@ function Table({
4069
4223
  const resolvedFloatingFilters = floatingFilters ?? profileTableProps?.floatingFilters;
4070
4224
  const resolvedColumnVirtualization = columnVirtualization ?? profileTableProps?.columnVirtualization;
4071
4225
  const resolvedColumnVirtualizationOverscan = columnVirtualizationOverscan ?? profileTableProps?.columnVirtualizationOverscan;
4072
- const [sidebarOpen, setSidebarOpen] = React3.useState(false);
4073
- const [sidebarPanel, setSidebarPanel] = React3.useState(
4226
+ const [sidebarOpen, setSidebarOpen] = React4.useState(false);
4227
+ const [sidebarPanel, setSidebarPanel] = React4.useState(
4074
4228
  resolvedDefaultSidebarPanel ?? "columns"
4075
4229
  );
4076
- const containerRef = React3.useRef(null);
4077
- const horizontalScrollRef = React3.useRef(null);
4230
+ const containerRef = React4.useRef(null);
4231
+ const horizontalScrollRef = React4.useRef(null);
4078
4232
  const isRtl = direction === "rtl";
4079
4233
  const classNames = [
4080
4234
  "yable",
@@ -4104,7 +4258,7 @@ function Table({
4104
4258
  enabled: canVirtualizeColumns,
4105
4259
  sizingKey: allVisibleColumnSizeSignature
4106
4260
  });
4107
- const renderTable = React3.useMemo(() => {
4261
+ const renderTable = React4.useMemo(() => {
4108
4262
  if (!canVirtualizeColumns || !columnVirtualState.isVirtualized) {
4109
4263
  return table;
4110
4264
  }
@@ -4130,13 +4284,16 @@ function Table({
4130
4284
  const showColumnVirtualizationShell = canVirtualizeColumns;
4131
4285
  const contextMenu = useContextMenu();
4132
4286
  useKeyboardNavigation(table, { containerRef });
4133
- const [announcement, setAnnouncement] = React3.useState("");
4134
- const prevSortingRef = React3.useRef(table.getState().sorting);
4135
- const prevFilterCountRef = React3.useRef(rows.length);
4136
- const prevHasFiltersRef = React3.useRef(isFiltered);
4137
- const prevPaginationRef = React3.useRef(table.getState().pagination);
4138
- const isFirstRenderRef = React3.useRef(true);
4139
- React3.useEffect(() => {
4287
+ const { onFillHandleMouseDown } = useFillHandle(table, {
4288
+ enabled: Boolean(table.options.enableFillHandle)
4289
+ });
4290
+ const [announcement, setAnnouncement] = React4.useState("");
4291
+ const prevSortingRef = React4.useRef(table.getState().sorting);
4292
+ const prevFilterCountRef = React4.useRef(rows.length);
4293
+ const prevHasFiltersRef = React4.useRef(isFiltered);
4294
+ const prevPaginationRef = React4.useRef(table.getState().pagination);
4295
+ const isFirstRenderRef = React4.useRef(true);
4296
+ React4.useEffect(() => {
4140
4297
  if (isFirstRenderRef.current) {
4141
4298
  isFirstRenderRef.current = false;
4142
4299
  return;
@@ -4174,7 +4331,7 @@ function Table({
4174
4331
  }
4175
4332
  }
4176
4333
  });
4177
- const handleContextMenu = React3.useCallback(
4334
+ const handleContextMenu = React4.useCallback(
4178
4335
  (e) => {
4179
4336
  e.preventDefault();
4180
4337
  const targetEl = e.target?.closest?.("[data-column-id]");
@@ -4189,7 +4346,7 @@ function Table({
4189
4346
  0
4190
4347
  );
4191
4348
  const colgroup = visibleLeafColumns.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: visibleLeafColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: col.getSize() } }, col.id)) });
4192
- const outerTableStyle = React3.useMemo(() => {
4349
+ const outerTableStyle = React4.useMemo(() => {
4193
4350
  if (columnVirtualState.isVirtualized) {
4194
4351
  return {
4195
4352
  width: columnVirtualState.visibleWidth,
@@ -4217,7 +4374,15 @@ function Table({
4217
4374
  children: [
4218
4375
  colgroup,
4219
4376
  /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { table: renderTable, floatingFilters: resolvedFloatingFilters }),
4220
- /* @__PURE__ */ jsxRuntime.jsx(TableBody, { table: renderTable, clickableRows: resolvedClickableRows, colgroup }),
4377
+ /* @__PURE__ */ jsxRuntime.jsx(
4378
+ TableBody,
4379
+ {
4380
+ table: renderTable,
4381
+ clickableRows: resolvedClickableRows,
4382
+ colgroup,
4383
+ onFillHandleMouseDown
4384
+ }
4385
+ ),
4221
4386
  footer && /* @__PURE__ */ jsxRuntime.jsx(TableFooter, { table: renderTable })
4222
4387
  ]
4223
4388
  }
@@ -4539,12 +4704,12 @@ function GlobalFilter({
4539
4704
  }) {
4540
4705
  const locale = yableCore.getDefaultLocale();
4541
4706
  const resolvedPlaceholder = placeholder ?? locale.searchPlaceholder;
4542
- const [value, setValue] = React3.useState(
4707
+ const [value, setValue] = React4.useState(
4543
4708
  table.getState().globalFilter ?? ""
4544
4709
  );
4545
- const timerRef = React3.useRef(void 0);
4546
- const inputRef = React3.useRef(null);
4547
- const handleChange = React3.useCallback(
4710
+ const timerRef = React4.useRef(void 0);
4711
+ const inputRef = React4.useRef(null);
4712
+ const handleChange = React4.useCallback(
4548
4713
  (e) => {
4549
4714
  const newValue = e.target.value;
4550
4715
  setValue(newValue);
@@ -4559,13 +4724,13 @@ function GlobalFilter({
4559
4724
  },
4560
4725
  [table, debounce]
4561
4726
  );
4562
- const handleClear = React3.useCallback(() => {
4727
+ const handleClear = React4.useCallback(() => {
4563
4728
  setValue("");
4564
4729
  table.setGlobalFilter("");
4565
4730
  clearTimeout(timerRef.current);
4566
4731
  inputRef.current?.focus();
4567
4732
  }, [table]);
4568
- const handleKeyDown = React3.useCallback(
4733
+ const handleKeyDown = React4.useCallback(
4569
4734
  (e) => {
4570
4735
  if (e.key === "Escape" && value) {
4571
4736
  e.preventDefault();
@@ -4574,10 +4739,10 @@ function GlobalFilter({
4574
4739
  },
4575
4740
  [value, handleClear]
4576
4741
  );
4577
- React3.useEffect(() => {
4742
+ React4.useEffect(() => {
4578
4743
  return () => clearTimeout(timerRef.current);
4579
4744
  }, []);
4580
- React3.useEffect(() => {
4745
+ React4.useEffect(() => {
4581
4746
  const externalValue = table.getState().globalFilter ?? "";
4582
4747
  if (externalValue !== value) {
4583
4748
  setValue(externalValue);
@@ -4622,7 +4787,7 @@ function CellInput({
4622
4787
  className
4623
4788
  }) {
4624
4789
  const { table, row, column, cell } = context;
4625
- const inputRef = React3.useRef(null);
4790
+ const inputRef = React4.useRef(null);
4626
4791
  const isEditing = cell.getIsEditing();
4627
4792
  const isAlwaysEditable = cell.getIsAlwaysEditable();
4628
4793
  const pending = table.getPendingValue(row.id, column.id);
@@ -4647,7 +4812,7 @@ function CellInput({
4647
4812
  }
4648
4813
  }
4649
4814
  };
4650
- React3.useEffect(() => {
4815
+ React4.useEffect(() => {
4651
4816
  if ((isEditing || autoFocus) && inputRef.current) {
4652
4817
  inputRef.current.focus();
4653
4818
  inputRef.current.select();
@@ -4683,8 +4848,8 @@ function CellSelect({
4683
4848
  const isAlwaysEditable = cell.getIsAlwaysEditable();
4684
4849
  const pending = table.getPendingValue(row.id, column.id);
4685
4850
  const currentValue = pending !== void 0 ? pending : cell.getValue();
4686
- const commitTimerRef = React3.useRef(null);
4687
- React3.useEffect(() => {
4851
+ const commitTimerRef = React4.useRef(null);
4852
+ React4.useEffect(() => {
4688
4853
  return () => {
4689
4854
  if (commitTimerRef.current !== null) {
4690
4855
  clearTimeout(commitTimerRef.current);
@@ -4765,7 +4930,7 @@ function CellDatePicker({
4765
4930
  className
4766
4931
  }) {
4767
4932
  const { table, row, column, cell } = context;
4768
- const inputRef = React3.useRef(null);
4933
+ const inputRef = React4.useRef(null);
4769
4934
  const isEditing = cell.getIsEditing();
4770
4935
  const isAlwaysEditable = cell.getIsAlwaysEditable();
4771
4936
  const pending = table.getPendingValue(row.id, column.id);
@@ -4779,7 +4944,7 @@ function CellDatePicker({
4779
4944
  table.commitEdit();
4780
4945
  }
4781
4946
  };
4782
- React3.useEffect(() => {
4947
+ React4.useEffect(() => {
4783
4948
  if (isEditing && inputRef.current) {
4784
4949
  inputRef.current.focus();
4785
4950
  }
@@ -4814,7 +4979,7 @@ function formatDateValue(value, type) {
4814
4979
  }
4815
4980
  function useClipboard(table, options = {}) {
4816
4981
  const { enabled = true, containerRef, onCopy, onCut, onPaste, ...clipboardOptions } = options;
4817
- const handleCopy = React3.useCallback(
4982
+ const handleCopy = React4.useCallback(
4818
4983
  (e) => {
4819
4984
  if (isEditableTarget2(e.target)) return;
4820
4985
  e.preventDefault();
@@ -4826,7 +4991,7 @@ function useClipboard(table, options = {}) {
4826
4991
  },
4827
4992
  [table, clipboardOptions, onCopy]
4828
4993
  );
4829
- const handleCut = React3.useCallback(
4994
+ const handleCut = React4.useCallback(
4830
4995
  (e) => {
4831
4996
  if (isEditableTarget2(e.target)) return;
4832
4997
  e.preventDefault();
@@ -4838,7 +5003,7 @@ function useClipboard(table, options = {}) {
4838
5003
  },
4839
5004
  [table, clipboardOptions, onCut]
4840
5005
  );
4841
- const handlePaste = React3.useCallback(
5006
+ const handlePaste = React4.useCallback(
4842
5007
  (e) => {
4843
5008
  if (isEditableTarget2(e.target)) return;
4844
5009
  e.preventDefault();
@@ -4883,7 +5048,7 @@ function useClipboard(table, options = {}) {
4883
5048
  },
4884
5049
  [table, clipboardOptions, onPaste]
4885
5050
  );
4886
- React3.useEffect(() => {
5051
+ React4.useEffect(() => {
4887
5052
  if (!enabled) return;
4888
5053
  const container = containerRef?.current ?? document;
4889
5054
  container.addEventListener("copy", handleCopy);
@@ -4905,110 +5070,6 @@ function isEditableTarget2(el) {
4905
5070
  if (el.isContentEditable) return true;
4906
5071
  return false;
4907
5072
  }
4908
- function useFillHandle(table, options = {}) {
4909
- const { enabled = true } = options;
4910
- const [dragState, setDragState] = React3.useState({
4911
- isDragging: false,
4912
- sourceCell: null,
4913
- currentCell: null
4914
- });
4915
- const dragRef = React3.useRef(dragState);
4916
- dragRef.current = dragState;
4917
- const onFillHandleMouseDown = React3.useCallback(
4918
- (rowIndex, columnIndex, e) => {
4919
- if (!enabled) return;
4920
- e.preventDefault();
4921
- e.stopPropagation();
4922
- setDragState({
4923
- isDragging: true,
4924
- sourceCell: { rowIndex, columnIndex },
4925
- currentCell: { rowIndex, columnIndex }
4926
- });
4927
- },
4928
- [enabled]
4929
- );
4930
- React3.useEffect(() => {
4931
- if (!dragState.isDragging) return;
4932
- const handleMouseMove = (e) => {
4933
- const target = document.elementFromPoint(e.clientX, e.clientY);
4934
- if (!target) return;
4935
- const td = target.closest("td[data-column-id]");
4936
- const tr = target.closest("tr[data-row-id]");
4937
- if (!td || !tr) return;
4938
- const columnId = td.getAttribute("data-column-id");
4939
- const rowId = tr.getAttribute("data-row-id");
4940
- if (!columnId || !rowId) return;
4941
- const rows = table.getRowModel().rows;
4942
- const columns = table.getVisibleLeafColumns();
4943
- const rowIndex = rows.findIndex((r) => r.id === rowId);
4944
- const columnIndex = columns.findIndex((c) => c.id === columnId);
4945
- if (rowIndex === -1 || columnIndex === -1) return;
4946
- setDragState((prev) => ({
4947
- ...prev,
4948
- currentCell: { rowIndex, columnIndex }
4949
- }));
4950
- };
4951
- const handleMouseUp = () => {
4952
- const current = dragRef.current;
4953
- if (current.sourceCell && current.currentCell) {
4954
- const source = current.sourceCell;
4955
- const target = current.currentCell;
4956
- if (source.rowIndex !== target.rowIndex || source.columnIndex !== target.columnIndex) {
4957
- const sourceRange = {
4958
- startRow: source.rowIndex,
4959
- startCol: source.columnIndex,
4960
- endRow: source.rowIndex,
4961
- endCol: source.columnIndex
4962
- };
4963
- const targetRange = {
4964
- startRow: Math.min(source.rowIndex, target.rowIndex),
4965
- startCol: Math.min(source.columnIndex, target.columnIndex),
4966
- endRow: Math.max(source.rowIndex, target.rowIndex),
4967
- endCol: Math.max(source.columnIndex, target.columnIndex)
4968
- };
4969
- table.fillRange(sourceRange, targetRange);
4970
- }
4971
- }
4972
- setDragState({
4973
- isDragging: false,
4974
- sourceCell: null,
4975
- currentCell: null
4976
- });
4977
- };
4978
- document.addEventListener("mousemove", handleMouseMove);
4979
- document.addEventListener("mouseup", handleMouseUp);
4980
- return () => {
4981
- document.removeEventListener("mousemove", handleMouseMove);
4982
- document.removeEventListener("mouseup", handleMouseUp);
4983
- };
4984
- }, [dragState.isDragging, table]);
4985
- return { dragState, onFillHandleMouseDown };
4986
- }
4987
- function FillHandle({
4988
- rowIndex,
4989
- columnIndex,
4990
- onMouseDown
4991
- }) {
4992
- const handleMouseDown = React3.useCallback(
4993
- (e) => {
4994
- e.preventDefault();
4995
- e.stopPropagation();
4996
- onMouseDown(rowIndex, columnIndex, e);
4997
- },
4998
- [rowIndex, columnIndex, onMouseDown]
4999
- );
5000
- return /* @__PURE__ */ jsxRuntime.jsx(
5001
- "div",
5002
- {
5003
- className: "yable-fill-handle",
5004
- onMouseDown: handleMouseDown,
5005
- role: "presentation",
5006
- "aria-hidden": "true",
5007
- title: "Drag to fill",
5008
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yable-fill-handle-dot" })
5009
- }
5010
- );
5011
- }
5012
5073
  function GripIcon() {
5013
5074
  return /* @__PURE__ */ jsxRuntime.jsxs(
5014
5075
  "svg",
@@ -5041,7 +5102,7 @@ function DragHandle({
5041
5102
  isDragging && "yable-row-drag-handle--dragging",
5042
5103
  className
5043
5104
  ].filter(Boolean).join(" ");
5044
- const handleDragStart = React3.useCallback(
5105
+ const handleDragStart = React4.useCallback(
5045
5106
  (e) => {
5046
5107
  if (e.dataTransfer && e.currentTarget instanceof HTMLElement) {
5047
5108
  e.dataTransfer.effectAllowed = "move";
@@ -5070,10 +5131,10 @@ function useRowDrag({
5070
5131
  onDataChange,
5071
5132
  onReorder
5072
5133
  }) {
5073
- const [dragState, setDragState] = React3.useState(rowDragging.getInitialRowDragState);
5074
- const dragRowIdRef = React3.useRef(null);
5075
- const dragRowIndexRef = React3.useRef(-1);
5076
- const getRowDragProps = React3.useCallback(
5134
+ const [dragState, setDragState] = React4.useState(rowDragging.getInitialRowDragState);
5135
+ const dragRowIdRef = React4.useRef(null);
5136
+ const dragRowIndexRef = React4.useRef(-1);
5137
+ const getRowDragProps = React4.useCallback(
5077
5138
  (rowId, rowIndex) => {
5078
5139
  return {
5079
5140
  draggable: true,
@@ -5172,7 +5233,7 @@ function useRowDrag({
5172
5233
  },
5173
5234
  [data, dragState, onDataChange, onReorder, table]
5174
5235
  );
5175
- const getDragHandleProps = React3.useCallback(
5236
+ const getDragHandleProps = React4.useCallback(
5176
5237
  (rowId) => ({
5177
5238
  onDragStart: (e) => {
5178
5239
  e.dataTransfer.effectAllowed = "move";
@@ -5199,7 +5260,7 @@ function TreeToggle({
5199
5260
  const isExpanded = row.getIsExpanded();
5200
5261
  const canToggle = showToggle !== void 0 ? showToggle : hasChildren;
5201
5262
  const indent = depth * indentWidth;
5202
- const handleClick = React3.useCallback(
5263
+ const handleClick = React4.useCallback(
5203
5264
  (e) => {
5204
5265
  e.stopPropagation();
5205
5266
  if (canToggle) {
@@ -5269,7 +5330,7 @@ function ExpandIcon({
5269
5330
  className
5270
5331
  ].filter(Boolean).join(" ");
5271
5332
  const label = ariaLabel ?? (isExpanded ? "Collapse details" : "Expand details");
5272
- const handleClick = React3.useCallback(
5333
+ const handleClick = React4.useCallback(
5273
5334
  (e) => {
5274
5335
  e.stopPropagation();
5275
5336
  onClick(e);
@@ -5334,20 +5395,20 @@ function PivotConfigPanel({
5334
5395
  aggregationOptions = DEFAULT_AGGREGATION_OPTIONS,
5335
5396
  className
5336
5397
  }) {
5337
- const [dragSource, setDragSource] = React3.useState(null);
5398
+ const [dragSource, setDragSource] = React4.useState(null);
5338
5399
  const usedFields = /* @__PURE__ */ new Set([
5339
5400
  ...rowFields.map((f) => f.field),
5340
5401
  ...columnFields.map((f) => f.field),
5341
5402
  ...valueFields.map((f) => f.field)
5342
5403
  ]);
5343
5404
  const unplacedFields = availableFields.filter((f) => !usedFields.has(f.field));
5344
- const handleDragStart = React3.useCallback(
5405
+ const handleDragStart = React4.useCallback(
5345
5406
  (field, zone) => {
5346
5407
  setDragSource({ field, zone });
5347
5408
  },
5348
5409
  []
5349
5410
  );
5350
- const handleDrop = React3.useCallback(
5411
+ const handleDrop = React4.useCallback(
5351
5412
  (targetZone) => {
5352
5413
  if (!dragSource) return;
5353
5414
  const { field, zone: sourceZone } = dragSource;
@@ -5390,7 +5451,7 @@ function PivotConfigPanel({
5390
5451
  onValueFieldsChange
5391
5452
  ]
5392
5453
  );
5393
- const handleAggregationChange = React3.useCallback(
5454
+ const handleAggregationChange = React4.useCallback(
5394
5455
  (field, aggregation) => {
5395
5456
  onValueFieldsChange(
5396
5457
  valueFields.map(
@@ -5400,7 +5461,7 @@ function PivotConfigPanel({
5400
5461
  },
5401
5462
  [valueFields, onValueFieldsChange]
5402
5463
  );
5403
- const handleRemoveField = React3.useCallback(
5464
+ const handleRemoveField = React4.useCallback(
5404
5465
  (field, zone) => {
5405
5466
  if (zone === "rows") {
5406
5467
  onRowFieldsChange(rowFields.filter((f) => f.field !== field));
@@ -5590,8 +5651,8 @@ function Tooltip({
5590
5651
  content,
5591
5652
  customComponent
5592
5653
  }) {
5593
- const tooltipRef = React3.useRef(null);
5594
- React3.useEffect(() => {
5654
+ const tooltipRef = React4.useRef(null);
5655
+ React4.useEffect(() => {
5595
5656
  if (!visible || !tooltipRef.current) return;
5596
5657
  const el = tooltipRef.current;
5597
5658
  const rect = el.getBoundingClientRect();
@@ -5656,16 +5717,16 @@ function Tooltip({
5656
5717
  }
5657
5718
  function useTooltip(options = {}) {
5658
5719
  const { delay = 500, placement = "top", enabled = true } = options;
5659
- const [visible, setVisible] = React3.useState(false);
5660
- const [position, setPosition] = React3.useState({
5720
+ const [visible, setVisible] = React4.useState(false);
5721
+ const [position, setPosition] = React4.useState({
5661
5722
  x: 0,
5662
5723
  y: 0,
5663
5724
  placement
5664
5725
  });
5665
- const [content, setContent] = React3.useState("");
5666
- const timerRef = React3.useRef(void 0);
5667
- const targetRef = React3.useRef(null);
5668
- const show = React3.useCallback(
5726
+ const [content, setContent] = React4.useState("");
5727
+ const timerRef = React4.useRef(void 0);
5728
+ const targetRef = React4.useRef(null);
5729
+ const show = React4.useCallback(
5669
5730
  (target, tooltipContent) => {
5670
5731
  if (!enabled || !tooltipContent) return;
5671
5732
  targetRef.current = target;
@@ -5712,12 +5773,12 @@ function useTooltip(options = {}) {
5712
5773
  },
5713
5774
  [delay, placement, enabled]
5714
5775
  );
5715
- const hide = React3.useCallback(() => {
5776
+ const hide = React4.useCallback(() => {
5716
5777
  clearTimeout(timerRef.current);
5717
5778
  setVisible(false);
5718
5779
  targetRef.current = null;
5719
5780
  }, []);
5720
- React3.useEffect(() => {
5781
+ React4.useEffect(() => {
5721
5782
  return () => clearTimeout(timerRef.current);
5722
5783
  }, []);
5723
5784
  return {
@@ -5939,10 +6000,10 @@ function FlashCell({
5939
6000
  }
5940
6001
  function useCellFlash(table, options = {}) {
5941
6002
  const { duration = 700 } = options;
5942
- const [flashes, setFlashes] = React3.useState(/* @__PURE__ */ new Map());
5943
- const prevDataRef = React3.useRef([]);
5944
- const timersRef = React3.useRef(/* @__PURE__ */ new Map());
5945
- const clearFlash = React3.useCallback((key) => {
6003
+ const [flashes, setFlashes] = React4.useState(/* @__PURE__ */ new Map());
6004
+ const prevDataRef = React4.useRef([]);
6005
+ const timersRef = React4.useRef(/* @__PURE__ */ new Map());
6006
+ const clearFlash = React4.useCallback((key) => {
5946
6007
  setFlashes((prev) => {
5947
6008
  const next = new Map(prev);
5948
6009
  next.delete(key);
@@ -5950,7 +6011,7 @@ function useCellFlash(table, options = {}) {
5950
6011
  });
5951
6012
  timersRef.current.delete(key);
5952
6013
  }, []);
5953
- React3.useEffect(() => {
6014
+ React4.useEffect(() => {
5954
6015
  const currentData = table.options.data;
5955
6016
  const prevData = prevDataRef.current;
5956
6017
  if (prevData.length > 0 && currentData !== prevData) {
@@ -5979,14 +6040,14 @@ function useCellFlash(table, options = {}) {
5979
6040
  }
5980
6041
  prevDataRef.current = currentData;
5981
6042
  }, [table.options.data, table, duration, clearFlash]);
5982
- React3.useEffect(() => {
6043
+ React4.useEffect(() => {
5983
6044
  return () => {
5984
6045
  for (const timer of timersRef.current.values()) {
5985
6046
  clearTimeout(timer);
5986
6047
  }
5987
6048
  };
5988
6049
  }, []);
5989
- const getFlash = React3.useCallback(
6050
+ const getFlash = React4.useCallback(
5990
6051
  (rowId, columnId) => {
5991
6052
  return flashes.get(`${rowId}:${columnId}`);
5992
6053
  },
@@ -5996,9 +6057,9 @@ function useCellFlash(table, options = {}) {
5996
6057
  }
5997
6058
  function useRowAnimation(_table, options = {}) {
5998
6059
  const { enabled = false, duration = 250, easing = "ease" } = options;
5999
- const prevPositionsRef = React3.useRef(/* @__PURE__ */ new Map());
6000
- const animatingRef = React3.useRef(false);
6001
- const capturePositions = React3.useCallback(
6060
+ const prevPositionsRef = React4.useRef(/* @__PURE__ */ new Map());
6061
+ const animatingRef = React4.useRef(false);
6062
+ const capturePositions = React4.useCallback(
6002
6063
  (containerEl) => {
6003
6064
  if (!enabled || !containerEl) return;
6004
6065
  const positions = /* @__PURE__ */ new Map();
@@ -6016,7 +6077,7 @@ function useRowAnimation(_table, options = {}) {
6016
6077
  },
6017
6078
  [enabled]
6018
6079
  );
6019
- const animateRows = React3.useCallback(
6080
+ const animateRows = React4.useCallback(
6020
6081
  (containerEl) => {
6021
6082
  if (!enabled || !containerEl || animatingRef.current) return;
6022
6083
  const prevPositions = prevPositionsRef.current;
@@ -6138,8 +6199,8 @@ function sanitizeCSS(css) {
6138
6199
  }
6139
6200
  function usePrintLayout(_table, options = {}) {
6140
6201
  const { title, additionalCSS } = options;
6141
- const isPrintingRef = React3.useRef(false);
6142
- const preparePrint = React3.useCallback(() => {
6202
+ const isPrintingRef = React4.useRef(false);
6203
+ const preparePrint = React4.useCallback(() => {
6143
6204
  const yableEl = document.querySelector(".yable");
6144
6205
  if (yableEl) {
6145
6206
  yableEl.classList.add("yable-print-mode");
@@ -6181,23 +6242,23 @@ function usePrintLayout(_table, options = {}) {
6181
6242
  }
6182
6243
  function useTheme(options = {}) {
6183
6244
  const { defaultTheme = "default", defaultColorScheme = "auto" } = options;
6184
- const [theme, setThemeState] = React3.useState(defaultTheme);
6185
- const [colorScheme, setColorSchemeState] = React3.useState(defaultColorScheme);
6186
- const containerRef = React3.useRef(null);
6187
- const setTheme = React3.useCallback((newTheme) => {
6245
+ const [theme, setThemeState] = React4.useState(defaultTheme);
6246
+ const [colorScheme, setColorSchemeState] = React4.useState(defaultColorScheme);
6247
+ const containerRef = React4.useRef(null);
6248
+ const setTheme = React4.useCallback((newTheme) => {
6188
6249
  setThemeState(newTheme);
6189
6250
  }, []);
6190
- const setColorScheme = React3.useCallback((scheme) => {
6251
+ const setColorScheme = React4.useCallback((scheme) => {
6191
6252
  setColorSchemeState(scheme);
6192
6253
  }, []);
6193
- const toggleColorScheme = React3.useCallback(() => {
6254
+ const toggleColorScheme = React4.useCallback(() => {
6194
6255
  setColorSchemeState((prev) => {
6195
6256
  if (prev === "auto") return "dark";
6196
6257
  if (prev === "dark") return "light";
6197
6258
  return "auto";
6198
6259
  });
6199
6260
  }, []);
6200
- React3.useEffect(() => {
6261
+ React4.useEffect(() => {
6201
6262
  const target = containerRef.current ?? document.documentElement;
6202
6263
  if (colorScheme === "auto") {
6203
6264
  target.removeAttribute("data-yable-theme");
@@ -6205,8 +6266,8 @@ function useTheme(options = {}) {
6205
6266
  target.setAttribute("data-yable-theme", colorScheme);
6206
6267
  }
6207
6268
  }, [colorScheme]);
6208
- const [systemDark, setSystemDark] = React3.useState(false);
6209
- React3.useEffect(() => {
6269
+ const [systemDark, setSystemDark] = React4.useState(false);
6270
+ React4.useEffect(() => {
6210
6271
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
6211
6272
  setSystemDark(mq.matches);
6212
6273
  const handler = (e) => setSystemDark(e.matches);