@lensui/lens-table 0.1.83 → 0.1.84
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/README.md +5 -0
- package/dist/index.cjs +24 -8
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +105 -89
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -315,6 +315,11 @@ const columns: GridColumn<Row>[] = [
|
|
|
315
315
|
| `time-range` | `'09:00 ~ 18:00'` | 时间范围选择器。 |
|
|
316
316
|
| `date-time-range` | `'2026-01-01 09:00 ~ 2026-01-01 18:00'` | 日期时间范围选择器,包含日期和时间面板。 |
|
|
317
317
|
|
|
318
|
+
`select` 可配置 `searchable` 开启输入筛选。需要把输入限制为已有选项时,设置
|
|
319
|
+
`strictOptions: true`:首次打开显示完整列表;开始输入后始终按输入内容筛选;失焦时只提交
|
|
320
|
+
精确匹配的选项,不匹配则恢复进入编辑前的值。若 `options` 包含 `{ label: '', value: '' }`,
|
|
321
|
+
清空输入会提交该空选项。
|
|
322
|
+
|
|
318
323
|
可选 `format` 用于控制提交到数据里的字符串格式,例如:
|
|
319
324
|
|
|
320
325
|
```tsx
|
package/dist/index.cjs
CHANGED
|
@@ -345,7 +345,7 @@ function getSearchableChoicePopupHorizontalLayout(anchorLeft, anchorWidth, longe
|
|
|
345
345
|
);
|
|
346
346
|
return { left, width };
|
|
347
347
|
}
|
|
348
|
-
function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
|
|
348
|
+
function SearchableChoiceEditor({ value, options, allowCustomValue, strictOptions, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
|
|
349
349
|
const editorRef = (0, import_react2.useRef)(null);
|
|
350
350
|
const popupRef = (0, import_react2.useRef)(null);
|
|
351
351
|
const activeOptionRef = (0, import_react2.useRef)(null);
|
|
@@ -355,6 +355,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
355
355
|
const listboxId = (0, import_react2.useId)();
|
|
356
356
|
const originalValue = originalValueRef.current;
|
|
357
357
|
const [inputValue, setInputValue] = (0, import_react2.useState)(value);
|
|
358
|
+
const [hasTyped, setHasTyped] = (0, import_react2.useState)(false);
|
|
358
359
|
const [activeIndex, setActiveIndex] = (0, import_react2.useState)(() => {
|
|
359
360
|
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
360
361
|
return selectedIndex >= 0 ? selectedIndex : 0;
|
|
@@ -364,10 +365,23 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
364
365
|
visibility: "hidden"
|
|
365
366
|
});
|
|
366
367
|
const filteredOptions = (0, import_react2.useMemo)(() => {
|
|
368
|
+
if (strictOptions) {
|
|
369
|
+
if (!hasTyped) return options;
|
|
370
|
+
if (inputValue === "") return options.filter((option) => option.value === "");
|
|
371
|
+
const strictQuery = inputValue.trim().toLocaleLowerCase();
|
|
372
|
+
if (!strictQuery) return [];
|
|
373
|
+
return options.filter((option) => option.label.toLocaleLowerCase().includes(strictQuery) || option.value.toLocaleLowerCase().includes(strictQuery));
|
|
374
|
+
}
|
|
367
375
|
const query = inputValue.trim().toLocaleLowerCase();
|
|
368
376
|
if (!query || query === originalValue.toLocaleLowerCase()) return options;
|
|
369
377
|
return options.filter((option) => option.label.toLocaleLowerCase().includes(query) || option.value.toLocaleLowerCase().includes(query));
|
|
370
|
-
}, [inputValue, options, originalValue]);
|
|
378
|
+
}, [hasTyped, inputValue, options, originalValue, strictOptions]);
|
|
379
|
+
const exactInputOption = options.find((option) => option.value === inputValue);
|
|
380
|
+
const selectedValue = exactInputOption?.value;
|
|
381
|
+
const resolveInputValue = (0, import_react2.useCallback)(() => {
|
|
382
|
+
if (strictOptions) return exactInputOption?.value ?? originalValue;
|
|
383
|
+
return allowCustomValue ? inputValue || originalValue : originalValue;
|
|
384
|
+
}, [allowCustomValue, exactInputOption, inputValue, originalValue, strictOptions]);
|
|
371
385
|
(0, import_react2.useLayoutEffect)(() => {
|
|
372
386
|
const positionPopup = () => {
|
|
373
387
|
const rect = editorRef.current?.getBoundingClientRect();
|
|
@@ -434,11 +448,11 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
434
448
|
const target = event.target;
|
|
435
449
|
if (!(target instanceof Node)) return;
|
|
436
450
|
if (editorRef.current?.contains(target) || popupRef.current?.contains(target)) return;
|
|
437
|
-
onCommit(
|
|
451
|
+
onCommit(resolveInputValue());
|
|
438
452
|
};
|
|
439
453
|
document.addEventListener("pointerdown", handleOutsidePointer, true);
|
|
440
454
|
return () => document.removeEventListener("pointerdown", handleOutsidePointer, true);
|
|
441
|
-
}, [
|
|
455
|
+
}, [onCommit, resolveInputValue]);
|
|
442
456
|
const selectOption = (option) => {
|
|
443
457
|
onChange(option.value);
|
|
444
458
|
onCommit(option.value);
|
|
@@ -460,7 +474,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
460
474
|
event.preventDefault();
|
|
461
475
|
const option = filteredOptions[activeIndex];
|
|
462
476
|
if (option) selectOption(option);
|
|
463
|
-
else if (allowCustomValue) onCommit(
|
|
477
|
+
else if (allowCustomValue || strictOptions) onCommit(resolveInputValue());
|
|
464
478
|
}
|
|
465
479
|
};
|
|
466
480
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { ref: editorRef, className: "rvg-choice-editor rvg-searchable-choice-editor", style, children: [
|
|
@@ -474,6 +488,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
474
488
|
"aria-controls": listboxId,
|
|
475
489
|
onFocus: (event) => event.currentTarget.select(),
|
|
476
490
|
onChange: (event) => {
|
|
491
|
+
setHasTyped(true);
|
|
477
492
|
setInputValue(event.target.value);
|
|
478
493
|
onChange(event.target.value);
|
|
479
494
|
navigationSourceRef.current = "filter";
|
|
@@ -489,8 +504,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
489
504
|
ref: index === activeIndex ? activeOptionRef : void 0,
|
|
490
505
|
type: "button",
|
|
491
506
|
role: "option",
|
|
492
|
-
"aria-selected": option.value ===
|
|
493
|
-
className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value ===
|
|
507
|
+
"aria-selected": option.value === selectedValue,
|
|
508
|
+
className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value === selectedValue ? " is-selected" : ""}`,
|
|
494
509
|
onPointerDown: (event) => event.preventDefault(),
|
|
495
510
|
onMouseEnter: () => {
|
|
496
511
|
navigationSourceRef.current = "pointer";
|
|
@@ -499,7 +514,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
499
514
|
onClick: () => selectOption(option),
|
|
500
515
|
children: [
|
|
501
516
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: option.label }),
|
|
502
|
-
option.value ===
|
|
517
|
+
option.value === selectedValue && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChoiceCheckIcon, {})
|
|
503
518
|
]
|
|
504
519
|
},
|
|
505
520
|
option.value
|
|
@@ -3722,6 +3737,7 @@ function TableInner({
|
|
|
3722
3737
|
options: column.editor.options,
|
|
3723
3738
|
searchable: column.editor.searchable,
|
|
3724
3739
|
allowCustomValue: column.editor.allowCustomValue,
|
|
3740
|
+
strictOptions: column.editor.strictOptions,
|
|
3725
3741
|
maxDropdownHeight: column.editor.maxDropdownHeight,
|
|
3726
3742
|
style: editorStyle,
|
|
3727
3743
|
labels,
|
package/dist/index.d.cts
CHANGED
|
@@ -211,6 +211,8 @@ interface GridColumn<Row> {
|
|
|
211
211
|
}>;
|
|
212
212
|
searchable?: boolean;
|
|
213
213
|
allowCustomValue?: boolean;
|
|
214
|
+
/** Keep typed input filtered and only commit values that exactly match an option. */
|
|
215
|
+
strictOptions?: boolean;
|
|
214
216
|
maxDropdownHeight?: number;
|
|
215
217
|
} | {
|
|
216
218
|
type: 'textarea';
|
package/dist/index.d.ts
CHANGED
|
@@ -211,6 +211,8 @@ interface GridColumn<Row> {
|
|
|
211
211
|
}>;
|
|
212
212
|
searchable?: boolean;
|
|
213
213
|
allowCustomValue?: boolean;
|
|
214
|
+
/** Keep typed input filtered and only commit values that exactly match an option. */
|
|
215
|
+
strictOptions?: boolean;
|
|
214
216
|
maxDropdownHeight?: number;
|
|
215
217
|
} | {
|
|
216
218
|
type: 'textarea';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/Table.tsx
|
|
2
|
-
import { forwardRef, useImperativeHandle, Fragment as Fragment2, useCallback as
|
|
2
|
+
import { forwardRef, useImperativeHandle, Fragment as Fragment2, useCallback as useCallback3, useEffect as useEffect3, useLayoutEffect as useLayoutEffect3, useMemo as useMemo2, useRef as useRef4, useState as useState6 } from "react";
|
|
3
3
|
import { flushSync } from "react-dom";
|
|
4
4
|
|
|
5
5
|
// src/components/EmptyState.tsx
|
|
@@ -199,7 +199,7 @@ function DefaultEmptyState({ label = ZH_CN_GRID_LABELS.empty }) {
|
|
|
199
199
|
// src/components/editors/ChoiceEditor.tsx
|
|
200
200
|
import { Portal } from "@ark-ui/react/portal";
|
|
201
201
|
import { Select, createListCollection } from "@ark-ui/react/select";
|
|
202
|
-
import { useEffect, useId as useId2, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
202
|
+
import { useCallback, useEffect, useId as useId2, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
203
203
|
|
|
204
204
|
// src/icons/gridIcons.tsx
|
|
205
205
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -315,7 +315,7 @@ function getSearchableChoicePopupHorizontalLayout(anchorLeft, anchorWidth, longe
|
|
|
315
315
|
);
|
|
316
316
|
return { left, width };
|
|
317
317
|
}
|
|
318
|
-
function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
|
|
318
|
+
function SearchableChoiceEditor({ value, options, allowCustomValue, strictOptions, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
|
|
319
319
|
const editorRef = useRef(null);
|
|
320
320
|
const popupRef = useRef(null);
|
|
321
321
|
const activeOptionRef = useRef(null);
|
|
@@ -325,6 +325,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
325
325
|
const listboxId = useId2();
|
|
326
326
|
const originalValue = originalValueRef.current;
|
|
327
327
|
const [inputValue, setInputValue] = useState(value);
|
|
328
|
+
const [hasTyped, setHasTyped] = useState(false);
|
|
328
329
|
const [activeIndex, setActiveIndex] = useState(() => {
|
|
329
330
|
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
330
331
|
return selectedIndex >= 0 ? selectedIndex : 0;
|
|
@@ -334,10 +335,23 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
334
335
|
visibility: "hidden"
|
|
335
336
|
});
|
|
336
337
|
const filteredOptions = useMemo(() => {
|
|
338
|
+
if (strictOptions) {
|
|
339
|
+
if (!hasTyped) return options;
|
|
340
|
+
if (inputValue === "") return options.filter((option) => option.value === "");
|
|
341
|
+
const strictQuery = inputValue.trim().toLocaleLowerCase();
|
|
342
|
+
if (!strictQuery) return [];
|
|
343
|
+
return options.filter((option) => option.label.toLocaleLowerCase().includes(strictQuery) || option.value.toLocaleLowerCase().includes(strictQuery));
|
|
344
|
+
}
|
|
337
345
|
const query = inputValue.trim().toLocaleLowerCase();
|
|
338
346
|
if (!query || query === originalValue.toLocaleLowerCase()) return options;
|
|
339
347
|
return options.filter((option) => option.label.toLocaleLowerCase().includes(query) || option.value.toLocaleLowerCase().includes(query));
|
|
340
|
-
}, [inputValue, options, originalValue]);
|
|
348
|
+
}, [hasTyped, inputValue, options, originalValue, strictOptions]);
|
|
349
|
+
const exactInputOption = options.find((option) => option.value === inputValue);
|
|
350
|
+
const selectedValue = exactInputOption?.value;
|
|
351
|
+
const resolveInputValue = useCallback(() => {
|
|
352
|
+
if (strictOptions) return exactInputOption?.value ?? originalValue;
|
|
353
|
+
return allowCustomValue ? inputValue || originalValue : originalValue;
|
|
354
|
+
}, [allowCustomValue, exactInputOption, inputValue, originalValue, strictOptions]);
|
|
341
355
|
useLayoutEffect(() => {
|
|
342
356
|
const positionPopup = () => {
|
|
343
357
|
const rect = editorRef.current?.getBoundingClientRect();
|
|
@@ -404,11 +418,11 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
404
418
|
const target = event.target;
|
|
405
419
|
if (!(target instanceof Node)) return;
|
|
406
420
|
if (editorRef.current?.contains(target) || popupRef.current?.contains(target)) return;
|
|
407
|
-
onCommit(
|
|
421
|
+
onCommit(resolveInputValue());
|
|
408
422
|
};
|
|
409
423
|
document.addEventListener("pointerdown", handleOutsidePointer, true);
|
|
410
424
|
return () => document.removeEventListener("pointerdown", handleOutsidePointer, true);
|
|
411
|
-
}, [
|
|
425
|
+
}, [onCommit, resolveInputValue]);
|
|
412
426
|
const selectOption = (option) => {
|
|
413
427
|
onChange(option.value);
|
|
414
428
|
onCommit(option.value);
|
|
@@ -430,7 +444,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
430
444
|
event.preventDefault();
|
|
431
445
|
const option = filteredOptions[activeIndex];
|
|
432
446
|
if (option) selectOption(option);
|
|
433
|
-
else if (allowCustomValue) onCommit(
|
|
447
|
+
else if (allowCustomValue || strictOptions) onCommit(resolveInputValue());
|
|
434
448
|
}
|
|
435
449
|
};
|
|
436
450
|
return /* @__PURE__ */ jsxs3("div", { ref: editorRef, className: "rvg-choice-editor rvg-searchable-choice-editor", style, children: [
|
|
@@ -444,6 +458,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
444
458
|
"aria-controls": listboxId,
|
|
445
459
|
onFocus: (event) => event.currentTarget.select(),
|
|
446
460
|
onChange: (event) => {
|
|
461
|
+
setHasTyped(true);
|
|
447
462
|
setInputValue(event.target.value);
|
|
448
463
|
onChange(event.target.value);
|
|
449
464
|
navigationSourceRef.current = "filter";
|
|
@@ -459,8 +474,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
459
474
|
ref: index === activeIndex ? activeOptionRef : void 0,
|
|
460
475
|
type: "button",
|
|
461
476
|
role: "option",
|
|
462
|
-
"aria-selected": option.value ===
|
|
463
|
-
className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value ===
|
|
477
|
+
"aria-selected": option.value === selectedValue,
|
|
478
|
+
className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value === selectedValue ? " is-selected" : ""}`,
|
|
464
479
|
onPointerDown: (event) => event.preventDefault(),
|
|
465
480
|
onMouseEnter: () => {
|
|
466
481
|
navigationSourceRef.current = "pointer";
|
|
@@ -469,7 +484,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
469
484
|
onClick: () => selectOption(option),
|
|
470
485
|
children: [
|
|
471
486
|
/* @__PURE__ */ jsx3("span", { children: option.label }),
|
|
472
|
-
option.value ===
|
|
487
|
+
option.value === selectedValue && /* @__PURE__ */ jsx3(ChoiceCheckIcon, {})
|
|
473
488
|
]
|
|
474
489
|
},
|
|
475
490
|
option.value
|
|
@@ -1690,11 +1705,11 @@ function paintGrid(options) {
|
|
|
1690
1705
|
}
|
|
1691
1706
|
|
|
1692
1707
|
// src/hooks/useControllable.ts
|
|
1693
|
-
import { useCallback, useState as useState5 } from "react";
|
|
1708
|
+
import { useCallback as useCallback2, useState as useState5 } from "react";
|
|
1694
1709
|
function useControllableKeys(value, defaultValue, onChange) {
|
|
1695
1710
|
const [internal, setInternal] = useState5(defaultValue ?? []);
|
|
1696
1711
|
const keys = value === void 0 ? internal : value;
|
|
1697
|
-
const setKeys =
|
|
1712
|
+
const setKeys = useCallback2((next) => {
|
|
1698
1713
|
if (value === void 0) setInternal(next);
|
|
1699
1714
|
onChange?.(next);
|
|
1700
1715
|
}, [onChange, value]);
|
|
@@ -1703,7 +1718,7 @@ function useControllableKeys(value, defaultValue, onChange) {
|
|
|
1703
1718
|
function useControllableValue(value, defaultValue, onChange) {
|
|
1704
1719
|
const [internal, setInternal] = useState5(defaultValue ?? null);
|
|
1705
1720
|
const selected = value === void 0 ? internal : value;
|
|
1706
|
-
const setSelected =
|
|
1721
|
+
const setSelected = useCallback2((next) => {
|
|
1707
1722
|
if (value === void 0) setInternal(next);
|
|
1708
1723
|
onChange?.(next);
|
|
1709
1724
|
}, [onChange, value]);
|
|
@@ -2173,7 +2188,7 @@ function TableInner({
|
|
|
2173
2188
|
if (headerTooltipTimerRef.current !== null) clearTimeout(headerTooltipTimerRef.current);
|
|
2174
2189
|
if (cellTooltipTimerRef.current !== null) clearTimeout(cellTooltipTimerRef.current);
|
|
2175
2190
|
}, []);
|
|
2176
|
-
const measureCustomHeaderHeight =
|
|
2191
|
+
const measureCustomHeaderHeight = useCallback3(() => {
|
|
2177
2192
|
const nextHeights = Array.from({ length: headerDepth }, () => baseHeaderHeight);
|
|
2178
2193
|
customHeaderContentRefs.current.forEach((node) => {
|
|
2179
2194
|
const headerCell = node.closest(".rvg-header-title");
|
|
@@ -2224,7 +2239,7 @@ function TableInner({
|
|
|
2224
2239
|
const [hoveredHeaderAction, setHoveredHeaderAction] = useState6(null);
|
|
2225
2240
|
const [visibleHeaderTooltip, setVisibleHeaderTooltip] = useState6(null);
|
|
2226
2241
|
const [hoveredCellTooltip, setHoveredCellTooltip] = useState6(null);
|
|
2227
|
-
const hideDragTooltips =
|
|
2242
|
+
const hideDragTooltips = useCallback3(() => {
|
|
2228
2243
|
if (headerTooltipTimerRef.current !== null) {
|
|
2229
2244
|
clearTimeout(headerTooltipTimerRef.current);
|
|
2230
2245
|
headerTooltipTimerRef.current = null;
|
|
@@ -2251,10 +2266,10 @@ function TableInner({
|
|
|
2251
2266
|
const [insertedRowKeys, setInsertedRowKeys] = useState6(() => /* @__PURE__ */ new Set());
|
|
2252
2267
|
const [rowOrderKeys, setRowOrderKeys] = useState6(null);
|
|
2253
2268
|
const settledPendingInsertIdsRef = useRef4(/* @__PURE__ */ new Set());
|
|
2254
|
-
const getDataRowKey =
|
|
2269
|
+
const getDataRowKey = useCallback3((row, index) => {
|
|
2255
2270
|
return typeof rowKey === "function" ? rowKey(row, index) : rowKey ? row[rowKey] : getDefaultRowKey(row, index);
|
|
2256
2271
|
}, [rowKey]);
|
|
2257
|
-
const getSourceRowIndexByKey =
|
|
2272
|
+
const getSourceRowIndexByKey = useCallback3((key, preferredIndex) => {
|
|
2258
2273
|
const preferredRow = sourceRows[preferredIndex];
|
|
2259
2274
|
if (preferredRow && getDataRowKey(preferredRow, preferredIndex) === key) return preferredIndex;
|
|
2260
2275
|
const start = Math.max(0, preferredIndex - 8);
|
|
@@ -2325,7 +2340,7 @@ function TableInner({
|
|
|
2325
2340
|
return result * direction;
|
|
2326
2341
|
});
|
|
2327
2342
|
}, [columns, filteredRows, language, onSortChange, sortState]);
|
|
2328
|
-
const resolveSelectionTarget =
|
|
2343
|
+
const resolveSelectionTarget = useCallback3((target) => {
|
|
2329
2344
|
if (target == null) return target;
|
|
2330
2345
|
const columnIndex = columns.findIndex((column) => column.key === target.columnKey);
|
|
2331
2346
|
const rowIndex = target.rowKey !== void 0 ? rows.findIndex((row2, index) => getDataRowKey(row2, index) === target.rowKey) : target.rowIndex ?? -1;
|
|
@@ -2340,7 +2355,7 @@ function TableInner({
|
|
|
2340
2355
|
}, [columns, getDataRowKey, rows]);
|
|
2341
2356
|
const resolvedSelectedCell = useMemo2(() => resolveSelectionTarget(selectedCell), [resolveSelectionTarget, selectedCell]);
|
|
2342
2357
|
const resolvedDefaultSelectedCell = useMemo2(() => resolveSelectionTarget(defaultSelectedCell), [defaultSelectedCell, resolveSelectionTarget]);
|
|
2343
|
-
const handleSelectedCellChange =
|
|
2358
|
+
const handleSelectedCellChange = useCallback3((next) => {
|
|
2344
2359
|
if (!onSelectedCellChange) return;
|
|
2345
2360
|
if (!next) {
|
|
2346
2361
|
onSelectedCellChange(null);
|
|
@@ -2369,7 +2384,7 @@ function TableInner({
|
|
|
2369
2384
|
document.addEventListener("pointerdown", handleOutsidePointerDown);
|
|
2370
2385
|
return () => document.removeEventListener("pointerdown", handleOutsidePointerDown);
|
|
2371
2386
|
}, [selection, setSelection]);
|
|
2372
|
-
const applyRowOrder =
|
|
2387
|
+
const applyRowOrder = useCallback3((sourceIndex, targetIndex) => {
|
|
2373
2388
|
if (sourceIndex === targetIndex || sourceIndex < 0 || targetIndex < 0 || sourceIndex >= rows.length || targetIndex >= rows.length) return;
|
|
2374
2389
|
const nextEntries = rows.map((row, index) => ({ row, key: getDataRowKey(row, index) }));
|
|
2375
2390
|
const [entry] = nextEntries.splice(sourceIndex, 1);
|
|
@@ -2378,7 +2393,7 @@ function TableInner({
|
|
|
2378
2393
|
setRowOrderKeys(nextEntries.map(({ key }) => key));
|
|
2379
2394
|
onRowsReorder?.(nextRows, { sourceIndex, targetIndex });
|
|
2380
2395
|
}, [getDataRowKey, onRowsReorder, rows]);
|
|
2381
|
-
const applyColumnOrder =
|
|
2396
|
+
const applyColumnOrder = useCallback3((sourceIndex, targetIndex, detail) => {
|
|
2382
2397
|
const nextColumns = reorderColumns(sourceColumns, detail);
|
|
2383
2398
|
setSourceColumns(nextColumns);
|
|
2384
2399
|
onColumnsReorder?.(nextColumns, { sourceIndex, targetIndex, ...detail });
|
|
@@ -2451,7 +2466,7 @@ function TableInner({
|
|
|
2451
2466
|
}
|
|
2452
2467
|
return lefts;
|
|
2453
2468
|
}, [columns, fixedWidth, metrics]);
|
|
2454
|
-
const getScrollableColumnLeft =
|
|
2469
|
+
const getScrollableColumnLeft = useCallback3((columnIndex) => scrollableColumnLefts[columnIndex] ?? fixedWidth, [fixedWidth, scrollableColumnLefts]);
|
|
2455
2470
|
const hasRowSelectionColumn = useMemo2(() => columns.some((column) => column.rowSelection), [columns]);
|
|
2456
2471
|
const rowSelectionMode = typeof rowSelection === "object" ? rowSelection.mode ?? "multiple" : "multiple";
|
|
2457
2472
|
const summarySignature = useMemo2(() => getSummarySignature(columns), [columns]);
|
|
@@ -2504,7 +2519,7 @@ function TableInner({
|
|
|
2504
2519
|
const rowScrollTop = fixedHeader ? currentScroll2.top : Math.max(0, currentScroll2.top - bodyTop);
|
|
2505
2520
|
return getViewportRange(currentScroll2.left, rowScrollTop, viewport.width, bodyViewportHeight, rows.length, rowHeight, metrics, virtualOverscan);
|
|
2506
2521
|
}, [bodyTop, bodyViewportHeight, columns.length, fixedHeader, isVirtualized, metrics, rowHeight, rows.length, scrollPosition, viewport.width, virtualOverscan]);
|
|
2507
|
-
const getRowKey =
|
|
2522
|
+
const getRowKey = useCallback3((row, index) => {
|
|
2508
2523
|
const key = getDataRowKey(row, index);
|
|
2509
2524
|
rowByKeyRef.current.set(key, row);
|
|
2510
2525
|
rowIndexByKeyRef.current.set(key, index);
|
|
@@ -2573,7 +2588,7 @@ function TableInner({
|
|
|
2573
2588
|
const selectedRowKeySet = useMemo2(() => new Set(rowKeys), [rowKeys]);
|
|
2574
2589
|
const selectedColumnKeySet = useMemo2(() => new Set(columnKeys), [columnKeys]);
|
|
2575
2590
|
const insertedRowKeySet = useMemo2(() => insertedRowKeys, [insertedRowKeys]);
|
|
2576
|
-
const measureHeaderTitleWidth =
|
|
2591
|
+
const measureHeaderTitleWidth = useCallback3((columnIndex) => {
|
|
2577
2592
|
const title = columns[columnIndex]?.title ?? "";
|
|
2578
2593
|
const context = canvasRef.current?.getContext("2d");
|
|
2579
2594
|
if (!context) return Array.from(title).reduce((width3, character) => width3 + (/^[\x00-\x7F]$/.test(character) ? 7 : 13), 0);
|
|
@@ -2583,7 +2598,7 @@ function TableInner({
|
|
|
2583
2598
|
context.restore();
|
|
2584
2599
|
return width2;
|
|
2585
2600
|
}, [columns]);
|
|
2586
|
-
const getCellLabel =
|
|
2601
|
+
const getCellLabel = useCallback3((rowIndex, columnIndex) => {
|
|
2587
2602
|
const row = rows[rowIndex];
|
|
2588
2603
|
const column = columns[columnIndex];
|
|
2589
2604
|
if (!row || !column || column.rowSelection || column.rowDragHandle) return "";
|
|
@@ -2594,8 +2609,8 @@ function TableInner({
|
|
|
2594
2609
|
return "Render error";
|
|
2595
2610
|
}
|
|
2596
2611
|
}, [columns, rows]);
|
|
2597
|
-
const getCellSpan =
|
|
2598
|
-
const getCellDisplayWidth =
|
|
2612
|
+
const getCellSpan = useCallback3((rowIndex, columnIndex) => cellSpanLookup.covered.get(getCellCoordKey2(rowIndex, columnIndex)), [cellSpanLookup]);
|
|
2613
|
+
const getCellDisplayWidth = useCallback3((columnIndex, colSpan = 1) => {
|
|
2599
2614
|
let width2 = 0;
|
|
2600
2615
|
for (let index = columnIndex; index < Math.min(columns.length, columnIndex + colSpan); index += 1) {
|
|
2601
2616
|
width2 += metrics[index]?.width ?? 0;
|
|
@@ -2610,7 +2625,7 @@ function TableInner({
|
|
|
2610
2625
|
if (nextRowIndex === selection.rowIndex && nextColumnIndex === selection.columnIndex) return;
|
|
2611
2626
|
setSelection({ ...selection, rowIndex: nextRowIndex, columnIndex: nextColumnIndex });
|
|
2612
2627
|
}, [columns, getRowKey, rows, selection, setSelection]);
|
|
2613
|
-
const draw =
|
|
2628
|
+
const draw = useCallback3(() => {
|
|
2614
2629
|
frameRef.current = null;
|
|
2615
2630
|
const canvas = canvasRef.current;
|
|
2616
2631
|
if (!canvas || viewport.width <= 0) return;
|
|
@@ -2656,15 +2671,15 @@ function TableInner({
|
|
|
2656
2671
|
const range = isVirtualized ? getViewportRange(scroll.left, rowScrollTop, viewport.width, bodyViewportHeight, rows.length, rowHeight, metrics, virtualOverscan) : { rowStart: 0, rowEnd: rows.length, columnStart: 0, columnEnd: columns.length };
|
|
2657
2672
|
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, bodyFontSize, headerActionSlotWidth, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, horizontalBorderless, frameBorderless, extendVerticalGridLines: !autoHeight, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, rowStyle, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, rowSelectionMode, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget, resolveColor: (color) => resolveCanvasColor(themeStyles, color), colors: themeColors });
|
|
2658
2673
|
}, [autoHeight, bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDragPreview, columnDraggable, columnDropTarget, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, frameBorderless, getRowKey, hasStripedRows, hasVerticalBorders, headerActionSlotWidth, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, horizontalBorderless, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rowSelectionMode, rowStyle, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
2659
|
-
const scheduleDraw =
|
|
2674
|
+
const scheduleDraw = useCallback3(() => {
|
|
2660
2675
|
if (frameRef.current === null) frameRef.current = requestAnimationFrame(draw);
|
|
2661
2676
|
}, [draw]);
|
|
2662
|
-
const drawImmediately =
|
|
2677
|
+
const drawImmediately = useCallback3(() => {
|
|
2663
2678
|
if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
|
|
2664
2679
|
frameRef.current = null;
|
|
2665
2680
|
draw();
|
|
2666
2681
|
}, [draw]);
|
|
2667
|
-
const getSelectionHorizontalVisibility =
|
|
2682
|
+
const getSelectionHorizontalVisibility = useCallback3((scrollLeft) => {
|
|
2668
2683
|
if (!selection || selectionRange) return "visible";
|
|
2669
2684
|
const column = columns[selection.columnIndex];
|
|
2670
2685
|
if (!column || column.fixed !== void 0) return "visible";
|
|
@@ -2675,7 +2690,7 @@ function TableInner({
|
|
|
2675
2690
|
if (left >= viewport.width - rightFixedWidth) return "hidden-right";
|
|
2676
2691
|
return "visible";
|
|
2677
2692
|
}, [columns, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, rightFixedWidth, selection, selectionRange, viewport.width]);
|
|
2678
|
-
const getSelectionEdgeIndicator =
|
|
2693
|
+
const getSelectionEdgeIndicator = useCallback3((scrollLeft, scrollTop) => {
|
|
2679
2694
|
if (!selection || selectionRange) return null;
|
|
2680
2695
|
const row = rows[selection.rowIndex];
|
|
2681
2696
|
const metric = metrics[selection.columnIndex];
|
|
@@ -2783,7 +2798,7 @@ function TableInner({
|
|
|
2783
2798
|
}
|
|
2784
2799
|
};
|
|
2785
2800
|
}, [bodyTop, columns, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, rows, selection, selectionRange, viewport.width]);
|
|
2786
|
-
const syncSelectionEdgeTarget =
|
|
2801
|
+
const syncSelectionEdgeTarget = useCallback3((scrollLeft, scrollTop) => {
|
|
2787
2802
|
const target = selectionEdgeTargetRef.current;
|
|
2788
2803
|
if (!target) return;
|
|
2789
2804
|
const indicator = getSelectionEdgeIndicator(scrollLeft, scrollTop);
|
|
@@ -2905,7 +2920,7 @@ function TableInner({
|
|
|
2905
2920
|
scroller.addEventListener("scroll", lockScroll);
|
|
2906
2921
|
return () => scroller.removeEventListener("scroll", lockScroll);
|
|
2907
2922
|
}, [insertBusy]);
|
|
2908
|
-
const showCustomScrollbar =
|
|
2923
|
+
const showCustomScrollbar = useCallback3((axis, persist = false) => {
|
|
2909
2924
|
const showVertical = axis === "vertical" || axis === "both";
|
|
2910
2925
|
const showHorizontal = axis === "horizontal" || axis === "both";
|
|
2911
2926
|
if (showVertical) {
|
|
@@ -2929,15 +2944,15 @@ function TableInner({
|
|
|
2929
2944
|
}
|
|
2930
2945
|
}
|
|
2931
2946
|
}, []);
|
|
2932
|
-
const keepCustomScrollbarVisible =
|
|
2947
|
+
const keepCustomScrollbarVisible = useCallback3((axis) => {
|
|
2933
2948
|
showCustomScrollbar(axis, true);
|
|
2934
2949
|
}, [showCustomScrollbar]);
|
|
2935
|
-
const releaseCustomScrollbarVisible =
|
|
2950
|
+
const releaseCustomScrollbarVisible = useCallback3((axis) => {
|
|
2936
2951
|
if (axis === "vertical" && verticalScrollbarDragRef.current) return;
|
|
2937
2952
|
if (axis === "horizontal" && horizontalScrollbarDragRef.current) return;
|
|
2938
2953
|
showCustomScrollbar(axis);
|
|
2939
2954
|
}, [showCustomScrollbar]);
|
|
2940
|
-
const updateCustomScrollbars =
|
|
2955
|
+
const updateCustomScrollbars = useCallback3(() => {
|
|
2941
2956
|
const scroller = scrollerRef.current;
|
|
2942
2957
|
const verticalTrack = verticalScrollbarRef.current;
|
|
2943
2958
|
const verticalThumb = verticalScrollbarThumbRef.current;
|
|
@@ -2990,7 +3005,7 @@ function TableInner({
|
|
|
2990
3005
|
useLayoutEffect3(() => {
|
|
2991
3006
|
updateCustomScrollbars();
|
|
2992
3007
|
}, [contentHeight, contentWidth, updateCustomScrollbars, viewport.height, viewport.width]);
|
|
2993
|
-
const handleVerticalScrollbarPointerDown =
|
|
3008
|
+
const handleVerticalScrollbarPointerDown = useCallback3((event) => {
|
|
2994
3009
|
const scroller = scrollerRef.current;
|
|
2995
3010
|
const track = verticalScrollbarRef.current;
|
|
2996
3011
|
const thumb = verticalScrollbarThumbRef.current;
|
|
@@ -3027,7 +3042,7 @@ function TableInner({
|
|
|
3027
3042
|
maxScrollTop
|
|
3028
3043
|
};
|
|
3029
3044
|
}, [showCustomScrollbar, updateCustomScrollbars]);
|
|
3030
|
-
const handleVerticalScrollbarPointerMove =
|
|
3045
|
+
const handleVerticalScrollbarPointerMove = useCallback3((event) => {
|
|
3031
3046
|
const drag = verticalScrollbarDragRef.current;
|
|
3032
3047
|
const scroller = scrollerRef.current;
|
|
3033
3048
|
if (!drag || !scroller || drag.pointerId !== event.pointerId) return;
|
|
@@ -3037,14 +3052,14 @@ function TableInner({
|
|
|
3037
3052
|
scroller.scrollTop = nextThumbTop / maxThumbTop * drag.maxScrollTop;
|
|
3038
3053
|
updateCustomScrollbars();
|
|
3039
3054
|
}, [updateCustomScrollbars]);
|
|
3040
|
-
const handleVerticalScrollbarPointerUp =
|
|
3055
|
+
const handleVerticalScrollbarPointerUp = useCallback3((event) => {
|
|
3041
3056
|
const drag = verticalScrollbarDragRef.current;
|
|
3042
3057
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3043
3058
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
3044
3059
|
verticalScrollbarDragRef.current = null;
|
|
3045
3060
|
showCustomScrollbar("vertical");
|
|
3046
3061
|
}, [showCustomScrollbar]);
|
|
3047
|
-
const handleHorizontalScrollbarPointerDown =
|
|
3062
|
+
const handleHorizontalScrollbarPointerDown = useCallback3((event) => {
|
|
3048
3063
|
const scroller = scrollerRef.current;
|
|
3049
3064
|
const track = horizontalScrollbarRef.current;
|
|
3050
3065
|
const thumb = horizontalScrollbarThumbRef.current;
|
|
@@ -3087,7 +3102,7 @@ function TableInner({
|
|
|
3087
3102
|
maxScrollLeft
|
|
3088
3103
|
};
|
|
3089
3104
|
}, [drawImmediately, getSelectionHorizontalVisibility, showCustomScrollbar, syncSelectionEdgeTarget, updateCustomScrollbars]);
|
|
3090
|
-
const handleHorizontalScrollbarPointerMove =
|
|
3105
|
+
const handleHorizontalScrollbarPointerMove = useCallback3((event) => {
|
|
3091
3106
|
const drag = horizontalScrollbarDragRef.current;
|
|
3092
3107
|
const scroller = scrollerRef.current;
|
|
3093
3108
|
if (!drag || !scroller || drag.pointerId !== event.pointerId) return;
|
|
@@ -3103,7 +3118,7 @@ function TableInner({
|
|
|
3103
3118
|
if (visibilityChanged) drawImmediately();
|
|
3104
3119
|
updateCustomScrollbars();
|
|
3105
3120
|
}, [drawImmediately, getSelectionHorizontalVisibility, syncSelectionEdgeTarget, updateCustomScrollbars]);
|
|
3106
|
-
const handleHorizontalScrollbarPointerUp =
|
|
3121
|
+
const handleHorizontalScrollbarPointerUp = useCallback3((event) => {
|
|
3107
3122
|
const drag = horizontalScrollbarDragRef.current;
|
|
3108
3123
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3109
3124
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
@@ -3117,7 +3132,7 @@ function TableInner({
|
|
|
3117
3132
|
clip.style.transform = "";
|
|
3118
3133
|
});
|
|
3119
3134
|
}, [scrollPosition.top]);
|
|
3120
|
-
const handleScroll =
|
|
3135
|
+
const handleScroll = useCallback3(() => {
|
|
3121
3136
|
const element = scrollerRef.current;
|
|
3122
3137
|
if (!element) return;
|
|
3123
3138
|
const previousScroll = scrollRef.current;
|
|
@@ -3194,7 +3209,7 @@ function TableInner({
|
|
|
3194
3209
|
setHoveredCellTooltip(null);
|
|
3195
3210
|
scheduleDraw();
|
|
3196
3211
|
}, [bodyTop, columns, renderHeight, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, metrics, rightFixedOffsets, rightFixedWidth, rowHeight, rows, scheduleDraw, selection, selectionRange, showCustomScrollbar, syncSelectionEdgeTarget, updateCustomScrollbars, viewport.width]);
|
|
3197
|
-
const locateColumn =
|
|
3212
|
+
const locateColumn = useCallback3((clientX) => {
|
|
3198
3213
|
const canvas = canvasRef.current;
|
|
3199
3214
|
if (!canvas) return -1;
|
|
3200
3215
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -3222,7 +3237,7 @@ function TableInner({
|
|
|
3222
3237
|
}
|
|
3223
3238
|
return columnIndex;
|
|
3224
3239
|
}, [columns, fixedWidth, getScrollableColumnLeft, leftFixedOffsets, metrics, rightFixedOffsets, rightFixedWidth, viewport.width]);
|
|
3225
|
-
const getDisplayedColumnLeft =
|
|
3240
|
+
const getDisplayedColumnLeft = useCallback3((columnIndex) => {
|
|
3226
3241
|
const metric = metrics[columnIndex];
|
|
3227
3242
|
if (columns[columnIndex].fixed === "left") return leftFixedOffsets.get(columnIndex) ?? 0;
|
|
3228
3243
|
if (columns[columnIndex].fixed === "right") return viewport.width - (rightFixedOffsets.get(columnIndex) ?? 0) - metric.width;
|
|
@@ -3232,7 +3247,7 @@ function TableInner({
|
|
|
3232
3247
|
const displayedContentRight = columns.reduce((right, _column, columnIndex) => Math.max(right, getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width), 0);
|
|
3233
3248
|
return displayedContentRight > 0 && displayedContentRight < viewport.width ? Math.round(displayedContentRight) - 1 : null;
|
|
3234
3249
|
}, [columns, getDisplayedColumnLeft, metrics, scrollPosition.left, viewport.width]);
|
|
3235
|
-
const getHeaderLevelAtY =
|
|
3250
|
+
const getHeaderLevelAtY = useCallback3((localY, headerY) => {
|
|
3236
3251
|
const y = localY - headerY;
|
|
3237
3252
|
for (let level = 0; level < headerRowHeights.length; level += 1) {
|
|
3238
3253
|
const top = headerRowOffsets[level] ?? 0;
|
|
@@ -3240,11 +3255,11 @@ function TableInner({
|
|
|
3240
3255
|
}
|
|
3241
3256
|
return headerDepth - 1;
|
|
3242
3257
|
}, [headerDepth, headerRowHeights, headerRowOffsets]);
|
|
3243
|
-
const resizeColumn =
|
|
3258
|
+
const resizeColumn = useCallback3((columnKey, width2) => {
|
|
3244
3259
|
setResizedColumnWidths((current) => current[columnKey] === width2 ? current : { ...current, [columnKey]: width2 });
|
|
3245
3260
|
onColumnResize?.(columnKey, width2);
|
|
3246
3261
|
}, [onColumnResize]);
|
|
3247
|
-
const locateHeaderAction =
|
|
3262
|
+
const locateHeaderAction = useCallback3((clientX, clientY, columnIndex) => {
|
|
3248
3263
|
if (columnIndex < 0 || !canvasRef.current) return null;
|
|
3249
3264
|
const column = columns[columnIndex];
|
|
3250
3265
|
if (column.rowSelection || column.rowDragHandle || column.rowNumber) return null;
|
|
@@ -3264,7 +3279,7 @@ function TableInner({
|
|
|
3264
3279
|
if (visibleActions.filter && localX >= right - headerActionSlotWidth && localX < right) return "filter";
|
|
3265
3280
|
return null;
|
|
3266
3281
|
}, [columnDraggable, columns, fixedHeader, getDisplayedColumnLeft, headerActionSize, headerActionSlotWidth, headerLeafHeight, headerLeafTop, measureHeaderTitleWidth, metrics]);
|
|
3267
|
-
const isHeaderTitleTruncated =
|
|
3282
|
+
const isHeaderTitleTruncated = useCallback3((columnIndex) => {
|
|
3268
3283
|
const canvas = canvasRef.current;
|
|
3269
3284
|
if (columnIndex < 0 || !canvas) return false;
|
|
3270
3285
|
const column = columns[columnIndex];
|
|
@@ -3274,7 +3289,7 @@ function TableInner({
|
|
|
3274
3289
|
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * headerActionSlotWidth;
|
|
3275
3290
|
return getHeaderTitleRequiredWidth(column, titleWidth) > Math.max(0, metric.width - actionWidth);
|
|
3276
3291
|
}, [columnDraggable, columns, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
|
|
3277
|
-
const locateHeaderDragHandle =
|
|
3292
|
+
const locateHeaderDragHandle = useCallback3((clientX, clientY, columnIndex) => {
|
|
3278
3293
|
if (!columnDraggable || columnIndex < 0 || !canvasRef.current) return false;
|
|
3279
3294
|
const column = columns[columnIndex];
|
|
3280
3295
|
if (column.rowSelection || column.rowDragHandle || column.rowNumber) return false;
|
|
@@ -3288,14 +3303,14 @@ function TableInner({
|
|
|
3288
3303
|
const columnRight = getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width;
|
|
3289
3304
|
return localX >= columnRight - headerActionSlotWidth && localX < columnRight - 2;
|
|
3290
3305
|
}, [columnDraggable, columns, fixedHeader, getDisplayedColumnLeft, headerActionSize, headerActionSlotWidth, headerLeafHeight, headerLeafTop, measureHeaderTitleWidth, metrics]);
|
|
3291
|
-
const getHeaderCellLeft =
|
|
3306
|
+
const getHeaderCellLeft = useCallback3((cell) => {
|
|
3292
3307
|
const startMetric = metrics[cell.startIndex];
|
|
3293
3308
|
const fixedSide = columns[cell.startIndex]?.fixed;
|
|
3294
3309
|
if (!startMetric) return 0;
|
|
3295
3310
|
return fixedSide === "left" ? leftFixedOffsets.get(cell.startIndex) ?? 0 : fixedSide === "right" ? viewport.width - (rightFixedOffsets.get(cell.startIndex) ?? 0) - startMetric.width : getScrollableColumnLeft(cell.startIndex) - scrollRef.current.left;
|
|
3296
3311
|
}, [columns, getScrollableColumnLeft, leftFixedOffsets, metrics, rightFixedOffsets, viewport.width]);
|
|
3297
|
-
const getHeaderCellWidth =
|
|
3298
|
-
const getHeaderCellEdgeFromMetrics =
|
|
3312
|
+
const getHeaderCellWidth = useCallback3((cell) => cell.leaf ? metrics[cell.startIndex]?.width ?? 0 : getCellDisplayWidth(cell.startIndex, cell.endIndex - cell.startIndex + 1), [getCellDisplayWidth, metrics]);
|
|
3313
|
+
const getHeaderCellEdgeFromMetrics = useCallback3((startIndex, endIndex, edge, nextMetrics) => {
|
|
3299
3314
|
const fixedSide = columns[startIndex]?.fixed;
|
|
3300
3315
|
const width2 = nextMetrics.slice(startIndex, endIndex + 1).reduce((total, metric) => total + metric.width, 0);
|
|
3301
3316
|
let left;
|
|
@@ -3319,7 +3334,7 @@ function TableInner({
|
|
|
3319
3334
|
}
|
|
3320
3335
|
return left + (edge === "right" ? width2 : 0);
|
|
3321
3336
|
}, [columns, fixedWidth, viewport.width]);
|
|
3322
|
-
const locateHeaderResizeHit =
|
|
3337
|
+
const locateHeaderResizeHit = useCallback3((clientX, clientY) => {
|
|
3323
3338
|
if (!columnResizable || !canvasRef.current) return null;
|
|
3324
3339
|
const rect = canvasRef.current.getBoundingClientRect();
|
|
3325
3340
|
const localX = clientX - rect.left;
|
|
@@ -3346,15 +3361,15 @@ function TableInner({
|
|
|
3346
3361
|
}
|
|
3347
3362
|
return closest;
|
|
3348
3363
|
}, [columnResizable, columns, fixedHeader, getHeaderCellLeft, getHeaderCellWidth, getHeaderLevelAtY, headerCells, headerHeight]);
|
|
3349
|
-
const locateHeaderResizeCell =
|
|
3350
|
-
const locateHeaderCellDragHandle =
|
|
3364
|
+
const locateHeaderResizeCell = useCallback3((clientX, clientY) => locateHeaderResizeHit(clientX, clientY)?.cell ?? null, [locateHeaderResizeHit]);
|
|
3365
|
+
const locateHeaderCellDragHandle = useCallback3((clientX, clientY, cell) => {
|
|
3351
3366
|
if (!columnDraggable || !canvasRef.current) return false;
|
|
3352
3367
|
if (cell.leaf) return locateHeaderDragHandle(clientX, clientY, cell.startIndex);
|
|
3353
3368
|
const localX = clientX - canvasRef.current.getBoundingClientRect().left;
|
|
3354
3369
|
const right = getHeaderCellLeft(cell) + getHeaderCellWidth(cell);
|
|
3355
3370
|
return localX >= right - headerActionSlotWidth && localX < right - 2;
|
|
3356
3371
|
}, [columnDraggable, getHeaderCellLeft, getHeaderCellWidth, headerActionSlotWidth, locateHeaderDragHandle]);
|
|
3357
|
-
const locateHeaderCell =
|
|
3372
|
+
const locateHeaderCell = useCallback3((clientX, clientY) => {
|
|
3358
3373
|
const canvas = canvasRef.current;
|
|
3359
3374
|
if (!canvas) return null;
|
|
3360
3375
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -3371,7 +3386,7 @@ function TableInner({
|
|
|
3371
3386
|
}
|
|
3372
3387
|
return null;
|
|
3373
3388
|
}, [fixedHeader, getHeaderCellLeft, getHeaderCellWidth, getHeaderLevelAtY, headerCells, headerHeight]);
|
|
3374
|
-
const setDragGuide =
|
|
3389
|
+
const setDragGuide = useCallback3((x, top = 0) => {
|
|
3375
3390
|
const guide = dragGuideRef.current;
|
|
3376
3391
|
if (!guide) return;
|
|
3377
3392
|
guide.style.display = x === null ? "none" : "block";
|
|
@@ -3380,20 +3395,20 @@ function TableInner({
|
|
|
3380
3395
|
guide.style.transform = `translateX(${Math.round(x)}px)`;
|
|
3381
3396
|
}
|
|
3382
3397
|
}, []);
|
|
3383
|
-
const setRowDragGuide =
|
|
3398
|
+
const setRowDragGuide = useCallback3((y) => {
|
|
3384
3399
|
const guide = rowDragGuideRef.current;
|
|
3385
3400
|
if (!guide) return;
|
|
3386
3401
|
guide.style.display = y === null ? "none" : "block";
|
|
3387
3402
|
if (y !== null) guide.style.transform = `translateY(${Math.round(y)}px)`;
|
|
3388
3403
|
}, []);
|
|
3389
|
-
const locateRow =
|
|
3404
|
+
const locateRow = useCallback3((clientY) => {
|
|
3390
3405
|
const canvas = canvasRef.current;
|
|
3391
3406
|
if (!canvas) return -1;
|
|
3392
3407
|
const localY = clientY - canvas.getBoundingClientRect().top;
|
|
3393
3408
|
const rowIndex = Math.floor((localY - bodyTop + scrollRef.current.top) / rowHeight);
|
|
3394
3409
|
return rowIndex >= 0 && rowIndex < rows.length ? rowIndex : -1;
|
|
3395
3410
|
}, [bodyTop, rowHeight, rows.length]);
|
|
3396
|
-
const handleRowOrderPointerDown =
|
|
3411
|
+
const handleRowOrderPointerDown = useCallback3((event) => {
|
|
3397
3412
|
if (!rowDraggable || event.button !== 0 || rowOrderDragRef.current) return;
|
|
3398
3413
|
const columnIndex = locateColumn(event.clientX);
|
|
3399
3414
|
const sourceIndex = locateRow(event.clientY);
|
|
@@ -3407,7 +3422,7 @@ function TableInner({
|
|
|
3407
3422
|
targetIndex: sourceIndex
|
|
3408
3423
|
};
|
|
3409
3424
|
}, [columns, locateColumn, locateRow, rowDraggable]);
|
|
3410
|
-
const handleRowOrderPointerMove =
|
|
3425
|
+
const handleRowOrderPointerMove = useCallback3((event) => {
|
|
3411
3426
|
const drag = rowOrderDragRef.current;
|
|
3412
3427
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3413
3428
|
if (!drag.active) {
|
|
@@ -3435,7 +3450,7 @@ function TableInner({
|
|
|
3435
3450
|
setRowDragPreview(null);
|
|
3436
3451
|
setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
|
|
3437
3452
|
}, [bodyTop, hideDragTooltips, locateRow, renderHeight, rowHeight, rows.length, setRowDragGuide]);
|
|
3438
|
-
const finishRowOrderPointerDrag =
|
|
3453
|
+
const finishRowOrderPointerDrag = useCallback3((event, apply) => {
|
|
3439
3454
|
const drag = rowOrderDragRef.current;
|
|
3440
3455
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3441
3456
|
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
@@ -3453,7 +3468,7 @@ function TableInner({
|
|
|
3453
3468
|
});
|
|
3454
3469
|
}
|
|
3455
3470
|
}, [applyRowOrder, setRowDragGuide]);
|
|
3456
|
-
const locateCell =
|
|
3471
|
+
const locateCell = useCallback3((clientX, clientY) => {
|
|
3457
3472
|
const canvas = canvasRef.current;
|
|
3458
3473
|
if (!canvas) return null;
|
|
3459
3474
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -3473,7 +3488,7 @@ function TableInner({
|
|
|
3473
3488
|
columnKey: columns[targetColumnIndex].key
|
|
3474
3489
|
};
|
|
3475
3490
|
}, [bodyTop, columns, fixedHeader, getCellSpan, getRowKey, locateColumn, rowHeight, rows]);
|
|
3476
|
-
const beginRangeDrag =
|
|
3491
|
+
const beginRangeDrag = useCallback3((event) => {
|
|
3477
3492
|
if (!rangeSelection) return;
|
|
3478
3493
|
if (event.button !== 0 || editing || event.target !== event.currentTarget) return;
|
|
3479
3494
|
const cell = locateCell(event.clientX, event.clientY);
|
|
@@ -3482,7 +3497,7 @@ function TableInner({
|
|
|
3482
3497
|
setSelectionRange(null);
|
|
3483
3498
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
3484
3499
|
}, [columns, editing, locateCell, rangeSelection]);
|
|
3485
|
-
const updateRangeDrag =
|
|
3500
|
+
const updateRangeDrag = useCallback3((event) => {
|
|
3486
3501
|
const drag = rangeDragRef.current;
|
|
3487
3502
|
if (!drag) return;
|
|
3488
3503
|
const focus = locateCell(event.clientX, event.clientY);
|
|
@@ -3492,7 +3507,7 @@ function TableInner({
|
|
|
3492
3507
|
event.preventDefault();
|
|
3493
3508
|
setSelectionRange((current) => current?.focus.rowIndex === focus.rowIndex && current.focus.columnIndex === focus.columnIndex ? current : { anchor: drag.anchor, focus });
|
|
3494
3509
|
}, [columns, locateCell]);
|
|
3495
|
-
const endRangeDrag =
|
|
3510
|
+
const endRangeDrag = useCallback3((event) => {
|
|
3496
3511
|
const drag = rangeDragRef.current;
|
|
3497
3512
|
if (!drag) return;
|
|
3498
3513
|
rangeDragRef.current = null;
|
|
@@ -3502,7 +3517,7 @@ function TableInner({
|
|
|
3502
3517
|
setSelection(drag.anchor);
|
|
3503
3518
|
scrollerRef.current?.focus({ preventScroll: true });
|
|
3504
3519
|
}, [setSelection]);
|
|
3505
|
-
const selectRow =
|
|
3520
|
+
const selectRow = useCallback3((rowIndex, event, forceToggle = false) => {
|
|
3506
3521
|
if (!rowSelection) return;
|
|
3507
3522
|
clickedCellRef.current = null;
|
|
3508
3523
|
setSelectionRange(null);
|
|
@@ -3522,7 +3537,7 @@ function TableInner({
|
|
|
3522
3537
|
rowAnchorRef.current = rowIndex;
|
|
3523
3538
|
setRowKeys(next);
|
|
3524
3539
|
}, [getRowKey, rowKeys, rowSelection, rows, selectedRowKeySet, setRowKeys, setSelection]);
|
|
3525
|
-
const selectColumn =
|
|
3540
|
+
const selectColumn = useCallback3((columnIndex, event) => {
|
|
3526
3541
|
if (!columnSelection || columnIndex < 0) return;
|
|
3527
3542
|
clickedCellRef.current = null;
|
|
3528
3543
|
setSelectionRange(null);
|
|
@@ -3542,7 +3557,7 @@ function TableInner({
|
|
|
3542
3557
|
columnAnchorRef.current = columnIndex;
|
|
3543
3558
|
setColumnKeys(next);
|
|
3544
3559
|
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys, setSelection]);
|
|
3545
|
-
const toggleColumnFromMenu =
|
|
3560
|
+
const toggleColumnFromMenu = useCallback3((columnIndex) => {
|
|
3546
3561
|
if (!columnSelection || columnIndex < 0) return;
|
|
3547
3562
|
clickedCellRef.current = null;
|
|
3548
3563
|
setSelectionRange(null);
|
|
@@ -3554,7 +3569,7 @@ function TableInner({
|
|
|
3554
3569
|
columnAnchorRef.current = columnIndex;
|
|
3555
3570
|
setColumnKeys(next);
|
|
3556
3571
|
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys, setSelection]);
|
|
3557
|
-
const revealCell =
|
|
3572
|
+
const revealCell = useCallback3((cell) => {
|
|
3558
3573
|
const scroller = scrollerRef.current;
|
|
3559
3574
|
const metric = metrics[cell.columnIndex];
|
|
3560
3575
|
const column = columns[cell.columnIndex];
|
|
@@ -3584,13 +3599,13 @@ function TableInner({
|
|
|
3584
3599
|
scrollRef.current = { left: scroller.scrollLeft, top: scroller.scrollTop };
|
|
3585
3600
|
scheduleDraw();
|
|
3586
3601
|
}, [bodyTop, columns, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, metrics, rightFixedWidth, rowHeight, scheduleDraw, viewport.width]);
|
|
3587
|
-
const isCellEditable =
|
|
3602
|
+
const isCellEditable = useCallback3((cell) => {
|
|
3588
3603
|
const column = columns[cell.columnIndex];
|
|
3589
3604
|
const row = rows[cell.rowIndex];
|
|
3590
3605
|
if (!column || !row || column.dataIndex === void 0 || column.rowNumber || column.rowSelection || column.rowDragHandle) return false;
|
|
3591
3606
|
return typeof column.editable === "function" ? column.editable(row[column.dataIndex], row, cell.rowIndex) : column.editable === true;
|
|
3592
3607
|
}, [columns, rows]);
|
|
3593
|
-
const beginEdit =
|
|
3608
|
+
const beginEdit = useCallback3((cell) => {
|
|
3594
3609
|
const column = columns[cell.columnIndex];
|
|
3595
3610
|
if (!isCellEditable(cell) || column.dataIndex === void 0) return;
|
|
3596
3611
|
const value = rows[cell.rowIndex]?.[column.dataIndex];
|
|
@@ -3660,7 +3675,7 @@ function TableInner({
|
|
|
3660
3675
|
return next;
|
|
3661
3676
|
});
|
|
3662
3677
|
};
|
|
3663
|
-
const commitEdit =
|
|
3678
|
+
const commitEdit = useCallback3((nextDraft, close = true) => {
|
|
3664
3679
|
if (!editing) return;
|
|
3665
3680
|
if (!isCellEditable(editing)) {
|
|
3666
3681
|
setEditing(null);
|
|
@@ -3692,6 +3707,7 @@ function TableInner({
|
|
|
3692
3707
|
options: column.editor.options,
|
|
3693
3708
|
searchable: column.editor.searchable,
|
|
3694
3709
|
allowCustomValue: column.editor.allowCustomValue,
|
|
3710
|
+
strictOptions: column.editor.strictOptions,
|
|
3695
3711
|
maxDropdownHeight: column.editor.maxDropdownHeight,
|
|
3696
3712
|
style: editorStyle,
|
|
3697
3713
|
labels,
|
|
@@ -3764,7 +3780,7 @@ function TableInner({
|
|
|
3764
3780
|
}
|
|
3765
3781
|
);
|
|
3766
3782
|
};
|
|
3767
|
-
const handleKeyDown =
|
|
3783
|
+
const handleKeyDown = useCallback3((event) => {
|
|
3768
3784
|
if (editing || !selection) return;
|
|
3769
3785
|
if (event.key === "Enter") {
|
|
3770
3786
|
event.preventDefault();
|
|
@@ -3837,7 +3853,7 @@ function TableInner({
|
|
|
3837
3853
|
clipPath: `inset(${Math.max(0, visibleTop - cellTop)}px ${Math.max(0, cellLeft + cellWidth - visibleRight)}px ${Math.max(0, cellTop + cellHeight - visibleBottom)}px ${Math.max(0, visibleLeft - cellLeft)}px)`
|
|
3838
3854
|
};
|
|
3839
3855
|
}, [bodyTop, columns, editing, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, rows, rowStyle, viewport.width]);
|
|
3840
|
-
const handleColumnPointerDown =
|
|
3856
|
+
const handleColumnPointerDown = useCallback3((event) => {
|
|
3841
3857
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
3842
3858
|
const localY = event.clientY - rect.top;
|
|
3843
3859
|
const headerY = fixedHeader ? 0 : -scrollRef.current.top;
|
|
@@ -3881,7 +3897,7 @@ function TableInner({
|
|
|
3881
3897
|
return;
|
|
3882
3898
|
}
|
|
3883
3899
|
}, [fixedHeader, getHeaderCellLeft, getHeaderCellWidth, headerHeight, headerRowOffsets, locateHeaderResizeHit, metrics]);
|
|
3884
|
-
const handleColumnPointerMove =
|
|
3900
|
+
const handleColumnPointerMove = useCallback3((event) => {
|
|
3885
3901
|
const drag = columnDragRef.current;
|
|
3886
3902
|
if (!drag) return;
|
|
3887
3903
|
const column = columns[drag.columnIndex];
|
|
@@ -3917,7 +3933,7 @@ function TableInner({
|
|
|
3917
3933
|
resizeColumn(column.key, width2);
|
|
3918
3934
|
setGuideFromWidths([width2]);
|
|
3919
3935
|
}, [columnDraggable, columns, getHeaderCellEdgeFromMetrics, resizeColumn, viewport.width]);
|
|
3920
|
-
const handleColumnPointerUp =
|
|
3936
|
+
const handleColumnPointerUp = useCallback3((event) => {
|
|
3921
3937
|
const drag = columnDragRef.current;
|
|
3922
3938
|
if (!drag) return;
|
|
3923
3939
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
@@ -3927,7 +3943,7 @@ function TableInner({
|
|
|
3927
3943
|
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3928
3944
|
event.currentTarget.style.cursor = "default";
|
|
3929
3945
|
}, []);
|
|
3930
|
-
const clearColumnOrderPointerDrag =
|
|
3946
|
+
const clearColumnOrderPointerDrag = useCallback3((canvas) => {
|
|
3931
3947
|
if (columnOrderLongPressTimerRef.current) {
|
|
3932
3948
|
clearTimeout(columnOrderLongPressTimerRef.current);
|
|
3933
3949
|
columnOrderLongPressTimerRef.current = null;
|
|
@@ -3940,7 +3956,7 @@ function TableInner({
|
|
|
3940
3956
|
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3941
3957
|
canvas.style.cursor = "default";
|
|
3942
3958
|
}, [setDragGuide]);
|
|
3943
|
-
const updateColumnDragPreview =
|
|
3959
|
+
const updateColumnDragPreview = useCallback3((sourceCell, clientX, canvas) => {
|
|
3944
3960
|
const rootRect = rootRef.current?.getBoundingClientRect() ?? canvas.getBoundingClientRect();
|
|
3945
3961
|
const sourceWidth = metrics[sourceCell.startIndex]?.width ?? 100;
|
|
3946
3962
|
const previewWidth = sourceWidth;
|
|
@@ -3952,7 +3968,7 @@ function TableInner({
|
|
|
3952
3968
|
sourceLeft: getDisplayedColumnLeft(sourceCell.startIndex)
|
|
3953
3969
|
});
|
|
3954
3970
|
}, [getDisplayedColumnLeft, metrics, viewport.width]);
|
|
3955
|
-
const activateColumnOrderPointerDrag =
|
|
3971
|
+
const activateColumnOrderPointerDrag = useCallback3((canvas, clientX) => {
|
|
3956
3972
|
const drag = columnOrderDragRef.current;
|
|
3957
3973
|
if (!drag || drag.active) return;
|
|
3958
3974
|
if (columnOrderLongPressTimerRef.current) {
|
|
@@ -3966,7 +3982,7 @@ function TableInner({
|
|
|
3966
3982
|
canvas.style.cursor = "move";
|
|
3967
3983
|
updateColumnDragPreview(drag.sourceCell, clientX, canvas);
|
|
3968
3984
|
}, [hideDragTooltips, updateColumnDragPreview]);
|
|
3969
|
-
const handleColumnOrderPointerDown =
|
|
3985
|
+
const handleColumnOrderPointerDown = useCallback3((event) => {
|
|
3970
3986
|
if (!columnDraggable || event.button !== 0 || columnDragRef.current) return;
|
|
3971
3987
|
const sourceCell = locateHeaderCell(event.clientX, event.clientY);
|
|
3972
3988
|
if (!sourceCell || locateHeaderResizeCell(event.clientX, event.clientY)) return;
|
|
@@ -3990,7 +4006,7 @@ function TableInner({
|
|
|
3990
4006
|
activateColumnOrderPointerDrag(canvas, drag.startX);
|
|
3991
4007
|
}, 320);
|
|
3992
4008
|
}, [activateColumnOrderPointerDrag, columnDraggable, columns, locateHeaderAction, locateHeaderCell, locateHeaderResizeCell]);
|
|
3993
|
-
const handleColumnOrderPointerMove =
|
|
4009
|
+
const handleColumnOrderPointerMove = useCallback3((event) => {
|
|
3994
4010
|
const drag = columnOrderDragRef.current;
|
|
3995
4011
|
if (!drag || drag.pointerId !== event.pointerId || columnDragRef.current) return;
|
|
3996
4012
|
if (!drag.active) {
|
|
@@ -4061,7 +4077,7 @@ function TableInner({
|
|
|
4061
4077
|
columnEdge
|
|
4062
4078
|
};
|
|
4063
4079
|
}, [activateColumnOrderPointerDrag, columns, getHeaderCellLeft, getHeaderCellWidth, headerCells, headerRowOffsets, locateColumn, locateHeaderCell, setDragGuide, updateColumnDragPreview]);
|
|
4064
|
-
const finishColumnOrderPointerDrag =
|
|
4080
|
+
const finishColumnOrderPointerDrag = useCallback3((event, apply) => {
|
|
4065
4081
|
const drag = columnOrderDragRef.current;
|
|
4066
4082
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
4067
4083
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
@@ -4085,7 +4101,7 @@ function TableInner({
|
|
|
4085
4101
|
suppressClickRef.current = false;
|
|
4086
4102
|
}, 0);
|
|
4087
4103
|
}, [applyColumnOrder, clearColumnOrderPointerDrag, utilityColumnCount]);
|
|
4088
|
-
const queueSortStateChange =
|
|
4104
|
+
const queueSortStateChange = useCallback3((next) => {
|
|
4089
4105
|
setSortState(next);
|
|
4090
4106
|
}, []);
|
|
4091
4107
|
const renderHeaderIcons = (columnIndex, left) => {
|
|
@@ -4120,7 +4136,7 @@ function TableInner({
|
|
|
4120
4136
|
}
|
|
4121
4137
|
return icons;
|
|
4122
4138
|
};
|
|
4123
|
-
const createHeaderTooltip =
|
|
4139
|
+
const createHeaderTooltip = useCallback3((action, columnIndex, cell) => {
|
|
4124
4140
|
const column = cell?.column ?? columns[columnIndex];
|
|
4125
4141
|
if (!column) return null;
|
|
4126
4142
|
const cellLeft = cell ? getHeaderCellLeft(cell) : getDisplayedColumnLeft(columnIndex);
|
|
@@ -4189,7 +4205,7 @@ function TableInner({
|
|
|
4189
4205
|
placement
|
|
4190
4206
|
};
|
|
4191
4207
|
}, [baseHeaderHeight, columnDraggable, columns, filterValues, fixedHeader, getDisplayedColumnLeft, getHeaderCellLeft, getHeaderCellWidth, headerActionSize, headerActionSlotWidth, headerDepth, headerLeafHeight, headerLeafTop, headerRowHeights, headerRowOffsets, labels, measureHeaderTitleWidth, metrics, scrollPosition.top, sortState, viewport.width]);
|
|
4192
|
-
const isPointerOnHeaderTitle =
|
|
4208
|
+
const isPointerOnHeaderTitle = useCallback3((clientX, clientY, cell) => {
|
|
4193
4209
|
const canvas = canvasRef.current;
|
|
4194
4210
|
if (!canvas) return false;
|
|
4195
4211
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -4210,7 +4226,7 @@ function TableInner({
|
|
|
4210
4226
|
const textTop = rowTop + 8;
|
|
4211
4227
|
return localX >= textLeft - 4 && localX <= textLeft + textWidth + 4 && localY >= textTop - 2 && localY <= textTop + 18;
|
|
4212
4228
|
}, [columnDraggable, fixedHeader, getHeaderCellLeft, getHeaderCellWidth, headerActionSlotWidth, headerRowOffsets]);
|
|
4213
|
-
const locateCustomHeaderTooltip =
|
|
4229
|
+
const locateCustomHeaderTooltip = useCallback3((clientX, clientY, columnIndex) => {
|
|
4214
4230
|
const root = rootRef.current;
|
|
4215
4231
|
const canvas = canvasRef.current;
|
|
4216
4232
|
if (!root || !canvas || columnIndex < 0) return null;
|