@crystallize/design-system 1.7.0 → 1.8.0

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/index.css +53 -332
  3. package/dist/index.d.ts +15 -8
  4. package/dist/index.js +1723 -4554
  5. package/dist/index.mjs +1643 -2339
  6. package/package.json +1 -1
  7. package/src/action-menu/action-item-separator.tsx +14 -0
  8. package/src/action-menu/action-item.tsx +2 -2
  9. package/src/action-menu/action-menu.css +8 -0
  10. package/src/action-menu/action-menu.tsx +2 -1
  11. package/src/dropdown-menu/dropdown-menu-root.tsx +3 -1
  12. package/src/dropdown-menu/index.ts +5 -2
  13. package/src/iconography/subscription-contracts.tsx +4 -4
  14. package/src/iconography/subscription-plans.tsx +5 -5
  15. package/src/rich-text-editor/model/crystallize-to-lexical.ts +12 -1
  16. package/src/rich-text-editor/model/lexical-to-crystallize.ts +38 -38
  17. package/src/rich-text-editor/nodes/BaseNodes.ts +0 -7
  18. package/src/rich-text-editor/nodes/TableCellNodes.ts +0 -7
  19. package/src/rich-text-editor/plugins/ActionsPlugin/index.tsx +1 -1
  20. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx +3 -2
  21. package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx +0 -1
  22. package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.css +17 -17
  23. package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +1 -1
  24. package/src/rich-text-editor/plugins/MaxLengthPlugin/index.tsx +2 -7
  25. package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx +80 -149
  26. package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +2 -2
  27. package/src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx +55 -0
  28. package/src/rich-text-editor/rich-text-editor.css +10 -322
  29. package/src/rich-text-editor/rich-text-editor.stories.tsx +35 -5
  30. package/src/rich-text-editor/rich-text-editor.tsx +6 -39
  31. package/src/rich-text-editor/tests/rich-text-editor-code.test.tsx +10 -6
  32. package/src/rich-text-editor/tests/rich-text-editor-model-conversions.test.tsx +19 -7
  33. package/src/rich-text-editor/themes/CrystallizeRTEditorTheme.css +3 -11
  34. package/dist/TableComponent-I2YOOYOU.css +0 -281
  35. package/dist/TableComponent-QINOO453.mjs +0 -1377
  36. package/dist/chevron-down-3FRWSIKS.svg +0 -1
  37. package/dist/chunk-VUXQZRSP.mjs +0 -737
  38. package/dist/markdown-4BGQNLLT.svg +0 -1
  39. package/src/rich-text-editor/nodes/KeywordNode.ts +0 -73
  40. package/src/rich-text-editor/nodes/TableComponent.tsx +0 -1547
  41. package/src/rich-text-editor/nodes/TableNode.tsx +0 -398
  42. package/src/rich-text-editor/plugins/ComponentPickerPlugin/index.tsx +0 -320
  43. package/src/rich-text-editor/plugins/DragDropPastePlugin/index.ts +0 -40
  44. package/src/rich-text-editor/plugins/MarkdownShortcutPlugin/index.tsx +0 -16
  45. package/src/rich-text-editor/plugins/MarkdownTransformers/index.ts +0 -195
  46. package/src/rich-text-editor/plugins/SpeechToTextPlugin/index.ts +0 -113
  47. package/src/rich-text-editor/plugins/TableCellResizer/index.css +0 -12
  48. package/src/rich-text-editor/plugins/TableCellResizer/index.tsx +0 -386
  49. package/src/rich-text-editor/plugins/TablePlugin.tsx +0 -190
  50. package/src/rich-text-editor/plugins/TreeViewPlugin/index.tsx +0 -25
  51. package/src/rich-text-editor/plugins/TypingPerfPlugin/index.ts +0 -117
