@lensui/lens-table 0.1.82 → 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 +122 -53
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +203 -134
- 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
|
|
@@ -1144,6 +1159,24 @@ function ellipsizeText(context, text, maxWidth) {
|
|
|
1144
1159
|
}
|
|
1145
1160
|
return `${text.slice(0, start)}${ellipsis}`;
|
|
1146
1161
|
}
|
|
1162
|
+
function getSelectionOutlineBounds({
|
|
1163
|
+
left,
|
|
1164
|
+
right,
|
|
1165
|
+
top,
|
|
1166
|
+
bottom,
|
|
1167
|
+
horizontalStart,
|
|
1168
|
+
horizontalEnd,
|
|
1169
|
+
verticalStart,
|
|
1170
|
+
verticalEnd,
|
|
1171
|
+
borderWidth = 2
|
|
1172
|
+
}) {
|
|
1173
|
+
return {
|
|
1174
|
+
left: Math.max(left - borderWidth, horizontalStart - borderWidth),
|
|
1175
|
+
right: Math.min(right + 1, horizontalEnd + 1),
|
|
1176
|
+
top: Math.max(top - borderWidth, verticalStart - borderWidth),
|
|
1177
|
+
bottom: Math.min(bottom + borderWidth, verticalEnd + borderWidth)
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1147
1180
|
function paintGrid(options) {
|
|
1148
1181
|
const { context: ctx, width, height, pixelRatio, scrollLeft, scrollTop, rowHeight, bodyFontSize, headerActionSlotWidth, headerHeight, fixedHeader, verticalBorderless, horizontalBorderless, frameBorderless, extendVerticalGridLines, striped, columnDraggable, sortState, filterValues, hoveredHeaderAction, rows, columns, metrics, range, selection, editing, hoveredRowIndex, selectionRange, selectedRowKeys, rowSelectionMode, selectedColumnKeys, highlightEditedCells, highlightInsertedRows, insertedRowKeys, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget } = options;
|
|
1149
1182
|
const headerLeafTop = options.headerLeafTop ?? 0;
|
|
@@ -1632,51 +1665,65 @@ function paintGrid(options) {
|
|
|
1632
1665
|
const visibleRight = x + selectionWidth;
|
|
1633
1666
|
const visibleBottom = y + selectionHeight;
|
|
1634
1667
|
const selectionTop = fixedHeader ? bodyTop : 0;
|
|
1635
|
-
const selectionClipTop = selectionTop;
|
|
1636
1668
|
const hiddenAboveHeader = visibleBottom <= selectionTop;
|
|
1637
1669
|
const hiddenBelowViewport = y >= height;
|
|
1638
1670
|
const hiddenBehindLeft = !isFixed && visibleRight <= visibleLeft;
|
|
1639
1671
|
const hiddenBehindRight = !isFixed && x >= selectionAreaRight;
|
|
1640
|
-
const leftMarkerX =
|
|
1672
|
+
const leftMarkerX = leftFixedWidth - borderWidth;
|
|
1673
|
+
const rightMarkerX = selectionAreaRight - 1;
|
|
1674
|
+
const topMarkerY = selectionTop - borderWidth;
|
|
1675
|
+
const bottomMarkerY = height;
|
|
1641
1676
|
if ((hiddenAboveHeader || hiddenBelowViewport) && (hiddenBehindLeft || hiddenBehindRight)) {
|
|
1642
1677
|
const markerSize = 2;
|
|
1643
|
-
const markerX = hiddenBehindLeft ? leftMarkerX :
|
|
1644
|
-
const markerY = hiddenAboveHeader ?
|
|
1678
|
+
const markerX = hiddenBehindLeft ? leftMarkerX : rightMarkerX;
|
|
1679
|
+
const markerY = hiddenAboveHeader ? topMarkerY : bottomMarkerY;
|
|
1645
1680
|
ctx.fillStyle = colors.selection;
|
|
1646
1681
|
ctx.fillRect(markerX, markerY, markerSize, markerSize);
|
|
1647
1682
|
return;
|
|
1648
1683
|
}
|
|
1684
|
+
const outline = getSelectionOutlineBounds({
|
|
1685
|
+
left: x,
|
|
1686
|
+
right: visibleRight,
|
|
1687
|
+
top: y,
|
|
1688
|
+
bottom: visibleBottom,
|
|
1689
|
+
horizontalStart: visibleLeft,
|
|
1690
|
+
horizontalEnd: selectionAreaRight,
|
|
1691
|
+
verticalStart: selectionTop,
|
|
1692
|
+
verticalEnd: height,
|
|
1693
|
+
borderWidth
|
|
1694
|
+
});
|
|
1649
1695
|
ctx.save();
|
|
1650
1696
|
ctx.beginPath();
|
|
1651
|
-
const clipLeft =
|
|
1697
|
+
const clipLeft = Math.max(0, outline.left);
|
|
1652
1698
|
const clipRight = Math.min(width, selectionAreaRight + 1);
|
|
1653
|
-
|
|
1699
|
+
const clipTop = Math.max(0, outline.top);
|
|
1700
|
+
ctx.rect(clipLeft, clipTop, clipRight - clipLeft, height - clipTop);
|
|
1654
1701
|
ctx.clip();
|
|
1655
1702
|
ctx.fillStyle = colors.selection;
|
|
1656
1703
|
if (hiddenAboveHeader) {
|
|
1657
|
-
const markerLeft = Math.max(x - borderWidth, visibleLeft -
|
|
1658
|
-
const markerRight = Math.min(visibleRight + 1, selectionAreaRight);
|
|
1659
|
-
if (markerRight > markerLeft) ctx.fillRect(markerLeft,
|
|
1704
|
+
const markerLeft = Math.max(x - borderWidth, visibleLeft - borderWidth);
|
|
1705
|
+
const markerRight = Math.min(visibleRight + 1, selectionAreaRight + 1);
|
|
1706
|
+
if (markerRight > markerLeft) ctx.fillRect(markerLeft, topMarkerY, markerRight - markerLeft, borderWidth);
|
|
1660
1707
|
}
|
|
1661
1708
|
if (hiddenBelowViewport) {
|
|
1662
|
-
const markerLeft = Math.max(x - borderWidth, visibleLeft -
|
|
1663
|
-
const markerRight = Math.min(visibleRight + 1, selectionAreaRight);
|
|
1664
|
-
if (markerRight > markerLeft) ctx.fillRect(markerLeft,
|
|
1709
|
+
const markerLeft = Math.max(x - borderWidth, visibleLeft - borderWidth);
|
|
1710
|
+
const markerRight = Math.min(visibleRight + 1, selectionAreaRight + 1);
|
|
1711
|
+
if (markerRight > markerLeft) ctx.fillRect(markerLeft, bottomMarkerY, markerRight - markerLeft, borderWidth);
|
|
1665
1712
|
}
|
|
1666
1713
|
if (hiddenBehindLeft || hiddenBehindRight) {
|
|
1667
|
-
const markerTop = Math.max(y - borderWidth, selectionTop);
|
|
1668
|
-
const markerBottom = Math.min(y + selectionHeight +
|
|
1669
|
-
const markerX = hiddenBehindLeft ? leftMarkerX :
|
|
1714
|
+
const markerTop = Math.max(y - borderWidth, selectionTop - borderWidth);
|
|
1715
|
+
const markerBottom = Math.min(y + selectionHeight + borderWidth, height + borderWidth);
|
|
1716
|
+
const markerX = hiddenBehindLeft ? leftMarkerX : rightMarkerX;
|
|
1670
1717
|
ctx.fillRect(markerX, markerTop, borderWidth, Math.max(0, markerBottom - markerTop));
|
|
1671
1718
|
}
|
|
1672
1719
|
if (hiddenAboveHeader || hiddenBelowViewport || hiddenBehindLeft || hiddenBehindRight) {
|
|
1673
1720
|
ctx.restore();
|
|
1674
1721
|
return;
|
|
1675
1722
|
}
|
|
1676
|
-
const borderLeft =
|
|
1677
|
-
const borderRight =
|
|
1678
|
-
const borderTop =
|
|
1679
|
-
const borderBottom =
|
|
1723
|
+
const borderLeft = outline.left;
|
|
1724
|
+
const borderRight = outline.right - borderWidth;
|
|
1725
|
+
const borderTop = outline.top;
|
|
1726
|
+
const borderBottom = outline.bottom - borderWidth;
|
|
1680
1727
|
const borderOuterWidth = borderRight + borderWidth - borderLeft;
|
|
1681
1728
|
ctx.fillRect(borderLeft, borderTop, borderOuterWidth, borderWidth);
|
|
1682
1729
|
ctx.fillRect(borderLeft, borderBottom, borderOuterWidth, borderWidth);
|
|
@@ -2696,14 +2743,17 @@ function TableInner({
|
|
|
2696
2743
|
const cornerLength = 10;
|
|
2697
2744
|
const hitSlop = 6;
|
|
2698
2745
|
const targetSize = borderWidth + hitSlop * 2;
|
|
2699
|
-
const
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2746
|
+
const leftBoundary = horizontalStart - borderWidth;
|
|
2747
|
+
const rightBoundary = horizontalEnd - 1;
|
|
2748
|
+
const topBoundary = verticalStart - borderWidth;
|
|
2749
|
+
const bottomBoundary = renderHeight;
|
|
2750
|
+
const markerX = hiddenLeft ? leftBoundary : rightBoundary;
|
|
2751
|
+
const markerY = hiddenTop ? topBoundary : bottomBoundary;
|
|
2702
2752
|
if (hiddenLeft || hiddenRight) {
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
const topClip = Math.max(0, verticalStart -
|
|
2706
|
-
const bottomClip = Math.max(0, rawBottom
|
|
2753
|
+
const markerTop = Math.max(rawTop - borderWidth, topBoundary);
|
|
2754
|
+
const markerBottom = Math.min(rawBottom + borderWidth, renderHeight + borderWidth);
|
|
2755
|
+
const topClip = Math.max(0, verticalStart - rawTop);
|
|
2756
|
+
const bottomClip = Math.max(0, rawBottom - renderHeight);
|
|
2707
2757
|
if (topClip > 0 || bottomClip > 0) {
|
|
2708
2758
|
const foldAtTop = topClip > 0;
|
|
2709
2759
|
const fold = Math.min(cornerLength, foldAtTop ? topClip : bottomClip);
|
|
@@ -2712,7 +2762,7 @@ function TableInner({
|
|
|
2712
2762
|
const cornerHeight = Math.max(cornerLength, markerBottom - markerTop);
|
|
2713
2763
|
const cornerOnLeft = hiddenLeft;
|
|
2714
2764
|
const shapeLeft = cornerOnLeft ? markerX : markerX + borderWidth - cornerWidth;
|
|
2715
|
-
const shapeTop = foldAtTop ?
|
|
2765
|
+
const shapeTop = foldAtTop ? topBoundary : renderHeight + borderWidth - cornerHeight;
|
|
2716
2766
|
return {
|
|
2717
2767
|
side: `${foldAtTop ? "top" : "bottom"}-${cornerOnLeft ? "left" : "right"}`,
|
|
2718
2768
|
orientation: "corner",
|
|
@@ -2739,19 +2789,19 @@ function TableInner({
|
|
|
2739
2789
|
}
|
|
2740
2790
|
};
|
|
2741
2791
|
}
|
|
2742
|
-
const horizontalMarkerEnd = horizontalEnd
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
const leftClip = Math.max(0, horizontalStart -
|
|
2746
|
-
const rightClip = Math.max(0, rawRight
|
|
2792
|
+
const horizontalMarkerEnd = horizontalEnd + 1;
|
|
2793
|
+
const markerLeft = Math.max(rawLeft - borderWidth, leftBoundary);
|
|
2794
|
+
const markerRight = Math.min(rawRight + 1, horizontalMarkerEnd);
|
|
2795
|
+
const leftClip = Math.max(0, horizontalStart - rawLeft);
|
|
2796
|
+
const rightClip = Math.max(0, rawRight - horizontalEnd);
|
|
2747
2797
|
if (leftClip > 0 || rightClip > 0) {
|
|
2748
2798
|
const foldAtLeft = leftClip > 0;
|
|
2749
2799
|
const fold = Math.min(cornerLength, foldAtLeft ? leftClip : rightClip);
|
|
2750
2800
|
if (fold > borderWidth) {
|
|
2751
2801
|
const cornerWidth = Math.max(cornerLength, markerRight - markerLeft);
|
|
2752
2802
|
const cornerHeight = fold;
|
|
2753
|
-
const shapeLeft = foldAtLeft ?
|
|
2754
|
-
const shapeTop = hiddenTop ?
|
|
2803
|
+
const shapeLeft = foldAtLeft ? leftBoundary : horizontalMarkerEnd - cornerWidth;
|
|
2804
|
+
const shapeTop = hiddenTop ? topBoundary : renderHeight + borderWidth - cornerHeight;
|
|
2755
2805
|
return {
|
|
2756
2806
|
side: `${hiddenTop ? "top" : "bottom"}-${foldAtLeft ? "left" : "right"}`,
|
|
2757
2807
|
orientation: "corner",
|
|
@@ -2777,7 +2827,7 @@ function TableInner({
|
|
|
2777
2827
|
height: targetSize
|
|
2778
2828
|
}
|
|
2779
2829
|
};
|
|
2780
|
-
}, [bodyTop, columns, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft,
|
|
2830
|
+
}, [bodyTop, columns, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, rows, selection, selectionRange, viewport.width]);
|
|
2781
2831
|
const syncSelectionEdgeTarget = (0, import_react8.useCallback)((scrollLeft, scrollTop) => {
|
|
2782
2832
|
const target = selectionEdgeTargetRef.current;
|
|
2783
2833
|
if (!target) return;
|
|
@@ -3147,11 +3197,20 @@ function TableInner({
|
|
|
3147
3197
|
if (rawRight <= horizontalStart || rawLeft >= horizontalEnd || rawBottom <= verticalStart || rawTop >= renderHeight) {
|
|
3148
3198
|
focus.style.display = "none";
|
|
3149
3199
|
} else {
|
|
3150
|
-
const
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3200
|
+
const bounds = getSelectionOutlineBounds({
|
|
3201
|
+
left: rawLeft,
|
|
3202
|
+
right: rawRight,
|
|
3203
|
+
top: rawTop,
|
|
3204
|
+
bottom: rawBottom,
|
|
3205
|
+
horizontalStart,
|
|
3206
|
+
horizontalEnd,
|
|
3207
|
+
verticalStart,
|
|
3208
|
+
verticalEnd: renderHeight
|
|
3209
|
+
});
|
|
3210
|
+
const left = Math.round(bounds.left);
|
|
3211
|
+
const right = Math.round(bounds.right);
|
|
3212
|
+
const top = Math.round(bounds.top);
|
|
3213
|
+
const bottom = Math.round(bounds.bottom);
|
|
3155
3214
|
focus.style.display = "block";
|
|
3156
3215
|
focus.style.left = `${left}px`;
|
|
3157
3216
|
focus.style.top = `${top}px`;
|
|
@@ -3678,6 +3737,7 @@ function TableInner({
|
|
|
3678
3737
|
options: column.editor.options,
|
|
3679
3738
|
searchable: column.editor.searchable,
|
|
3680
3739
|
allowCustomValue: column.editor.allowCustomValue,
|
|
3740
|
+
strictOptions: column.editor.strictOptions,
|
|
3681
3741
|
maxDropdownHeight: column.editor.maxDropdownHeight,
|
|
3682
3742
|
style: editorStyle,
|
|
3683
3743
|
labels,
|
|
@@ -4687,11 +4747,20 @@ function TableInner({
|
|
|
4687
4747
|
const horizontalEnd = column.fixed === void 0 ? viewport.width - rightFixedWidth : viewport.width;
|
|
4688
4748
|
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
4689
4749
|
if (rawRight <= horizontalStart || rawLeft >= horizontalEnd || rawBottom + dragOffset <= verticalStart || rawTop + dragOffset >= renderHeight) return null;
|
|
4690
|
-
const
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4750
|
+
const bounds = getSelectionOutlineBounds({
|
|
4751
|
+
left: rawLeft,
|
|
4752
|
+
right: rawRight,
|
|
4753
|
+
top: rawTop,
|
|
4754
|
+
bottom: rawBottom,
|
|
4755
|
+
horizontalStart,
|
|
4756
|
+
horizontalEnd,
|
|
4757
|
+
verticalStart,
|
|
4758
|
+
verticalEnd: renderHeight
|
|
4759
|
+
});
|
|
4760
|
+
const left = Math.round(bounds.left);
|
|
4761
|
+
const right = Math.round(bounds.right);
|
|
4762
|
+
const top = Math.round(bounds.top);
|
|
4763
|
+
const bottom = Math.round(bounds.bottom);
|
|
4695
4764
|
return {
|
|
4696
4765
|
left,
|
|
4697
4766
|
top,
|
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';
|