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