@thangph2146/lexical-editor 0.0.4 → 0.0.6

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 (101) hide show
  1. package/README.md +47 -0
  2. package/dist/editor-x/editor.cjs +732 -443
  3. package/dist/editor-x/editor.cjs.map +1 -1
  4. package/dist/editor-x/editor.css +1418 -1120
  5. package/dist/editor-x/editor.css.map +1 -1
  6. package/dist/editor-x/editor.d.cts +2 -1
  7. package/dist/editor-x/editor.d.ts +2 -1
  8. package/dist/editor-x/editor.js +736 -447
  9. package/dist/editor-x/editor.js.map +1 -1
  10. package/dist/index.cjs +772 -482
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.css +1418 -1120
  13. package/dist/index.css.map +1 -1
  14. package/dist/index.d.cts +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +775 -485
  17. package/dist/index.js.map +1 -1
  18. package/package.json +86 -84
  19. package/src/components/lexical-editor.tsx +140 -123
  20. package/src/editor-x/editor.tsx +20 -5
  21. package/src/editor-x/plugins.tsx +385 -380
  22. package/src/nodes/list-with-color-node.tsx +160 -160
  23. package/src/plugins/autocomplete-plugin.tsx +2574 -2574
  24. package/src/plugins/context-menu-plugin.tsx +239 -9
  25. package/src/plugins/floating-text-format-plugin.tsx +84 -92
  26. package/src/plugins/images-plugin.tsx +4 -4
  27. package/src/plugins/list-color-plugin.tsx +178 -178
  28. package/src/plugins/tab-focus-plugin.tsx +66 -66
  29. package/src/plugins/table-column-resizer-plugin.tsx +329 -190
  30. package/src/plugins/toolbar/block-format/block-format-data.tsx +4 -0
  31. package/src/plugins/toolbar/block-format/format-bulleted-list.tsx +40 -40
  32. package/src/plugins/toolbar/block-format/format-list-with-marker.tsx +74 -74
  33. package/src/plugins/toolbar/block-format/format-numbered-list.tsx +40 -40
  34. package/src/plugins/toolbar/block-format-toolbar-plugin.tsx +118 -117
  35. package/src/plugins/toolbar/element-format-toolbar-plugin.tsx +37 -53
  36. package/src/plugins/toolbar/font-format-toolbar-plugin.tsx +8 -15
  37. package/src/plugins/toolbar/font-size-toolbar-plugin.tsx +2 -3
  38. package/src/plugins/toolbar/history-toolbar-plugin.tsx +2 -5
  39. package/src/plugins/toolbar/subsuper-toolbar-plugin.tsx +15 -23
  40. package/src/themes/_mixins.scss +158 -10
  41. package/src/themes/_variables.scss +168 -0
  42. package/src/themes/core/_code.scss +59 -0
  43. package/src/themes/core/_images.scss +80 -0
  44. package/src/themes/core/_lists.scss +214 -0
  45. package/src/themes/core/_misc.scss +46 -0
  46. package/src/themes/core/_reset.scss +119 -0
  47. package/src/themes/core/_tables.scss +145 -0
  48. package/src/themes/core/_text.scss +35 -0
  49. package/src/themes/core/_typography.scss +73 -0
  50. package/src/themes/editor-theme.scss +9 -623
  51. package/src/themes/editor-theme.ts +118 -118
  52. package/src/themes/plugins/_auto-embed.scss +11 -0
  53. package/src/themes/plugins/_color-picker.scss +103 -0
  54. package/src/themes/plugins/_draggable-block.scss +32 -0
  55. package/src/themes/plugins/_floating-link-editor.scss +47 -0
  56. package/src/themes/plugins/_floating-toolbars.scss +61 -0
  57. package/src/themes/plugins/_image-resizer.scss +38 -0
  58. package/src/themes/plugins/_image.scss +57 -0
  59. package/src/themes/plugins/_layout.scss +39 -0
  60. package/src/themes/plugins/_list-color.scss +23 -0
  61. package/src/themes/plugins/_mentions.scss +21 -0
  62. package/src/themes/plugins/_menus-and-pickers.scss +153 -0
  63. package/src/themes/plugins/_table.scss +20 -0
  64. package/src/themes/plugins/_toolbar.scss +36 -0
  65. package/src/themes/plugins/_tree-view.scss +11 -0
  66. package/src/themes/plugins.scss +20 -1165
  67. package/src/themes/ui-components/_animations.scss +31 -0
  68. package/src/themes/ui-components/_backgrounds.scss +27 -0
  69. package/src/themes/ui-components/_borders.scss +20 -0
  70. package/src/themes/ui-components/_button.scss +176 -0
  71. package/src/themes/ui-components/_checkbox.scss +14 -0
  72. package/src/themes/ui-components/_cursors.scss +31 -0
  73. package/src/themes/ui-components/_dialog.scss +86 -0
  74. package/src/themes/ui-components/_display-sizing.scss +100 -0
  75. package/src/themes/ui-components/_flex.scss +124 -0
  76. package/src/themes/ui-components/_form-layout.scss +15 -0
  77. package/src/themes/ui-components/_icons.scss +23 -0
  78. package/src/themes/ui-components/_input.scss +86 -0
  79. package/src/themes/ui-components/_label.scss +19 -0
  80. package/src/themes/ui-components/_loader.scss +9 -0
  81. package/src/themes/ui-components/_margins-paddings.scss +45 -0
  82. package/src/themes/ui-components/_popover.scss +16 -0
  83. package/src/themes/ui-components/_positioning.scss +73 -0
  84. package/src/themes/ui-components/_rounded.scss +19 -0
  85. package/src/themes/ui-components/_scroll-area.scss +11 -0
  86. package/src/themes/ui-components/_select.scss +110 -0
  87. package/src/themes/ui-components/_separator.scss +19 -0
  88. package/src/themes/ui-components/_shadow.scss +15 -0
  89. package/src/themes/ui-components/_tabs.scss +46 -0
  90. package/src/themes/ui-components/_text-utilities.scss +48 -0
  91. package/src/themes/ui-components/_toggle-toolbar.scss +128 -0
  92. package/src/themes/ui-components/_toggle.scss +80 -0
  93. package/src/themes/ui-components/_typography.scss +22 -0
  94. package/src/themes/ui-components.scss +27 -937
  95. package/src/transformers/markdown-list-transformer.ts +51 -51
  96. package/src/ui/button.tsx +11 -2
  97. package/src/ui/collapsible.tsx +1 -1
  98. package/src/ui/dialog.tsx +2 -2
  99. package/src/ui/flex.tsx +4 -4
  100. package/src/ui/popover.tsx +1 -1
  101. package/src/ui/tooltip.tsx +2 -2
