@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,386 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
- import type {Cell} from '@lexical/table';
9
- import type {LexicalEditor} from 'lexical';
10
-
11
- import './index.css';
12
-
13
- import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
14
- import useLexicalEditable from '@lexical/react/useLexicalEditable';
15
- import {
16
- $getTableColumnIndexFromTableCellNode,
17
- $getTableNodeFromLexicalNodeOrThrow,
18
- $getTableRowIndexFromTableCellNode,
19
- $isTableCellNode,
20
- $isTableRowNode,
21
- getCellFromTarget,
22
- } from '@lexical/table';
23
- import {
24
- $getNearestNodeFromDOMNode,
25
- $getSelection,
26
- COMMAND_PRIORITY_HIGH,
27
- DEPRECATED_$isGridSelection,
28
- SELECTION_CHANGE_COMMAND,
29
- } from 'lexical';
30
- import * as React from 'react';
31
- import {
32
- MouseEventHandler,
33
- ReactPortal,
34
- useCallback,
35
- useEffect,
36
- useMemo,
37
- useRef,
38
- useState,
39
- } from 'react';
40
- import {createPortal} from 'react-dom';
41
-
42
- type MousePosition = {
43
- x: number;
44
- y: number;
45
- };
46
-
47
- type MouseDraggingDirection = 'right' | 'bottom';
48
-
49
- const MIN_ROW_HEIGHT = 33;
50
- const MIN_COLUMN_WIDTH = 50;
51
-
52
- function TableCellResizer({editor}: {editor: LexicalEditor}): JSX.Element {
53
- const targetRef = useRef<HTMLElement | null>(null);
54
- const resizerRef = useRef<HTMLDivElement | null>(null);
55
- const tableRectRef = useRef<ClientRect | null>(null);
56
-
57
- const mouseStartPosRef = useRef<MousePosition | null>(null);
58
- const [mouseCurrentPos, updateMouseCurrentPos] =
59
- useState<MousePosition | null>(null);
60
-
61
- const [activeCell, updateActiveCell] = useState<Cell | null>(null);
62
- const [isSelectingGrid, updateIsSelectingGrid] = useState<boolean>(false);
63
- const [draggingDirection, updateDraggingDirection] =
64
- useState<MouseDraggingDirection | null>(null);
65
-
66
- useEffect(() => {
67
- return editor.registerCommand(
68
- SELECTION_CHANGE_COMMAND,
69
- (payload) => {
70
- const selection = $getSelection();
71
- const isGridSelection = DEPRECATED_$isGridSelection(selection);
72
-
73
- if (isSelectingGrid !== isGridSelection) {
74
- updateIsSelectingGrid(isGridSelection);
75
- }
76
-
77
- return false;
78
- },
79
- COMMAND_PRIORITY_HIGH,
80
- );
81
- });
82
-
83
- const resetState = useCallback(() => {
84
- updateActiveCell(null);
85
- targetRef.current = null;
86
- updateDraggingDirection(null);
87
- mouseStartPosRef.current = null;
88
- tableRectRef.current = null;
89
- }, []);
90
-
91
- useEffect(() => {
92
- const onMouseMove = (event: MouseEvent) => {
93
- setTimeout(() => {
94
- const target = event.target;
95
-
96
- if (draggingDirection) {
97
- updateMouseCurrentPos({
98
- x: event.clientX,
99
- y: event.clientY,
100
- });
101
- return;
102
- }
103
-
104
- if (resizerRef.current && resizerRef.current.contains(target as Node)) {
105
- return;
106
- }
107
-
108
- if (targetRef.current !== target) {
109
- targetRef.current = target as HTMLElement;
110
- const cell = getCellFromTarget(target as HTMLElement);
111
-
112
- if (cell && activeCell !== cell) {
113
- editor.update(() => {
114
- const tableCellNode = $getNearestNodeFromDOMNode(cell.elem);
115
- if (!tableCellNode) {
116
- throw new Error('TableCellResizer: Table cell node not found.');
117
- }
118
-
119
- const tableNode =
120
- $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
121
- const tableElement = editor.getElementByKey(tableNode.getKey());
122
-
123
- if (!tableElement) {
124
- throw new Error('TableCellResizer: Table element not found.');
125
- }
126
-
127
- targetRef.current = target as HTMLElement;
128
- tableRectRef.current = tableElement.getBoundingClientRect();
129
- updateActiveCell(cell);
130
- });
131
- } else if (cell == null) {
132
- resetState();
133
- }
134
- }
135
- }, 0);
136
- };
137
-
138
- document.addEventListener('mousemove', onMouseMove);
139
-
140
- return () => {
141
- document.removeEventListener('mousemove', onMouseMove);
142
- };
143
- }, [activeCell, draggingDirection, editor, resetState]);
144
-
145
- const isHeightChanging = (direction: MouseDraggingDirection) => {
146
- if (direction === 'bottom') return true;
147
- return false;
148
- };
149
-
150
- const updateRowHeight = useCallback(
151
- (newHeight: number) => {
152
- if (!activeCell) {
153
- throw new Error('TableCellResizer: Expected active cell.');
154
- }
155
-
156
- editor.update(() => {
157
- const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
158
- if (!$isTableCellNode(tableCellNode)) {
159
- throw new Error('TableCellResizer: Table cell node not found.');
160
- }
161
-
162
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
163
-
164
- const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
165
-
166
- const tableRows = tableNode.getChildren();
167
-
168
- if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
169
- throw new Error('Expected table cell to be inside of table row.');
170
- }
171
-
172
- const tableRow = tableRows[tableRowIndex];
173
-
174
- if (!$isTableRowNode(tableRow)) {
175
- throw new Error('Expected table row');
176
- }
177
-
178
- tableRow.setHeight(newHeight);
179
- });
180
- },
181
- [activeCell, editor],
182
- );
183
-
184
- const updateColumnWidth = useCallback(
185
- (newWidth: number) => {
186
- if (!activeCell) {
187
- throw new Error('TableCellResizer: Expected active cell.');
188
- }
189
- editor.update(() => {
190
- const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
191
- if (!$isTableCellNode(tableCellNode)) {
192
- throw new Error('TableCellResizer: Table cell node not found.');
193
- }
194
-
195
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
196
-
197
- const tableColumnIndex =
198
- $getTableColumnIndexFromTableCellNode(tableCellNode);
199
-
200
- const tableRows = tableNode.getChildren();
201
-
202
- for (let r = 0; r < tableRows.length; r++) {
203
- const tableRow = tableRows[r];
204
-
205
- if (!$isTableRowNode(tableRow)) {
206
- throw new Error('Expected table row');
207
- }
208
-
209
- const tableCells = tableRow.getChildren();
210
-
211
- if (tableColumnIndex >= tableCells.length || tableColumnIndex < 0) {
212
- throw new Error('Expected table cell to be inside of table row.');
213
- }
214
-
215
- const tableCell = tableCells[tableColumnIndex];
216
-
217
- if (!$isTableCellNode(tableCell)) {
218
- throw new Error('Expected table cell');
219
- }
220
-
221
- tableCell.setWidth(newWidth);
222
- }
223
- });
224
- },
225
- [activeCell, editor],
226
- );
227
-
228
- const toggleResize = useCallback(
229
- (direction: MouseDraggingDirection): MouseEventHandler<HTMLDivElement> =>
230
- (event) => {
231
- event.preventDefault();
232
- event.stopPropagation();
233
-
234
- if (!activeCell) {
235
- throw new Error('TableCellResizer: Expected active cell.');
236
- }
237
-
238
- if (draggingDirection === direction && mouseStartPosRef.current) {
239
- const {x, y} = mouseStartPosRef.current;
240
-
241
- if (activeCell === null) {
242
- return;
243
- }
244
-
245
- const {height, width} = activeCell.elem.getBoundingClientRect();
246
-
247
- if (isHeightChanging(direction)) {
248
- const heightChange = Math.abs(event.clientY - y);
249
-
250
- const isShrinking = direction === 'bottom' && y > event.clientY;
251
-
252
- updateRowHeight(
253
- Math.max(
254
- isShrinking ? height - heightChange : heightChange + height,
255
- MIN_ROW_HEIGHT,
256
- ),
257
- );
258
- } else {
259
- const widthChange = Math.abs(event.clientX - x);
260
-
261
- const isShrinking = direction === 'right' && x > event.clientX;
262
-
263
- updateColumnWidth(
264
- Math.max(
265
- isShrinking ? width - widthChange : widthChange + width,
266
- MIN_COLUMN_WIDTH,
267
- ),
268
- );
269
- }
270
-
271
- resetState();
272
- } else {
273
- mouseStartPosRef.current = {
274
- x: event.clientX,
275
- y: event.clientY,
276
- };
277
- updateMouseCurrentPos(mouseStartPosRef.current);
278
- updateDraggingDirection(direction);
279
- }
280
- },
281
- [
282
- activeCell,
283
- draggingDirection,
284
- resetState,
285
- updateColumnWidth,
286
- updateRowHeight,
287
- ],
288
- );
289
-
290
- const getResizers = useCallback(() => {
291
- if (activeCell) {
292
- const {height, width, top, left} =
293
- activeCell.elem.getBoundingClientRect();
294
-
295
- const styles = {
296
- bottom: {
297
- backgroundColor: 'none',
298
- cursor: 'row-resize',
299
- height: '10px',
300
- left: `${window.pageXOffset + left}px`,
301
- top: `${window.pageYOffset + top + height}px`,
302
- width: `${width}px`,
303
- },
304
- right: {
305
- backgroundColor: 'none',
306
- cursor: 'col-resize',
307
- height: `${height}px`,
308
- left: `${window.pageXOffset + left + width}px`,
309
- top: `${window.pageYOffset + top}px`,
310
- width: '10px',
311
- },
312
- };
313
-
314
- const tableRect = tableRectRef.current;
315
-
316
- if (draggingDirection && mouseCurrentPos && tableRect) {
317
- if (isHeightChanging(draggingDirection)) {
318
- styles[draggingDirection].left = `${
319
- window.pageXOffset + tableRect.left
320
- }px`;
321
- styles[draggingDirection].top = `${
322
- window.pageYOffset + mouseCurrentPos.y
323
- }px`;
324
- styles[draggingDirection].height = '3px';
325
- styles[draggingDirection].width = `${tableRect.width}px`;
326
- } else {
327
- styles[draggingDirection].top = `${
328
- window.pageYOffset + tableRect.top
329
- }px`;
330
- styles[draggingDirection].left = `${
331
- window.pageXOffset + mouseCurrentPos.x
332
- }px`;
333
- styles[draggingDirection].width = '3px';
334
- styles[draggingDirection].height = `${tableRect.height}px`;
335
- }
336
-
337
- styles[draggingDirection].backgroundColor = '#adf';
338
- }
339
-
340
- return styles;
341
- }
342
-
343
- return {
344
- bottom: null,
345
- left: null,
346
- right: null,
347
- top: null,
348
- };
349
- }, [activeCell, draggingDirection, mouseCurrentPos]);
350
-
351
- const resizerStyles = getResizers();
352
-
353
- return (
354
- <div ref={resizerRef}>
355
- {activeCell != null && !isSelectingGrid && (
356
- <>
357
- <div
358
- className="TableCellResizer__resizer TableCellResizer__ui"
359
- style={resizerStyles.right || undefined}
360
- onMouseDown={toggleResize('right')}
361
- onMouseUp={toggleResize('right')}
362
- />
363
- <div
364
- className="TableCellResizer__resizer TableCellResizer__ui"
365
- style={resizerStyles.bottom || undefined}
366
- onMouseDown={toggleResize('bottom')}
367
- onMouseUp={toggleResize('bottom')}
368
- />
369
- </>
370
- )}
371
- </div>
372
- );
373
- }
374
-
375
- export default function TableCellResizerPlugin(): null | ReactPortal {
376
- const [editor] = useLexicalComposerContext();
377
- const isEditable = useLexicalEditable();
378
-
379
- return useMemo(
380
- () =>
381
- isEditable
382
- ? createPortal(<TableCellResizer editor={editor} />, document.body)
383
- : null,
384
- [editor, isEditable],
385
- );
386
- }
@@ -1,190 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
-
9
- import { createContext, useContext, useEffect, useMemo, useState } from 'react';
10
- import * as React from 'react';
11
- import {
12
- $createNodeSelection,
13
- $createParagraphNode,
14
- $getSelection,
15
- $isRangeSelection,
16
- $isRootOrShadowRoot,
17
- $setSelection,
18
- COMMAND_PRIORITY_EDITOR,
19
- createCommand,
20
- EditorThemeClasses,
21
- Klass,
22
- LexicalCommand,
23
- LexicalEditor,
24
- LexicalNode,
25
- } from 'lexical';
26
- import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
27
-
28
- import { Button } from '../../button';
29
- import { InputWithLabel } from '../../input-with-label';
30
- import { $createTableNodeWithDimensions, TableNode } from '../nodes/TableNode';
31
-
32
- export type InsertTableCommandPayload = Readonly<{
33
- columns: string;
34
- rows: string;
35
- includeHeaders?: boolean;
36
- }>;
37
-
38
- export type CellContextShape = {
39
- cellEditorConfig: null | CellEditorConfig;
40
- cellEditorPlugins: null | JSX.Element | Array<JSX.Element>;
41
- set: (cellEditorConfig: null | CellEditorConfig, cellEditorPlugins: null | JSX.Element | Array<JSX.Element>) => void;
42
- };
43
-
44
- export type CellEditorConfig = Readonly<{
45
- namespace: string;
46
- nodes?: ReadonlyArray<Klass<LexicalNode>>;
47
- onError: (error: Error, editor: LexicalEditor) => void;
48
- readOnly?: boolean;
49
- theme?: EditorThemeClasses;
50
- }>;
51
-
52
- export const INSERT_NEW_TABLE_COMMAND: LexicalCommand<InsertTableCommandPayload> =
53
- createCommand('INSERT_NEW_TABLE_COMMAND');
54
-
55
- export const CellContext = createContext<CellContextShape>({
56
- cellEditorConfig: null,
57
- cellEditorPlugins: null,
58
- set: () => {
59
- // Empty
60
- },
61
- });
62
-
63
- export function TableContext({ children }: { children: JSX.Element }) {
64
- const [contextValue, setContextValue] = useState<{
65
- cellEditorConfig: null | CellEditorConfig;
66
- cellEditorPlugins: null | JSX.Element | Array<JSX.Element>;
67
- }>({
68
- cellEditorConfig: null,
69
- cellEditorPlugins: null,
70
- });
71
- return (
72
- <CellContext.Provider
73
- value={useMemo(
74
- () => ({
75
- cellEditorConfig: contextValue.cellEditorConfig,
76
- cellEditorPlugins: contextValue.cellEditorPlugins,
77
- set: (cellEditorConfig, cellEditorPlugins) => {
78
- setContextValue({ cellEditorConfig, cellEditorPlugins });
79
- },
80
- }),
81
- [contextValue.cellEditorConfig, contextValue.cellEditorPlugins],
82
- )}
83
- >
84
- {children}
85
- </CellContext.Provider>
86
- );
87
- }
88
-
89
- export function InsertNewTableDialog({ activeEditor }: { activeEditor: LexicalEditor }): JSX.Element {
90
- const [rows, setRows] = useState('5');
91
- const [columns, setColumns] = useState('5');
92
-
93
- const onClick = () => {
94
- if (parseInt(rows) < 1 || parseInt(columns) < 1) {
95
- return;
96
- }
97
- activeEditor.dispatchCommand(INSERT_NEW_TABLE_COMMAND, { columns, rows });
98
- };
99
-
100
- return (
101
- <>
102
- <div className="grid grid-cols-[1fr_1px_1fr] border border-gray-100-800 border-solid shadow-sm rounded-md ">
103
- <InputWithLabel
104
- label="Rows"
105
- value={rows}
106
- placeholder="0"
107
- type="text"
108
- inputMode="numeric"
109
- onChange={e => setRows(e.target.value)}
110
- />
111
- <span className="h-full bg-gray-100-800" />
112
- <InputWithLabel
113
- type="text"
114
- label="Columns"
115
- placeholder="0"
116
- value={columns}
117
- inputMode="numeric"
118
- onChange={e => setColumns(e.target.value)}
119
- />
120
- </div>
121
- <div className="flex justify-end mt-3">
122
- <Button size="sm" intent="action" aria-label="Confirm" onClick={onClick}>
123
- Confirm
124
- </Button>
125
- </div>
126
- </>
127
- );
128
- }
129
-
130
- export function TablePlugin({
131
- cellEditorConfig,
132
- children,
133
- }: {
134
- cellEditorConfig: CellEditorConfig;
135
- children: JSX.Element | Array<JSX.Element>;
136
- }): JSX.Element | null {
137
- const [editor] = useLexicalComposerContext();
138
- const cellContext = useContext(CellContext);
139
-
140
- useEffect(() => {
141
- if (!editor.hasNodes([TableNode])) {
142
- throw new Error('TablePlugin: TableNode is not registered on editor');
143
- }
144
-
145
- cellContext.set(cellEditorConfig, children);
146
-
147
- return editor.registerCommand<InsertTableCommandPayload>(
148
- INSERT_NEW_TABLE_COMMAND,
149
- ({ columns, rows, includeHeaders }) => {
150
- const selection = $getSelection();
151
-
152
- if (!$isRangeSelection(selection)) {
153
- return true;
154
- }
155
-
156
- const focus = selection.focus;
157
- const focusNode = focus.getNode();
158
-
159
- if (focusNode !== null) {
160
- const tableNode = $createTableNodeWithDimensions(Number(rows), Number(columns), includeHeaders);
161
-
162
- if ($isRootOrShadowRoot(focusNode)) {
163
- const target = focusNode.getChildAtIndex(focus.offset);
164
-
165
- if (target !== null) {
166
- target.insertBefore(tableNode);
167
- } else {
168
- focusNode.append(tableNode);
169
- }
170
-
171
- tableNode.insertBefore($createParagraphNode());
172
- } else {
173
- const topLevelNode = focusNode.getTopLevelElementOrThrow();
174
- topLevelNode.insertAfter(tableNode);
175
- }
176
-
177
- tableNode.insertAfter($createParagraphNode());
178
- const nodeSelection = $createNodeSelection();
179
- nodeSelection.add(tableNode.getKey());
180
- $setSelection(nodeSelection);
181
- }
182
-
183
- return true;
184
- },
185
- COMMAND_PRIORITY_EDITOR,
186
- );
187
- }, [cellContext, cellEditorConfig, children, editor]);
188
-
189
- return null;
190
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
-
9
- import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
10
- import { TreeView } from '@lexical/react/LexicalTreeView';
11
- import * as React from 'react';
12
-
13
- export default function TreeViewPlugin(): JSX.Element {
14
- const [editor] = useLexicalComposerContext();
15
- return (
16
- <TreeView
17
- viewClassName="tree-view-output"
18
- timeTravelPanelClassName="debug-timetravel-panel"
19
- timeTravelButtonClassName="debug-timetravel-button"
20
- timeTravelPanelSliderClassName="debug-timetravel-panel-slider"
21
- timeTravelPanelButtonClassName="debug-timetravel-panel-button"
22
- editor={editor}
23
- />
24
- );
25
- }