@@ -1,1377 +0,0 @@
1
- import {
2
- $isTableNode,
3
- CellContext,
4
- IS_APPLE,
5
- cellHTMLCache,
6
- cellTextContentCache,
7
- createRow,
8
- createUID,
9
- exportTableCellsToHTML,
10
- extractRowsFromHTML
11
- } from "./chunk-VUXQZRSP.mjs";
12
-
13
- // src/rich-text-editor/nodes/TableComponent.tsx
14
- import {
15
- $generateJSONFromSelectedNodes,
16
- $generateNodesFromSerializedNodes,
17
- $insertGeneratedNodes
18
- } from "@lexical/clipboard";
19
- import { $generateHtmlFromNodes, $generateNodesFromDOM } from "@lexical/html";
20
- import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
21
- import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
22
- import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
23
- import { mergeRegister } from "@lexical/utils";
24
- import {
25
- $addUpdateTag,
26
- $createParagraphNode,
27
- $createRangeSelection,
28
- $getNodeByKey,
29
- $getRoot,
30
- $getSelection,
31
- $isNodeSelection,
32
- $isRangeSelection,
33
- CLICK_COMMAND,
34
- COMMAND_PRIORITY_LOW,
35
- COPY_COMMAND,
36
- createEditor,
37
- CUT_COMMAND,
38
- FORMAT_TEXT_COMMAND,
39
- KEY_ARROW_DOWN_COMMAND,
40
- KEY_ARROW_LEFT_COMMAND,
41
- KEY_ARROW_RIGHT_COMMAND,
42
- KEY_ARROW_UP_COMMAND,
43
- KEY_BACKSPACE_COMMAND,
44
- KEY_DELETE_COMMAND,
45
- KEY_ENTER_COMMAND,
46
- KEY_ESCAPE_COMMAND,
47
- KEY_TAB_COMMAND,
48
- PASTE_COMMAND
49
- } from "lexical";
50
- import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
51
- import "react";
52
- import { createPortal } from "react-dom";
53
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
54
- var NO_CELLS = [];
55
- function $createSelectAll() {
56
- const sel = $createRangeSelection();
57
- sel.focus.set("root", $getRoot().getChildrenSize(), "element");
58
- return sel;
59
- }
60
- function createEmptyParagraphHTML(theme) {
61
- return `<p class="${theme.paragraph}"><br></p>`;
62
- }
63
- function focusCell(tableElem, id) {
64
- const cellElem = tableElem.querySelector(`[data-id=${id}]`);
65
- if (cellElem == null) {
66
- return;
67
- }
68
- cellElem.focus();
69
- }
70
- function isStartingResize(target) {
71
- return target.nodeType === 1 && target.hasAttribute("data-table-resize");
72
- }
73
- function generateHTMLFromJSON(editorStateJSON, cellEditor) {
74
- const editorState = cellEditor.parseEditorState(editorStateJSON);
75
- let html = cellHTMLCache.get(editorStateJSON);
76
- if (html === void 0) {
77
- html = editorState.read(() => $generateHtmlFromNodes(cellEditor, null));
78
- const textContent = editorState.read(() => $getRoot().getTextContent());
79
- cellHTMLCache.set(editorStateJSON, html);
80
- cellTextContentCache.set(editorStateJSON, textContent);
81
- }
82
- return html;
83
- }
84
- function getCurrentDocument(editor) {
85
- const rootElement = editor.getRootElement();
86
- return rootElement !== null ? rootElement.ownerDocument : document;
87
- }
88
- function isCopy(keyCode, shiftKey, metaKey, ctrlKey) {
89
- if (shiftKey) {
90
- return false;
91
- }
92
- if (keyCode === 67) {
93
- return IS_APPLE ? metaKey : ctrlKey;
94
- }
95
- return false;
96
- }
97
- function isCut(keyCode, shiftKey, metaKey, ctrlKey) {
98
- if (shiftKey) {
99
- return false;
100
- }
101
- if (keyCode === 88) {
102
- return IS_APPLE ? metaKey : ctrlKey;
103
- }
104
- return false;
105
- }
106
- function isPaste(keyCode, shiftKey, metaKey, ctrlKey) {
107
- if (shiftKey) {
108
- return false;
109
- }
110
- if (keyCode === 86) {
111
- return IS_APPLE ? metaKey : ctrlKey;
112
- }
113
- return false;
114
- }
115
- function getCellID(domElement) {
116
- let node = domElement;
117
- while (node !== null) {
118
- const possibleID = node.getAttribute("data-id");
119
- if (possibleID != null) {
120
- return possibleID;
121
- }
122
- node = node.parentElement;
123
- }
124
- return null;
125
- }
126
- function getTableCellWidth(domElement) {
127
- let node = domElement;
128
- while (node !== null) {
129
- if (node.nodeName === "TH" || node.nodeName === "TD") {
130
- return node.getBoundingClientRect().width;
131
- }
132
- node = node.parentElement;
133
- }
134
- return 0;
135
- }
136
- function $updateCells(rows, ids, cellCoordMap, cellEditor, updateTableNode, fn) {
137
- for (const id of ids) {
138
- const cell = getCell(rows, id, cellCoordMap);
139
- if (cell !== null && cellEditor !== null) {
140
- const editorState = cellEditor.parseEditorState(cell.json);
141
- cellEditor._headless = true;
142
- cellEditor.setEditorState(editorState);
143
- cellEditor.update(fn, { discrete: true });
144
- cellEditor._headless = false;
145
- const newJSON = JSON.stringify(cellEditor.getEditorState());
146
- updateTableNode((tableNode) => {
147
- const [x, y] = cellCoordMap.get(id);
148
- $addUpdateTag("history-push");
149
- tableNode.updateCellJSON(x, y, newJSON);
150
- });
151
- }
152
- }
153
- }
154
- function isTargetOnPossibleUIControl(target) {
155
- let node = target;
156
- while (node !== null) {
157
- const nodeName = node.nodeName;
158
- if (nodeName === "BUTTON" || nodeName === "INPUT" || nodeName === "TEXTAREA") {
159
- return true;
160
- }
161
- node = node.parentElement;
162
- }
163
- return false;
164
- }
165
- function getSelectedRect(startID, endID, cellCoordMap) {
166
- const startCoords = cellCoordMap.get(startID);
167
- const endCoords = cellCoordMap.get(endID);
168
- if (startCoords === void 0 || endCoords === void 0) {
169
- return null;
170
- }
171
- const startX = Math.min(startCoords[0], endCoords[0]);
172
- const endX = Math.max(startCoords[0], endCoords[0]);
173
- const startY = Math.min(startCoords[1], endCoords[1]);
174
- const endY = Math.max(startCoords[1], endCoords[1]);
175
- return {
176
- endX,
177
- endY,
178
- startX,
179
- startY
180
- };
181
- }
182
- function getSelectedIDs(rows, startID, endID, cellCoordMap) {
183
- const rect = getSelectedRect(startID, endID, cellCoordMap);
184
- if (rect === null) {
185
- return [];
186
- }
187
- const { startX, endY, endX, startY } = rect;
188
- const ids = [];
189
- for (let x = startX; x <= endX; x++) {
190
- for (let y = startY; y <= endY; y++) {
191
- ids.push(rows[y].cells[x].id);
192
- }
193
- }
194
- return ids;
195
- }
196
- function extractCellsFromRows(rows, rect) {
197
- const { startX, endY, endX, startY } = rect;
198
- const newRows = [];
199
- for (let y = startY; y <= endY; y++) {
200
- const row = rows[y];
201
- const newRow = createRow();
202
- for (let x = startX; x <= endX; x++) {
203
- const cellClone = { ...row.cells[x] };
204
- cellClone.id = createUID();
205
- newRow.cells.push(cellClone);
206
- }
207
- newRows.push(newRow);
208
- }
209
- return newRows;
210
- }
211
- function TableCellEditor({ cellEditor }) {
212
- const { cellEditorConfig, cellEditorPlugins } = useContext(CellContext);
213
- if (cellEditorPlugins === null || cellEditorConfig === null) {
214
- return null;
215
- }
216
- return /* @__PURE__ */ jsx(LexicalNestedComposer, {
217
- initialEditor: cellEditor,
218
- initialTheme: cellEditorConfig.theme,
219
- initialNodes: cellEditorConfig.nodes,
220
- skipCollabChecks: true,
221
- children: cellEditorPlugins
222
- });
223
- }
224
- function getCell(rows, cellID, cellCoordMap) {
225
- const coords = cellCoordMap.get(cellID);
226
- if (coords === void 0) {
227
- return null;
228
- }
229
- const [x, y] = coords;
230
- const row = rows[y];
231
- return row.cells[x];
232
- }
233
- function TableActionMenu({
234
- cell,
235
- rows,
236
- cellCoordMap,
237
- menuElem,
238
- updateCellsByID,
239
- onClose,
240
- updateTableNode,
241
- setSortingOptions,
242
- sortingOptions
243
- }) {
244
- const dropDownRef = useRef(null);
245
- useEffect(() => {
246
- const dropdownElem = dropDownRef.current;
247
- if (dropdownElem !== null) {
248
- const rect = menuElem.getBoundingClientRect();
249
- dropdownElem.style.top = `${rect.y}px`;
250
- dropdownElem.style.left = `${rect.x}px`;
251
- }
252
- }, [menuElem]);
253
- useEffect(() => {
254
- const handleClickOutside = (event) => {
255
- const dropdownElem = dropDownRef.current;
256
- if (dropdownElem !== null && !dropdownElem.contains(event.target)) {
257
- event.stopPropagation();
258
- }
259
- };
260
- window.addEventListener("click", handleClickOutside);
261
- return () => window.removeEventListener("click", handleClickOutside);
262
- }, [onClose]);
263
- const coords = cellCoordMap.get(cell.id);
264
- if (coords === void 0) {
265
- return null;
266
- }
267
- const [x, y] = coords;
268
- return /* @__PURE__ */ jsxs("div", {
269
- className: "dropdown",
270
- ref: dropDownRef,
271
- onPointerMove: (e) => {
272
- e.stopPropagation();
273
- },
274
- onPointerDown: (e) => {
275
- e.stopPropagation();
276
- },
277
- onPointerUp: (e) => {
278
- e.stopPropagation();
279
- },
280
- onClick: (e) => {
281
- e.stopPropagation();
282
- },
283
- children: [
284
- /* @__PURE__ */ jsx("button", {
285
- className: "item",
286
- onClick: () => {
287
- updateTableNode((tableNode) => {
288
- $addUpdateTag("history-push");
289
- tableNode.updateCellType(x, y, cell.type === "normal" ? "header" : "normal");
290
- });
291
- onClose();
292
- },
293
- children: /* @__PURE__ */ jsx("span", {
294
- className: "text",
295
- children: cell.type === "normal" ? "Make header" : "Remove header"
296
- })
297
- }),
298
- /* @__PURE__ */ jsx("button", {
299
- className: "item",
300
- onClick: () => {
301
- updateCellsByID([cell.id], () => {
302
- const root = $getRoot();
303
- root.clear();
304
- root.append($createParagraphNode());
305
- });
306
- onClose();
307
- },
308
- children: /* @__PURE__ */ jsx("span", {
309
- className: "text",
310
- children: "Clear cell"
311
- })
312
- }),
313
- /* @__PURE__ */ jsx("hr", {}),
314
- cell.type === "header" && y === 0 && /* @__PURE__ */ jsxs(Fragment, {
315
- children: [
316
- sortingOptions !== null && sortingOptions.x === x && /* @__PURE__ */ jsx("button", {
317
- className: "item",
318
- onClick: () => {
319
- setSortingOptions(null);
320
- onClose();
321
- },
322
- children: /* @__PURE__ */ jsx("span", {
323
- className: "text",
324
- children: "Remove sorting"
325
- })
326
- }),
327
- (sortingOptions === null || sortingOptions.x !== x || sortingOptions.type === "descending") && /* @__PURE__ */ jsx("button", {
328
- className: "item",
329
- onClick: () => {
330
- setSortingOptions({ type: "ascending", x });
331
- onClose();
332
- },
333
- children: /* @__PURE__ */ jsx("span", {
334
- className: "text",
335
- children: "Sort ascending"
336
- })
337
- }),
338
- (sortingOptions === null || sortingOptions.x !== x || sortingOptions.type === "ascending") && /* @__PURE__ */ jsx("button", {
339
- className: "item",
340
- onClick: () => {
341
- setSortingOptions({ type: "descending", x });
342
- onClose();
343
- },
344
- children: /* @__PURE__ */ jsx("span", {
345
- className: "text",
346
- children: "Sort descending"
347
- })
348
- }),
349
- /* @__PURE__ */ jsx("hr", {})
350
- ]
351
- }),
352
- /* @__PURE__ */ jsx("button", {
353
- className: "item",
354
- onClick: () => {
355
- updateTableNode((tableNode) => {
356
- $addUpdateTag("history-push");
357
- tableNode.insertRowAt(y);
358
- });
359
- onClose();
360
- },
361
- children: /* @__PURE__ */ jsx("span", {
362
- className: "text",
363
- children: "Insert row above"
364
- })
365
- }),
366
- /* @__PURE__ */ jsx("button", {
367
- className: "item",
368
- onClick: () => {
369
- updateTableNode((tableNode) => {
370
- $addUpdateTag("history-push");
371
- tableNode.insertRowAt(y + 1);
372
- });
373
- onClose();
374
- },
375
- children: /* @__PURE__ */ jsx("span", {
376
- className: "text",
377
- children: "Insert row below"
378
- })
379
- }),
380
- /* @__PURE__ */ jsx("hr", {}),
381
- /* @__PURE__ */ jsx("button", {
382
- className: "item",
383
- onClick: () => {
384
- updateTableNode((tableNode) => {
385
- $addUpdateTag("history-push");
386
- tableNode.insertColumnAt(x);
387
- });
388
- onClose();
389
- },
390
- children: /* @__PURE__ */ jsx("span", {
391
- className: "text",
392
- children: "Insert column left"
393
- })
394
- }),
395
- /* @__PURE__ */ jsx("button", {
396
- className: "item",
397
- onClick: () => {
398
- updateTableNode((tableNode) => {
399
- $addUpdateTag("history-push");
400
- tableNode.insertColumnAt(x + 1);
401
- });
402
- onClose();
403
- },
404
- children: /* @__PURE__ */ jsx("span", {
405
- className: "text",
406
- children: "Insert column right"
407
- })
408
- }),
409
- /* @__PURE__ */ jsx("hr", {}),
410
- rows[0].cells.length !== 1 && /* @__PURE__ */ jsx("button", {
411
- className: "item",
412
- onClick: () => {
413
- updateTableNode((tableNode) => {
414
- $addUpdateTag("history-push");
415
- tableNode.deleteColumnAt(x);
416
- });
417
- onClose();
418
- },
419
- children: /* @__PURE__ */ jsx("span", {
420
- className: "text",
421
- children: "Delete column"
422
- })
423
- }),
424
- rows.length !== 1 && /* @__PURE__ */ jsx("button", {
425
- className: "item",
426
- onClick: () => {
427
- updateTableNode((tableNode) => {
428
- $addUpdateTag("history-push");
429
- tableNode.deleteRowAt(y);
430
- });
431
- onClose();
432
- },
433
- children: /* @__PURE__ */ jsx("span", {
434
- className: "text",
435
- children: "Delete row"
436
- })
437
- }),
438
- /* @__PURE__ */ jsx("button", {
439
- className: "item",
440
- onClick: () => {
441
- updateTableNode((tableNode) => {
442
- $addUpdateTag("history-push");
443
- tableNode.selectNext();
444
- tableNode.remove();
445
- });
446
- onClose();
447
- },
448
- children: /* @__PURE__ */ jsx("span", {
449
- className: "text",
450
- children: "Delete table"
451
- })
452
- })
453
- ]
454
- });
455
- }
456
- function TableCell({
457
- cell,
458
- cellCoordMap,
459
- cellEditor,
460
- isEditing,
461
- isSelected,
462
- isPrimarySelected,
463
- theme,
464
- updateCellsByID,
465
- updateTableNode,
466
- rows,
467
- setSortingOptions,
468
- sortingOptions
469
- }) {
470
- const [showMenu, setShowMenu] = useState(false);
471
- const menuRootRef = useRef(null);
472
- const isHeader = cell.type !== "normal";
473
- const editorStateJSON = cell.json;
474
- const CellComponent = isHeader ? "th" : "td";
475
- const cellWidth = cell.width;
476
- const menuElem = menuRootRef.current;
477
- const coords = cellCoordMap.get(cell.id);
478
- const isSorted = sortingOptions !== null && coords !== void 0 && coords[0] === sortingOptions.x && coords[1] === 0;
479
- useEffect(() => {
480
- if (isEditing || !isPrimarySelected) {
481
- setShowMenu(false);
482
- }
483
- }, [isEditing, isPrimarySelected]);
484
- return /* @__PURE__ */ jsxs(CellComponent, {
485
- className: `${theme.tableCell} ${isHeader ? theme.tableCellHeader : ""} ${isSelected ? theme.tableCellSelected : ""}`,
486
- "data-id": cell.id,
487
- tabIndex: -1,
488
- style: { width: cellWidth !== null ? cellWidth : void 0 },
489
- children: [
490
- isPrimarySelected && /* @__PURE__ */ jsx("div", {
491
- className: `${theme.tableCellPrimarySelected} ${isEditing ? theme.tableCellEditing : ""}`
492
- }),
493
- isPrimarySelected && isEditing ? /* @__PURE__ */ jsx(TableCellEditor, {
494
- cellEditor
495
- }) : /* @__PURE__ */ jsxs(Fragment, {
496
- children: [
497
- /* @__PURE__ */ jsx("div", {
498
- dangerouslySetInnerHTML: {
499
- __html: editorStateJSON === "" ? createEmptyParagraphHTML(theme) : generateHTMLFromJSON(editorStateJSON, cellEditor)
500
- }
501
- }),
502
- /* @__PURE__ */ jsx("div", {
503
- className: theme.tableCellResizer,
504
- "data-table-resize": "true"
505
- })
506
- ]
507
- }),
508
- isPrimarySelected && !isEditing && /* @__PURE__ */ jsx("div", {
509
- className: theme.tableCellActionButtonContainer,
510
- ref: menuRootRef,
511
- children: /* @__PURE__ */ jsx("button", {
512
- className: theme.tableCellActionButton,
513
- onClick: (e) => {
514
- setShowMenu(!showMenu);
515
- e.stopPropagation();
516
- },
517
- children: /* @__PURE__ */ jsx("i", {
518
- className: "chevron-down"
519
- })
520
- })
521
- }),
522
- showMenu && menuElem !== null && createPortal(
523
- /* @__PURE__ */ jsx(TableActionMenu, {
524
- cell,
525
- menuElem,
526
- updateCellsByID,
527
- onClose: () => setShowMenu(false),
528
- updateTableNode,
529
- cellCoordMap,
530
- rows,
531
- setSortingOptions,
532
- sortingOptions
533
- }),
534
- document.body
535
- ),
536
- isSorted && /* @__PURE__ */ jsx("div", {
537
- className: theme.tableCellSortedIndicator
538
- })
539
- ]
540
- });
541
- }
542
- function TableComponent({
543
- nodeKey,
544
- rows: rawRows,
545
- theme
546
- }) {
547
- const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
548
- const resizeMeasureRef = useRef({
549
- point: 0,
550
- size: 0
551
- });
552
- const [sortingOptions, setSortingOptions] = useState(null);
553
- const addRowsRef = useRef(null);
554
- const lastCellIDRef = useRef(null);
555
- const tableResizerRulerRef = useRef(null);
556
- const { cellEditorConfig } = useContext(CellContext);
557
- const [isEditing, setIsEditing] = useState(false);
558
- const [showAddColumns, setShowAddColumns] = useState(false);
559
- const [showAddRows, setShowAddRows] = useState(false);
560
- const [editor] = useLexicalComposerContext();
561
- const mouseDownRef = useRef(false);
562
- const [resizingID, setResizingID] = useState(null);
563
- const tableRef = useRef(null);
564
- const cellCoordMap = useMemo(() => {
565
- const map = /* @__PURE__ */ new Map();
566
- for (let y = 0; y < rawRows.length; y++) {
567
- const row = rawRows[y];
568
- const cells = row.cells;
569
- for (let x = 0; x < cells.length; x++) {
570
- const cell = cells[x];
571
- map.set(cell.id, [x, y]);
572
- }
573
- }
574
- return map;
575
- }, [rawRows]);
576
- const rows = useMemo(() => {
577
- if (sortingOptions === null) {
578
- return rawRows;
579
- }
580
- const _rows = rawRows.slice(1);
581
- _rows.sort((a, b) => {
582
- const aCells = a.cells;
583
- const bCells = b.cells;
584
- const x = sortingOptions.x;
585
- const aContent = cellTextContentCache.get(aCells[x].json) || "";
586
- const bContent = cellTextContentCache.get(bCells[x].json) || "";
587
- if (aContent === "" || bContent === "") {
588
- return 1;
589
- }
590
- if (sortingOptions.type === "ascending") {
591
- return aContent.localeCompare(bContent);
592
- }
593
- return bContent.localeCompare(aContent);
594
- });
595
- _rows.unshift(rawRows[0]);
596
- return _rows;
597
- }, [rawRows, sortingOptions]);
598
- const [primarySelectedCellID, setPrimarySelectedCellID] = useState(null);
599
- const cellEditor = useMemo(() => {
600
- if (cellEditorConfig === null) {
601
- return null;
602
- }
603
- const _cellEditor = createEditor({
604
- namespace: cellEditorConfig.namespace,
605
- nodes: cellEditorConfig.nodes,
606
- onError: (error) => cellEditorConfig.onError(error, _cellEditor),
607
- theme: cellEditorConfig.theme
608
- });
609
- return _cellEditor;
610
- }, [cellEditorConfig]);
611
- const [selectedCellIDs, setSelectedCellIDs] = useState([]);
612
- const selectedCellSet = useMemo(() => new Set(selectedCellIDs), [selectedCellIDs]);
613
- useEffect(() => {
614
- const tableElem = tableRef.current;
615
- if (isSelected && document.activeElement === document.body && tableElem !== null) {
616
- tableElem.focus();
617
- }
618
- }, [isSelected]);
619
- const updateTableNode = useCallback(
620
- (fn) => {
621
- editor.update(() => {
622
- const tableNode = $getNodeByKey(nodeKey);
623
- if ($isTableNode(tableNode)) {
624
- fn(tableNode);
625
- }
626
- });
627
- },
628
- [editor, nodeKey]
629
- );
630
- const addColumns = () => {
631
- updateTableNode((tableNode) => {
632
- $addUpdateTag("history-push");
633
- tableNode.addColumns(1);
634
- });
635
- };
636
- const addRows = () => {
637
- updateTableNode((tableNode) => {
638
- $addUpdateTag("history-push");
639
- tableNode.addRows(1);
640
- });
641
- };
642
- const modifySelectedCells = useCallback(
643
- (x, y, extend) => {
644
- const id = rows[y].cells[x].id;
645
- lastCellIDRef.current = id;
646
- if (extend) {
647
- const selectedIDs = getSelectedIDs(rows, primarySelectedCellID, id, cellCoordMap);
648
- setSelectedCellIDs(selectedIDs);
649
- } else {
650
- setPrimarySelectedCellID(id);
651
- setSelectedCellIDs(NO_CELLS);
652
- focusCell(tableRef.current, id);
653
- }
654
- },
655
- [cellCoordMap, primarySelectedCellID, rows]
656
- );
657
- const saveEditorToJSON = useCallback(() => {
658
- if (cellEditor !== null && primarySelectedCellID !== null) {
659
- const json = JSON.stringify(cellEditor.getEditorState());
660
- updateTableNode((tableNode) => {
661
- const coords = cellCoordMap.get(primarySelectedCellID);
662
- if (coords === void 0) {
663
- return;
664
- }
665
- $addUpdateTag("history-push");
666
- const [x, y] = coords;
667
- tableNode.updateCellJSON(x, y, json);
668
- });
669
- }
670
- }, [cellCoordMap, cellEditor, primarySelectedCellID, updateTableNode]);
671
- const selectTable = useCallback(() => {
672
- setTimeout(() => {
673
- const parentRootElement = editor.getRootElement();
674
- if (parentRootElement !== null) {
675
- parentRootElement.focus({ preventScroll: true });
676
- window.getSelection()?.removeAllRanges();
677
- }
678
- }, 20);
679
- }, [editor]);
680
- useEffect(() => {
681
- const tableElem = tableRef.current;
682
- if (tableElem === null) {
683
- return;
684
- }
685
- const doc = getCurrentDocument(editor);
686
- const isAtEdgeOfTable = (event) => {
687
- const x = event.clientX - tableRect.x;
688
- const y = event.clientY - tableRect.y;
689
- return x < 5 || y < 5;
690
- };
691
- const handlePointerDown = (event) => {
692
- const possibleID = getCellID(event.target);
693
- if (possibleID !== null && editor.isEditable() && tableElem.contains(event.target)) {
694
- if (isAtEdgeOfTable(event)) {
695
- setSelected(true);
696
- setPrimarySelectedCellID(null);
697
- selectTable();
698
- return;
699
- }
700
- setSelected(false);
701
- if (isStartingResize(event.target)) {
702
- setResizingID(possibleID);
703
- tableElem.style.userSelect = "none";
704
- resizeMeasureRef.current = {
705
- point: event.clientX,
706
- size: getTableCellWidth(event.target)
707
- };
708
- return;
709
- }
710
- mouseDownRef.current = true;
711
- if (primarySelectedCellID !== possibleID) {
712
- if (isEditing) {
713
- saveEditorToJSON();
714
- }
715
- setPrimarySelectedCellID(possibleID);
716
- setIsEditing(false);
717
- lastCellIDRef.current = possibleID;
718
- } else {
719
- lastCellIDRef.current = null;
720
- }
721
- setSelectedCellIDs(NO_CELLS);
722
- } else if (primarySelectedCellID !== null && !isTargetOnPossibleUIControl(event.target)) {
723
- setSelected(false);
724
- mouseDownRef.current = false;
725
- if (isEditing) {
726
- saveEditorToJSON();
727
- }
728
- setPrimarySelectedCellID(null);
729
- setSelectedCellIDs(NO_CELLS);
730
- setIsEditing(false);
731
- lastCellIDRef.current = null;
732
- }
733
- };
734
- const tableRect = tableElem.getBoundingClientRect();
735
- const handlePointerMove = (event) => {
736
- if (resizingID !== null) {
737
- const tableResizerRulerElem = tableResizerRulerRef.current;
738
- if (tableResizerRulerElem !== null) {
739
- const { size, point } = resizeMeasureRef.current;
740
- const diff = event.clientX - point;
741
- const newWidth = size + diff;
742
- let x = event.clientX - tableRect.x;
743
- if (x < 10) {
744
- x = 10;
745
- } else if (x > tableRect.width - 10) {
746
- x = tableRect.width - 10;
747
- } else if (newWidth < 20) {
748
- x = point - size + 20 - tableRect.x;
749
- }
750
- tableResizerRulerElem.style.left = `${x}px`;
751
- }
752
- return;
753
- }
754
- if (!isEditing) {
755
- const { clientX, clientY } = event;
756
- const { width, x, y, height } = tableRect;
757
- const isOnRightEdge = clientX > x + width * 0.9 && clientX < x + width + 40 && !mouseDownRef.current;
758
- setShowAddColumns(isOnRightEdge);
759
- const isOnBottomEdge = event.target === addRowsRef.current || clientY > y + height * 0.85 && clientY < y + height + 5 && !mouseDownRef.current;
760
- setShowAddRows(isOnBottomEdge);
761
- }
762
- if (isEditing || !mouseDownRef.current || primarySelectedCellID === null) {
763
- return;
764
- }
765
- const possibleID = getCellID(event.target);
766
- if (possibleID !== null && possibleID !== lastCellIDRef.current) {
767
- if (selectedCellIDs.length === 0) {
768
- tableElem.style.userSelect = "none";
769
- }
770
- const selectedIDs = getSelectedIDs(rows, primarySelectedCellID, possibleID, cellCoordMap);
771
- if (selectedIDs.length === 1) {
772
- setSelectedCellIDs(NO_CELLS);
773
- } else {
774
- setSelectedCellIDs(selectedIDs);
775
- }
776
- lastCellIDRef.current = possibleID;
777
- }
778
- };
779
- const handlePointerUp = (event) => {
780
- if (resizingID !== null) {
781
- const { size, point } = resizeMeasureRef.current;
782
- const diff = event.clientX - point;
783
- let newWidth = size + diff;
784
- if (newWidth < 10) {
785
- newWidth = 10;
786
- }
787
- updateTableNode((tableNode) => {
788
- const [x] = cellCoordMap.get(resizingID);
789
- $addUpdateTag("history-push");
790
- tableNode.updateColumnWidth(x, newWidth);
791
- });
792
- setResizingID(null);
793
- }
794
- if (tableElem !== null && selectedCellIDs.length > 1 && mouseDownRef.current) {
795
- tableElem.style.userSelect = "text";
796
- window.getSelection()?.removeAllRanges();
797
- }
798
- mouseDownRef.current = false;
799
- };
800
- doc.addEventListener("pointerdown", handlePointerDown);
801
- doc.addEventListener("pointermove", handlePointerMove);
802
- doc.addEventListener("pointerup", handlePointerUp);
803
- return () => {
804
- doc.removeEventListener("pointerdown", handlePointerDown);
805
- doc.removeEventListener("pointermove", handlePointerMove);
806
- doc.removeEventListener("pointerup", handlePointerUp);
807
- };
808
- }, [
809
- cellEditor,
810
- editor,
811
- isEditing,
812
- rows,
813
- saveEditorToJSON,
814
- primarySelectedCellID,
815
- selectedCellSet,
816
- selectedCellIDs,
817
- cellCoordMap,
818
- resizingID,
819
- updateTableNode,
820
- setSelected,
821
- selectTable
822
- ]);
823
- useEffect(() => {
824
- if (!isEditing && primarySelectedCellID !== null) {
825
- const doc = getCurrentDocument(editor);
826
- const loadContentIntoCell = (cell) => {
827
- if (cell !== null && cellEditor !== null) {
828
- const editorStateJSON = cell.json;
829
- const editorState = cellEditor.parseEditorState(editorStateJSON);
830
- cellEditor.setEditorState(editorState);
831
- }
832
- };
833
- const handleDblClick = (event) => {
834
- const possibleID = getCellID(event.target);
835
- if (possibleID === primarySelectedCellID && editor.isEditable()) {
836
- const cell = getCell(rows, possibleID, cellCoordMap);
837
- loadContentIntoCell(cell);
838
- setIsEditing(true);
839
- setSelectedCellIDs(NO_CELLS);
840
- }
841
- };
842
- const handleKeyDown = (event) => {
843
- const keyCode = event.keyCode;
844
- if (keyCode === 16 || keyCode === 27 || keyCode === 9 || keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40 || keyCode === 8 || keyCode === 46 || !editor.isEditable()) {
845
- return;
846
- }
847
- if (keyCode === 13) {
848
- event.preventDefault();
849
- }
850
- if (!isEditing && primarySelectedCellID !== null && editor.getEditorState().read(() => $getSelection() === null) && event.target.contentEditable !== "true") {
851
- if (isCopy(keyCode, event.shiftKey, event.metaKey, event.ctrlKey)) {
852
- editor.dispatchCommand(COPY_COMMAND, event);
853
- return;
854
- }
855
- if (isCut(keyCode, event.shiftKey, event.metaKey, event.ctrlKey)) {
856
- editor.dispatchCommand(CUT_COMMAND, event);
857
- return;
858
- }
859
- if (isPaste(keyCode, event.shiftKey, event.metaKey, event.ctrlKey)) {
860
- editor.dispatchCommand(PASTE_COMMAND, event);
861
- return;
862
- }
863
- }
864
- if (event.metaKey || event.ctrlKey || event.altKey) {
865
- return;
866
- }
867
- const cell = getCell(rows, primarySelectedCellID, cellCoordMap);
868
- loadContentIntoCell(cell);
869
- setIsEditing(true);
870
- setSelectedCellIDs(NO_CELLS);
871
- };
872
- doc.addEventListener("dblclick", handleDblClick);
873
- doc.addEventListener("keydown", handleKeyDown);
874
- return () => {
875
- doc.removeEventListener("dblclick", handleDblClick);
876
- doc.removeEventListener("keydown", handleKeyDown);
877
- };
878
- }
879
- }, [cellEditor, editor, isEditing, rows, primarySelectedCellID, cellCoordMap]);
880
- const updateCellsByID = useCallback(
881
- (ids, fn) => {
882
- $updateCells(rows, ids, cellCoordMap, cellEditor, updateTableNode, fn);
883
- },
884
- [cellCoordMap, cellEditor, rows, updateTableNode]
885
- );
886
- const clearCellsCommand = useCallback(() => {
887
- if (primarySelectedCellID !== null && !isEditing) {
888
- updateCellsByID([primarySelectedCellID, ...selectedCellIDs], () => {
889
- const root = $getRoot();
890
- root.clear();
891
- root.append($createParagraphNode());
892
- });
893
- return true;
894
- } else if (isSelected) {
895
- updateTableNode((tableNode) => {
896
- $addUpdateTag("history-push");
897
- tableNode.selectNext();
898
- tableNode.remove();
899
- });
900
- }
901
- return false;
902
- }, [isEditing, isSelected, primarySelectedCellID, selectedCellIDs, updateCellsByID, updateTableNode]);
903
- useEffect(() => {
904
- const tableElem = tableRef.current;
905
- if (tableElem === null) {
906
- return;
907
- }
908
- const copyDataToClipboard = (event, htmlString, lexicalString, plainTextString) => {
909
- const clipboardData = event instanceof KeyboardEvent ? null : event.clipboardData;
910
- event.preventDefault();
911
- if (clipboardData != null) {
912
- clipboardData.setData("text/html", htmlString);
913
- clipboardData.setData("text/plain", plainTextString);
914
- clipboardData.setData("application/x-lexical-editor", lexicalString);
915
- } else {
916
- const clipboard = navigator.clipboard;
917
- if (clipboard != null) {
918
- const data = [
919
- new ClipboardItem({
920
- "text/html": new Blob([htmlString], {
921
- type: "text/html"
922
- })
923
- })
924
- ];
925
- clipboard.write(data);
926
- }
927
- }
928
- };
929
- const getTypeFromObject = async (clipboardData, type) => {
930
- try {
931
- return clipboardData instanceof DataTransfer ? clipboardData.getData(type) : clipboardData instanceof ClipboardItem ? await (await clipboardData.getType(type)).text() : "";
932
- } catch {
933
- return "";
934
- }
935
- };
936
- const pasteContent = async (event) => {
937
- let clipboardData = (event instanceof InputEvent ? null : event.clipboardData) || null;
938
- if (primarySelectedCellID !== null && cellEditor !== null) {
939
- event.preventDefault();
940
- if (clipboardData === null) {
941
- try {
942
- const items = await navigator.clipboard.read();
943
- clipboardData = items[0];
944
- } catch {
945
- }
946
- }
947
- const lexicalString = clipboardData !== null ? await getTypeFromObject(clipboardData, "application/x-lexical-editor") : "";
948
- if (lexicalString) {
949
- try {
950
- const payload = JSON.parse(lexicalString);
951
- if (payload.namespace === editor._config.namespace && Array.isArray(payload.nodes)) {
952
- $updateCells(rows, [primarySelectedCellID], cellCoordMap, cellEditor, updateTableNode, () => {
953
- const root = $getRoot();
954
- root.clear();
955
- root.append($createParagraphNode());
956
- root.selectEnd();
957
- const nodes = $generateNodesFromSerializedNodes(payload.nodes);
958
- const sel = $getSelection();
959
- if ($isRangeSelection(sel)) {
960
- $insertGeneratedNodes(cellEditor, nodes, sel);
961
- }
962
- });
963
- return;
964
- }
965
- } catch {
966
- }
967
- }
968
- const htmlString = clipboardData !== null ? await getTypeFromObject(clipboardData, "text/html") : "";
969
- if (htmlString) {
970
- try {
971
- const parser = new DOMParser();
972
- const dom = parser.parseFromString(htmlString, "text/html");
973
- const possibleTableElement = dom.querySelector("table");
974
- if (possibleTableElement != null) {
975
- const pasteRows = extractRowsFromHTML(possibleTableElement);
976
- updateTableNode((tableNode) => {
977
- const [x, y] = cellCoordMap.get(primarySelectedCellID);
978
- $addUpdateTag("history-push");
979
- tableNode.mergeRows(x, y, pasteRows);
980
- });
981
- return;
982
- }
983
- $updateCells(rows, [primarySelectedCellID], cellCoordMap, cellEditor, updateTableNode, () => {
984
- const root = $getRoot();
985
- root.clear();
986
- root.append($createParagraphNode());
987
- root.selectEnd();
988
- const nodes = $generateNodesFromDOM(editor, dom);
989
- const sel = $getSelection();
990
- if ($isRangeSelection(sel)) {
991
- $insertGeneratedNodes(cellEditor, nodes, sel);
992
- }
993
- });
994
- return;
995
- } catch {
996
- }
997
- }
998
- const text = clipboardData !== null ? await getTypeFromObject(clipboardData, "text/plain") : "";
999
- if (text != null) {
1000
- $updateCells(rows, [primarySelectedCellID], cellCoordMap, cellEditor, updateTableNode, () => {
1001
- const root = $getRoot();
1002
- root.clear();
1003
- root.selectEnd();
1004
- const sel = $getSelection();
1005
- if (sel !== null) {
1006
- sel.insertRawText(text);
1007
- }
1008
- });
1009
- }
1010
- }
1011
- };
1012
- const copyPrimaryCell = (event) => {
1013
- if (primarySelectedCellID !== null && cellEditor !== null) {
1014
- const cell = getCell(rows, primarySelectedCellID, cellCoordMap);
1015
- const json = cell.json;
1016
- const htmlString = cellHTMLCache.get(json) || null;
1017
- if (htmlString === null) {
1018
- return;
1019
- }
1020
- const editorState = cellEditor.parseEditorState(json);
1021
- const plainTextString = editorState.read(() => $getRoot().getTextContent());
1022
- const lexicalString = editorState.read(() => {
1023
- return JSON.stringify($generateJSONFromSelectedNodes(cellEditor, null));
1024
- });
1025
- copyDataToClipboard(event, htmlString, lexicalString, plainTextString);
1026
- }
1027
- };
1028
- const copyCellRange = (event) => {
1029
- const lastCellID = lastCellIDRef.current;
1030
- if (primarySelectedCellID !== null && cellEditor !== null && lastCellID !== null) {
1031
- const rect = getSelectedRect(primarySelectedCellID, lastCellID, cellCoordMap);
1032
- if (rect === null) {
1033
- return;
1034
- }
1035
- const dom = exportTableCellsToHTML(rows, rect);
1036
- const htmlString = dom.outerHTML;
1037
- const plainTextString = dom.outerText;
1038
- const tableNodeJSON = editor.getEditorState().read(() => {
1039
- const tableNode = $getNodeByKey(nodeKey);
1040
- return tableNode.exportJSON();
1041
- });
1042
- tableNodeJSON.rows = extractCellsFromRows(rows, rect);
1043
- const lexicalJSON = {
1044
- namespace: cellEditor._config.namespace,
1045
- nodes: [tableNodeJSON]
1046
- };
1047
- const lexicalString = JSON.stringify(lexicalJSON);
1048
- copyDataToClipboard(event, htmlString, lexicalString, plainTextString);
1049
- }
1050
- };
1051
- const handlePaste = (event, activeEditor) => {
1052
- const selection = $getSelection();
1053
- if (primarySelectedCellID !== null && !isEditing && selection === null && activeEditor === editor) {
1054
- pasteContent(event);
1055
- mouseDownRef.current = false;
1056
- setSelectedCellIDs(NO_CELLS);
1057
- return true;
1058
- }
1059
- return false;
1060
- };
1061
- const handleCopy = (event, activeEditor) => {
1062
- const selection = $getSelection();
1063
- if (primarySelectedCellID !== null && !isEditing && selection === null && activeEditor === editor) {
1064
- if (selectedCellIDs.length === 0) {
1065
- copyPrimaryCell(event);
1066
- } else {
1067
- copyCellRange(event);
1068
- }
1069
- return true;
1070
- }
1071
- return false;
1072
- };
1073
- return mergeRegister(
1074
- editor.registerCommand(
1075
- CLICK_COMMAND,
1076
- () => {
1077
- const selection = $getSelection();
1078
- if ($isNodeSelection(selection)) {
1079
- return true;
1080
- }
1081
- return false;
1082
- },
1083
- COMMAND_PRIORITY_LOW
1084
- ),
1085
- editor.registerCommand(PASTE_COMMAND, handlePaste, COMMAND_PRIORITY_LOW),
1086
- editor.registerCommand(COPY_COMMAND, handleCopy, COMMAND_PRIORITY_LOW),
1087
- editor.registerCommand(
1088
- CUT_COMMAND,
1089
- (event, activeEditor) => {
1090
- if (handleCopy(event, activeEditor)) {
1091
- clearCellsCommand();
1092
- return true;
1093
- }
1094
- return false;
1095
- },
1096
- COMMAND_PRIORITY_LOW
1097
- ),
1098
- editor.registerCommand(KEY_BACKSPACE_COMMAND, clearCellsCommand, COMMAND_PRIORITY_LOW),
1099
- editor.registerCommand(KEY_DELETE_COMMAND, clearCellsCommand, COMMAND_PRIORITY_LOW),
1100
- editor.registerCommand(
1101
- FORMAT_TEXT_COMMAND,
1102
- (payload) => {
1103
- if (primarySelectedCellID !== null && !isEditing) {
1104
- $updateCells(
1105
- rows,
1106
- [primarySelectedCellID, ...selectedCellIDs],
1107
- cellCoordMap,
1108
- cellEditor,
1109
- updateTableNode,
1110
- () => {
1111
- const sel = $createSelectAll();
1112
- sel.formatText(payload);
1113
- }
1114
- );
1115
- return true;
1116
- }
1117
- return false;
1118
- },
1119
- COMMAND_PRIORITY_LOW
1120
- ),
1121
- editor.registerCommand(
1122
- KEY_ENTER_COMMAND,
1123
- (event, targetEditor) => {
1124
- const selection = $getSelection();
1125
- if (primarySelectedCellID === null && !isEditing && $isNodeSelection(selection) && selection.has(nodeKey) && selection.getNodes().length === 1 && targetEditor === editor) {
1126
- const firstCellID = rows[0].cells[0].id;
1127
- setPrimarySelectedCellID(firstCellID);
1128
- focusCell(tableElem, firstCellID);
1129
- event.preventDefault();
1130
- event.stopPropagation();
1131
- clearSelection();
1132
- return true;
1133
- }
1134
- return false;
1135
- },
1136
- COMMAND_PRIORITY_LOW
1137
- ),
1138
- editor.registerCommand(
1139
- KEY_TAB_COMMAND,
1140
- (event) => {
1141
- const selection = $getSelection();
1142
- if (!isEditing && selection === null && primarySelectedCellID !== null) {
1143
- const isBackward = event.shiftKey;
1144
- const [x, y] = cellCoordMap.get(primarySelectedCellID);
1145
- event.preventDefault();
1146
- let nextX = null;
1147
- let nextY = null;
1148
- if (x === 0 && isBackward) {
1149
- if (y !== 0) {
1150
- nextY = y - 1;
1151
- nextX = rows[nextY].cells.length - 1;
1152
- }
1153
- } else if (x === rows[y].cells.length - 1 && !isBackward) {
1154
- if (y !== rows.length - 1) {
1155
- nextY = y + 1;
1156
- nextX = 0;
1157
- }
1158
- } else if (!isBackward) {
1159
- nextX = x + 1;
1160
- nextY = y;
1161
- } else {
1162
- nextX = x - 1;
1163
- nextY = y;
1164
- }
1165
- if (nextX !== null && nextY !== null) {
1166
- modifySelectedCells(nextX, nextY, false);
1167
- return true;
1168
- }
1169
- }
1170
- return false;
1171
- },
1172
- COMMAND_PRIORITY_LOW
1173
- ),
1174
- editor.registerCommand(
1175
- KEY_ARROW_UP_COMMAND,
1176
- (event, targetEditor) => {
1177
- const selection = $getSelection();
1178
- if (!isEditing && selection === null) {
1179
- const extend = event.shiftKey;
1180
- const cellID = extend ? lastCellIDRef.current || primarySelectedCellID : primarySelectedCellID;
1181
- if (cellID !== null) {
1182
- const [x, y] = cellCoordMap.get(cellID);
1183
- if (y !== 0) {
1184
- modifySelectedCells(x, y - 1, extend);
1185
- return true;
1186
- }
1187
- }
1188
- }
1189
- if (!$isRangeSelection(selection) || targetEditor !== cellEditor) {
1190
- return false;
1191
- }
1192
- if (selection.isCollapsed() && selection.anchor.getNode().getTopLevelElementOrThrow().getPreviousSibling() === null) {
1193
- event.preventDefault();
1194
- return true;
1195
- }
1196
- return false;
1197
- },
1198
- COMMAND_PRIORITY_LOW
1199
- ),
1200
- editor.registerCommand(
1201
- KEY_ARROW_DOWN_COMMAND,
1202
- (event, targetEditor) => {
1203
- const selection = $getSelection();
1204
- if (!isEditing && selection === null) {
1205
- const extend = event.shiftKey;
1206
- const cellID = extend ? lastCellIDRef.current || primarySelectedCellID : primarySelectedCellID;
1207
- if (cellID !== null) {
1208
- const [x, y] = cellCoordMap.get(cellID);
1209
- if (y !== rows.length - 1) {
1210
- modifySelectedCells(x, y + 1, extend);
1211
- return true;
1212
- }
1213
- }
1214
- }
1215
- if (!$isRangeSelection(selection) || targetEditor !== cellEditor) {
1216
- return false;
1217
- }
1218
- if (selection.isCollapsed() && selection.anchor.getNode().getTopLevelElementOrThrow().getNextSibling() === null) {
1219
- event.preventDefault();
1220
- return true;
1221
- }
1222
- return false;
1223
- },
1224
- COMMAND_PRIORITY_LOW
1225
- ),
1226
- editor.registerCommand(
1227
- KEY_ARROW_LEFT_COMMAND,
1228
- (event, targetEditor) => {
1229
- const selection = $getSelection();
1230
- if (!isEditing && selection === null) {
1231
- const extend = event.shiftKey;
1232
- const cellID = extend ? lastCellIDRef.current || primarySelectedCellID : primarySelectedCellID;
1233
- if (cellID !== null) {
1234
- const [x, y] = cellCoordMap.get(cellID);
1235
- if (x !== 0) {
1236
- modifySelectedCells(x - 1, y, extend);
1237
- return true;
1238
- }
1239
- }
1240
- }
1241
- if (!$isRangeSelection(selection) || targetEditor !== cellEditor) {
1242
- return false;
1243
- }
1244
- if (selection.isCollapsed() && selection.anchor.offset === 0) {
1245
- event.preventDefault();
1246
- return true;
1247
- }
1248
- return false;
1249
- },
1250
- COMMAND_PRIORITY_LOW
1251
- ),
1252
- editor.registerCommand(
1253
- KEY_ARROW_RIGHT_COMMAND,
1254
- (event, targetEditor) => {
1255
- const selection = $getSelection();
1256
- if (!isEditing && selection === null) {
1257
- const extend = event.shiftKey;
1258
- const cellID = extend ? lastCellIDRef.current || primarySelectedCellID : primarySelectedCellID;
1259
- if (cellID !== null) {
1260
- const [x, y] = cellCoordMap.get(cellID);
1261
- if (x !== rows[y].cells.length - 1) {
1262
- modifySelectedCells(x + 1, y, extend);
1263
- return true;
1264
- }
1265
- }
1266
- }
1267
- if (!$isRangeSelection(selection) || targetEditor !== cellEditor) {
1268
- return false;
1269
- }
1270
- if (selection.isCollapsed()) {
1271
- const anchor = selection.anchor;
1272
- if (anchor.type === "text" && anchor.offset === anchor.getNode().getTextContentSize() || anchor.type === "element" && anchor.offset === anchor.getNode().getChildrenSize()) {
1273
- event.preventDefault();
1274
- return true;
1275
- }
1276
- }
1277
- return false;
1278
- },
1279
- COMMAND_PRIORITY_LOW
1280
- ),
1281
- editor.registerCommand(
1282
- KEY_ESCAPE_COMMAND,
1283
- (event, targetEditor) => {
1284
- const selection = $getSelection();
1285
- if (!isEditing && selection === null && targetEditor === editor) {
1286
- setSelected(true);
1287
- setPrimarySelectedCellID(null);
1288
- selectTable();
1289
- return true;
1290
- }
1291
- if (!$isRangeSelection(selection)) {
1292
- return false;
1293
- }
1294
- if (isEditing) {
1295
- saveEditorToJSON();
1296
- setIsEditing(false);
1297
- if (primarySelectedCellID !== null) {
1298
- setTimeout(() => {
1299
- focusCell(tableElem, primarySelectedCellID);
1300
- }, 20);
1301
- }
1302
- return true;
1303
- }
1304
- return false;
1305
- },
1306
- COMMAND_PRIORITY_LOW
1307
- )
1308
- );
1309
- }, [
1310
- cellCoordMap,
1311
- cellEditor,
1312
- clearCellsCommand,
1313
- clearSelection,
1314
- editor,
1315
- isEditing,
1316
- modifySelectedCells,
1317
- nodeKey,
1318
- primarySelectedCellID,
1319
- rows,
1320
- saveEditorToJSON,
1321
- selectTable,
1322
- selectedCellIDs,
1323
- setSelected,
1324
- updateTableNode
1325
- ]);
1326
- if (cellEditor === null) {
1327
- return;
1328
- }
1329
- return /* @__PURE__ */ jsxs("div", {
1330
- style: { position: "relative" },
1331
- children: [
1332
- /* @__PURE__ */ jsx("table", {
1333
- className: `${theme.table} ${isSelected ? theme.tableSelected : ""}`,
1334
- ref: tableRef,
1335
- tabIndex: -1,
1336
- children: /* @__PURE__ */ jsx("tbody", {
1337
- children: rows.map((row) => /* @__PURE__ */ jsx("tr", {
1338
- className: theme.tableRow,
1339
- children: row.cells.map((cell) => {
1340
- const { id } = cell;
1341
- return /* @__PURE__ */ jsx(TableCell, {
1342
- cell,
1343
- theme,
1344
- isSelected: selectedCellSet.has(id),
1345
- isPrimarySelected: primarySelectedCellID === id,
1346
- isEditing,
1347
- sortingOptions,
1348
- cellEditor,
1349
- updateCellsByID,
1350
- updateTableNode,
1351
- cellCoordMap,
1352
- rows,
1353
- setSortingOptions
1354
- }, id);
1355
- })
1356
- }, row.id))
1357
- })
1358
- }),
1359
- showAddColumns && /* @__PURE__ */ jsx("button", {
1360
- className: theme.tableAddColumns,
1361
- onClick: addColumns
1362
- }),
1363
- showAddRows && /* @__PURE__ */ jsx("button", {
1364
- className: theme.tableAddRows,
1365
- onClick: addRows,
1366
- ref: addRowsRef
1367
- }),
1368
- resizingID !== null && /* @__PURE__ */ jsx("div", {
1369
- className: theme.tableResizeRuler,
1370
- ref: tableResizerRulerRef
1371
- })
1372
- ]
1373
- });
1374
- }
1375
- export {
1376
- TableComponent as default
1377
- };