@@ -1,380 +1,385 @@
1
- "use client"
2
- import { useState } from "react"
3
- import {
4
- CHECK_LIST,
5
- ELEMENT_TRANSFORMERS,
6
- MULTILINE_ELEMENT_TRANSFORMERS,
7
- TEXT_FORMAT_TRANSFORMERS,
8
- TEXT_MATCH_TRANSFORMERS,
9
- } from "@lexical/markdown"
10
- import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin"
11
- import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin"
12
- import { ClickableLinkPlugin } from "@lexical/react/LexicalClickableLinkPlugin"
13
- import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary"
14
- import { HashtagPlugin } from "@lexical/react/LexicalHashtagPlugin"
15
- import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin"
16
- import { HorizontalRulePlugin } from "@lexical/react/LexicalHorizontalRulePlugin"
17
- import { ListPlugin } from "@lexical/react/LexicalListPlugin"
18
- import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin"
19
- import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin"
20
- import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin"
21
- import { TablePlugin } from "@lexical/react/LexicalTablePlugin"
22
-
23
- import { ContentEditable } from "../editor-ui/content-editable"
24
- import { cn } from "../lib/utils"
25
- import { ActionsPlugin } from "../plugins/actions/actions-plugin"
26
- import { AlignPlugin } from "../plugins/align-plugin"
27
- import { ClearEditorActionPlugin } from "../plugins/actions/clear-editor-plugin"
28
- import { CounterCharacterPlugin } from "../plugins/actions/counter-character-plugin"
29
- import { EditModeTogglePlugin } from "../plugins/actions/edit-mode-toggle-plugin"
30
- import { ImportExportPlugin } from "../plugins/actions/import-export-plugin"
31
- import { MarkdownTogglePlugin } from "../plugins/actions/markdown-toggle-plugin"
32
- import { ShareContentPlugin } from "../plugins/actions/share-content-plugin"
33
- import { SpeechToTextPlugin } from "../plugins/actions/speech-to-text-plugin"
34
- import { TreeViewPlugin } from "../plugins/actions/tree-view-plugin"
35
- import { AutoLinkPlugin } from "../plugins/auto-link-plugin"
36
- import { AutocompletePlugin } from "../plugins/autocomplete-plugin"
37
- import { CodeActionMenuPlugin } from "../plugins/code-action-menu-plugin"
38
- import { CodeHighlightPlugin } from "../plugins/code-highlight-plugin"
39
- import { ComponentPickerMenuPlugin } from "../plugins/component-picker-menu-plugin"
40
- import { ContextMenuPlugin } from "../plugins/context-menu-plugin"
41
- import { DragDropPastePlugin } from "../plugins/drag-drop-paste-plugin"
42
- import { DraggableBlockPlugin } from "../plugins/draggable-block-plugin"
43
- import { AutoEmbedPlugin } from "../plugins/embeds/auto-embed-plugin"
44
- import { TwitterPlugin } from "../plugins/embeds/twitter-plugin"
45
- import { YouTubePlugin } from "../plugins/embeds/youtube-plugin"
46
- import { EmojiPickerPlugin } from "../plugins/emoji-picker-plugin"
47
- import { EmojisPlugin } from "../plugins/emojis-plugin"
48
- import { FloatingLinkEditorPlugin } from "../plugins/floating-link-editor-plugin"
49
- import { FloatingTextFormatToolbarPlugin } from "../plugins/floating-text-format-plugin"
50
- import { ImagesPlugin } from "../plugins/images-plugin"
51
- import { KeywordsPlugin } from "../plugins/keywords-plugin"
52
- import { LayoutPlugin } from "../plugins/layout-plugin"
53
- import { LinkPlugin } from "../plugins/link-plugin"
54
- import { ListColorPlugin } from "../plugins/list-color-plugin"
55
- import { ListMaxIndentLevelPlugin } from "../plugins/list-max-indent-level-plugin"
56
- import { MentionsPlugin } from "../plugins/mentions-plugin"
57
- import { AlignmentPickerPlugin } from "../plugins/picker/alignment-picker-plugin"
58
- import { BulletedListPickerPlugin } from "../plugins/picker/bulleted-list-picker-plugin"
59
- import { CheckListPickerPlugin } from "../plugins/picker/check-list-picker-plugin"
60
- import { CodePickerPlugin } from "../plugins/picker/code-picker-plugin"
61
- import { ColumnsLayoutPickerPlugin } from "../plugins/picker/columns-layout-picker-plugin"
62
- import { DividerPickerPlugin } from "../plugins/picker/divider-picker-plugin"
63
- import { EmbedsPickerPlugin } from "../plugins/picker/embeds-picker-plugin"
64
- import { HeadingPickerPlugin } from "../plugins/picker/heading-picker-plugin"
65
- import { ImagePickerPlugin } from "../plugins/picker/image-picker-plugin"
66
- import { NumberedListPickerPlugin } from "../plugins/picker/numbered-list-picker-plugin"
67
- import { ParagraphPickerPlugin } from "../plugins/picker/paragraph-picker-plugin"
68
- import { QuotePickerPlugin } from "../plugins/picker/quote-picker-plugin"
69
- import {
70
- DynamicTablePickerPlugin,
71
- TablePickerPlugin,
72
- } from "../plugins/picker/table-picker-plugin"
73
- import { TabFocusPlugin } from "../plugins/tab-focus-plugin"
74
- import { TableColumnResizerPlugin } from "../plugins/table-column-resizer-plugin"
75
- import {
76
- InsertTableCommandPlugin,
77
- } from "../plugins/table-plugin"
78
- import { BlockFormatDropDown } from "../plugins/toolbar/block-format-toolbar-plugin"
79
- import { FormatBulletedList } from "../plugins/toolbar/block-format/format-bulleted-list"
80
- import { FormatCheckList } from "../plugins/toolbar/block-format/format-check-list"
81
- import { FormatCodeBlock } from "../plugins/toolbar/block-format/format-code-block"
82
- import { FormatHeading } from "../plugins/toolbar/block-format/format-heading"
83
- import { FormatListWithMarker } from "../plugins/toolbar/block-format/format-list-with-marker"
84
- import { FormatNumberedList } from "../plugins/toolbar/block-format/format-numbered-list"
85
- import { FormatParagraph } from "../plugins/toolbar/block-format/format-paragraph"
86
- import { FormatQuote } from "../plugins/toolbar/block-format/format-quote"
87
- import { BlockInsertPlugin } from "../plugins/toolbar/block-insert-plugin"
88
- import { InsertColumnsLayout } from "../plugins/toolbar/block-insert/insert-columns-layout"
89
- import { InsertEmbeds } from "../plugins/toolbar/block-insert/insert-embeds"
90
- import { InsertHorizontalRule } from "../plugins/toolbar/block-insert/insert-horizontal-rule"
91
- import { InsertImage } from "../plugins/toolbar/block-insert/insert-image"
92
- import { InsertTable } from "../plugins/toolbar/block-insert/insert-table"
93
- import { ClearFormattingToolbarPlugin } from "../plugins/toolbar/clear-formatting-toolbar-plugin"
94
- import { CodeLanguageToolbarPlugin } from "../plugins/toolbar/code-language-toolbar-plugin"
95
- import { ElementFormatToolbarPlugin } from "../plugins/toolbar/element-format-toolbar-plugin"
96
- import { FontBackgroundToolbarPlugin } from "../plugins/toolbar/font-background-toolbar-plugin"
97
- import { FontColorToolbarPlugin } from "../plugins/toolbar/font-color-toolbar-plugin"
98
- import { FontFamilyToolbarPlugin } from "../plugins/toolbar/font-family-toolbar-plugin"
99
- import { FontFormatToolbarPlugin } from "../plugins/toolbar/font-format-toolbar-plugin"
100
- import { FontSizeToolbarPlugin } from "../plugins/toolbar/font-size-toolbar-plugin"
101
- import { HistoryToolbarPlugin } from "../plugins/toolbar/history-toolbar-plugin"
102
- import { LinkToolbarPlugin } from "../plugins/toolbar/link-toolbar-plugin"
103
- import { SubSuperToolbarPlugin } from "../plugins/toolbar/subsuper-toolbar-plugin"
104
- import { ToolbarPlugin } from "../plugins/toolbar/toolbar-plugin"
105
- import { TypingPerfPlugin } from "../plugins/typing-pref-plugin"
106
- import { EMOJI } from "../transformers/markdown-emoji-transformer"
107
- import { HR } from "../transformers/markdown-hr-transformer"
108
- import { IMAGE } from "../transformers/markdown-image-transformer"
109
- import { TABLE } from "../transformers/markdown-table-transformer"
110
- import { TWEET } from "../transformers/markdown-tweet-transformer"
111
- import { UNORDERED_LIST } from "../transformers/markdown-list-transformer"
112
- import { Separator } from "../ui/separator"
113
-
114
- const placeholder = "Press / for commands..."
115
-
116
- export function Plugins({
117
- readOnly = false,
118
- }: {
119
- readOnly?: boolean
120
- }) {
121
- const [floatingAnchorElem, setFloatingAnchorElem] =
122
- useState<HTMLDivElement | null>(null)
123
- const [isLinkEditMode, setIsLinkEditMode] = useState<boolean>(false)
124
-
125
- const onRef = (_floatingAnchorElem: HTMLDivElement) => {
126
- if (_floatingAnchorElem !== null) {
127
- setFloatingAnchorElem(_floatingAnchorElem)
128
- }
129
- }
130
-
131
- return (
132
- <div className="editor-relative-full">
133
- {!readOnly && (
134
- <ToolbarPlugin
135
- className="editor-toolbar"
136
- >
137
- {({ blockType }) => (
138
- <>
139
- <div className="editor-toolbar-group">
140
- <HistoryToolbarPlugin />
141
- </div>
142
- <Separator orientation="vertical" className="editor-toolbar-separator" />
143
- <div className="editor-toolbar-group">
144
- <BlockInsertPlugin>
145
- <InsertHorizontalRule />
146
- <InsertImage />
147
- <InsertTable />
148
- <InsertColumnsLayout />
149
- <InsertEmbeds />
150
- </BlockInsertPlugin>
151
- </div>
152
- <Separator orientation="vertical" className="editor-toolbar-separator" />
153
- <div className="editor-toolbar-group">
154
- <BlockFormatDropDown>
155
- <FormatParagraph />
156
- <FormatHeading levels={["h1", "h2", "h3"]} />
157
- <FormatNumberedList />
158
- <FormatListWithMarker
159
- blockFormatValue="number-alpha"
160
- listType="number"
161
- markerType="alpha"
162
- />
163
- <FormatBulletedList />
164
- <FormatListWithMarker
165
- blockFormatValue="bullet-dash"
166
- listType="bullet"
167
- markerType="-"
168
- />
169
- <FormatListWithMarker
170
- blockFormatValue="bullet-plus"
171
- listType="bullet"
172
- markerType="+"
173
- />
174
- <FormatCheckList />
175
- <FormatCodeBlock />
176
- <FormatQuote />
177
- </BlockFormatDropDown>
178
- </div>
179
- {blockType === "code" ? (
180
- <div className="editor-toolbar-group">
181
- <CodeLanguageToolbarPlugin />
182
- </div>
183
- ) : (
184
- <>
185
- <div className="editor-toolbar-group">
186
- <FontFamilyToolbarPlugin />
187
- <FontSizeToolbarPlugin />
188
- </div>
189
- <Separator orientation="vertical" className="editor-toolbar-separator" />
190
- <div className="editor-toolbar-group">
191
- <FontFormatToolbarPlugin />
192
- </div>
193
- <Separator orientation="vertical" className="editor-toolbar-separator" />
194
- <div className="editor-toolbar-group">
195
- <SubSuperToolbarPlugin />
196
- <LinkToolbarPlugin setIsLinkEditMode={setIsLinkEditMode} />
197
- </div>
198
- <Separator orientation="vertical" className="editor-toolbar-separator" />
199
- <div className="editor-toolbar-group">
200
- <ClearFormattingToolbarPlugin />
201
- </div>
202
- <Separator orientation="vertical" className="editor-toolbar-separator" />
203
- <div className="editor-toolbar-group">
204
- <FontColorToolbarPlugin />
205
- <FontBackgroundToolbarPlugin />
206
- </div>
207
- <Separator orientation="vertical" className="editor-toolbar-separator" />
208
- <div className="editor-toolbar-group">
209
- <ElementFormatToolbarPlugin />
210
- </div>
211
- </>
212
- )}
213
- </>
214
- )}
215
- </ToolbarPlugin>
216
- )}
217
-
218
- <div className={cn("editor-relative-full")}>
219
- {/* AutoFocusPlugin removed to prevent auto-scroll on page load */}
220
- <RichTextPlugin
221
- contentEditable={
222
- <div className={cn("editor-relative-full")}>
223
- <div className={cn("editor-relative-full")} ref={onRef}>
224
- <ContentEditable
225
- placeholder={readOnly ? "" : placeholder}
226
- className={cn(
227
- "editor-content-editable",
228
- readOnly && "editor-content-editable--readonly"
229
- )}
230
- />
231
- </div>
232
- </div>
233
- }
234
- ErrorBoundary={LexicalErrorBoundary}
235
- placeholder={readOnly ? null : <div className="editor-placeholder">{placeholder}</div>}
236
- />
237
-
238
- <ClickableLinkPlugin />
239
- {!readOnly && (
240
- <>
241
- <CheckListPlugin />
242
- <AlignPlugin />
243
- <HorizontalRulePlugin />
244
- <TablePlugin hasHorizontalScroll={true} />
245
- <InsertTableCommandPlugin />
246
- <TableColumnResizerPlugin />
247
- <ListPlugin />
248
- <TabIndentationPlugin />
249
- <HistoryPlugin />
250
- </>
251
- )}
252
- <HashtagPlugin />
253
-
254
- <MentionsPlugin />
255
- {!readOnly && <DraggableBlockPlugin anchorElem={floatingAnchorElem} />}
256
- <KeywordsPlugin />
257
- <EmojisPlugin />
258
- {!readOnly && <ImagesPlugin />}
259
-
260
- {!readOnly && <LayoutPlugin />}
261
- {!readOnly && <ListColorPlugin />}
262
-
263
- {!readOnly && (
264
- <>
265
- <AutoEmbedPlugin />
266
- <TwitterPlugin />
267
- <YouTubePlugin />
268
- </>
269
- )}
270
-
271
- <CodeHighlightPlugin />
272
- {!readOnly && <CodeActionMenuPlugin anchorElem={floatingAnchorElem} />}
273
-
274
- {!readOnly && (
275
- <>
276
- <MarkdownShortcutPlugin
277
- transformers={[
278
- TABLE,
279
- HR,
280
- IMAGE,
281
- EMOJI,
282
- TWEET,
283
- CHECK_LIST,
284
- UNORDERED_LIST,
285
- ...ELEMENT_TRANSFORMERS.filter(
286
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
- (t) => t.type !== "element" || (t as any).regExp?.toString().indexOf("[*+-]") === -1
288
- ),
289
- ...MULTILINE_ELEMENT_TRANSFORMERS,
290
- ...TEXT_FORMAT_TRANSFORMERS,
291
- ...TEXT_MATCH_TRANSFORMERS,
292
- ]}
293
- />
294
- <TypingPerfPlugin />
295
- <TabFocusPlugin />
296
- <AutocompletePlugin />
297
- <AutoLinkPlugin />
298
- <LinkPlugin />
299
- <ClearEditorPlugin />
300
-
301
- <ComponentPickerMenuPlugin
302
- baseOptions={[
303
- ParagraphPickerPlugin(),
304
- HeadingPickerPlugin({ n: 1 }),
305
- HeadingPickerPlugin({ n: 2 }),
306
- HeadingPickerPlugin({ n: 3 }),
307
- TablePickerPlugin(),
308
- CheckListPickerPlugin(),
309
- NumberedListPickerPlugin(),
310
- BulletedListPickerPlugin(),
311
- QuotePickerPlugin(),
312
- CodePickerPlugin(),
313
- DividerPickerPlugin(),
314
- EmbedsPickerPlugin({ embed: "tweet" }),
315
- EmbedsPickerPlugin({ embed: "youtube-video" }),
316
- ImagePickerPlugin(),
317
- ColumnsLayoutPickerPlugin(),
318
- AlignmentPickerPlugin({ alignment: "left" }),
319
- AlignmentPickerPlugin({ alignment: "center" }),
320
- AlignmentPickerPlugin({ alignment: "right" }),
321
- AlignmentPickerPlugin({ alignment: "justify" }),
322
- ]}
323
- dynamicOptionsFn={DynamicTablePickerPlugin}
324
- />
325
-
326
- <ContextMenuPlugin />
327
- <DragDropPastePlugin />
328
- <EmojiPickerPlugin />
329
-
330
- <FloatingLinkEditorPlugin
331
- anchorElem={floatingAnchorElem}
332
- isLinkEditMode={isLinkEditMode}
333
- setIsLinkEditMode={setIsLinkEditMode}
334
- />
335
- <FloatingTextFormatToolbarPlugin
336
- anchorElem={floatingAnchorElem}
337
- setIsLinkEditMode={setIsLinkEditMode}
338
- />
339
-
340
- <ListMaxIndentLevelPlugin />
341
- </>
342
- )}
343
- </div>
344
- {!readOnly && (
345
- <ActionsPlugin>
346
- <div className="editor-actions-bar">
347
- <div className="editor-flex-shrink-0">
348
- <CounterCharacterPlugin charset="UTF-16" />
349
- </div>
350
- <div className="editor-flex-1" />
351
- <div className="editor-flex-shrink-0 editor-flex-end">
352
- <SpeechToTextPlugin />
353
- <ShareContentPlugin />
354
- <ImportExportPlugin />
355
- <MarkdownTogglePlugin
356
- shouldPreserveNewLinesInMarkdown={true}
357
- transformers={[
358
- TABLE,
359
- HR,
360
- IMAGE,
361
- EMOJI,
362
- TWEET,
363
- CHECK_LIST,
364
- UNORDERED_LIST,
365
- ...ELEMENT_TRANSFORMERS,
366
- ...MULTILINE_ELEMENT_TRANSFORMERS,
367
- ...TEXT_FORMAT_TRANSFORMERS,
368
- ...TEXT_MATCH_TRANSFORMERS,
369
- ]}
370
- />
371
- <EditModeTogglePlugin />
372
- <ClearEditorActionPlugin />
373
- <TreeViewPlugin />
374
- </div>
375
- </div>
376
- </ActionsPlugin>
377
- )}
378
- </div>
379
- )
380
- }
1
+ "use client"
2
+ import { useState } from "react"
3
+ import {
4
+ CHECK_LIST,
5
+ ELEMENT_TRANSFORMERS,
6
+ MULTILINE_ELEMENT_TRANSFORMERS,
7
+ TEXT_FORMAT_TRANSFORMERS,
8
+ TEXT_MATCH_TRANSFORMERS,
9
+ } from "@lexical/markdown"
10
+ import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin"
11
+ import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin"
12
+ import { ClickableLinkPlugin } from "@lexical/react/LexicalClickableLinkPlugin"
13
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary"
14
+ import { HashtagPlugin } from "@lexical/react/LexicalHashtagPlugin"
15
+ import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin"
16
+ import { HorizontalRulePlugin } from "@lexical/react/LexicalHorizontalRulePlugin"
17
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin"
18
+ import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin"
19
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin"
20
+ import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin"
21
+ import { TablePlugin } from "@lexical/react/LexicalTablePlugin"
22
+
23
+ import { ContentEditable } from "../editor-ui/content-editable"
24
+ import { cn } from "../lib/utils"
25
+ import { ActionsPlugin } from "../plugins/actions/actions-plugin"
26
+ import { AlignPlugin } from "../plugins/align-plugin"
27
+ import { ClearEditorActionPlugin } from "../plugins/actions/clear-editor-plugin"
28
+ import { CounterCharacterPlugin } from "../plugins/actions/counter-character-plugin"
29
+ import { EditModeTogglePlugin } from "../plugins/actions/edit-mode-toggle-plugin"
30
+ import { ImportExportPlugin } from "../plugins/actions/import-export-plugin"
31
+ import { MarkdownTogglePlugin } from "../plugins/actions/markdown-toggle-plugin"
32
+ import { ShareContentPlugin } from "../plugins/actions/share-content-plugin"
33
+ import { SpeechToTextPlugin } from "../plugins/actions/speech-to-text-plugin"
34
+ import { TreeViewPlugin } from "../plugins/actions/tree-view-plugin"
35
+ import { AutoLinkPlugin } from "../plugins/auto-link-plugin"
36
+ import { AutocompletePlugin } from "../plugins/autocomplete-plugin"
37
+ import { CodeActionMenuPlugin } from "../plugins/code-action-menu-plugin"
38
+ import { CodeHighlightPlugin } from "../plugins/code-highlight-plugin"
39
+ import { ComponentPickerMenuPlugin } from "../plugins/component-picker-menu-plugin"
40
+ import { ContextMenuPlugin } from "../plugins/context-menu-plugin"
41
+ import { DragDropPastePlugin } from "../plugins/drag-drop-paste-plugin"
42
+ import { DraggableBlockPlugin } from "../plugins/draggable-block-plugin"
43
+ import { AutoEmbedPlugin } from "../plugins/embeds/auto-embed-plugin"
44
+ import { TwitterPlugin } from "../plugins/embeds/twitter-plugin"
45
+ import { YouTubePlugin } from "../plugins/embeds/youtube-plugin"
46
+ import { EmojiPickerPlugin } from "../plugins/emoji-picker-plugin"
47
+ import { EmojisPlugin } from "../plugins/emojis-plugin"
48
+ import { FloatingLinkEditorPlugin } from "../plugins/floating-link-editor-plugin"
49
+ import { FloatingTextFormatToolbarPlugin } from "../plugins/floating-text-format-plugin"
50
+ import { ImagesPlugin } from "../plugins/images-plugin"
51
+ import { KeywordsPlugin } from "../plugins/keywords-plugin"
52
+ import { LayoutPlugin } from "../plugins/layout-plugin"
53
+ import { LinkPlugin } from "../plugins/link-plugin"
54
+ import { ListColorPlugin } from "../plugins/list-color-plugin"
55
+ import { ListMaxIndentLevelPlugin } from "../plugins/list-max-indent-level-plugin"
56
+ import { MentionsPlugin } from "../plugins/mentions-plugin"
57
+ import { AlignmentPickerPlugin } from "../plugins/picker/alignment-picker-plugin"
58
+ import { BulletedListPickerPlugin } from "../plugins/picker/bulleted-list-picker-plugin"
59
+ import { CheckListPickerPlugin } from "../plugins/picker/check-list-picker-plugin"
60
+ import { CodePickerPlugin } from "../plugins/picker/code-picker-plugin"
61
+ import { ColumnsLayoutPickerPlugin } from "../plugins/picker/columns-layout-picker-plugin"
62
+ import { DividerPickerPlugin } from "../plugins/picker/divider-picker-plugin"
63
+ import { EmbedsPickerPlugin } from "../plugins/picker/embeds-picker-plugin"
64
+ import { HeadingPickerPlugin } from "../plugins/picker/heading-picker-plugin"
65
+ import { ImagePickerPlugin } from "../plugins/picker/image-picker-plugin"
66
+ import { NumberedListPickerPlugin } from "../plugins/picker/numbered-list-picker-plugin"
67
+ import { ParagraphPickerPlugin } from "../plugins/picker/paragraph-picker-plugin"
68
+ import { QuotePickerPlugin } from "../plugins/picker/quote-picker-plugin"
69
+ import {
70
+ DynamicTablePickerPlugin,
71
+ TablePickerPlugin,
72
+ } from "../plugins/picker/table-picker-plugin"
73
+ import { TabFocusPlugin } from "../plugins/tab-focus-plugin"
74
+ import { TableColumnResizerPlugin } from "../plugins/table-column-resizer-plugin"
75
+ import {
76
+ InsertTableCommandPlugin,
77
+ } from "../plugins/table-plugin"
78
+ import { BlockFormatDropDown } from "../plugins/toolbar/block-format-toolbar-plugin"
79
+ import { FormatBulletedList } from "../plugins/toolbar/block-format/format-bulleted-list"
80
+ import { FormatCheckList } from "../plugins/toolbar/block-format/format-check-list"
81
+ import { FormatCodeBlock } from "../plugins/toolbar/block-format/format-code-block"
82
+ import { FormatHeading } from "../plugins/toolbar/block-format/format-heading"
83
+ import { FormatListWithMarker } from "../plugins/toolbar/block-format/format-list-with-marker"
84
+ import { FormatNumberedList } from "../plugins/toolbar/block-format/format-numbered-list"
85
+ import { FormatParagraph } from "../plugins/toolbar/block-format/format-paragraph"
86
+ import { FormatQuote } from "../plugins/toolbar/block-format/format-quote"
87
+ import { BlockInsertPlugin } from "../plugins/toolbar/block-insert-plugin"
88
+ import { InsertColumnsLayout } from "../plugins/toolbar/block-insert/insert-columns-layout"
89
+ import { InsertEmbeds } from "../plugins/toolbar/block-insert/insert-embeds"
90
+ import { InsertHorizontalRule } from "../plugins/toolbar/block-insert/insert-horizontal-rule"
91
+ import { InsertImage } from "../plugins/toolbar/block-insert/insert-image"
92
+ import { InsertTable } from "../plugins/toolbar/block-insert/insert-table"
93
+ import { ClearFormattingToolbarPlugin } from "../plugins/toolbar/clear-formatting-toolbar-plugin"
94
+ import { CodeLanguageToolbarPlugin } from "../plugins/toolbar/code-language-toolbar-plugin"
95
+ import { ElementFormatToolbarPlugin } from "../plugins/toolbar/element-format-toolbar-plugin"
96
+ import { FontBackgroundToolbarPlugin } from "../plugins/toolbar/font-background-toolbar-plugin"
97
+ import { FontColorToolbarPlugin } from "../plugins/toolbar/font-color-toolbar-plugin"
98
+ import { FontFamilyToolbarPlugin } from "../plugins/toolbar/font-family-toolbar-plugin"
99
+ import { FontFormatToolbarPlugin } from "../plugins/toolbar/font-format-toolbar-plugin"
100
+ import { FontSizeToolbarPlugin } from "../plugins/toolbar/font-size-toolbar-plugin"
101
+ import { HistoryToolbarPlugin } from "../plugins/toolbar/history-toolbar-plugin"
102
+ import { LinkToolbarPlugin } from "../plugins/toolbar/link-toolbar-plugin"
103
+ import { SubSuperToolbarPlugin } from "../plugins/toolbar/subsuper-toolbar-plugin"
104
+ import { ToolbarPlugin } from "../plugins/toolbar/toolbar-plugin"
105
+ import { TypingPerfPlugin } from "../plugins/typing-pref-plugin"
106
+ import { EMOJI } from "../transformers/markdown-emoji-transformer"
107
+ import { HR } from "../transformers/markdown-hr-transformer"
108
+ import { IMAGE } from "../transformers/markdown-image-transformer"
109
+ import { TABLE } from "../transformers/markdown-table-transformer"
110
+ import { TWEET } from "../transformers/markdown-tweet-transformer"
111
+ import { UNORDERED_LIST } from "../transformers/markdown-list-transformer"
112
+ import { Separator } from "../ui/separator"
113
+
114
+ export function Plugins({
115
+ readOnly = false,
116
+ placeholder = "",
117
+ }: {
118
+ readOnly?: boolean
119
+ placeholder?: string
120
+ }) {
121
+ const [floatingAnchorElem, setFloatingAnchorElem] =
122
+ useState<HTMLDivElement | null>(null)
123
+ const [isLinkEditMode, setIsLinkEditMode] = useState<boolean>(false)
124
+
125
+ const onRef = (_floatingAnchorElem: HTMLDivElement) => {
126
+ if (_floatingAnchorElem !== null) {
127
+ setFloatingAnchorElem(_floatingAnchorElem)
128
+ }
129
+ }
130
+
131
+ return (
132
+ <div className="editor-relative-full">
133
+ {!readOnly && (
134
+ <ToolbarPlugin
135
+ className="editor-toolbar"
136
+ >
137
+ {({ blockType }) => (
138
+ <>
139
+ <div className="editor-toolbar-group">
140
+ <HistoryToolbarPlugin />
141
+ </div>
142
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
143
+ {blockType !== "code" && (
144
+ <>
145
+ <div className="editor-toolbar-group">
146
+ <BlockInsertPlugin>
147
+ <InsertHorizontalRule />
148
+ <InsertImage />
149
+ <InsertTable />
150
+ <InsertColumnsLayout />
151
+ <InsertEmbeds />
152
+ </BlockInsertPlugin>
153
+ </div>
154
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
155
+ <div className="editor-toolbar-group">
156
+ <BlockFormatDropDown>
157
+ <FormatParagraph />
158
+ <FormatHeading levels={["h1", "h2", "h3"]} />
159
+ <FormatNumberedList />
160
+ <FormatListWithMarker
161
+ blockFormatValue="number-alpha"
162
+ listType="number"
163
+ markerType="alpha"
164
+ />
165
+ <FormatBulletedList />
166
+ <FormatListWithMarker
167
+ blockFormatValue="bullet-dash"
168
+ listType="bullet"
169
+ markerType="-"
170
+ />
171
+ <FormatListWithMarker
172
+ blockFormatValue="bullet-plus"
173
+ listType="bullet"
174
+ markerType="+"
175
+ />
176
+ <FormatCheckList />
177
+ <FormatCodeBlock />
178
+ <FormatQuote />
179
+ </BlockFormatDropDown>
180
+ </div>
181
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
182
+ </>
183
+ )}
184
+ {blockType === "code" ? (
185
+ <div className="editor-toolbar-group">
186
+ <CodeLanguageToolbarPlugin />
187
+ </div>
188
+ ) : (
189
+ <>
190
+ <div className="editor-toolbar-group">
191
+ <FontFamilyToolbarPlugin />
192
+ <FontSizeToolbarPlugin />
193
+ </div>
194
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
195
+ <div className="editor-toolbar-group">
196
+ <FontFormatToolbarPlugin />
197
+ </div>
198
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
199
+ <div className="editor-toolbar-group">
200
+ <SubSuperToolbarPlugin />
201
+ <LinkToolbarPlugin setIsLinkEditMode={setIsLinkEditMode} />
202
+ </div>
203
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
204
+ <div className="editor-toolbar-group">
205
+ <ClearFormattingToolbarPlugin />
206
+ </div>
207
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
208
+ <div className="editor-toolbar-group">
209
+ <FontColorToolbarPlugin />
210
+ <FontBackgroundToolbarPlugin />
211
+ </div>
212
+ <Separator orientation="vertical" className="editor-toolbar-separator" />
213
+ <div className="editor-toolbar-group">
214
+ <ElementFormatToolbarPlugin />
215
+ </div>
216
+ </>
217
+ )}
218
+ </>
219
+ )}
220
+ </ToolbarPlugin>
221
+ )}
222
+
223
+ <div className={cn("editor-relative-full")}>
224
+ {/* AutoFocusPlugin removed to prevent auto-scroll on page load */}
225
+ <RichTextPlugin
226
+ contentEditable={
227
+ <div className={cn("editor-relative-full")}>
228
+ <div className={cn("editor-relative-full")} ref={onRef}>
229
+ <ContentEditable
230
+ placeholder={readOnly ? "" : placeholder}
231
+ className={cn(
232
+ "editor-content-editable",
233
+ readOnly && "editor-content-editable--readonly"
234
+ )}
235
+ />
236
+ </div>
237
+ </div>
238
+ }
239
+ ErrorBoundary={LexicalErrorBoundary}
240
+ placeholder={readOnly ? null : <div className="editor-placeholder">{placeholder}</div>}
241
+ />
242
+
243
+ <ClickableLinkPlugin />
244
+ {!readOnly && (
245
+ <>
246
+ <CheckListPlugin />
247
+ <AlignPlugin />
248
+ <HorizontalRulePlugin />
249
+ <TablePlugin hasHorizontalScroll={true} />
250
+ <InsertTableCommandPlugin />
251
+ <TableColumnResizerPlugin anchorElem={floatingAnchorElem ?? document.body} />
252
+ <ListPlugin />
253
+ <TabIndentationPlugin />
254
+ <HistoryPlugin />
255
+ </>
256
+ )}
257
+ <HashtagPlugin />
258
+
259
+ <MentionsPlugin />
260
+ {!readOnly && <DraggableBlockPlugin anchorElem={floatingAnchorElem} />}
261
+ <KeywordsPlugin />
262
+ <EmojisPlugin />
263
+ {!readOnly && <ImagesPlugin />}
264
+
265
+ {!readOnly && <LayoutPlugin />}
266
+ {!readOnly && <ListColorPlugin />}
267
+
268
+ {!readOnly && (
269
+ <>
270
+ <AutoEmbedPlugin />
271
+ <TwitterPlugin />
272
+ <YouTubePlugin />
273
+ </>
274
+ )}
275
+
276
+ <CodeHighlightPlugin />
277
+ {!readOnly && <CodeActionMenuPlugin anchorElem={floatingAnchorElem} />}
278
+
279
+ {!readOnly && (
280
+ <>
281
+ <MarkdownShortcutPlugin
282
+ transformers={[
283
+ TABLE,
284
+ HR,
285
+ IMAGE,
286
+ EMOJI,
287
+ TWEET,
288
+ CHECK_LIST,
289
+ UNORDERED_LIST,
290
+ ...ELEMENT_TRANSFORMERS.filter(
291
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
292
+ (t) => t.type !== "element" || (t as any).regExp?.toString().indexOf("[*+-]") === -1
293
+ ),
294
+ ...MULTILINE_ELEMENT_TRANSFORMERS,
295
+ ...TEXT_FORMAT_TRANSFORMERS,
296
+ ...TEXT_MATCH_TRANSFORMERS,
297
+ ]}
298
+ />
299
+ <TypingPerfPlugin />
300
+ <TabFocusPlugin />
301
+ <AutocompletePlugin />
302
+ <AutoLinkPlugin />
303
+ <LinkPlugin />
304
+ <ClearEditorPlugin />
305
+
306
+ <ComponentPickerMenuPlugin
307
+ baseOptions={[
308
+ ParagraphPickerPlugin(),
309
+ HeadingPickerPlugin({ n: 1 }),
310
+ HeadingPickerPlugin({ n: 2 }),
311
+ HeadingPickerPlugin({ n: 3 }),
312
+ TablePickerPlugin(),
313
+ CheckListPickerPlugin(),
314
+ NumberedListPickerPlugin(),
315
+ BulletedListPickerPlugin(),
316
+ QuotePickerPlugin(),
317
+ CodePickerPlugin(),
318
+ DividerPickerPlugin(),
319
+ EmbedsPickerPlugin({ embed: "tweet" }),
320
+ EmbedsPickerPlugin({ embed: "youtube-video" }),
321
+ ImagePickerPlugin(),
322
+ ColumnsLayoutPickerPlugin(),
323
+ AlignmentPickerPlugin({ alignment: "left" }),
324
+ AlignmentPickerPlugin({ alignment: "center" }),
325
+ AlignmentPickerPlugin({ alignment: "right" }),
326
+ AlignmentPickerPlugin({ alignment: "justify" }),
327
+ ]}
328
+ dynamicOptionsFn={DynamicTablePickerPlugin}
329
+ />
330
+
331
+ <ContextMenuPlugin />
332
+ <DragDropPastePlugin />
333
+ <EmojiPickerPlugin />
334
+
335
+ <FloatingLinkEditorPlugin
336
+ anchorElem={floatingAnchorElem}
337
+ isLinkEditMode={isLinkEditMode}
338
+ setIsLinkEditMode={setIsLinkEditMode}
339
+ />
340
+ <FloatingTextFormatToolbarPlugin
341
+ anchorElem={floatingAnchorElem}
342
+ setIsLinkEditMode={setIsLinkEditMode}
343
+ />
344
+
345
+ <ListMaxIndentLevelPlugin />
346
+ </>
347
+ )}
348
+ </div>
349
+ {!readOnly && (
350
+ <ActionsPlugin>
351
+ <div className="editor-actions-bar">
352
+ <div className="editor-flex-shrink-0">
353
+ <CounterCharacterPlugin charset="UTF-16" />
354
+ </div>
355
+ <div className="editor-flex-1" />
356
+ <div className="editor-flex-shrink-0 editor-flex-end">
357
+ <SpeechToTextPlugin />
358
+ <ShareContentPlugin />
359
+ <ImportExportPlugin />
360
+ <MarkdownTogglePlugin
361
+ shouldPreserveNewLinesInMarkdown={true}
362
+ transformers={[
363
+ TABLE,
364
+ HR,
365
+ IMAGE,
366
+ EMOJI,
367
+ TWEET,
368
+ CHECK_LIST,
369
+ UNORDERED_LIST,
370
+ ...ELEMENT_TRANSFORMERS,
371
+ ...MULTILINE_ELEMENT_TRANSFORMERS,
372
+ ...TEXT_FORMAT_TRANSFORMERS,
373
+ ...TEXT_MATCH_TRANSFORMERS,
374
+ ]}
375
+ />
376
+ <EditModeTogglePlugin />
377
+ <ClearEditorActionPlugin />
378
+ <TreeViewPlugin />
379
+ </div>
380
+ </div>
381
+ </ActionsPlugin>
382
+ )}
383
+ </div>
384
+ )
385
+ }