@crystallize/design-system 1.6.1 → 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 +13 -0
  2. package/dist/index.css +53 -332
  3. package/dist/index.d.ts +15 -8
  4. package/dist/index.js +1736 -4555
  5. package/dist/index.mjs +1655 -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 +13 -2
  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,398 +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 * as React from 'react';
10
- import { Suspense } from 'react';
11
- import {
12
- DecoratorNode,
13
- type DOMConversionMap,
14
- type DOMConversionOutput,
15
- type DOMExportOutput,
16
- type EditorConfig,
17
- type LexicalEditor,
18
- type LexicalNode,
19
- type NodeKey,
20
- type SerializedLexicalNode,
21
- type Spread,
22
- } from 'lexical';
23
-
24
- export type Cell = {
25
- colSpan: number;
26
- json: string;
27
- type: 'normal' | 'header';
28
- id: string;
29
- width: number | null;
30
- };
31
-
32
- export type Row = {
33
- cells: Array<Cell>;
34
- height: null | number;
35
- id: string;
36
- };
37
-
38
- export type Rows = Array<Row>;
39
-
40
- export const cellHTMLCache: Map<string, string> = new Map();
41
- export const cellTextContentCache: Map<string, string> = new Map();
42
-
43
- const emptyEditorJSON =
44
- '{"root":{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}';
45
-
46
- const plainTextEditorJSON = (text: string) =>
47
- text === ''
48
- ? emptyEditorJSON
49
- : `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":${text},"type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`;
50
-
51
- const TableComponent = React.lazy(
52
- // @ts-ignore
53
- () => import('./TableComponent'),
54
- );
55
-
56
- export function createUID(): string {
57
- return Math.random()
58
- .toString(36)
59
- .replace(/[^a-z]+/g, '')
60
- .substr(0, 5);
61
- }
62
-
63
- function createCell(type: 'normal' | 'header'): Cell {
64
- return {
65
- colSpan: 1,
66
- id: createUID(),
67
- json: emptyEditorJSON,
68
- type,
69
- width: null,
70
- };
71
- }
72
-
73
- export function createRow(): Row {
74
- return {
75
- cells: [],
76
- height: null,
77
- id: createUID(),
78
- };
79
- }
80
-
81
- export type SerializedTableNode = Spread<
82
- {
83
- rows: Rows;
84
- type: 'tablesheet';
85
- version: 1;
86
- },
87
- SerializedLexicalNode
88
- >;
89
-
90
- export function extractRowsFromHTML(tableElem: HTMLTableElement): Rows {
91
- const rowElems = tableElem.querySelectorAll('tr');
92
- const rows: Rows = [];
93
- for (let y = 0; y < rowElems.length; y++) {
94
- const rowElem = rowElems[y];
95
- const cellElems = rowElem.querySelectorAll('td,th');
96
- if (!cellElems || cellElems.length === 0) {
97
- continue;
98
- }
99
- const cells: Array<Cell> = [];
100
- for (let x = 0; x < cellElems.length; x++) {
101
- const cellElem = cellElems[x] as HTMLElement;
102
- const isHeader = cellElem.nodeName === 'TH';
103
- const cell = createCell(isHeader ? 'header' : 'normal');
104
- cell.json = plainTextEditorJSON(JSON.stringify(cellElem.innerText.replace(/\n/g, ' ')));
105
- cells.push(cell);
106
- }
107
- const row = createRow();
108
- row.cells = cells;
109
- rows.push(row);
110
- }
111
- return rows;
112
- }
113
-
114
- function convertTableElement(domNode: HTMLElement): null | DOMConversionOutput {
115
- const rowElems = domNode.querySelectorAll('tr');
116
- if (!rowElems || rowElems.length === 0) {
117
- return null;
118
- }
119
- const rows: Rows = [];
120
- for (let y = 0; y < rowElems.length; y++) {
121
- const rowElem = rowElems[y];
122
- const cellElems = rowElem.querySelectorAll('td,th');
123
- if (!cellElems || cellElems.length === 0) {
124
- continue;
125
- }
126
- const cells: Array<Cell> = [];
127
- for (let x = 0; x < cellElems.length; x++) {
128
- const cellElem = cellElems[x] as HTMLElement;
129
- const isHeader = cellElem.nodeName === 'TH';
130
- const cell = createCell(isHeader ? 'header' : 'normal');
131
- cell.json = plainTextEditorJSON(JSON.stringify(cellElem.innerText.replace(/\n/g, ' ')));
132
- cells.push(cell);
133
- }
134
- const row = createRow();
135
- row.cells = cells;
136
- rows.push(row);
137
- }
138
- return { node: $createTableNode(rows) };
139
- }
140
-
141
- export function exportTableCellsToHTML(
142
- rows: Rows,
143
- rect?: { startX: number; endX: number; startY: number; endY: number },
144
- ): HTMLElement {
145
- const table = document.createElement('table');
146
- const colGroup = document.createElement('colgroup');
147
- const tBody = document.createElement('tbody');
148
- const firstRow = rows[0];
149
-
150
- for (let x = rect != null ? rect.startX : 0; x < (rect != null ? rect.endX + 1 : firstRow.cells.length); x++) {
151
- const col = document.createElement('col');
152
- colGroup.append(col);
153
- }
154
-
155
- for (let y = rect != null ? rect.startY : 0; y < (rect != null ? rect.endY + 1 : rows.length); y++) {
156
- const row = rows[y];
157
- const cells = row.cells;
158
- const rowElem = document.createElement('tr');
159
-
160
- for (let x = rect != null ? rect.startX : 0; x < (rect != null ? rect.endX + 1 : cells.length); x++) {
161
- const cell = cells[x];
162
- const cellElem = document.createElement(cell.type === 'header' ? 'th' : 'td');
163
- cellElem.innerHTML = cellHTMLCache.get(cell.json) || '';
164
- rowElem.appendChild(cellElem);
165
- }
166
- tBody.appendChild(rowElem);
167
- }
168
-
169
- table.appendChild(colGroup);
170
- table.appendChild(tBody);
171
- return table;
172
- }
173
-
174
- export class TableNode extends DecoratorNode<JSX.Element> {
175
- __rows: Rows;
176
-
177
- static getType(): string {
178
- return 'tablesheet';
179
- }
180
-
181
- static clone(node: TableNode): TableNode {
182
- return new TableNode(Array.from(node.__rows), node.__key);
183
- }
184
-
185
- static importJSON(serializedNode: SerializedTableNode): TableNode {
186
- return $createTableNode(serializedNode.rows);
187
- }
188
-
189
- exportJSON(): SerializedTableNode {
190
- return {
191
- rows: this.__rows,
192
- type: 'tablesheet',
193
- version: 1,
194
- };
195
- }
196
-
197
- static importDOM(): DOMConversionMap | null {
198
- return {
199
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
200
- table: (_node: Node) => ({
201
- conversion: convertTableElement,
202
- priority: 0,
203
- }),
204
- };
205
- }
206
-
207
- exportDOM(): DOMExportOutput {
208
- return { element: exportTableCellsToHTML(this.__rows) };
209
- }
210
-
211
- constructor(rows?: Rows, key?: NodeKey) {
212
- super(key);
213
- this.__rows = rows || [];
214
- }
215
-
216
- createDOM(): HTMLElement {
217
- return document.createElement('div');
218
- }
219
-
220
- updateDOM(): false {
221
- return false;
222
- }
223
-
224
- mergeRows(startX: number, startY: number, mergeRows: Rows): void {
225
- const self = this.getWritable();
226
- const rows = self.__rows;
227
- const endY = Math.min(rows.length, startY + mergeRows.length);
228
- for (let y = startY; y < endY; y++) {
229
- const row = rows[y];
230
- const mergeRow = mergeRows[y - startY];
231
- const cells = row.cells;
232
- const cellsClone = Array.from(cells);
233
- const rowClone = { ...row, cells: cellsClone };
234
- const mergeCells = mergeRow.cells;
235
- const endX = Math.min(cells.length, startX + mergeCells.length);
236
- for (let x = startX; x < endX; x++) {
237
- const cell = cells[x];
238
- const mergeCell = mergeCells[x - startX];
239
- const cellClone = { ...cell, json: mergeCell.json, type: mergeCell.type };
240
- cellsClone[x] = cellClone;
241
- }
242
- rows[y] = rowClone;
243
- }
244
- }
245
-
246
- updateCellJSON(x: number, y: number, json: string): void {
247
- const self = this.getWritable();
248
- const rows = self.__rows;
249
- const row = rows[y];
250
- const cells = row.cells;
251
- const cell = cells[x];
252
- const cellsClone = Array.from(cells);
253
- const cellClone = { ...cell, json };
254
- const rowClone = { ...row, cells: cellsClone };
255
- cellsClone[x] = cellClone;
256
- rows[y] = rowClone;
257
- }
258
-
259
- updateCellType(x: number, y: number, type: 'header' | 'normal'): void {
260
- const self = this.getWritable();
261
- const rows = self.__rows;
262
- const row = rows[y];
263
- const cells = row.cells;
264
- const cell = cells[x];
265
- const cellsClone = Array.from(cells);
266
- const cellClone = { ...cell, type };
267
- const rowClone = { ...row, cells: cellsClone };
268
- cellsClone[x] = cellClone;
269
- rows[y] = rowClone;
270
- }
271
-
272
- insertColumnAt(x: number): void {
273
- const self = this.getWritable();
274
- const rows = self.__rows;
275
- for (let y = 0; y < rows.length; y++) {
276
- const row = rows[y];
277
- const cells = row.cells;
278
- const cellsClone = Array.from(cells);
279
- const rowClone = { ...row, cells: cellsClone };
280
- const type = (cells[x] || cells[x - 1]).type;
281
- cellsClone.splice(x, 0, createCell(type));
282
- rows[y] = rowClone;
283
- }
284
- }
285
-
286
- deleteColumnAt(x: number): void {
287
- const self = this.getWritable();
288
- const rows = self.__rows;
289
- for (let y = 0; y < rows.length; y++) {
290
- const row = rows[y];
291
- const cells = row.cells;
292
- const cellsClone = Array.from(cells);
293
- const rowClone = { ...row, cells: cellsClone };
294
- cellsClone.splice(x, 1);
295
- rows[y] = rowClone;
296
- }
297
- }
298
-
299
- addColumns(count: number): void {
300
- const self = this.getWritable();
301
- const rows = self.__rows;
302
- for (let y = 0; y < rows.length; y++) {
303
- const row = rows[y];
304
- const cells = row.cells;
305
- const cellsClone = Array.from(cells);
306
- const rowClone = { ...row, cells: cellsClone };
307
- const type = cells[cells.length - 1].type;
308
- for (let x = 0; x < count; x++) {
309
- cellsClone.push(createCell(type));
310
- }
311
- rows[y] = rowClone;
312
- }
313
- }
314
-
315
- insertRowAt(y: number): void {
316
- const self = this.getWritable();
317
- const rows = self.__rows;
318
- const prevRow = rows[y] || rows[y - 1];
319
- const cellCount = prevRow.cells.length;
320
- const row = createRow();
321
- for (let x = 0; x < cellCount; x++) {
322
- const cell = createCell(prevRow.cells[x].type);
323
- row.cells.push(cell);
324
- }
325
- rows.splice(y, 0, row);
326
- }
327
-
328
- deleteRowAt(y: number): void {
329
- const self = this.getWritable();
330
- const rows = self.__rows;
331
- rows.splice(y, 1);
332
- }
333
-
334
- addRows(count: number): void {
335
- const self = this.getWritable();
336
- const rows = self.__rows;
337
- const prevRow = rows[rows.length - 1];
338
- const cellCount = prevRow.cells.length;
339
-
340
- for (let y = 0; y < count; y++) {
341
- const row = createRow();
342
- for (let x = 0; x < cellCount; x++) {
343
- const cell = createCell(prevRow.cells[x].type);
344
- row.cells.push(cell);
345
- }
346
- rows.push(row);
347
- }
348
- }
349
-
350
- updateColumnWidth(x: number, width: number): void {
351
- const self = this.getWritable();
352
- const rows = self.__rows;
353
- for (let y = 0; y < rows.length; y++) {
354
- const row = rows[y];
355
- const cells = row.cells;
356
- const cellsClone = Array.from(cells);
357
- const rowClone = { ...row, cells: cellsClone };
358
- cellsClone[x].width = width;
359
- rows[y] = rowClone;
360
- }
361
- }
362
-
363
- decorate(_: LexicalEditor, config: EditorConfig): JSX.Element {
364
- return (
365
- <Suspense fallback="...">
366
- <TableComponent nodeKey={this.__key} theme={config.theme} rows={this.__rows} />
367
- </Suspense>
368
- );
369
- }
370
-
371
- isInline(): false {
372
- return false;
373
- }
374
- }
375
-
376
- export function $isTableNode(node: LexicalNode | null | undefined): node is TableNode {
377
- return node instanceof TableNode;
378
- }
379
-
380
- export function $createTableNode(rows: Rows): TableNode {
381
- return new TableNode(rows);
382
- }
383
-
384
- export function $createTableNodeWithDimensions(
385
- rowCount: number,
386
- columnCount: number,
387
- includeHeaders = true,
388
- ): TableNode {
389
- const rows: Rows = [];
390
- for (let y = 0; y < columnCount; y++) {
391
- const row: Row = createRow();
392
- rows.push(row);
393
- for (let x = 0; x < rowCount; x++) {
394
- row.cells.push(createCell(includeHeaders === true && (y === 0 || x === 0) ? 'header' : 'normal'));
395
- }
396
- }
397
- return new TableNode(rows);
398
- }