@blocklet/editor 2.2.47 → 2.3.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/lib/ext/PostLinkEmbedPlugin/PostLinkNode.d.ts +2 -2
- package/lib/ext/PostLinkEmbedPlugin/PostLinkNode.js +3 -3
- package/lib/main/editor.js +3 -7
- package/lib/main/index.css +16 -18
- package/lib/main/markdown-editor/editor.js +1 -1
- package/lib/main/markdown-editor/transformers.js +7 -6
- package/lib/main/nodes/EmojiNode.d.ts +1 -2
- package/lib/main/nodes/EmojiNode.js +4 -9
- package/lib/main/nodes/EquationNode.js +14 -7
- package/lib/main/nodes/ImageComponent.js +2 -2
- package/lib/main/nodes/PlaygroundNodes.js +0 -2
- package/lib/main/nodes/StickyComponent.js +1 -1
- package/lib/main/plugins/CodeActionMenuPlugin/index.js +24 -28
- package/lib/main/plugins/MarkdownTransformers/index.d.ts +1 -4
- package/lib/main/plugins/MarkdownTransformers/index.js +48 -79
- package/lib/main/plugins/TableActionMenuPlugin/index.js +229 -171
- package/lib/main/plugins/TableCellResizer/index.css +8 -2
- package/lib/main/plugins/TableCellResizer/index.js +168 -120
- package/lib/main/plugins/TableOfContentsPlugin/index.js +2 -2
- package/lib/main/plugins/TablePlugin.d.ts +3 -4
- package/lib/main/plugins/TablePlugin.js +7 -24
- package/lib/main/plugins/ToolbarPlugin/index.js +0 -1
- package/lib/main/themes/defaultTheme.js +3 -1
- package/lib/main/ui/ContentEditable.d.ts +1 -4
- package/lib/main/ui/Modal.css +1 -1
- package/lib/main/ui/TextInput.d.ts +4 -3
- package/lib/main/ui/TextInput.js +3 -19
- package/package.json +23 -24
- package/lib/main/nodes/AutocompleteNode.d.ts +0 -34
- package/lib/main/nodes/AutocompleteNode.js +0 -52
- package/lib/main/nodes/EquationComponent.d.ts +0 -16
- package/lib/main/nodes/EquationComponent.js +0 -64
- package/lib/main/plugins/ActionsPlugin/index.d.ts +0 -11
- package/lib/main/plugins/ActionsPlugin/index.js +0 -129
- package/lib/main/plugins/AutocompletePlugin/index.d.ts +0 -10
- package/lib/main/plugins/AutocompletePlugin/index.js +0 -2461
- package/lib/main/plugins/CodeActionMenuPlugin/components/PrettierButton/index.css +0 -14
- package/lib/main/plugins/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +0 -17
- package/lib/main/plugins/CodeActionMenuPlugin/components/PrettierButton/index.js +0 -95
- package/lib/main/plugins/EquationsPlugin/index.d.ts +0 -21
- package/lib/main/plugins/EquationsPlugin/index.js +0 -42
- package/lib/main/plugins/SpeechToTextPlugin/index.d.ts +0 -12
- package/lib/main/plugins/SpeechToTextPlugin/index.js +0 -87
- package/lib/main/ui/EquationEditor.css +0 -38
- package/lib/main/ui/EquationEditor.d.ts +0 -19
- package/lib/main/ui/EquationEditor.js +0 -26
- package/lib/main/ui/KatexEquationAlterer.css +0 -41
- package/lib/main/ui/KatexEquationAlterer.d.ts +0 -15
- package/lib/main/ui/KatexEquationAlterer.js +0 -34
- package/lib/main/ui/KatexRenderer.d.ts +0 -13
- package/lib/main/ui/KatexRenderer.js +0 -33
|
@@ -1,93 +1,125 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import './index.css';
|
|
3
3
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
-
import useLexicalEditable from '@lexical/react/useLexicalEditable';
|
|
5
|
-
import { $
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
|
|
5
|
+
import { $computeTableMapSkipCellCheck, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $isTableCellNode, $isTableRowNode, getDOMCellFromTarget, getTableElement, TableNode, } from '@lexical/table';
|
|
6
|
+
import { calculateZoomLevel, mergeRegister } from '@lexical/utils';
|
|
7
|
+
import { $getNearestNodeFromDOMNode, isHTMLElement } from 'lexical';
|
|
8
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
8
9
|
import { createPortal } from 'react-dom';
|
|
9
10
|
const MIN_ROW_HEIGHT = 33;
|
|
10
|
-
const MIN_COLUMN_WIDTH =
|
|
11
|
+
const MIN_COLUMN_WIDTH = 92;
|
|
11
12
|
function TableCellResizer({ editor }) {
|
|
12
13
|
const targetRef = useRef(null);
|
|
13
14
|
const resizerRef = useRef(null);
|
|
14
15
|
const tableRectRef = useRef(null);
|
|
15
|
-
const
|
|
16
|
-
const
|
|
16
|
+
const [hasTable, setHasTable] = useState(false);
|
|
17
|
+
const pointerStartPosRef = useRef(null);
|
|
18
|
+
const [pointerCurrentPos, updatePointerCurrentPos] = useState(null);
|
|
17
19
|
const [activeCell, updateActiveCell] = useState(null);
|
|
18
|
-
const [isSelectingGrid, updateIsSelectingGrid] = useState(false);
|
|
19
20
|
const [draggingDirection, updateDraggingDirection] = useState(null);
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
return editor.registerCommand(SELECTION_CHANGE_COMMAND, (payload) => {
|
|
22
|
-
const selection = $getSelection();
|
|
23
|
-
const isTableSelection = $isTableSelection(selection);
|
|
24
|
-
if (isSelectingGrid !== isTableSelection) {
|
|
25
|
-
updateIsSelectingGrid(isTableSelection);
|
|
26
|
-
}
|
|
27
|
-
return false;
|
|
28
|
-
}, COMMAND_PRIORITY_HIGH);
|
|
29
|
-
});
|
|
30
21
|
const resetState = useCallback(() => {
|
|
31
22
|
updateActiveCell(null);
|
|
32
23
|
targetRef.current = null;
|
|
33
24
|
updateDraggingDirection(null);
|
|
34
|
-
|
|
25
|
+
pointerStartPosRef.current = null;
|
|
35
26
|
tableRectRef.current = null;
|
|
36
27
|
}, []);
|
|
37
28
|
useEffect(() => {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
x: event.clientX,
|
|
44
|
-
y: event.clientY,
|
|
45
|
-
});
|
|
46
|
-
return;
|
|
29
|
+
const tableKeys = new Set();
|
|
30
|
+
return mergeRegister(editor.registerMutationListener(TableNode, (nodeMutations) => {
|
|
31
|
+
for (const [nodeKey, mutation] of nodeMutations) {
|
|
32
|
+
if (mutation === 'destroyed') {
|
|
33
|
+
tableKeys.delete(nodeKey);
|
|
47
34
|
}
|
|
48
|
-
|
|
49
|
-
|
|
35
|
+
else {
|
|
36
|
+
tableKeys.add(nodeKey);
|
|
50
37
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
38
|
+
}
|
|
39
|
+
setHasTable(tableKeys.size > 0);
|
|
40
|
+
}), editor.registerNodeTransform(TableNode, (tableNode) => {
|
|
41
|
+
if (tableNode.getColWidths()) {
|
|
42
|
+
return tableNode;
|
|
43
|
+
}
|
|
44
|
+
const numColumns = tableNode.getColumnCount();
|
|
45
|
+
const columnWidth = MIN_COLUMN_WIDTH;
|
|
46
|
+
tableNode.setColWidths(Array(numColumns).fill(columnWidth));
|
|
47
|
+
return tableNode;
|
|
48
|
+
}));
|
|
49
|
+
}, [editor]);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!hasTable) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const onPointerMove = (event) => {
|
|
55
|
+
const { target } = event;
|
|
56
|
+
if (!isHTMLElement(target)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (draggingDirection) {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
event.stopPropagation();
|
|
62
|
+
updatePointerCurrentPos({
|
|
63
|
+
x: event.clientX,
|
|
64
|
+
y: event.clientY,
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (resizerRef.current && resizerRef.current.contains(target)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (targetRef.current !== target) {
|
|
72
|
+
targetRef.current = target;
|
|
73
|
+
const cell = getDOMCellFromTarget(target);
|
|
74
|
+
if (cell && activeCell !== cell) {
|
|
75
|
+
editor.getEditorState().read(() => {
|
|
76
|
+
const tableCellNode = $getNearestNodeFromDOMNode(cell.elem);
|
|
77
|
+
if (!tableCellNode) {
|
|
78
|
+
throw new Error('TableCellResizer: Table cell node not found.');
|
|
79
|
+
}
|
|
80
|
+
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
81
|
+
const tableElement = getTableElement(tableNode, editor.getElementByKey(tableNode.getKey()));
|
|
82
|
+
if (!tableElement) {
|
|
83
|
+
throw new Error('TableCellResizer: Table element not found.');
|
|
84
|
+
}
|
|
85
|
+
targetRef.current = target;
|
|
86
|
+
tableRectRef.current = tableElement.getBoundingClientRect();
|
|
87
|
+
updateActiveCell(cell);
|
|
88
|
+
}, { editor });
|
|
77
89
|
}
|
|
78
|
-
|
|
90
|
+
else if (cell == null) {
|
|
91
|
+
resetState();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
79
94
|
};
|
|
80
|
-
|
|
95
|
+
const onPointerDown = (event) => {
|
|
96
|
+
const isTouchEvent = event.pointerType === 'touch';
|
|
97
|
+
if (isTouchEvent) {
|
|
98
|
+
onPointerMove(event);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const resizerContainer = resizerRef.current;
|
|
102
|
+
resizerContainer?.addEventListener('pointermove', onPointerMove, {
|
|
103
|
+
capture: true,
|
|
104
|
+
});
|
|
105
|
+
const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => {
|
|
106
|
+
prevRootElement?.removeEventListener('pointermove', onPointerMove);
|
|
107
|
+
prevRootElement?.removeEventListener('pointerdown', onPointerDown);
|
|
108
|
+
rootElement?.addEventListener('pointermove', onPointerMove);
|
|
109
|
+
rootElement?.addEventListener('pointerdown', onPointerDown);
|
|
110
|
+
});
|
|
81
111
|
return () => {
|
|
82
|
-
|
|
112
|
+
removeRootListener();
|
|
113
|
+
resizerContainer?.removeEventListener('pointermove', onPointerMove);
|
|
83
114
|
};
|
|
84
|
-
}, [activeCell, draggingDirection, editor, resetState]);
|
|
115
|
+
}, [activeCell, draggingDirection, editor, resetState, hasTable]);
|
|
85
116
|
const isHeightChanging = (direction) => {
|
|
86
|
-
if (direction === 'bottom')
|
|
117
|
+
if (direction === 'bottom') {
|
|
87
118
|
return true;
|
|
119
|
+
}
|
|
88
120
|
return false;
|
|
89
121
|
};
|
|
90
|
-
const updateRowHeight = useCallback((
|
|
122
|
+
const updateRowHeight = useCallback((heightChange) => {
|
|
91
123
|
if (!activeCell) {
|
|
92
124
|
throw new Error('TableCellResizer: Expected active cell.');
|
|
93
125
|
}
|
|
@@ -97,8 +129,12 @@ function TableCellResizer({ editor }) {
|
|
|
97
129
|
throw new Error('TableCellResizer: Table cell node not found.');
|
|
98
130
|
}
|
|
99
131
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
100
|
-
const
|
|
132
|
+
const baseRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
|
|
101
133
|
const tableRows = tableNode.getChildren();
|
|
134
|
+
// Determine if this is a full row merge by checking colspan
|
|
135
|
+
const isFullRowMerge = tableCellNode.getColSpan() === tableNode.getColumnCount();
|
|
136
|
+
// For full row merges, apply to first row. For partial merges, apply to last row
|
|
137
|
+
const tableRowIndex = isFullRowMerge ? baseRowIndex : baseRowIndex + tableCellNode.getRowSpan() - 1;
|
|
102
138
|
if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
|
|
103
139
|
throw new Error('Expected table cell to be inside of table row.');
|
|
104
140
|
}
|
|
@@ -106,10 +142,29 @@ function TableCellResizer({ editor }) {
|
|
|
106
142
|
if (!$isTableRowNode(tableRow)) {
|
|
107
143
|
throw new Error('Expected table row');
|
|
108
144
|
}
|
|
145
|
+
let height = tableRow.getHeight();
|
|
146
|
+
if (height === undefined) {
|
|
147
|
+
const rowCells = tableRow.getChildren();
|
|
148
|
+
height = Math.min(...rowCells.map((cell) => getCellNodeHeight(cell, editor) ?? Infinity));
|
|
149
|
+
}
|
|
150
|
+
const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
|
|
109
151
|
tableRow.setHeight(newHeight);
|
|
110
|
-
});
|
|
152
|
+
}, { tag: 'skip-scroll-into-view' });
|
|
111
153
|
}, [activeCell, editor]);
|
|
112
|
-
const
|
|
154
|
+
const getCellNodeHeight = (cell, activeEditor) => {
|
|
155
|
+
const domCellNode = activeEditor.getElementByKey(cell.getKey());
|
|
156
|
+
return domCellNode?.clientHeight;
|
|
157
|
+
};
|
|
158
|
+
const getCellColumnIndex = (tableCellNode, tableMap) => {
|
|
159
|
+
for (let row = 0; row < tableMap.length; row++) {
|
|
160
|
+
for (let column = 0; column < tableMap[row].length; column++) {
|
|
161
|
+
if (tableMap[row][column].cell === tableCellNode) {
|
|
162
|
+
return column;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const updateColumnWidth = useCallback((widthChange) => {
|
|
113
168
|
if (!activeCell) {
|
|
114
169
|
throw new Error('TableCellResizer: Expected active cell.');
|
|
115
170
|
}
|
|
@@ -119,60 +174,48 @@ function TableCellResizer({ editor }) {
|
|
|
119
174
|
throw new Error('TableCellResizer: Table cell node not found.');
|
|
120
175
|
}
|
|
121
176
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!$isTableRowNode(tableRow)) {
|
|
127
|
-
throw new Error('Expected table row');
|
|
128
|
-
}
|
|
129
|
-
const rowCells = tableRow.getChildren();
|
|
130
|
-
const rowCellsSpan = rowCells.map((cell) => cell.getColSpan());
|
|
131
|
-
const aggregatedRowSpans = rowCellsSpan.reduce((rowSpans, cellSpan) => {
|
|
132
|
-
const previousCell = rowSpans[rowSpans.length - 1] ?? 0;
|
|
133
|
-
rowSpans.push(previousCell + cellSpan);
|
|
134
|
-
return rowSpans;
|
|
135
|
-
}, []);
|
|
136
|
-
const rowColumnIndexWithSpan = aggregatedRowSpans.findIndex((cellSpan) => cellSpan > tableColumnIndex);
|
|
137
|
-
if (rowColumnIndexWithSpan >= rowCells.length || rowColumnIndexWithSpan < 0) {
|
|
138
|
-
throw new Error('Expected table cell to be inside of table row.');
|
|
139
|
-
}
|
|
140
|
-
const tableCell = rowCells[rowColumnIndexWithSpan];
|
|
141
|
-
if (!$isTableCellNode(tableCell)) {
|
|
142
|
-
throw new Error('Expected table cell');
|
|
143
|
-
}
|
|
144
|
-
tableCell.setWidth(newWidth);
|
|
177
|
+
const [tableMap] = $computeTableMapSkipCellCheck(tableNode, null, null);
|
|
178
|
+
const columnIndex = getCellColumnIndex(tableCellNode, tableMap);
|
|
179
|
+
if (columnIndex === undefined) {
|
|
180
|
+
throw new Error('TableCellResizer: Table column not found.');
|
|
145
181
|
}
|
|
146
|
-
|
|
182
|
+
const colWidths = tableNode.getColWidths();
|
|
183
|
+
if (!colWidths) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const width = colWidths[columnIndex];
|
|
187
|
+
if (width === undefined) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const newColWidths = [...colWidths];
|
|
191
|
+
const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
|
|
192
|
+
newColWidths[columnIndex] = newWidth;
|
|
193
|
+
tableNode.setColWidths(newColWidths);
|
|
194
|
+
}, { tag: 'skip-scroll-into-view' });
|
|
147
195
|
}, [activeCell, editor]);
|
|
148
|
-
const
|
|
196
|
+
const pointerUpHandler = useCallback((direction) => {
|
|
149
197
|
const handler = (event) => {
|
|
150
198
|
event.preventDefault();
|
|
151
199
|
event.stopPropagation();
|
|
152
200
|
if (!activeCell) {
|
|
153
201
|
throw new Error('TableCellResizer: Expected active cell.');
|
|
154
202
|
}
|
|
155
|
-
if (
|
|
156
|
-
const { x, y } =
|
|
203
|
+
if (pointerStartPosRef.current) {
|
|
204
|
+
const { x, y } = pointerStartPosRef.current;
|
|
157
205
|
if (activeCell === null) {
|
|
158
206
|
return;
|
|
159
207
|
}
|
|
208
|
+
const zoom = calculateZoomLevel(event.target);
|
|
160
209
|
if (isHeightChanging(direction)) {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
const isShrinking = direction === 'bottom' && y > event.clientY;
|
|
164
|
-
updateRowHeight(Math.max(isShrinking ? height - heightChange : heightChange + height, MIN_ROW_HEIGHT));
|
|
210
|
+
const heightChange = (event.clientY - y) / zoom;
|
|
211
|
+
updateRowHeight(heightChange);
|
|
165
212
|
}
|
|
166
213
|
else {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
width -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
|
|
170
|
-
const widthChange = Math.abs(event.clientX - x);
|
|
171
|
-
const isShrinking = direction === 'right' && x > event.clientX;
|
|
172
|
-
updateColumnWidth(Math.max(isShrinking ? width - widthChange : widthChange + width, MIN_COLUMN_WIDTH));
|
|
214
|
+
const widthChange = (event.clientX - x) / zoom;
|
|
215
|
+
updateColumnWidth(widthChange);
|
|
173
216
|
}
|
|
174
217
|
resetState();
|
|
175
|
-
document.removeEventListener('
|
|
218
|
+
document.removeEventListener('pointerup', handler);
|
|
176
219
|
}
|
|
177
220
|
};
|
|
178
221
|
return handler;
|
|
@@ -183,50 +226,55 @@ function TableCellResizer({ editor }) {
|
|
|
183
226
|
if (!activeCell) {
|
|
184
227
|
throw new Error('TableCellResizer: Expected active cell.');
|
|
185
228
|
}
|
|
186
|
-
|
|
229
|
+
pointerStartPosRef.current = {
|
|
187
230
|
x: event.clientX,
|
|
188
231
|
y: event.clientY,
|
|
189
232
|
};
|
|
190
|
-
|
|
233
|
+
updatePointerCurrentPos(pointerStartPosRef.current);
|
|
191
234
|
updateDraggingDirection(direction);
|
|
192
|
-
document.addEventListener('
|
|
193
|
-
}, [activeCell,
|
|
235
|
+
document.addEventListener('pointerup', pointerUpHandler(direction));
|
|
236
|
+
}, [activeCell, pointerUpHandler]);
|
|
194
237
|
const getResizers = useCallback(() => {
|
|
195
238
|
if (activeCell) {
|
|
196
239
|
const { height, width, top, left } = activeCell.elem.getBoundingClientRect();
|
|
240
|
+
const zoom = calculateZoomLevel(activeCell.elem);
|
|
241
|
+
const zoneWidth = 16; // Pixel width of the zone where you can drag the edge
|
|
197
242
|
const styles = {
|
|
198
243
|
bottom: {
|
|
199
244
|
backgroundColor: 'none',
|
|
200
245
|
cursor: 'row-resize',
|
|
201
|
-
height:
|
|
202
|
-
left: `${window.
|
|
203
|
-
top: `${window.
|
|
246
|
+
height: `${zoneWidth}px`,
|
|
247
|
+
left: `${window.scrollX + left}px`,
|
|
248
|
+
top: `${window.scrollY + top + height - zoneWidth / 2}px`,
|
|
249
|
+
zIndex: 1,
|
|
204
250
|
width: `${width}px`,
|
|
205
251
|
},
|
|
206
252
|
right: {
|
|
207
253
|
backgroundColor: 'none',
|
|
208
254
|
cursor: 'col-resize',
|
|
209
255
|
height: `${height}px`,
|
|
210
|
-
left: `${window.
|
|
211
|
-
top: `${window.
|
|
212
|
-
|
|
256
|
+
left: `${window.scrollX + left + width - zoneWidth / 2}px`,
|
|
257
|
+
top: `${window.scrollY + top}px`,
|
|
258
|
+
zIndex: 1,
|
|
259
|
+
width: `${zoneWidth}px`,
|
|
213
260
|
},
|
|
214
261
|
};
|
|
215
262
|
const tableRect = tableRectRef.current;
|
|
216
|
-
if (draggingDirection &&
|
|
263
|
+
if (draggingDirection && pointerCurrentPos && tableRect) {
|
|
217
264
|
if (isHeightChanging(draggingDirection)) {
|
|
218
|
-
styles[draggingDirection].left = `${window.
|
|
219
|
-
styles[draggingDirection].top = `${window.
|
|
265
|
+
styles[draggingDirection].left = `${window.scrollX + tableRect.left}px`;
|
|
266
|
+
styles[draggingDirection].top = `${window.scrollY + pointerCurrentPos.y / zoom}px`;
|
|
220
267
|
styles[draggingDirection].height = '3px';
|
|
221
268
|
styles[draggingDirection].width = `${tableRect.width}px`;
|
|
222
269
|
}
|
|
223
270
|
else {
|
|
224
|
-
styles[draggingDirection].top = `${window.
|
|
225
|
-
styles[draggingDirection].left = `${window.
|
|
271
|
+
styles[draggingDirection].top = `${window.scrollY + tableRect.top}px`;
|
|
272
|
+
styles[draggingDirection].left = `${window.scrollX + pointerCurrentPos.x / zoom}px`;
|
|
226
273
|
styles[draggingDirection].width = '3px';
|
|
227
274
|
styles[draggingDirection].height = `${tableRect.height}px`;
|
|
228
275
|
}
|
|
229
276
|
styles[draggingDirection].backgroundColor = '#adf';
|
|
277
|
+
styles[draggingDirection].mixBlendMode = 'unset';
|
|
230
278
|
}
|
|
231
279
|
return styles;
|
|
232
280
|
}
|
|
@@ -236,9 +284,9 @@ function TableCellResizer({ editor }) {
|
|
|
236
284
|
right: null,
|
|
237
285
|
top: null,
|
|
238
286
|
};
|
|
239
|
-
}, [activeCell, draggingDirection,
|
|
287
|
+
}, [activeCell, draggingDirection, pointerCurrentPos]);
|
|
240
288
|
const resizerStyles = getResizers();
|
|
241
|
-
return (_jsx("div", { ref: resizerRef, children: activeCell != null &&
|
|
289
|
+
return (_jsx("div", { ref: resizerRef, children: activeCell != null && (_jsxs(_Fragment, { children: [_jsx("div", { className: "TableCellResizer__resizer TableCellResizer__ui", style: resizerStyles.right || undefined, onPointerDown: toggleResize('right') }), _jsx("div", { className: "TableCellResizer__resizer TableCellResizer__ui", style: resizerStyles.bottom || undefined, onPointerDown: toggleResize('bottom') })] })) }));
|
|
242
290
|
}
|
|
243
291
|
export default function TableCellResizerPlugin() {
|
|
244
292
|
const [editor] = useLexicalComposerContext();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import './index.css';
|
|
3
3
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
-
import
|
|
4
|
+
import { TableOfContentsPlugin as LexicalTableOfContentsPlugin } from '@lexical/react/LexicalTableOfContentsPlugin';
|
|
5
5
|
import { useEffect, useRef, useState } from 'react';
|
|
6
6
|
const MARGIN_ABOVE_EDITOR = 624;
|
|
7
7
|
const HEADING_WIDTH = 9;
|
|
@@ -100,7 +100,7 @@ function TableOfContentsList({ tableOfContents }) {
|
|
|
100
100
|
}) }) }));
|
|
101
101
|
}
|
|
102
102
|
export default function TableOfContentsPlugin() {
|
|
103
|
-
return (_jsx(
|
|
103
|
+
return (_jsx(LexicalTableOfContentsPlugin, { children: (tableOfContents) => {
|
|
104
104
|
return _jsx(TableOfContentsList, { tableOfContents: tableOfContents });
|
|
105
105
|
} }));
|
|
106
106
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
8
|
+
import type { JSX } from 'react';
|
|
9
|
+
import { EditorThemeClasses, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
10
10
|
export type InsertTableCommandPayload = Readonly<{
|
|
11
11
|
columns: string;
|
|
12
12
|
rows: string;
|
|
@@ -24,8 +24,7 @@ export type CellEditorConfig = Readonly<{
|
|
|
24
24
|
readOnly?: boolean;
|
|
25
25
|
theme?: EditorThemeClasses;
|
|
26
26
|
}>;
|
|
27
|
-
export declare const
|
|
28
|
-
export declare const CellContext: React.Context<CellContextShape>;
|
|
27
|
+
export declare const CellContext: import("react").Context<CellContextShape>;
|
|
29
28
|
export declare function TableContext({ children }: {
|
|
30
29
|
children: JSX.Element;
|
|
31
30
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
2
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
10
|
-
import {
|
|
11
|
-
import { $insertNodes, COMMAND_PRIORITY_EDITOR, createCommand, } from 'lexical';
|
|
3
|
+
import { INSERT_TABLE_COMMAND, TableCellNode, TableNode, TableRowNode } from '@lexical/table';
|
|
12
4
|
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
|
13
|
-
import invariant from '../../shared/invariant';
|
|
14
5
|
import Button from '../ui/Button';
|
|
15
6
|
import { DialogActions } from '../ui/Dialog';
|
|
16
7
|
import TextInput from '../ui/TextInput';
|
|
17
|
-
export const INSERT_NEW_TABLE_COMMAND = createCommand('INSERT_NEW_TABLE_COMMAND');
|
|
18
8
|
export const CellContext = createContext({
|
|
19
9
|
cellEditorConfig: null,
|
|
20
10
|
cellEditorPlugins: null,
|
|
@@ -56,25 +46,18 @@ export function InsertTableDialog({ activeEditor, onClose, }) {
|
|
|
56
46
|
});
|
|
57
47
|
onClose();
|
|
58
48
|
};
|
|
59
|
-
return (_jsxs(_Fragment, { children: [_jsx(TextInput, { placeholder: "# of rows (1-500)", label: "Rows", onChange: setRows, value: rows, "data-test-id": "table-modal-rows",
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
type: "number" }), _jsx(TextInput, { placeholder: "# of columns (1-50)", label: "Columns", onChange: setColumns, value: columns, "data-test-id": "table-modal-columns",
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
type: "number" }), _jsx(DialogActions, { "data-test-id": "table-model-confirm-insert", children: _jsx(Button, { disabled: isDisabled, onClick: onClick, children: "Confirm" }) })] }));
|
|
49
|
+
return (_jsxs(_Fragment, { children: [_jsx(TextInput, { placeholder: "# of rows (1-500)", label: "Rows", onChange: setRows, value: rows, "data-test-id": "table-modal-rows", type: "number" }), _jsx(TextInput, { placeholder: "# of columns (1-50)", label: "Columns", onChange: setColumns, value: columns, "data-test-id": "table-modal-columns", type: "number" }), _jsx(DialogActions, { "data-test-id": "table-model-confirm-insert", children: _jsx(Button, { disabled: isDisabled, onClick: onClick, children: "Confirm" }) })] }));
|
|
64
50
|
}
|
|
65
51
|
export function TablePlugin({ cellEditorConfig, children, }) {
|
|
66
52
|
const [editor] = useLexicalComposerContext();
|
|
67
53
|
const cellContext = useContext(CellContext);
|
|
68
54
|
useEffect(() => {
|
|
69
|
-
if (!editor.hasNodes([TableNode])) {
|
|
70
|
-
|
|
55
|
+
if (!editor.hasNodes([TableNode, TableRowNode, TableCellNode])) {
|
|
56
|
+
throw new Error('TablePlugin: TableNode, TableRowNode, or TableCellNode is not registered on editor');
|
|
71
57
|
}
|
|
58
|
+
}, [editor]);
|
|
59
|
+
useEffect(() => {
|
|
72
60
|
cellContext.set(cellEditorConfig, children);
|
|
73
|
-
|
|
74
|
-
const tableNode = $createTableNodeWithDimensions(Number(rows), Number(columns), includeHeaders);
|
|
75
|
-
$insertNodes([tableNode]);
|
|
76
|
-
return true;
|
|
77
|
-
}, COMMAND_PRIORITY_EDITOR);
|
|
78
|
-
}, [cellContext, cellEditorConfig, children, editor]);
|
|
61
|
+
}, [cellContext, cellEditorConfig, children]);
|
|
79
62
|
return null;
|
|
80
63
|
}
|
|
@@ -22,7 +22,6 @@ import { getSelectedNode } from '../../utils/getSelectedNode';
|
|
|
22
22
|
import { sanitizeUrl } from '../../utils/sanitizeUrl';
|
|
23
23
|
// import { EmbedConfigs } from "../AutoEmbedPlugin";
|
|
24
24
|
// import { INSERT_COLLAPSIBLE_COMMAND } from "../CollapsiblePlugin";
|
|
25
|
-
// import { InsertEquationDialog } from "../EquationsPlugin";
|
|
26
25
|
// import { INSERT_EXCALIDRAW_COMMAND } from "../ExcalidrawPlugin";
|
|
27
26
|
import { INSERT_IMAGE_COMMAND } from '../ImagesPlugin';
|
|
28
27
|
import { uploadFile, INSERT_COMPONENT_COMMAND } from '../ComponentPickerPlugin';
|
|
@@ -143,7 +143,7 @@ const table = css `
|
|
|
143
143
|
border-collapse: collapse;
|
|
144
144
|
border-spacing: 0;
|
|
145
145
|
table-layout: fixed;
|
|
146
|
-
width:
|
|
146
|
+
width: fit-content;
|
|
147
147
|
|
|
148
148
|
p {
|
|
149
149
|
margin: 0;
|
|
@@ -157,6 +157,7 @@ const tableSelection = css `
|
|
|
157
157
|
const tableSelected = css `
|
|
158
158
|
outline: 2px solid rgb(60, 132, 244);
|
|
159
159
|
`;
|
|
160
|
+
const tableScrollableWrapper = css ``;
|
|
160
161
|
const tableCell = css `
|
|
161
162
|
border: 1px solid #bbb;
|
|
162
163
|
min-width: 75px;
|
|
@@ -676,6 +677,7 @@ const defaultTheme = {
|
|
|
676
677
|
tableCellSortedIndicator,
|
|
677
678
|
tableResizeRuler,
|
|
678
679
|
tableSelected,
|
|
680
|
+
tableScrollableWrapper,
|
|
679
681
|
characterLimit,
|
|
680
682
|
list: {
|
|
681
683
|
listitem: listItem,
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import React from 'react';
|
|
3
|
-
export interface ContentEditableProps extends React.ComponentProps<typeof LexicalContentEditable> {
|
|
4
|
-
}
|
|
1
|
+
import { ContentEditableProps } from '@lexical/react/LexicalContentEditable';
|
|
5
2
|
export default function ContentEditable(props: ContentEditableProps): import("react/jsx-runtime").JSX.Element;
|
package/lib/main/ui/Modal.css
CHANGED
|
@@ -5,15 +5,16 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
import type { JSX } from 'react';
|
|
9
9
|
import './Input.css';
|
|
10
|
+
import { HTMLInputTypeAttribute } from 'react';
|
|
10
11
|
type Props = Readonly<{
|
|
11
12
|
'data-test-id'?: string;
|
|
12
13
|
label: string;
|
|
13
14
|
onChange: (val: string) => void;
|
|
14
15
|
placeholder?: string;
|
|
15
16
|
value: string;
|
|
16
|
-
|
|
17
|
+
type?: HTMLInputTypeAttribute;
|
|
17
18
|
}>;
|
|
18
|
-
export default function TextInput({ label, value, onChange, placeholder, 'data-test-id': dataTestId,
|
|
19
|
+
export default function TextInput({ label, value, onChange, placeholder, 'data-test-id': dataTestId, type, }: Props): JSX.Element;
|
|
19
20
|
export {};
|
package/lib/main/ui/TextInput.js
CHANGED
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
|
-
import { useEffect, useRef } from 'react';
|
|
10
2
|
import './Input.css';
|
|
11
|
-
export default function TextInput({ label, value, onChange, placeholder = '', 'data-test-id': dataTestId,
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
if (autoFocus) {
|
|
15
|
-
setTimeout(() => {
|
|
16
|
-
input.current?.focus();
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}, [autoFocus]);
|
|
20
|
-
return (_jsxs("div", { className: "Input__wrapper", children: [_jsx("label", { className: "Input__label", children: label }), _jsx("input", { ref: input, type: "text", className: "Input__input", placeholder: placeholder, value: value, onChange: (e) => {
|
|
3
|
+
export default function TextInput({ label, value, onChange, placeholder = '', 'data-test-id': dataTestId, type = 'text', }) {
|
|
4
|
+
return (_jsxs("div", { className: "Input__wrapper", children: [_jsx("label", { className: "Input__label", children: label }), _jsx("input", { type: type, className: "Input__input", placeholder: placeholder, value: value, onChange: (e) => {
|
|
21
5
|
onChange(e.target.value);
|
|
22
|
-
}, "data-test-id": dataTestId
|
|
6
|
+
}, "data-test-id": dataTestId })] }));
|
|
23
7
|
}
|