@lensui/lens-table 0.1.92 → 0.1.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +91 -27
- package/dist/index.css +22 -4
- package/dist/index.js +152 -84
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -953,18 +953,55 @@ function TextEditor({ value, type, min, max, integer = false, style, labels, onC
|
|
|
953
953
|
var import_react6 = require("react");
|
|
954
954
|
var import_react_dom = require("react-dom");
|
|
955
955
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
956
|
-
function TextAreaEditor({
|
|
956
|
+
function TextAreaEditor({
|
|
957
|
+
value,
|
|
958
|
+
title,
|
|
959
|
+
maxLength,
|
|
960
|
+
inline = false,
|
|
961
|
+
keepRightBorderVisible = false,
|
|
962
|
+
style,
|
|
963
|
+
labels,
|
|
964
|
+
onChange,
|
|
965
|
+
onCommit,
|
|
966
|
+
onCancel
|
|
967
|
+
}) {
|
|
957
968
|
const [open, setOpen] = (0, import_react6.useState)(false);
|
|
969
|
+
const inputRef = (0, import_react6.useRef)(null);
|
|
970
|
+
const textareaRef = (0, import_react6.useRef)(null);
|
|
971
|
+
const selectionRef = (0, import_react6.useRef)(null);
|
|
958
972
|
const inlineHeaderHeight = typeof style.height === "number" ? style.height : 34;
|
|
959
973
|
const editorStyle = inline && open ? {
|
|
960
974
|
...style,
|
|
961
|
-
"--rvg-textarea-inline-header-height": `${inlineHeaderHeight}px
|
|
975
|
+
"--rvg-textarea-inline-header-height": `${inlineHeaderHeight}px`,
|
|
976
|
+
"--rvg-textarea-inline-outline-right": keepRightBorderVisible ? "0px" : "-1px"
|
|
962
977
|
} : style;
|
|
963
978
|
const handleKeyDown = (event) => {
|
|
964
979
|
event.stopPropagation();
|
|
965
980
|
if (event.key === "Enter") onCommit(value);
|
|
966
981
|
if (event.key === "Escape") onCancel();
|
|
967
982
|
};
|
|
983
|
+
const rememberSelection = (control) => {
|
|
984
|
+
if (!control || control.selectionStart === null || control.selectionEnd === null)
|
|
985
|
+
return;
|
|
986
|
+
selectionRef.current = {
|
|
987
|
+
start: control.selectionStart,
|
|
988
|
+
end: control.selectionEnd,
|
|
989
|
+
direction: control.selectionDirection ?? "none"
|
|
990
|
+
};
|
|
991
|
+
};
|
|
992
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
993
|
+
if (!inline || !selectionRef.current) return;
|
|
994
|
+
const control = open ? textareaRef.current : inputRef.current;
|
|
995
|
+
if (!control) return;
|
|
996
|
+
const selection = selectionRef.current;
|
|
997
|
+
const length = control.value.length;
|
|
998
|
+
control.focus();
|
|
999
|
+
control.setSelectionRange(
|
|
1000
|
+
Math.min(selection.start, length),
|
|
1001
|
+
Math.min(selection.end, length),
|
|
1002
|
+
selection.direction
|
|
1003
|
+
);
|
|
1004
|
+
}, [inline, open]);
|
|
968
1005
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
969
1006
|
"div",
|
|
970
1007
|
{
|
|
@@ -974,6 +1011,7 @@ function TextAreaEditor({ value, title, maxLength, inline = false, style, labels
|
|
|
974
1011
|
!(inline && open) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
975
1012
|
"input",
|
|
976
1013
|
{
|
|
1014
|
+
ref: inputRef,
|
|
977
1015
|
value,
|
|
978
1016
|
autoFocus: true,
|
|
979
1017
|
maxLength,
|
|
@@ -992,13 +1030,21 @@ function TextAreaEditor({ value, title, maxLength, inline = false, style, labels
|
|
|
992
1030
|
event.preventDefault();
|
|
993
1031
|
event.stopPropagation();
|
|
994
1032
|
},
|
|
995
|
-
onClick: () =>
|
|
1033
|
+
onClick: () => {
|
|
1034
|
+
if (!inline) {
|
|
1035
|
+
setOpen(true);
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
rememberSelection(open ? textareaRef.current : inputRef.current);
|
|
1039
|
+
setOpen((current) => !current);
|
|
1040
|
+
},
|
|
996
1041
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MultilineEditorIcon, {})
|
|
997
1042
|
}
|
|
998
1043
|
),
|
|
999
1044
|
open && inline && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1000
1045
|
"textarea",
|
|
1001
1046
|
{
|
|
1047
|
+
ref: textareaRef,
|
|
1002
1048
|
className: "rvg-textarea-inline",
|
|
1003
1049
|
"aria-label": title,
|
|
1004
1050
|
"data-rvg-preserve-edit": true,
|
|
@@ -1009,30 +1055,44 @@ function TextAreaEditor({ value, title, maxLength, inline = false, style, labels
|
|
|
1009
1055
|
onChange: (event) => onChange(event.target.value),
|
|
1010
1056
|
onKeyDown: (event) => {
|
|
1011
1057
|
event.stopPropagation();
|
|
1012
|
-
if ((event.metaKey || event.ctrlKey) && event.key === "Enter")
|
|
1013
|
-
|
|
1058
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "Enter")
|
|
1059
|
+
onCommit(value);
|
|
1060
|
+
if (event.key === "Escape") {
|
|
1061
|
+
rememberSelection(event.currentTarget);
|
|
1062
|
+
setOpen(false);
|
|
1063
|
+
}
|
|
1014
1064
|
}
|
|
1015
1065
|
}
|
|
1016
1066
|
),
|
|
1017
1067
|
open && !inline && (0, import_react_dom.createPortal)(
|
|
1018
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-textarea-backdrop", role: "presentation", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
"textarea",
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1068
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-textarea-backdrop", role: "presentation", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1069
|
+
"section",
|
|
1070
|
+
{
|
|
1071
|
+
className: "rvg-textarea-dialog",
|
|
1072
|
+
role: "dialog",
|
|
1073
|
+
"aria-modal": "true",
|
|
1074
|
+
"aria-label": title,
|
|
1075
|
+
children: [
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("header", { children: title }),
|
|
1077
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1078
|
+
"textarea",
|
|
1079
|
+
{
|
|
1080
|
+
value,
|
|
1081
|
+
autoFocus: true,
|
|
1082
|
+
maxLength,
|
|
1083
|
+
onChange: (event) => onChange(event.target.value),
|
|
1084
|
+
onKeyDown: (event) => {
|
|
1085
|
+
event.stopPropagation();
|
|
1086
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "Enter")
|
|
1087
|
+
onCommit(value);
|
|
1088
|
+
if (event.key === "Escape") setOpen(false);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
),
|
|
1092
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("footer", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => onCommit(value), children: labels.confirm }) })
|
|
1093
|
+
]
|
|
1094
|
+
}
|
|
1095
|
+
) }),
|
|
1036
1096
|
document.body
|
|
1037
1097
|
)
|
|
1038
1098
|
]
|
|
@@ -1198,11 +1258,12 @@ function getSelectionOutlineBounds({
|
|
|
1198
1258
|
horizontalEnd,
|
|
1199
1259
|
verticalStart,
|
|
1200
1260
|
verticalEnd,
|
|
1201
|
-
borderWidth = 2
|
|
1261
|
+
borderWidth = 2,
|
|
1262
|
+
keepRightBorderVisible = false
|
|
1202
1263
|
}) {
|
|
1203
1264
|
return {
|
|
1204
1265
|
left: Math.max(left - borderWidth, horizontalStart - borderWidth),
|
|
1205
|
-
right: Math.min(right + 1, horizontalEnd + 1),
|
|
1266
|
+
right: Math.min(right + 1, horizontalEnd + (keepRightBorderVisible ? 0 : 1)),
|
|
1206
1267
|
top: Math.max(top - borderWidth, verticalStart - borderWidth),
|
|
1207
1268
|
bottom: Math.min(bottom + borderWidth, verticalEnd + borderWidth)
|
|
1208
1269
|
};
|
|
@@ -3302,7 +3363,8 @@ function TableInner({
|
|
|
3302
3363
|
horizontalStart,
|
|
3303
3364
|
horizontalEnd,
|
|
3304
3365
|
verticalStart,
|
|
3305
|
-
verticalEnd: renderHeight
|
|
3366
|
+
verticalEnd: renderHeight,
|
|
3367
|
+
keepRightBorderVisible: horizontalEnd === viewport.width
|
|
3306
3368
|
});
|
|
3307
3369
|
const left = Math.round(bounds.left);
|
|
3308
3370
|
const right = Math.round(bounds.right);
|
|
@@ -3861,6 +3923,7 @@ function TableInner({
|
|
|
3861
3923
|
title: column.editor.title ?? column.title,
|
|
3862
3924
|
maxLength: column.editor.maxLength,
|
|
3863
3925
|
inline: column.editor.inline,
|
|
3926
|
+
keepRightBorderVisible: typeof editorStyle.left === "number" && typeof editorStyle.width === "number" && editorStyle.left + editorStyle.width >= viewport.width,
|
|
3864
3927
|
style: editorStyle,
|
|
3865
3928
|
labels,
|
|
3866
3929
|
onChange: setDraft,
|
|
@@ -4856,7 +4919,8 @@ function TableInner({
|
|
|
4856
4919
|
horizontalStart,
|
|
4857
4920
|
horizontalEnd,
|
|
4858
4921
|
verticalStart,
|
|
4859
|
-
verticalEnd: renderHeight
|
|
4922
|
+
verticalEnd: renderHeight,
|
|
4923
|
+
keepRightBorderVisible: horizontalEnd === viewport.width
|
|
4860
4924
|
});
|
|
4861
4925
|
const left = Math.round(bounds.left);
|
|
4862
4926
|
const right = Math.round(bounds.right);
|
package/dist/index.css
CHANGED
|
@@ -2753,14 +2753,30 @@
|
|
|
2753
2753
|
.rvg-textarea-editor {
|
|
2754
2754
|
padding-right: 24px;
|
|
2755
2755
|
}
|
|
2756
|
+
.rvg-root:has(.rvg-textarea-editor.is-inline-expanded) .rvg-selection-focus {
|
|
2757
|
+
display: none;
|
|
2758
|
+
}
|
|
2756
2759
|
.rvg-textarea-editor.is-inline-expanded {
|
|
2757
2760
|
z-index: 8;
|
|
2758
2761
|
display: block;
|
|
2759
2762
|
height: calc(var(--rvg-textarea-inline-header-height) + 116px) !important;
|
|
2760
2763
|
padding: 0;
|
|
2761
|
-
overflow:
|
|
2762
|
-
border:
|
|
2764
|
+
overflow: visible;
|
|
2765
|
+
border: 0;
|
|
2763
2766
|
background: var(--rvg-color-bg);
|
|
2767
|
+
box-shadow: none;
|
|
2768
|
+
}
|
|
2769
|
+
.rvg-textarea-editor.is-inline-expanded::before {
|
|
2770
|
+
position: absolute;
|
|
2771
|
+
z-index: 1;
|
|
2772
|
+
top: -2px;
|
|
2773
|
+
right: var(--rvg-textarea-inline-outline-right, -1px);
|
|
2774
|
+
bottom: -2px;
|
|
2775
|
+
left: -2px;
|
|
2776
|
+
border: 2px solid var(--rvg-color-primary);
|
|
2777
|
+
content: "";
|
|
2778
|
+
pointer-events: none;
|
|
2779
|
+
box-sizing: border-box;
|
|
2764
2780
|
}
|
|
2765
2781
|
.rvg-textarea-trigger {
|
|
2766
2782
|
position: absolute;
|
|
@@ -2793,7 +2809,7 @@
|
|
|
2793
2809
|
min-width: 0;
|
|
2794
2810
|
min-height: 0;
|
|
2795
2811
|
margin: 0;
|
|
2796
|
-
padding:
|
|
2812
|
+
padding: 0 24px 8px 4px;
|
|
2797
2813
|
resize: none;
|
|
2798
2814
|
border: 0;
|
|
2799
2815
|
border-radius: 0;
|
|
@@ -2801,10 +2817,12 @@
|
|
|
2801
2817
|
background: transparent;
|
|
2802
2818
|
color: var(--rvg-color-text);
|
|
2803
2819
|
font:
|
|
2804
|
-
var(--rvg-font-size-body)
|
|
2820
|
+
var(--rvg-font-size-body) Inter,
|
|
2805
2821
|
ui-sans-serif,
|
|
2806
2822
|
system-ui,
|
|
2807
2823
|
sans-serif;
|
|
2824
|
+
line-height: var(--rvg-textarea-inline-header-height);
|
|
2825
|
+
box-shadow: none;
|
|
2808
2826
|
box-sizing: border-box;
|
|
2809
2827
|
}
|
|
2810
2828
|
.rvg-textarea-backdrop {
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/Table.tsx
|
|
2
|
-
import { forwardRef, useImperativeHandle, Fragment as Fragment2, useCallback as useCallback3, useEffect as useEffect3, useLayoutEffect as
|
|
2
|
+
import { forwardRef, useImperativeHandle, Fragment as Fragment2, useCallback as useCallback3, useEffect as useEffect3, useLayoutEffect as useLayoutEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState6 } from "react";
|
|
3
3
|
import { flushSync } from "react-dom";
|
|
4
4
|
|
|
5
5
|
// src/components/EmptyState.tsx
|
|
@@ -920,21 +920,62 @@ function TextEditor({ value, type, min, max, integer = false, style, labels, onC
|
|
|
920
920
|
}
|
|
921
921
|
|
|
922
922
|
// src/components/editors/TextAreaEditor.tsx
|
|
923
|
-
import {
|
|
923
|
+
import {
|
|
924
|
+
useLayoutEffect as useLayoutEffect3,
|
|
925
|
+
useRef as useRef4,
|
|
926
|
+
useState as useState4
|
|
927
|
+
} from "react";
|
|
924
928
|
import { createPortal } from "react-dom";
|
|
925
929
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
926
|
-
function TextAreaEditor({
|
|
930
|
+
function TextAreaEditor({
|
|
931
|
+
value,
|
|
932
|
+
title,
|
|
933
|
+
maxLength,
|
|
934
|
+
inline = false,
|
|
935
|
+
keepRightBorderVisible = false,
|
|
936
|
+
style,
|
|
937
|
+
labels,
|
|
938
|
+
onChange,
|
|
939
|
+
onCommit,
|
|
940
|
+
onCancel
|
|
941
|
+
}) {
|
|
927
942
|
const [open, setOpen] = useState4(false);
|
|
943
|
+
const inputRef = useRef4(null);
|
|
944
|
+
const textareaRef = useRef4(null);
|
|
945
|
+
const selectionRef = useRef4(null);
|
|
928
946
|
const inlineHeaderHeight = typeof style.height === "number" ? style.height : 34;
|
|
929
947
|
const editorStyle = inline && open ? {
|
|
930
948
|
...style,
|
|
931
|
-
"--rvg-textarea-inline-header-height": `${inlineHeaderHeight}px
|
|
949
|
+
"--rvg-textarea-inline-header-height": `${inlineHeaderHeight}px`,
|
|
950
|
+
"--rvg-textarea-inline-outline-right": keepRightBorderVisible ? "0px" : "-1px"
|
|
932
951
|
} : style;
|
|
933
952
|
const handleKeyDown = (event) => {
|
|
934
953
|
event.stopPropagation();
|
|
935
954
|
if (event.key === "Enter") onCommit(value);
|
|
936
955
|
if (event.key === "Escape") onCancel();
|
|
937
956
|
};
|
|
957
|
+
const rememberSelection = (control) => {
|
|
958
|
+
if (!control || control.selectionStart === null || control.selectionEnd === null)
|
|
959
|
+
return;
|
|
960
|
+
selectionRef.current = {
|
|
961
|
+
start: control.selectionStart,
|
|
962
|
+
end: control.selectionEnd,
|
|
963
|
+
direction: control.selectionDirection ?? "none"
|
|
964
|
+
};
|
|
965
|
+
};
|
|
966
|
+
useLayoutEffect3(() => {
|
|
967
|
+
if (!inline || !selectionRef.current) return;
|
|
968
|
+
const control = open ? textareaRef.current : inputRef.current;
|
|
969
|
+
if (!control) return;
|
|
970
|
+
const selection = selectionRef.current;
|
|
971
|
+
const length = control.value.length;
|
|
972
|
+
control.focus();
|
|
973
|
+
control.setSelectionRange(
|
|
974
|
+
Math.min(selection.start, length),
|
|
975
|
+
Math.min(selection.end, length),
|
|
976
|
+
selection.direction
|
|
977
|
+
);
|
|
978
|
+
}, [inline, open]);
|
|
938
979
|
return /* @__PURE__ */ jsxs7(
|
|
939
980
|
"div",
|
|
940
981
|
{
|
|
@@ -944,6 +985,7 @@ function TextAreaEditor({ value, title, maxLength, inline = false, style, labels
|
|
|
944
985
|
!(inline && open) && /* @__PURE__ */ jsx7(
|
|
945
986
|
"input",
|
|
946
987
|
{
|
|
988
|
+
ref: inputRef,
|
|
947
989
|
value,
|
|
948
990
|
autoFocus: true,
|
|
949
991
|
maxLength,
|
|
@@ -962,13 +1004,21 @@ function TextAreaEditor({ value, title, maxLength, inline = false, style, labels
|
|
|
962
1004
|
event.preventDefault();
|
|
963
1005
|
event.stopPropagation();
|
|
964
1006
|
},
|
|
965
|
-
onClick: () =>
|
|
1007
|
+
onClick: () => {
|
|
1008
|
+
if (!inline) {
|
|
1009
|
+
setOpen(true);
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
rememberSelection(open ? textareaRef.current : inputRef.current);
|
|
1013
|
+
setOpen((current) => !current);
|
|
1014
|
+
},
|
|
966
1015
|
children: /* @__PURE__ */ jsx7(MultilineEditorIcon, {})
|
|
967
1016
|
}
|
|
968
1017
|
),
|
|
969
1018
|
open && inline && /* @__PURE__ */ jsx7(
|
|
970
1019
|
"textarea",
|
|
971
1020
|
{
|
|
1021
|
+
ref: textareaRef,
|
|
972
1022
|
className: "rvg-textarea-inline",
|
|
973
1023
|
"aria-label": title,
|
|
974
1024
|
"data-rvg-preserve-edit": true,
|
|
@@ -979,30 +1029,44 @@ function TextAreaEditor({ value, title, maxLength, inline = false, style, labels
|
|
|
979
1029
|
onChange: (event) => onChange(event.target.value),
|
|
980
1030
|
onKeyDown: (event) => {
|
|
981
1031
|
event.stopPropagation();
|
|
982
|
-
if ((event.metaKey || event.ctrlKey) && event.key === "Enter")
|
|
983
|
-
|
|
1032
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "Enter")
|
|
1033
|
+
onCommit(value);
|
|
1034
|
+
if (event.key === "Escape") {
|
|
1035
|
+
rememberSelection(event.currentTarget);
|
|
1036
|
+
setOpen(false);
|
|
1037
|
+
}
|
|
984
1038
|
}
|
|
985
1039
|
}
|
|
986
1040
|
),
|
|
987
1041
|
open && !inline && createPortal(
|
|
988
|
-
/* @__PURE__ */ jsx7("div", { className: "rvg-textarea-backdrop", role: "presentation", children: /* @__PURE__ */ jsxs7(
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
"textarea",
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1042
|
+
/* @__PURE__ */ jsx7("div", { className: "rvg-textarea-backdrop", role: "presentation", children: /* @__PURE__ */ jsxs7(
|
|
1043
|
+
"section",
|
|
1044
|
+
{
|
|
1045
|
+
className: "rvg-textarea-dialog",
|
|
1046
|
+
role: "dialog",
|
|
1047
|
+
"aria-modal": "true",
|
|
1048
|
+
"aria-label": title,
|
|
1049
|
+
children: [
|
|
1050
|
+
/* @__PURE__ */ jsx7("header", { children: title }),
|
|
1051
|
+
/* @__PURE__ */ jsx7(
|
|
1052
|
+
"textarea",
|
|
1053
|
+
{
|
|
1054
|
+
value,
|
|
1055
|
+
autoFocus: true,
|
|
1056
|
+
maxLength,
|
|
1057
|
+
onChange: (event) => onChange(event.target.value),
|
|
1058
|
+
onKeyDown: (event) => {
|
|
1059
|
+
event.stopPropagation();
|
|
1060
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "Enter")
|
|
1061
|
+
onCommit(value);
|
|
1062
|
+
if (event.key === "Escape") setOpen(false);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
),
|
|
1066
|
+
/* @__PURE__ */ jsx7("footer", { children: /* @__PURE__ */ jsx7("button", { type: "button", onClick: () => onCommit(value), children: labels.confirm }) })
|
|
1067
|
+
]
|
|
1068
|
+
}
|
|
1069
|
+
) }),
|
|
1006
1070
|
document.body
|
|
1007
1071
|
)
|
|
1008
1072
|
]
|
|
@@ -1168,11 +1232,12 @@ function getSelectionOutlineBounds({
|
|
|
1168
1232
|
horizontalEnd,
|
|
1169
1233
|
verticalStart,
|
|
1170
1234
|
verticalEnd,
|
|
1171
|
-
borderWidth = 2
|
|
1235
|
+
borderWidth = 2,
|
|
1236
|
+
keepRightBorderVisible = false
|
|
1172
1237
|
}) {
|
|
1173
1238
|
return {
|
|
1174
1239
|
left: Math.max(left - borderWidth, horizontalStart - borderWidth),
|
|
1175
|
-
right: Math.min(right + 1, horizontalEnd + 1),
|
|
1240
|
+
right: Math.min(right + 1, horizontalEnd + (keepRightBorderVisible ? 0 : 1)),
|
|
1176
1241
|
top: Math.max(top - borderWidth, verticalStart - borderWidth),
|
|
1177
1242
|
bottom: Math.min(bottom + borderWidth, verticalEnd + borderWidth)
|
|
1178
1243
|
};
|
|
@@ -2066,8 +2131,8 @@ function TableInner({
|
|
|
2066
2131
|
const baseHeaderHeight = layout?.headerHeight ?? headerHeightProp ?? 40;
|
|
2067
2132
|
const headerDepth = useMemo2(() => Math.max(1, ...sourceColumns.map(getColumnDepth)), [sourceColumns]);
|
|
2068
2133
|
const { language, labels } = useMemo2(() => resolveGridLocale(locale), [locale]);
|
|
2069
|
-
const customHeaderContentRefs =
|
|
2070
|
-
const customHeaderMeasurementsRef =
|
|
2134
|
+
const customHeaderContentRefs = useRef5(/* @__PURE__ */ new Map());
|
|
2135
|
+
const customHeaderMeasurementsRef = useRef5(/* @__PURE__ */ new Map());
|
|
2071
2136
|
const [measuredHeaderRowHeights, setMeasuredHeaderRowHeights] = useState6([]);
|
|
2072
2137
|
const headerRowHeights = useMemo2(() => Array.from({ length: headerDepth }, (_, level) => Math.max(baseHeaderHeight, measuredHeaderRowHeights[level] ?? 0)), [baseHeaderHeight, headerDepth, measuredHeaderRowHeights]);
|
|
2073
2138
|
const headerRowOffsets = useMemo2(() => {
|
|
@@ -2103,7 +2168,7 @@ function TableInner({
|
|
|
2103
2168
|
const customContextMenuConfig = typeof contextMenuConfig === "object" ? contextMenuConfig : void 0;
|
|
2104
2169
|
const [resizedColumnWidths, setResizedColumnWidths] = useState6({});
|
|
2105
2170
|
const leafSourceColumns = useMemo2(() => flattenDataColumns(sourceColumns), [sourceColumns]);
|
|
2106
|
-
const sourceColumnWidthsRef =
|
|
2171
|
+
const sourceColumnWidthsRef = useRef5(new Map(leafSourceColumns.map((column) => [column.key, column.width])));
|
|
2107
2172
|
const showRowCheckbox = Boolean(rowSelection) && (typeof rowSelection !== "object" || rowSelection.showCheckbox !== false);
|
|
2108
2173
|
const rowSelectionIndicator = typeof rowSelection === "object" ? rowSelection.indicator ?? "checkbox" : "checkbox";
|
|
2109
2174
|
const rowSelectionColumnWidth = typeof rowSelection === "object" ? Math.max(24, rowSelection.columnWidth ?? 44) : 44;
|
|
@@ -2156,54 +2221,54 @@ function TableInner({
|
|
|
2156
2221
|
});
|
|
2157
2222
|
return levels;
|
|
2158
2223
|
}, [columns, headerCells, headerDepth]);
|
|
2159
|
-
const canvasRef =
|
|
2160
|
-
const scrollerRef =
|
|
2161
|
-
const rootRef =
|
|
2162
|
-
const frameRef =
|
|
2163
|
-
const textFrameRef =
|
|
2164
|
-
const textLayoutScrollTopRef =
|
|
2165
|
-
const toastTimerRef =
|
|
2166
|
-
const headerTooltipTimerRef =
|
|
2167
|
-
const cellTooltipTimerRef =
|
|
2168
|
-
const pendingHeaderTooltipKeyRef =
|
|
2169
|
-
const pendingCellTooltipKeyRef =
|
|
2170
|
-
const clickedCellRef =
|
|
2171
|
-
const rowAnchorRef =
|
|
2172
|
-
const columnAnchorRef =
|
|
2173
|
-
const columnDragRef =
|
|
2174
|
-
const columnOrderDragRef =
|
|
2175
|
-
const columnOrderLongPressTimerRef =
|
|
2176
|
-
const rowOrderDragRef =
|
|
2177
|
-
const dragGuideRef =
|
|
2178
|
-
const rowDragGuideRef =
|
|
2179
|
-
const selectionFocusRef =
|
|
2180
|
-
const selectionEdgeTargetRef =
|
|
2181
|
-
const verticalScrollbarRef =
|
|
2182
|
-
const verticalScrollbarThumbRef =
|
|
2183
|
-
const verticalScrollbarDragRef =
|
|
2184
|
-
const horizontalScrollbarRef =
|
|
2185
|
-
const horizontalScrollbarThumbRef =
|
|
2186
|
-
const horizontalScrollbarDragRef =
|
|
2187
|
-
const verticalScrollbarVisibilityTimerRef =
|
|
2188
|
-
const horizontalScrollbarVisibilityTimerRef =
|
|
2189
|
-
const rowByKeyRef =
|
|
2190
|
-
const rowIndexByKeyRef =
|
|
2191
|
-
const headerIconsRef =
|
|
2192
|
-
const scrollingHeaderIconsRef =
|
|
2193
|
-
const scrollingTextRef =
|
|
2194
|
-
const filterRef =
|
|
2195
|
-
const contextMenuRef =
|
|
2196
|
-
const suppressClickRef =
|
|
2197
|
-
const hasCompletedLoadRef =
|
|
2198
|
-
const validColumnDropRef =
|
|
2199
|
-
const hoveredHeaderActionRef =
|
|
2200
|
-
const hoveredRowIndexRef =
|
|
2224
|
+
const canvasRef = useRef5(null);
|
|
2225
|
+
const scrollerRef = useRef5(null);
|
|
2226
|
+
const rootRef = useRef5(null);
|
|
2227
|
+
const frameRef = useRef5(null);
|
|
2228
|
+
const textFrameRef = useRef5(null);
|
|
2229
|
+
const textLayoutScrollTopRef = useRef5(0);
|
|
2230
|
+
const toastTimerRef = useRef5(null);
|
|
2231
|
+
const headerTooltipTimerRef = useRef5(null);
|
|
2232
|
+
const cellTooltipTimerRef = useRef5(null);
|
|
2233
|
+
const pendingHeaderTooltipKeyRef = useRef5("");
|
|
2234
|
+
const pendingCellTooltipKeyRef = useRef5("");
|
|
2235
|
+
const clickedCellRef = useRef5(null);
|
|
2236
|
+
const rowAnchorRef = useRef5(null);
|
|
2237
|
+
const columnAnchorRef = useRef5(null);
|
|
2238
|
+
const columnDragRef = useRef5(null);
|
|
2239
|
+
const columnOrderDragRef = useRef5(null);
|
|
2240
|
+
const columnOrderLongPressTimerRef = useRef5(null);
|
|
2241
|
+
const rowOrderDragRef = useRef5(null);
|
|
2242
|
+
const dragGuideRef = useRef5(null);
|
|
2243
|
+
const rowDragGuideRef = useRef5(null);
|
|
2244
|
+
const selectionFocusRef = useRef5(null);
|
|
2245
|
+
const selectionEdgeTargetRef = useRef5(null);
|
|
2246
|
+
const verticalScrollbarRef = useRef5(null);
|
|
2247
|
+
const verticalScrollbarThumbRef = useRef5(null);
|
|
2248
|
+
const verticalScrollbarDragRef = useRef5(null);
|
|
2249
|
+
const horizontalScrollbarRef = useRef5(null);
|
|
2250
|
+
const horizontalScrollbarThumbRef = useRef5(null);
|
|
2251
|
+
const horizontalScrollbarDragRef = useRef5(null);
|
|
2252
|
+
const verticalScrollbarVisibilityTimerRef = useRef5(null);
|
|
2253
|
+
const horizontalScrollbarVisibilityTimerRef = useRef5(null);
|
|
2254
|
+
const rowByKeyRef = useRef5(/* @__PURE__ */ new Map());
|
|
2255
|
+
const rowIndexByKeyRef = useRef5(/* @__PURE__ */ new Map());
|
|
2256
|
+
const headerIconsRef = useRef5(null);
|
|
2257
|
+
const scrollingHeaderIconsRef = useRef5(null);
|
|
2258
|
+
const scrollingTextRef = useRef5(null);
|
|
2259
|
+
const filterRef = useRef5(null);
|
|
2260
|
+
const contextMenuRef = useRef5(null);
|
|
2261
|
+
const suppressClickRef = useRef5(false);
|
|
2262
|
+
const hasCompletedLoadRef = useRef5(!loading);
|
|
2263
|
+
const validColumnDropRef = useRef5(null);
|
|
2264
|
+
const hoveredHeaderActionRef = useRef5(null);
|
|
2265
|
+
const hoveredRowIndexRef = useRef5(null);
|
|
2201
2266
|
const [viewport, setViewport] = useState6({ width: 0, height: typeof height === "number" ? height : FALLBACK_HEIGHT });
|
|
2202
2267
|
const [horizontalScrollbarHeight, setHorizontalScrollbarHeight] = useState6(0);
|
|
2203
2268
|
const [availableHeight, setAvailableHeight] = useState6(FALLBACK_HEIGHT);
|
|
2204
2269
|
const resolvedHeight = typeof height === "number" ? height : availableHeight;
|
|
2205
2270
|
const [scrollPosition, setScrollPosition] = useState6({ left: 0, top: 0 });
|
|
2206
|
-
const scrollRef =
|
|
2271
|
+
const scrollRef = useRef5({ left: 0, top: 0 });
|
|
2207
2272
|
const [rowKeys, setRowKeys] = useControllableKeys(selectedRowKeys, defaultSelectedRowKeys, (keys) => {
|
|
2208
2273
|
if (!onSelectedRowChange) return;
|
|
2209
2274
|
const missing = new Set(keys.filter((key) => !rowByKeyRef.current.has(key)));
|
|
@@ -2303,7 +2368,7 @@ function TableInner({
|
|
|
2303
2368
|
return changed ? nextHeights : current;
|
|
2304
2369
|
});
|
|
2305
2370
|
}, [activeCustomHeaderLevels, baseHeaderHeight, headerDepth]);
|
|
2306
|
-
|
|
2371
|
+
useLayoutEffect4(() => {
|
|
2307
2372
|
customHeaderContentRefs.current.forEach((_, key) => {
|
|
2308
2373
|
if (!activeCustomHeaderLevels.has(key)) customHeaderContentRefs.current.delete(key);
|
|
2309
2374
|
});
|
|
@@ -2357,12 +2422,12 @@ function TableInner({
|
|
|
2357
2422
|
const [annotationContent, setAnnotationContent] = useState6("");
|
|
2358
2423
|
const [annotationOpen, setAnnotationOpen] = useState6(false);
|
|
2359
2424
|
const [annotationPlacement, setAnnotationPlacement] = useState6("right-down");
|
|
2360
|
-
const originalCellValuesRef =
|
|
2425
|
+
const originalCellValuesRef = useRef5(/* @__PURE__ */ new Map());
|
|
2361
2426
|
const [pendingDeletedRowKeys, setPendingDeletedRowKeys] = useState6(() => /* @__PURE__ */ new Set());
|
|
2362
2427
|
const [pendingInserts, setPendingInserts] = useState6(() => []);
|
|
2363
2428
|
const [insertedRowKeys, setInsertedRowKeys] = useState6(() => /* @__PURE__ */ new Set());
|
|
2364
2429
|
const [rowOrderKeys, setRowOrderKeys] = useState6(null);
|
|
2365
|
-
const settledPendingInsertIdsRef =
|
|
2430
|
+
const settledPendingInsertIdsRef = useRef5(/* @__PURE__ */ new Set());
|
|
2366
2431
|
const getDataRowKey = useCallback3((row, index) => {
|
|
2367
2432
|
return typeof rowKey === "function" ? rowKey(row, index) : rowKey ? row[rowKey] : getDefaultRowKey(row, index);
|
|
2368
2433
|
}, [rowKey]);
|
|
@@ -2465,7 +2530,7 @@ function TableInner({
|
|
|
2465
2530
|
}, [columns, onSelectedCellChange, rows]);
|
|
2466
2531
|
const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
|
|
2467
2532
|
const [selectionRange, setSelectionRange] = useState6(null);
|
|
2468
|
-
const rangeDragRef =
|
|
2533
|
+
const rangeDragRef = useRef5(null);
|
|
2469
2534
|
useEffect3(() => {
|
|
2470
2535
|
if (!selection) return void 0;
|
|
2471
2536
|
const handleOutsidePointerDown = (event) => {
|
|
@@ -2520,7 +2585,7 @@ function TableInner({
|
|
|
2520
2585
|
return changed ? next : current;
|
|
2521
2586
|
});
|
|
2522
2587
|
}, [getDataRowKey, pendingDeletedRowKeys.size, sourceRows]);
|
|
2523
|
-
|
|
2588
|
+
useLayoutEffect4(() => {
|
|
2524
2589
|
if (!editing) return;
|
|
2525
2590
|
if (selection?.rowKey === editing.rowKey && selection.columnKey === editing.columnKey) return;
|
|
2526
2591
|
setEditing(null);
|
|
@@ -2926,7 +2991,7 @@ function TableInner({
|
|
|
2926
2991
|
target.classList.remove("is-shape-syncing");
|
|
2927
2992
|
}
|
|
2928
2993
|
}, [getSelectionEdgeIndicator]);
|
|
2929
|
-
|
|
2994
|
+
useLayoutEffect4(() => {
|
|
2930
2995
|
const element = scrollerRef.current;
|
|
2931
2996
|
if (!element) return;
|
|
2932
2997
|
const root = element.parentElement;
|
|
@@ -3099,7 +3164,7 @@ function TableInner({
|
|
|
3099
3164
|
horizontalThumb.style.width = `${Math.min(trackWidth, thumbWidth)}px`;
|
|
3100
3165
|
horizontalThumb.style.transform = `translateX(${thumbLeft}px)`;
|
|
3101
3166
|
}, [autoHeight, bodyTop, bottomSummaryHeight, effectiveHeight, fixedHeader, fixedWidth, realContentHeight, renderHeight, rightFixedWidth, viewport.width]);
|
|
3102
|
-
|
|
3167
|
+
useLayoutEffect4(() => {
|
|
3103
3168
|
updateCustomScrollbars();
|
|
3104
3169
|
}, [contentHeight, contentWidth, updateCustomScrollbars, viewport.height, viewport.width]);
|
|
3105
3170
|
const handleVerticalScrollbarPointerDown = useCallback3((event) => {
|
|
@@ -3222,7 +3287,7 @@ function TableInner({
|
|
|
3222
3287
|
horizontalScrollbarDragRef.current = null;
|
|
3223
3288
|
showCustomScrollbar("horizontal");
|
|
3224
3289
|
}, [showCustomScrollbar]);
|
|
3225
|
-
|
|
3290
|
+
useLayoutEffect4(() => {
|
|
3226
3291
|
textLayoutScrollTopRef.current = scrollPosition.top;
|
|
3227
3292
|
const clips = rootRef.current?.querySelectorAll(".rvg-body-text-clip");
|
|
3228
3293
|
clips?.forEach((clip) => {
|
|
@@ -3272,7 +3337,8 @@ function TableInner({
|
|
|
3272
3337
|
horizontalStart,
|
|
3273
3338
|
horizontalEnd,
|
|
3274
3339
|
verticalStart,
|
|
3275
|
-
verticalEnd: renderHeight
|
|
3340
|
+
verticalEnd: renderHeight,
|
|
3341
|
+
keepRightBorderVisible: horizontalEnd === viewport.width
|
|
3276
3342
|
});
|
|
3277
3343
|
const left = Math.round(bounds.left);
|
|
3278
3344
|
const right = Math.round(bounds.right);
|
|
@@ -3831,6 +3897,7 @@ function TableInner({
|
|
|
3831
3897
|
title: column.editor.title ?? column.title,
|
|
3832
3898
|
maxLength: column.editor.maxLength,
|
|
3833
3899
|
inline: column.editor.inline,
|
|
3900
|
+
keepRightBorderVisible: typeof editorStyle.left === "number" && typeof editorStyle.width === "number" && editorStyle.left + editorStyle.width >= viewport.width,
|
|
3834
3901
|
style: editorStyle,
|
|
3835
3902
|
labels,
|
|
3836
3903
|
onChange: setDraft,
|
|
@@ -4826,7 +4893,8 @@ function TableInner({
|
|
|
4826
4893
|
horizontalStart,
|
|
4827
4894
|
horizontalEnd,
|
|
4828
4895
|
verticalStart,
|
|
4829
|
-
verticalEnd: renderHeight
|
|
4896
|
+
verticalEnd: renderHeight,
|
|
4897
|
+
keepRightBorderVisible: horizontalEnd === viewport.width
|
|
4830
4898
|
});
|
|
4831
4899
|
const left = Math.round(bounds.left);
|
|
4832
4900
|
const right = Math.round(bounds.right);
|
|
@@ -4850,7 +4918,7 @@ function TableInner({
|
|
|
4850
4918
|
"--rvg-corner-hover-height-extension": "4px"
|
|
4851
4919
|
} : null
|
|
4852
4920
|
} : void 0;
|
|
4853
|
-
|
|
4921
|
+
useLayoutEffect4(() => {
|
|
4854
4922
|
syncSelectionEdgeTarget(scrollPosition.left, scrollPosition.top);
|
|
4855
4923
|
}, [scrollPosition.left, scrollPosition.top, syncSelectionEdgeTarget]);
|
|
4856
4924
|
const handleContextMenu = (event) => {
|