@revisium/schema-toolkit-ui 0.6.0 → 0.6.1
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 +364 -275
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +26 -26
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +364 -275
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7033,6 +7033,9 @@ function selectDefaultColumns(columns, maxVisible = 4) {
|
|
|
7033
7033
|
//#region src/table-editor/Columns/model/ColumnsModel.ts
|
|
7034
7034
|
const DEFAULT_COLUMN_WIDTH = 150;
|
|
7035
7035
|
const DEFAULT_ID_COLUMN_WIDTH = 240;
|
|
7036
|
+
function fieldToCssVar(field) {
|
|
7037
|
+
return `--cw-${field.replaceAll(".", "-")}`;
|
|
7038
|
+
}
|
|
7036
7039
|
function isValidPinZoneOrder(fields, pins) {
|
|
7037
7040
|
let zone = "left";
|
|
7038
7041
|
for (const field of fields) {
|
|
@@ -7222,7 +7225,7 @@ var ColumnsModel = class {
|
|
|
7222
7225
|
setColumnWidth(field, width) {
|
|
7223
7226
|
this._isResizing = true;
|
|
7224
7227
|
this._columnWidths.set(field, width);
|
|
7225
|
-
if (this._wrapperElement) this._wrapperElement.style.setProperty(
|
|
7228
|
+
if (this._wrapperElement) this._wrapperElement.style.setProperty(fieldToCssVar(field), `${width}px`);
|
|
7226
7229
|
}
|
|
7227
7230
|
commitColumnWidth() {
|
|
7228
7231
|
this._isResizing = false;
|
|
@@ -7242,7 +7245,7 @@ var ColumnsModel = class {
|
|
|
7242
7245
|
return this._buildCssVarsUntracked();
|
|
7243
7246
|
}
|
|
7244
7247
|
columnWidthCssVar(field) {
|
|
7245
|
-
return `var(
|
|
7248
|
+
return `var(${fieldToCssVar(field)}, ${field === "id" ? DEFAULT_ID_COLUMN_WIDTH : DEFAULT_COLUMN_WIDTH}px)`;
|
|
7246
7249
|
}
|
|
7247
7250
|
getPinState(field) {
|
|
7248
7251
|
return this._pinnedColumns.get(field);
|
|
@@ -7469,7 +7472,7 @@ var ColumnsModel = class {
|
|
|
7469
7472
|
const vars = {};
|
|
7470
7473
|
for (const field of this._visibleFields) {
|
|
7471
7474
|
const width = this._columnWidths.get(field) ?? (field === "id" ? DEFAULT_ID_COLUMN_WIDTH : DEFAULT_COLUMN_WIDTH);
|
|
7472
|
-
vars[
|
|
7475
|
+
vars[fieldToCssVar(field)] = `${width}px`;
|
|
7473
7476
|
}
|
|
7474
7477
|
return vars;
|
|
7475
7478
|
}
|
|
@@ -7478,7 +7481,7 @@ var ColumnsModel = class {
|
|
|
7478
7481
|
const vars = {};
|
|
7479
7482
|
for (const field of this._visibleFields) {
|
|
7480
7483
|
const width = this._columnWidths.get(field) ?? (field === "id" ? DEFAULT_ID_COLUMN_WIDTH : DEFAULT_COLUMN_WIDTH);
|
|
7481
|
-
vars[
|
|
7484
|
+
vars[fieldToCssVar(field)] = `${width}px`;
|
|
7482
7485
|
}
|
|
7483
7486
|
return vars;
|
|
7484
7487
|
});
|
|
@@ -10851,6 +10854,242 @@ const CellContextMenu = (0, mobx_react_lite.observer)(({ cell, onEditPointerDown
|
|
|
10851
10854
|
}) }) });
|
|
10852
10855
|
});
|
|
10853
10856
|
|
|
10857
|
+
//#endregion
|
|
10858
|
+
//#region src/table-editor/Table/ui/Cell/cellStyles.ts
|
|
10859
|
+
const SELECTION_BORDER_COLOR = "#3b82f6";
|
|
10860
|
+
function getCellState(cell) {
|
|
10861
|
+
if (cell.isReadOnly) {
|
|
10862
|
+
if (cell.isFocused && !cell.isInSelection) return "readonlyFocused";
|
|
10863
|
+
if (cell.isInSelection) return "selected";
|
|
10864
|
+
return "readonly";
|
|
10865
|
+
}
|
|
10866
|
+
if (cell.isEditing) return "editing";
|
|
10867
|
+
if (cell.isFocused && !cell.isInSelection) return "focused";
|
|
10868
|
+
if (cell.isInSelection) return "selected";
|
|
10869
|
+
return "display";
|
|
10870
|
+
}
|
|
10871
|
+
function isPrintableKey(e) {
|
|
10872
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return false;
|
|
10873
|
+
return e.key.length === 1;
|
|
10874
|
+
}
|
|
10875
|
+
|
|
10876
|
+
//#endregion
|
|
10877
|
+
//#region src/table-editor/Table/ui/Cell/cellCss.ts
|
|
10878
|
+
const CLS = "cw";
|
|
10879
|
+
const CLS_DISPLAY = `${CLS} cw-display`;
|
|
10880
|
+
const CLS_READONLY = `${CLS} cw-readonly`;
|
|
10881
|
+
const CLS_FOCUSED = `${CLS} cw-focused`;
|
|
10882
|
+
const CLS_EDITING = `${CLS} cw-editing`;
|
|
10883
|
+
const CLS_READONLY_FOCUSED = `${CLS} cw-readonlyFocused`;
|
|
10884
|
+
const CLS_SELECTED = `${CLS} cw-selected`;
|
|
10885
|
+
const CLS_ANCHOR = "cw-anchor";
|
|
10886
|
+
const STATE_CLASS = {
|
|
10887
|
+
display: CLS_DISPLAY,
|
|
10888
|
+
readonly: CLS_READONLY,
|
|
10889
|
+
focused: CLS_FOCUSED,
|
|
10890
|
+
editing: CLS_EDITING,
|
|
10891
|
+
readonlyFocused: CLS_READONLY_FOCUSED,
|
|
10892
|
+
selected: CLS_SELECTED
|
|
10893
|
+
};
|
|
10894
|
+
const CELL_STYLE_ID = "cell-wrapper-styles";
|
|
10895
|
+
function ensureCellStyles() {
|
|
10896
|
+
if (typeof document === "undefined") return;
|
|
10897
|
+
if (document.getElementById(CELL_STYLE_ID)) return;
|
|
10898
|
+
const style = document.createElement("style");
|
|
10899
|
+
style.id = CELL_STYLE_ID;
|
|
10900
|
+
style.textContent = [
|
|
10901
|
+
".cw{height:40px;padding:0 8px;position:relative;overflow:hidden;cursor:cell;box-shadow:var(--cw-shadow,none)}",
|
|
10902
|
+
".cw:focus,.cw:focus-visible{outline:none;box-shadow:var(--cw-shadow,none)}",
|
|
10903
|
+
".cw-display:hover,.cw-readonly:hover{background-color:var(--chakra-colors-gray-50);box-shadow:inset 0 -1px 0 0 #ededed}",
|
|
10904
|
+
".cw-focused{background-color:var(--chakra-colors-blue-50)}",
|
|
10905
|
+
".cw-focused::before,.cw-editing::before,.cw-readonlyFocused::before,.cw-anchor::before{content:\"\";position:absolute;inset:1px;border-radius:1px;pointer-events:none}",
|
|
10906
|
+
".cw-focused::before{border:2px solid var(--chakra-colors-blue-400)}",
|
|
10907
|
+
".cw-editing{cursor:text;background-color:white;z-index:1}",
|
|
10908
|
+
".cw-editing::before{border:2px solid var(--chakra-colors-blue-500)}",
|
|
10909
|
+
".cw-readonlyFocused{background-color:var(--chakra-colors-gray-50)}",
|
|
10910
|
+
".cw-readonlyFocused::before{border:2px solid var(--chakra-colors-gray-400)}",
|
|
10911
|
+
".cw-selected{background-color:var(--chakra-colors-blue-100);user-select:none}",
|
|
10912
|
+
".cw-anchor::before{border:2px solid var(--chakra-colors-blue-400)}"
|
|
10913
|
+
].join("");
|
|
10914
|
+
document.head.appendChild(style);
|
|
10915
|
+
}
|
|
10916
|
+
const INNER_STYLE = {
|
|
10917
|
+
display: "flex",
|
|
10918
|
+
alignItems: "center",
|
|
10919
|
+
height: "100%",
|
|
10920
|
+
width: "100%",
|
|
10921
|
+
minWidth: 0,
|
|
10922
|
+
overflow: "hidden"
|
|
10923
|
+
};
|
|
10924
|
+
function buildSelectionBoxShadow(edges) {
|
|
10925
|
+
const shadows = [];
|
|
10926
|
+
if (edges.top) shadows.push(`inset 0 2px 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10927
|
+
if (edges.bottom) shadows.push(`inset 0 -2px 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10928
|
+
if (edges.left) shadows.push(`inset 2px 0 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10929
|
+
if (edges.right) shadows.push(`inset -2px 0 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10930
|
+
return shadows.length > 0 ? shadows.join(", ") : null;
|
|
10931
|
+
}
|
|
10932
|
+
|
|
10933
|
+
//#endregion
|
|
10934
|
+
//#region src/table-editor/Table/ui/Cell/useCellContextMenu.ts
|
|
10935
|
+
let pendingContextMenu = null;
|
|
10936
|
+
function clearPendingContextMenu() {
|
|
10937
|
+
const pending = pendingContextMenu;
|
|
10938
|
+
pendingContextMenu = null;
|
|
10939
|
+
return pending;
|
|
10940
|
+
}
|
|
10941
|
+
function setPendingContextMenu(value) {
|
|
10942
|
+
pendingContextMenu = value;
|
|
10943
|
+
}
|
|
10944
|
+
const cellMenuRegistry = /* @__PURE__ */ new WeakMap();
|
|
10945
|
+
function useCellContextMenu(cell, cellRef, deferredEdit) {
|
|
10946
|
+
const [menuAnchor, setMenuAnchor] = (0, react.useState)(null);
|
|
10947
|
+
const menuOpen = menuAnchor !== null;
|
|
10948
|
+
const openContextMenuAt = (0, react.useCallback)((clientX, clientY) => {
|
|
10949
|
+
if (!cell.isFocused && !cell.isInSelection) cell.focus();
|
|
10950
|
+
setMenuAnchor(new DOMRect(clientX, clientY, 0, 0));
|
|
10951
|
+
}, [cell]);
|
|
10952
|
+
(0, react.useEffect)(() => {
|
|
10953
|
+
const el = cellRef.current;
|
|
10954
|
+
if (el) cellMenuRegistry.set(el, openContextMenuAt);
|
|
10955
|
+
return () => {
|
|
10956
|
+
if (el) cellMenuRegistry.delete(el);
|
|
10957
|
+
};
|
|
10958
|
+
}, [cellRef, openContextMenuAt]);
|
|
10959
|
+
const menuCloseRef = (0, react.useRef)(null);
|
|
10960
|
+
const handleMenuClose = (0, react.useCallback)(() => {
|
|
10961
|
+
const pending = clearPendingContextMenu();
|
|
10962
|
+
const didTriggerEdit = deferredEdit.triggerIfRequested();
|
|
10963
|
+
if (!pending && !didTriggerEdit && !cell.isEditing) if (cell.isAnchor || cell.isFocused && !cell.hasRangeSelection) cellRef.current?.focus();
|
|
10964
|
+
else ((cellRef.current?.closest("[data-testid=\"table-widget\"]"))?.querySelector("[data-testid^=\"cell-\"][tabindex=\"0\"]"))?.focus();
|
|
10965
|
+
setMenuAnchor(null);
|
|
10966
|
+
if (pending) {
|
|
10967
|
+
const openFn = cellMenuRegistry.get(pending.target);
|
|
10968
|
+
if (openFn) setTimeout(() => {
|
|
10969
|
+
openFn(pending.clientX, pending.clientY);
|
|
10970
|
+
}, 0);
|
|
10971
|
+
}
|
|
10972
|
+
}, [
|
|
10973
|
+
cell,
|
|
10974
|
+
cellRef,
|
|
10975
|
+
deferredEdit
|
|
10976
|
+
]);
|
|
10977
|
+
menuCloseRef.current = handleMenuClose;
|
|
10978
|
+
return {
|
|
10979
|
+
menuAnchor,
|
|
10980
|
+
menuOpen,
|
|
10981
|
+
openContextMenuAt,
|
|
10982
|
+
handleMenuClose,
|
|
10983
|
+
menuCloseRef
|
|
10984
|
+
};
|
|
10985
|
+
}
|
|
10986
|
+
|
|
10987
|
+
//#endregion
|
|
10988
|
+
//#region src/table-editor/Table/ui/Cell/useCellFocus.ts
|
|
10989
|
+
function useCellFocus(cellRef, state, isAnchorInRange, navVersion) {
|
|
10990
|
+
(0, react.useEffect)(() => {
|
|
10991
|
+
if (!cellRef.current) return;
|
|
10992
|
+
if (state === "focused" || state === "readonlyFocused" || isAnchorInRange) cellRef.current.focus();
|
|
10993
|
+
else if (state === "display" || state === "readonly" || state === "selected") cellRef.current.blur();
|
|
10994
|
+
}, [
|
|
10995
|
+
cellRef,
|
|
10996
|
+
state,
|
|
10997
|
+
isAnchorInRange,
|
|
10998
|
+
navVersion
|
|
10999
|
+
]);
|
|
11000
|
+
}
|
|
11001
|
+
|
|
11002
|
+
//#endregion
|
|
11003
|
+
//#region src/table-editor/Table/ui/Cell/useCellKeyboard.ts
|
|
11004
|
+
function handleArrowKey(cell, e, shiftAction, moveAction) {
|
|
11005
|
+
e.preventDefault();
|
|
11006
|
+
if (e.shiftKey) shiftAction();
|
|
11007
|
+
else if (cell.hasRangeSelection) cell.focus();
|
|
11008
|
+
else moveAction();
|
|
11009
|
+
}
|
|
11010
|
+
function handleEditableKeys(cell, e, callbacks) {
|
|
11011
|
+
if (cell.isReadOnly) {
|
|
11012
|
+
if (e.key === "Enter" || e.key === "Delete" || e.key === "Backspace" || isPrintableKey(e)) {
|
|
11013
|
+
e.preventDefault();
|
|
11014
|
+
cell.notifyReadonlyEditAttempt();
|
|
11015
|
+
}
|
|
11016
|
+
return;
|
|
11017
|
+
}
|
|
11018
|
+
const hasRange = cell.hasRangeSelection;
|
|
11019
|
+
if (!hasRange && e.key === "Enter") {
|
|
11020
|
+
e.preventDefault();
|
|
11021
|
+
if (callbacks.onStartEdit) callbacks.onStartEdit();
|
|
11022
|
+
else if (callbacks.onDoubleClick) callbacks.onDoubleClick();
|
|
11023
|
+
} else if (!hasRange && (e.key === "Delete" || e.key === "Backspace") && callbacks.onDelete) {
|
|
11024
|
+
e.preventDefault();
|
|
11025
|
+
callbacks.onDelete();
|
|
11026
|
+
} else if (isPrintableKey(e) && callbacks.onTypeChar) {
|
|
11027
|
+
e.preventDefault();
|
|
11028
|
+
callbacks.onTypeChar(e.key);
|
|
11029
|
+
}
|
|
11030
|
+
}
|
|
11031
|
+
function useCellKeyboard(cell, state, isAnchorInRange, menuOpen, menuCloseRef, callbacks) {
|
|
11032
|
+
const { onStartEdit, onDoubleClick, onTypeChar, onDelete } = callbacks;
|
|
11033
|
+
return {
|
|
11034
|
+
handleKeyDown: (0, react.useCallback)((e) => {
|
|
11035
|
+
if (menuOpen && e.key === "Escape") {
|
|
11036
|
+
e.preventDefault();
|
|
11037
|
+
menuCloseRef.current?.();
|
|
11038
|
+
return;
|
|
11039
|
+
}
|
|
11040
|
+
if (!(state === "focused" || state === "readonlyFocused" || isAnchorInRange)) return;
|
|
11041
|
+
const isMod = e.ctrlKey || e.metaKey;
|
|
11042
|
+
if (isMod && e.key === "c" && !cell.hasRangeSelection) {
|
|
11043
|
+
e.preventDefault();
|
|
11044
|
+
cell.copyToClipboard();
|
|
11045
|
+
return;
|
|
11046
|
+
}
|
|
11047
|
+
if (isMod && e.key === "v") return;
|
|
11048
|
+
const arrow = {
|
|
11049
|
+
ArrowUp: [cell.shiftMoveUp, cell.moveUp],
|
|
11050
|
+
ArrowDown: [cell.shiftMoveDown, cell.moveDown],
|
|
11051
|
+
ArrowLeft: [cell.shiftMoveLeft, cell.moveLeft],
|
|
11052
|
+
ArrowRight: [cell.shiftMoveRight, cell.moveRight]
|
|
11053
|
+
}[e.key];
|
|
11054
|
+
if (e.key === "Escape") {
|
|
11055
|
+
e.preventDefault();
|
|
11056
|
+
if (cell.hasRangeSelection) cell.focus();
|
|
11057
|
+
else cell.blur();
|
|
11058
|
+
} else if (arrow) handleArrowKey(cell, e, arrow[0], arrow[1]);
|
|
11059
|
+
else if (e.key === "Tab") {
|
|
11060
|
+
e.preventDefault();
|
|
11061
|
+
cell.handleTab(e.shiftKey);
|
|
11062
|
+
} else handleEditableKeys(cell, e, {
|
|
11063
|
+
onStartEdit,
|
|
11064
|
+
onDoubleClick,
|
|
11065
|
+
onTypeChar,
|
|
11066
|
+
onDelete
|
|
11067
|
+
});
|
|
11068
|
+
}, [
|
|
11069
|
+
state,
|
|
11070
|
+
cell,
|
|
11071
|
+
isAnchorInRange,
|
|
11072
|
+
menuOpen,
|
|
11073
|
+
menuCloseRef,
|
|
11074
|
+
onStartEdit,
|
|
11075
|
+
onDoubleClick,
|
|
11076
|
+
onTypeChar,
|
|
11077
|
+
onDelete
|
|
11078
|
+
]),
|
|
11079
|
+
handleDoubleClick: (0, react.useCallback)((e) => {
|
|
11080
|
+
if (state === "readonly" || state === "readonlyFocused") {
|
|
11081
|
+
cell.notifyReadonlyEditAttempt();
|
|
11082
|
+
return;
|
|
11083
|
+
}
|
|
11084
|
+
onDoubleClick?.(e.clientX);
|
|
11085
|
+
}, [
|
|
11086
|
+
state,
|
|
11087
|
+
cell,
|
|
11088
|
+
onDoubleClick
|
|
11089
|
+
])
|
|
11090
|
+
};
|
|
11091
|
+
}
|
|
11092
|
+
|
|
10854
11093
|
//#endregion
|
|
10855
11094
|
//#region src/table-editor/Table/ui/Cell/useDeferredMenuEdit.ts
|
|
10856
11095
|
/**
|
|
@@ -10905,299 +11144,117 @@ function useDeferredMenuEdit(editFn) {
|
|
|
10905
11144
|
};
|
|
10906
11145
|
}
|
|
10907
11146
|
|
|
10908
|
-
//#endregion
|
|
10909
|
-
//#region src/table-editor/Table/ui/borderConstants.ts
|
|
10910
|
-
const CELL_BORDER_COLOR = "#ededed";
|
|
10911
|
-
const BOTTOM_BORDER_SHADOW = `inset 0 -1px 0 0 ${CELL_BORDER_COLOR}`;
|
|
10912
|
-
function buildAddColumnShadowCss() {
|
|
10913
|
-
return { "&::after": {
|
|
10914
|
-
content: "\"\"",
|
|
10915
|
-
position: "absolute",
|
|
10916
|
-
top: 0,
|
|
10917
|
-
bottom: 0,
|
|
10918
|
-
width: "8px",
|
|
10919
|
-
left: "-8px",
|
|
10920
|
-
pointerEvents: "none",
|
|
10921
|
-
transition: "opacity 0.15s",
|
|
10922
|
-
opacity: "var(--shadow-right-opacity, 0)",
|
|
10923
|
-
boxShadow: "inset -8px 0 12px -8px rgba(0,0,0,0.1)"
|
|
10924
|
-
} };
|
|
10925
|
-
}
|
|
10926
|
-
function adjustRightOffsetCss(rightCss, addColOffset) {
|
|
10927
|
-
if (addColOffset <= 0) return rightCss;
|
|
10928
|
-
if (rightCss === "0px") return `${addColOffset}px`;
|
|
10929
|
-
return `calc(${rightCss} + ${addColOffset}px)`;
|
|
10930
|
-
}
|
|
10931
|
-
|
|
10932
|
-
//#endregion
|
|
10933
|
-
//#region src/table-editor/Table/ui/Cell/cellStyles.ts
|
|
10934
|
-
const FOCUS_RING_RESET = {
|
|
10935
|
-
outline: "none",
|
|
10936
|
-
boxShadow: "none"
|
|
10937
|
-
};
|
|
10938
|
-
const SELECTION_BORDER_COLOR = "#3b82f6";
|
|
10939
|
-
function buildSelectionBoxShadow(edges) {
|
|
10940
|
-
const shadows = [];
|
|
10941
|
-
if (edges.top) shadows.push(`inset 0 2px 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10942
|
-
if (edges.bottom) shadows.push(`inset 0 -2px 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10943
|
-
if (edges.left) shadows.push(`inset 2px 0 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10944
|
-
if (edges.right) shadows.push(`inset -2px 0 0 0 ${SELECTION_BORDER_COLOR}`);
|
|
10945
|
-
return shadows.length > 0 ? shadows.join(", ") : null;
|
|
10946
|
-
}
|
|
10947
|
-
const stateStyles = {
|
|
10948
|
-
display: {
|
|
10949
|
-
cursor: "cell",
|
|
10950
|
-
_hover: {
|
|
10951
|
-
bg: "gray.50",
|
|
10952
|
-
boxShadow: BOTTOM_BORDER_SHADOW
|
|
10953
|
-
}
|
|
10954
|
-
},
|
|
10955
|
-
focused: {
|
|
10956
|
-
cursor: "cell",
|
|
10957
|
-
bg: "blue.50",
|
|
10958
|
-
_before: {
|
|
10959
|
-
content: "\"\"",
|
|
10960
|
-
position: "absolute",
|
|
10961
|
-
inset: "1px",
|
|
10962
|
-
border: "2px solid",
|
|
10963
|
-
borderColor: "blue.400",
|
|
10964
|
-
borderRadius: "1px",
|
|
10965
|
-
pointerEvents: "none"
|
|
10966
|
-
},
|
|
10967
|
-
_focus: FOCUS_RING_RESET,
|
|
10968
|
-
_focusVisible: FOCUS_RING_RESET
|
|
10969
|
-
},
|
|
10970
|
-
editing: {
|
|
10971
|
-
cursor: "text",
|
|
10972
|
-
bg: "white",
|
|
10973
|
-
zIndex: 1,
|
|
10974
|
-
_before: {
|
|
10975
|
-
content: "\"\"",
|
|
10976
|
-
position: "absolute",
|
|
10977
|
-
inset: "1px",
|
|
10978
|
-
border: "2px solid",
|
|
10979
|
-
borderColor: "blue.500",
|
|
10980
|
-
borderRadius: "1px",
|
|
10981
|
-
pointerEvents: "none"
|
|
10982
|
-
},
|
|
10983
|
-
_focus: FOCUS_RING_RESET,
|
|
10984
|
-
_focusVisible: FOCUS_RING_RESET
|
|
10985
|
-
},
|
|
10986
|
-
readonly: {
|
|
10987
|
-
cursor: "cell",
|
|
10988
|
-
_hover: {
|
|
10989
|
-
bg: "gray.50",
|
|
10990
|
-
boxShadow: BOTTOM_BORDER_SHADOW
|
|
10991
|
-
}
|
|
10992
|
-
},
|
|
10993
|
-
readonlyFocused: {
|
|
10994
|
-
cursor: "cell",
|
|
10995
|
-
bg: "gray.50",
|
|
10996
|
-
_before: {
|
|
10997
|
-
content: "\"\"",
|
|
10998
|
-
position: "absolute",
|
|
10999
|
-
inset: "1px",
|
|
11000
|
-
border: "2px solid",
|
|
11001
|
-
borderColor: "gray.400",
|
|
11002
|
-
borderRadius: "1px",
|
|
11003
|
-
pointerEvents: "none"
|
|
11004
|
-
},
|
|
11005
|
-
_focus: FOCUS_RING_RESET,
|
|
11006
|
-
_focusVisible: FOCUS_RING_RESET
|
|
11007
|
-
},
|
|
11008
|
-
selected: {
|
|
11009
|
-
cursor: "cell",
|
|
11010
|
-
bg: "blue.100"
|
|
11011
|
-
}
|
|
11012
|
-
};
|
|
11013
|
-
function getCellState(cell) {
|
|
11014
|
-
if (cell.isReadOnly) {
|
|
11015
|
-
if (cell.isFocused && !cell.isInSelection) return "readonlyFocused";
|
|
11016
|
-
if (cell.isInSelection) return "selected";
|
|
11017
|
-
return "readonly";
|
|
11018
|
-
}
|
|
11019
|
-
if (cell.isEditing) return "editing";
|
|
11020
|
-
if (cell.isFocused && !cell.isInSelection) return "focused";
|
|
11021
|
-
if (cell.isInSelection) return "selected";
|
|
11022
|
-
return "display";
|
|
11023
|
-
}
|
|
11024
|
-
function isPrintableKey(e) {
|
|
11025
|
-
if (e.ctrlKey || e.metaKey || e.altKey) return false;
|
|
11026
|
-
return e.key.length === 1;
|
|
11027
|
-
}
|
|
11028
|
-
|
|
11029
11147
|
//#endregion
|
|
11030
11148
|
//#region src/table-editor/Table/ui/Cell/CellWrapper.tsx
|
|
11031
|
-
|
|
11032
|
-
|
|
11033
|
-
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
|
|
11038
|
-
|
|
11039
|
-
if (
|
|
11040
|
-
|
|
11041
|
-
|
|
11042
|
-
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
}
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
|
|
11052
|
-
|
|
11053
|
-
|
|
11054
|
-
|
|
11149
|
+
const LazyContextMenu = (0, mobx_react_lite.observer)(({ cell, cellRef, anchorRect, onClose, onEditPointerDown }) => {
|
|
11150
|
+
const handleOpenChange = (0, react.useCallback)((details) => {
|
|
11151
|
+
if (!details.open) onClose();
|
|
11152
|
+
}, [onClose]);
|
|
11153
|
+
const handleInteractOutside = (0, react.useCallback)((e) => {
|
|
11154
|
+
const originalEvent = e.detail?.originalEvent;
|
|
11155
|
+
if (!originalEvent || originalEvent.button !== 2) return;
|
|
11156
|
+
const targetCell = originalEvent.target?.closest("[data-testid^=\"cell-\"]");
|
|
11157
|
+
if (targetCell) setPendingContextMenu({
|
|
11158
|
+
target: targetCell,
|
|
11159
|
+
clientX: originalEvent.clientX,
|
|
11160
|
+
clientY: originalEvent.clientY
|
|
11161
|
+
});
|
|
11162
|
+
}, []);
|
|
11163
|
+
const getAnchorRect = (0, react.useCallback)(() => {
|
|
11164
|
+
return anchorRect ?? (cellRef.current?.getBoundingClientRect() || null);
|
|
11165
|
+
}, [anchorRect, cellRef]);
|
|
11166
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Menu.Root, {
|
|
11167
|
+
open: true,
|
|
11168
|
+
onOpenChange: handleOpenChange,
|
|
11169
|
+
onInteractOutside: handleInteractOutside,
|
|
11170
|
+
positioning: {
|
|
11171
|
+
placement: "bottom-start",
|
|
11172
|
+
getAnchorRect
|
|
11173
|
+
},
|
|
11174
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CellContextMenu, {
|
|
11175
|
+
cell,
|
|
11176
|
+
onEditPointerDown
|
|
11177
|
+
})
|
|
11178
|
+
});
|
|
11179
|
+
});
|
|
11055
11180
|
const CellWrapper = (0, mobx_react_lite.observer)(({ cell, children, onDoubleClick, onStartEdit, onTypeChar, onDelete }) => {
|
|
11181
|
+
ensureCellStyles();
|
|
11056
11182
|
const cellRef = (0, react.useRef)(null);
|
|
11057
|
-
const menuOpenRef = (0, react.useRef)(false);
|
|
11058
|
-
const deferredEdit = useDeferredMenuEdit(onStartEdit ?? onDoubleClick);
|
|
11059
11183
|
const state = getCellState(cell);
|
|
11060
11184
|
const selectionEdges = cell.selectionEdges;
|
|
11061
11185
|
const isAnchorInRange = cell.isAnchor && cell.isInSelection;
|
|
11062
11186
|
const navVersion = cell.navigationVersion;
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
},
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
if (state === "editing") return;
|
|
11074
|
-
if (e.shiftKey) cell.selectTo();
|
|
11075
|
-
else cell.focus();
|
|
11076
|
-
}, [state, cell]);
|
|
11187
|
+
const isActive = state === "focused" || state === "editing" || state === "readonlyFocused" || isAnchorInRange;
|
|
11188
|
+
const deferredEdit = useDeferredMenuEdit(onStartEdit ?? onDoubleClick);
|
|
11189
|
+
const { menuAnchor, menuOpen, openContextMenuAt, handleMenuClose, menuCloseRef } = useCellContextMenu(cell, cellRef, deferredEdit);
|
|
11190
|
+
useCellFocus(cellRef, state, isAnchorInRange, navVersion);
|
|
11191
|
+
const { handleKeyDown, handleDoubleClick } = useCellKeyboard(cell, state, isAnchorInRange, menuOpen, menuCloseRef, {
|
|
11192
|
+
onStartEdit,
|
|
11193
|
+
onDoubleClick,
|
|
11194
|
+
onTypeChar,
|
|
11195
|
+
onDelete
|
|
11196
|
+
});
|
|
11077
11197
|
const handleMouseDown = (0, react.useCallback)((e) => {
|
|
11078
11198
|
if (e.detail === 2 && state !== "readonly" && state !== "readonlyFocused") e.preventDefault();
|
|
11199
|
+
if (e.button === 2) {
|
|
11200
|
+
openContextMenuAt(e.clientX, e.clientY);
|
|
11201
|
+
return;
|
|
11202
|
+
}
|
|
11079
11203
|
if (!e.shiftKey && e.button === 0 && state !== "editing") {
|
|
11080
11204
|
e.preventDefault();
|
|
11081
11205
|
cell.dragStart();
|
|
11082
11206
|
cellRef.current?.focus();
|
|
11083
11207
|
}
|
|
11084
|
-
}, [state, cell]);
|
|
11085
|
-
const handleMouseEnter = (0, react.useCallback)((e) => {
|
|
11086
|
-
if (e.buttons === 1) cell.dragExtend();
|
|
11087
|
-
}, [cell]);
|
|
11088
|
-
const handleDoubleClick = (0, react.useCallback)((e) => {
|
|
11089
|
-
if (state === "readonly" || state === "readonlyFocused") {
|
|
11090
|
-
cell.notifyReadonlyEditAttempt();
|
|
11091
|
-
return;
|
|
11092
|
-
}
|
|
11093
|
-
onDoubleClick?.(e.clientX);
|
|
11094
11208
|
}, [
|
|
11095
11209
|
state,
|
|
11096
11210
|
cell,
|
|
11097
|
-
|
|
11211
|
+
openContextMenuAt
|
|
11098
11212
|
]);
|
|
11099
|
-
const
|
|
11100
|
-
if (
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
if (isMod && e.key === "v") return;
|
|
11108
|
-
if (e.key === "Escape") {
|
|
11109
|
-
e.preventDefault();
|
|
11110
|
-
if (cell.hasRangeSelection) cell.focus();
|
|
11111
|
-
else cell.blur();
|
|
11112
|
-
} else if (e.key === "ArrowUp") handleArrowKey(cell, e, cell.shiftMoveUp, cell.moveUp);
|
|
11113
|
-
else if (e.key === "ArrowDown") handleArrowKey(cell, e, cell.shiftMoveDown, cell.moveDown);
|
|
11114
|
-
else if (e.key === "ArrowLeft") handleArrowKey(cell, e, cell.shiftMoveLeft, cell.moveLeft);
|
|
11115
|
-
else if (e.key === "ArrowRight") handleArrowKey(cell, e, cell.shiftMoveRight, cell.moveRight);
|
|
11116
|
-
else if (e.key === "Tab") {
|
|
11117
|
-
e.preventDefault();
|
|
11118
|
-
cell.handleTab(e.shiftKey);
|
|
11119
|
-
} else handleEditableKeys(cell, e, onStartEdit, onDoubleClick, onTypeChar, onDelete);
|
|
11120
|
-
}, [
|
|
11121
|
-
state,
|
|
11122
|
-
cell,
|
|
11123
|
-
isAnchorInRange,
|
|
11124
|
-
onStartEdit,
|
|
11125
|
-
onDoubleClick,
|
|
11126
|
-
onTypeChar,
|
|
11127
|
-
onDelete
|
|
11128
|
-
]);
|
|
11129
|
-
const selectionShadow = selectionEdges ? buildSelectionBoxShadow(selectionEdges) : null;
|
|
11130
|
-
const needsFocus = state === "focused" || state === "editing" || state === "readonlyFocused" || isAnchorInRange;
|
|
11213
|
+
const handleClick = (0, react.useCallback)((e) => {
|
|
11214
|
+
if (state === "editing") return;
|
|
11215
|
+
if (e.shiftKey) cell.selectTo();
|
|
11216
|
+
else cell.focus();
|
|
11217
|
+
}, [state, cell]);
|
|
11218
|
+
const handleMouseEnter = (0, react.useCallback)((e) => {
|
|
11219
|
+
if (e.buttons === 1) cell.dragExtend();
|
|
11220
|
+
}, [cell]);
|
|
11131
11221
|
const handleBlur = (0, react.useCallback)((e) => {
|
|
11132
11222
|
if (!cell.isFocused || cell.isEditing) return;
|
|
11133
|
-
if (
|
|
11223
|
+
if (menuOpen) return;
|
|
11134
11224
|
if (e.relatedTarget?.closest("[data-testid^=\"cell-\"]")) return;
|
|
11135
11225
|
cell.blur();
|
|
11136
|
-
}, [cell]);
|
|
11137
|
-
const
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
|
|
11151
|
-
|
|
11152
|
-
|
|
11153
|
-
|
|
11154
|
-
|
|
11155
|
-
|
|
11156
|
-
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Menu.ContextTrigger, {
|
|
11165
|
-
asChild: true,
|
|
11166
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Box, {
|
|
11167
|
-
ref: cellRef,
|
|
11168
|
-
height: "40px",
|
|
11169
|
-
px: "8px",
|
|
11170
|
-
position: "relative",
|
|
11171
|
-
overflow: "hidden",
|
|
11172
|
-
onClick: handleClick,
|
|
11173
|
-
onMouseDown: handleMouseDown,
|
|
11174
|
-
onMouseEnter: handleMouseEnter,
|
|
11175
|
-
onDoubleClick: handleDoubleClick,
|
|
11176
|
-
onKeyDown: handleKeyDown,
|
|
11177
|
-
onBlur: handleBlur,
|
|
11178
|
-
onContextMenu: handleContextMenu,
|
|
11179
|
-
tabIndex: needsFocus ? 0 : -1,
|
|
11180
|
-
userSelect: state === "selected" ? "none" : void 0,
|
|
11181
|
-
"data-testid": `cell-${cell.rowId}-${cell.field}`,
|
|
11182
|
-
...stateStyles[state],
|
|
11183
|
-
...extraStyles,
|
|
11184
|
-
boxShadow: selectionShadow || void 0,
|
|
11185
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Box, {
|
|
11186
|
-
display: "flex",
|
|
11187
|
-
alignItems: "center",
|
|
11188
|
-
height: "100%",
|
|
11189
|
-
width: "100%",
|
|
11190
|
-
minWidth: 0,
|
|
11191
|
-
overflow: "hidden",
|
|
11192
|
-
children
|
|
11193
|
-
})
|
|
11194
|
-
})
|
|
11195
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CellContextMenu, {
|
|
11196
|
-
cell,
|
|
11197
|
-
onEditPointerDown: deferredEdit.requestEdit
|
|
11198
|
-
})]
|
|
11199
|
-
});
|
|
11226
|
+
}, [cell, menuOpen]);
|
|
11227
|
+
const selectionShadow = selectionEdges ? buildSelectionBoxShadow(selectionEdges) : null;
|
|
11228
|
+
let className = STATE_CLASS[state];
|
|
11229
|
+
if (isAnchorInRange) className += ` ${CLS_ANCHOR}`;
|
|
11230
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11231
|
+
ref: cellRef,
|
|
11232
|
+
className,
|
|
11233
|
+
style: selectionShadow ? { "--cw-shadow": selectionShadow } : void 0,
|
|
11234
|
+
tabIndex: isActive ? 0 : -1,
|
|
11235
|
+
onClick: handleClick,
|
|
11236
|
+
onMouseDown: handleMouseDown,
|
|
11237
|
+
onMouseEnter: handleMouseEnter,
|
|
11238
|
+
onDoubleClick: isActive ? handleDoubleClick : void 0,
|
|
11239
|
+
onKeyDown: isActive ? handleKeyDown : void 0,
|
|
11240
|
+
onBlur: isActive ? handleBlur : void 0,
|
|
11241
|
+
onContextMenu: preventContextMenu,
|
|
11242
|
+
"data-testid": `cell-${cell.rowId}-${cell.field}`,
|
|
11243
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11244
|
+
style: INNER_STYLE,
|
|
11245
|
+
children
|
|
11246
|
+
})
|
|
11247
|
+
}), menuOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyContextMenu, {
|
|
11248
|
+
cell,
|
|
11249
|
+
cellRef,
|
|
11250
|
+
anchorRect: menuAnchor,
|
|
11251
|
+
onClose: handleMenuClose,
|
|
11252
|
+
onEditPointerDown: deferredEdit.requestEdit
|
|
11253
|
+
})] });
|
|
11200
11254
|
});
|
|
11255
|
+
function preventContextMenu(e) {
|
|
11256
|
+
e.preventDefault();
|
|
11257
|
+
}
|
|
11201
11258
|
|
|
11202
11259
|
//#endregion
|
|
11203
11260
|
//#region src/table-editor/Table/ui/Cell/useTextareaCell.ts
|
|
@@ -11830,6 +11887,30 @@ function clearRange(range, rows, cols) {
|
|
|
11830
11887
|
}
|
|
11831
11888
|
}
|
|
11832
11889
|
|
|
11890
|
+
//#endregion
|
|
11891
|
+
//#region src/table-editor/Table/ui/borderConstants.ts
|
|
11892
|
+
const CELL_BORDER_COLOR = "#ededed";
|
|
11893
|
+
const BOTTOM_BORDER_SHADOW = `inset 0 -1px 0 0 ${CELL_BORDER_COLOR}`;
|
|
11894
|
+
function buildAddColumnShadowCss() {
|
|
11895
|
+
return { "&::after": {
|
|
11896
|
+
content: "\"\"",
|
|
11897
|
+
position: "absolute",
|
|
11898
|
+
top: 0,
|
|
11899
|
+
bottom: 0,
|
|
11900
|
+
width: "8px",
|
|
11901
|
+
left: "-8px",
|
|
11902
|
+
pointerEvents: "none",
|
|
11903
|
+
transition: "opacity 0.15s",
|
|
11904
|
+
opacity: "var(--shadow-right-opacity, 0)",
|
|
11905
|
+
boxShadow: "inset -8px 0 12px -8px rgba(0,0,0,0.1)"
|
|
11906
|
+
} };
|
|
11907
|
+
}
|
|
11908
|
+
function adjustRightOffsetCss(rightCss, addColOffset) {
|
|
11909
|
+
if (addColOffset <= 0) return rightCss;
|
|
11910
|
+
if (rightCss === "0px") return `${addColOffset}px`;
|
|
11911
|
+
return `calc(${rightCss} + ${addColOffset}px)`;
|
|
11912
|
+
}
|
|
11913
|
+
|
|
11833
11914
|
//#endregion
|
|
11834
11915
|
//#region src/table-editor/Table/ui/ResizeHandle.tsx
|
|
11835
11916
|
const MIN_COLUMN_WIDTH = 40;
|
|
@@ -13018,12 +13099,20 @@ const TableWidget = (0, mobx_react_lite.observer)(({ rows, columnsModel, cellFSM
|
|
|
13018
13099
|
if (isResizing) shadowModel.pause();
|
|
13019
13100
|
else shadowModel.resume();
|
|
13020
13101
|
}, [isResizing, shadowModel]);
|
|
13102
|
+
const [wrapperEl, setWrapperEl] = (0, react.useState)(null);
|
|
13021
13103
|
const wrapperRefCallback = (0, react.useCallback)((el) => {
|
|
13104
|
+
setWrapperEl(el);
|
|
13022
13105
|
columnsModel.setWrapperElement(el);
|
|
13023
|
-
|
|
13106
|
+
}, [columnsModel]);
|
|
13107
|
+
(0, react.useEffect)(() => {
|
|
13108
|
+
if (!useWindowScrollProp || !wrapperEl) return;
|
|
13109
|
+
setScrollerRef(wrapperEl);
|
|
13110
|
+
return () => {
|
|
13111
|
+
setScrollerRef(null);
|
|
13112
|
+
};
|
|
13024
13113
|
}, [
|
|
13025
|
-
columnsModel,
|
|
13026
13114
|
useWindowScrollProp,
|
|
13115
|
+
wrapperEl,
|
|
13027
13116
|
setScrollerRef
|
|
13028
13117
|
]);
|
|
13029
13118
|
const handleSelectRow = (0, react.useCallback)((rowId) => {
|