@haklex/rich-plugin-toolbar 0.1.1 → 0.2.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.
package/dist/index.mjs CHANGED
@@ -1,14 +1,15 @@
1
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { collectCommandItems, $selectionTouchesSpoiler, $toggleSpoilerSelection } from "@haklex/rich-editor/commands";
3
- import { TooltipTrigger, TooltipRoot, TooltipContent, DropdownMenuContent, DropdownMenuItem, DropdownMenu, DropdownMenuTrigger, createTooltipHandle, TooltipProvider } from "@haklex/rich-editor-ui";
4
- import { $isListNode, INSERT_UNORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND } from "@lexical/list";
1
+ import { $selectionTouchesSpoiler, $toggleSpoilerSelection, collectCommandItems } from "@haklex/rich-editor/commands";
2
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger, createTooltipHandle } from "@haklex/rich-editor-ui";
3
+ import { $isListNode, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from "@lexical/list";
5
4
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
6
5
  import { $createHeadingNode, $isHeadingNode } from "@lexical/rich-text";
7
6
  import { $getSelectionStyleValueForProperty, $patchStyleText, $setBlocksType } from "@lexical/selection";
8
7
  import { $findMatchingParent } from "@lexical/utils";
9
- import { $getSelection, $isRangeSelection, $isRootOrShadowRoot, $isElementNode, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, CAN_REDO_COMMAND, $createParagraphNode, UNDO_COMMAND, REDO_COMMAND, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND } from "lexical";
10
- import { ChevronDown, Pilcrow, Heading1, Heading2, Heading3, Undo, Redo, Bold, Italic, Underline, Strikethrough, Code, Highlighter, EyeOff, List, ListOrdered, ListChecks, AlignLeft, AlignCenter, AlignRight, AlignJustify, Ellipsis } from "lucide-react";
11
- import { useState, useMemo, useCallback, useEffect } from "react";
8
+ import { $createParagraphNode, $getSelection, $isElementNode, $isRangeSelection, $isRootOrShadowRoot, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, REDO_COMMAND, UNDO_COMMAND } from "lexical";
9
+ import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold, ChevronDown, Code, Ellipsis, EyeOff, Heading1, Heading2, Heading3, Highlighter, Italic, List, ListChecks, ListOrdered, Pilcrow, Redo, Strikethrough, Underline, Undo } from "lucide-react";
10
+ import { useCallback, useEffect, useMemo, useState } from "react";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ //#region src/styles.css.ts
12
13
  var toolbarContainer = "_1e1ersc0";
13
14
  var toolbarRow = "_1e1ersc1";
14
15
  var toolbarButton = "_1e1ersc2";
@@ -17,598 +18,568 @@ var toolbarDropdownTrigger = "_1e1ersc4";
17
18
  var toolbarDropdownTriggerChevron = "_1e1ersc5";
18
19
  var toolbarSeparator = "_1e1ersc6";
19
20
  var toolbarDropdownItemActive = "_1e1ersc7";
20
- var tooltipShortcut = "_1e1ersc8";
21
- function ToolbarButton({
22
- icon,
23
- title,
24
- shortcut,
25
- active,
26
- disabled,
27
- onClick,
28
- tooltipHandle
29
- }) {
30
- const button = /* @__PURE__ */ jsx(
31
- "button",
32
- {
33
- "aria-label": title,
34
- "aria-pressed": active,
35
- className: `${toolbarButton}${active ? ` ${toolbarButtonActive}` : ""}`,
36
- disabled,
37
- type: "button",
38
- onMouseDown: (e) => {
39
- e.preventDefault();
40
- onClick();
41
- }
42
- }
43
- );
44
- if (tooltipHandle) {
45
- return /* @__PURE__ */ jsx(
46
- TooltipTrigger,
47
- {
48
- handle: tooltipHandle,
49
- payload: { title, shortcut },
50
- render: button,
51
- children: icon
52
- }
53
- );
54
- }
55
- return /* @__PURE__ */ jsxs(TooltipRoot, { children: [
56
- /* @__PURE__ */ jsx(TooltipTrigger, { render: button, children: icon }),
57
- /* @__PURE__ */ jsxs(TooltipContent, { side: "bottom", sideOffset: 4, children: [
58
- title,
59
- shortcut && /* @__PURE__ */ jsx("span", { className: tooltipShortcut, children: shortcut })
60
- ] })
61
- ] });
21
+ //#endregion
22
+ //#region src/ToolbarButton.tsx
23
+ function ToolbarButton({ icon, title, shortcut, active, disabled, onClick, tooltipHandle }) {
24
+ const button = /* @__PURE__ */ jsx("button", {
25
+ "aria-label": title,
26
+ "aria-pressed": active,
27
+ className: `${toolbarButton}${active ? ` ${toolbarButtonActive}` : ""}`,
28
+ disabled,
29
+ type: "button",
30
+ onMouseDown: (e) => {
31
+ e.preventDefault();
32
+ onClick();
33
+ }
34
+ });
35
+ if (tooltipHandle) return /* @__PURE__ */ jsx(TooltipTrigger, {
36
+ handle: tooltipHandle,
37
+ payload: {
38
+ title,
39
+ shortcut
40
+ },
41
+ render: button,
42
+ children: icon
43
+ });
44
+ return /* @__PURE__ */ jsxs(TooltipRoot, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
45
+ render: button,
46
+ children: icon
47
+ }), /* @__PURE__ */ jsxs(TooltipContent, {
48
+ side: "bottom",
49
+ sideOffset: 4,
50
+ children: [title, shortcut && /* @__PURE__ */ jsx("span", {
51
+ className: "_1e1ersc8",
52
+ children: shortcut
53
+ })]
54
+ })] });
62
55
  }
63
- function ToolbarDropdown({
64
- label,
65
- title,
66
- items,
67
- triggerWidth,
68
- tooltipHandle
69
- }) {
70
- const triggerStyle = triggerWidth ? { width: triggerWidth } : void 0;
71
- const trigger = /* @__PURE__ */ jsx(
72
- DropdownMenuTrigger,
73
- {
74
- className: toolbarDropdownTrigger,
75
- render: /* @__PURE__ */ jsx("button", { type: "button" }),
76
- style: triggerStyle
77
- }
78
- );
79
- const triggerContent = /* @__PURE__ */ jsxs(Fragment, { children: [
80
- label,
81
- /* @__PURE__ */ jsx("span", { className: toolbarDropdownTriggerChevron, children: /* @__PURE__ */ jsx(ChevronDown, { size: 12 }) })
82
- ] });
83
- const menu = /* @__PURE__ */ jsx(DropdownMenuContent, { sideOffset: 4, children: items.map((item) => /* @__PURE__ */ jsxs(
84
- DropdownMenuItem,
85
- {
86
- className: item.active ? toolbarDropdownItemActive : void 0,
87
- style: item.style,
88
- onClick: item.onSelect,
89
- children: [
90
- item.icon && /* @__PURE__ */ jsx(
91
- "span",
92
- {
93
- style: {
94
- marginRight: 8,
95
- display: "inline-flex",
96
- transform: "scale(0.8)",
97
- transformOrigin: "left center"
98
- },
99
- children: item.icon
100
- }
101
- ),
102
- item.label
103
- ]
104
- },
105
- item.label
106
- )) });
107
- if (tooltipHandle) {
108
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
109
- /* @__PURE__ */ jsx(
110
- TooltipTrigger,
111
- {
112
- handle: tooltipHandle,
113
- payload: { title },
114
- render: trigger,
115
- children: triggerContent
116
- }
117
- ),
118
- menu
119
- ] });
120
- }
121
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
122
- /* @__PURE__ */ jsxs(TooltipRoot, { children: [
123
- /* @__PURE__ */ jsx(TooltipTrigger, { render: trigger, children: triggerContent }),
124
- /* @__PURE__ */ jsx(TooltipContent, { side: "bottom", sideOffset: 4, children: title })
125
- ] }),
126
- menu
127
- ] });
56
+ //#endregion
57
+ //#region src/ToolbarDropdown.tsx
58
+ function ToolbarDropdown({ label, title, items, triggerWidth, tooltipHandle }) {
59
+ const trigger = /* @__PURE__ */ jsx(DropdownMenuTrigger, {
60
+ className: toolbarDropdownTrigger,
61
+ render: /* @__PURE__ */ jsx("button", { type: "button" }),
62
+ style: triggerWidth ? { width: triggerWidth } : void 0
63
+ });
64
+ const triggerContent = /* @__PURE__ */ jsxs(Fragment, { children: [label, /* @__PURE__ */ jsx("span", {
65
+ className: toolbarDropdownTriggerChevron,
66
+ children: /* @__PURE__ */ jsx(ChevronDown, { size: 12 })
67
+ })] });
68
+ const menu = /* @__PURE__ */ jsx(DropdownMenuContent, {
69
+ sideOffset: 4,
70
+ children: items.map((item) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
71
+ className: item.active ? toolbarDropdownItemActive : void 0,
72
+ style: item.style,
73
+ onClick: item.onSelect,
74
+ children: [item.icon && /* @__PURE__ */ jsx("span", {
75
+ style: {
76
+ marginRight: 8,
77
+ display: "inline-flex",
78
+ transform: "scale(0.8)",
79
+ transformOrigin: "left center"
80
+ },
81
+ children: item.icon
82
+ }), item.label]
83
+ }, item.label))
84
+ });
85
+ if (tooltipHandle) return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
86
+ handle: tooltipHandle,
87
+ payload: { title },
88
+ render: trigger,
89
+ children: triggerContent
90
+ }), menu] });
91
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(TooltipRoot, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
92
+ render: trigger,
93
+ children: triggerContent
94
+ }), /* @__PURE__ */ jsx(TooltipContent, {
95
+ side: "bottom",
96
+ sideOffset: 4,
97
+ children: title
98
+ })] }), menu] });
128
99
  }
100
+ //#endregion
101
+ //#region src/ToolbarSeparator.tsx
129
102
  function ToolbarSeparator() {
130
- return /* @__PURE__ */ jsx("div", { className: toolbarSeparator });
103
+ return /* @__PURE__ */ jsx("div", { className: toolbarSeparator });
131
104
  }
132
- const ICON_SIZE = 15;
133
- const ICON_STROKE = 2;
134
- const FONT_FAMILIES = [
135
- { label: "默认", value: "" },
136
- {
137
- label: "宋体",
138
- value: '"Noto Serif CJK SC", "Source Han Serif SC", SimSun, serif'
139
- },
140
- {
141
- label: "黑体",
142
- value: '"Noto Sans CJK SC", "Source Han Sans SC", SimHei, sans-serif'
143
- },
144
- { label: "楷体", value: "KaiTi, STKaiti, serif" },
145
- { label: "Sans", value: "system-ui, -apple-system, sans-serif" },
146
- { label: "Serif", value: 'Georgia, "Times New Roman", serif' },
147
- { label: "Mono", value: 'ui-monospace, "SF Mono", "Fira Code", monospace' }
105
+ //#endregion
106
+ //#region src/ToolbarPlugin.tsx
107
+ var ICON_SIZE = 15;
108
+ var ICON_STROKE = 2;
109
+ var FONT_FAMILIES = [
110
+ {
111
+ label: "默认",
112
+ value: ""
113
+ },
114
+ {
115
+ label: "宋体",
116
+ value: "\"Noto Serif CJK SC\", \"Source Han Serif SC\", SimSun, serif"
117
+ },
118
+ {
119
+ label: "黑体",
120
+ value: "\"Noto Sans CJK SC\", \"Source Han Sans SC\", SimHei, sans-serif"
121
+ },
122
+ {
123
+ label: "楷体",
124
+ value: "KaiTi, STKaiti, serif"
125
+ },
126
+ {
127
+ label: "Sans",
128
+ value: "system-ui, -apple-system, sans-serif"
129
+ },
130
+ {
131
+ label: "Serif",
132
+ value: "Georgia, \"Times New Roman\", serif"
133
+ },
134
+ {
135
+ label: "Mono",
136
+ value: "ui-monospace, \"SF Mono\", \"Fira Code\", monospace"
137
+ }
148
138
  ];
149
139
  function getFontLabel(fontFamily) {
150
- if (!fontFamily) return "默认";
151
- const match = FONT_FAMILIES.find((f) => f.value === fontFamily);
152
- if (match) return match.label;
153
- for (const def of FONT_FAMILIES) {
154
- if (def.value && fontFamily.startsWith(def.value.split(",")[0])) {
155
- return def.label;
156
- }
157
- }
158
- return "默认";
140
+ if (!fontFamily) return "默认";
141
+ const match = FONT_FAMILIES.find((f) => f.value === fontFamily);
142
+ if (match) return match.label;
143
+ for (const def of FONT_FAMILIES) if (def.value && fontFamily.startsWith(def.value.split(",")[0])) return def.label;
144
+ return "默认";
159
145
  }
160
- const BLOCK_TYPE_LABELS = {
161
- paragraph: "Text",
162
- h1: "Heading 1",
163
- h2: "Heading 2",
164
- h3: "Heading 3",
165
- bullet: "Bulleted List",
166
- number: "Numbered List",
167
- check: "To-do List",
168
- other: "Other"
146
+ var BLOCK_TYPE_LABELS = {
147
+ paragraph: "Text",
148
+ h1: "Heading 1",
149
+ h2: "Heading 2",
150
+ h3: "Heading 3",
151
+ bullet: "Bulleted List",
152
+ number: "Numbered List",
153
+ check: "To-do List",
154
+ other: "Other"
169
155
  };
170
- const INITIAL_STATE = {
171
- canUndo: false,
172
- canRedo: false,
173
- blockType: "paragraph",
174
- fontFamily: "",
175
- elementFormat: "left",
176
- isBold: false,
177
- isItalic: false,
178
- isUnderline: false,
179
- isStrikethrough: false,
180
- isCode: false,
181
- isHighlight: false,
182
- isSpoiler: false
156
+ var INITIAL_STATE = {
157
+ canUndo: false,
158
+ canRedo: false,
159
+ blockType: "paragraph",
160
+ fontFamily: "",
161
+ elementFormat: "left",
162
+ isBold: false,
163
+ isItalic: false,
164
+ isUnderline: false,
165
+ isStrikethrough: false,
166
+ isCode: false,
167
+ isHighlight: false,
168
+ isSpoiler: false
183
169
  };
184
170
  function getBlockType(anchorNode) {
185
- if ($isHeadingNode(anchorNode)) {
186
- const tag = anchorNode.getTag();
187
- if (tag === "h1" || tag === "h2" || tag === "h3") return tag;
188
- return "other";
189
- }
190
- if ($isListNode(anchorNode)) {
191
- const listType = anchorNode.getListType();
192
- if (listType === "bullet") return "bullet";
193
- if (listType === "number") return "number";
194
- if (listType === "check") return "check";
195
- return "other";
196
- }
197
- const type = anchorNode.getType();
198
- if (type === "paragraph") return "paragraph";
199
- return "other";
171
+ if ($isHeadingNode(anchorNode)) {
172
+ const tag = anchorNode.getTag();
173
+ if (tag === "h1" || tag === "h2" || tag === "h3") return tag;
174
+ return "other";
175
+ }
176
+ if ($isListNode(anchorNode)) {
177
+ const listType = anchorNode.getListType();
178
+ if (listType === "bullet") return "bullet";
179
+ if (listType === "number") return "number";
180
+ if (listType === "check") return "check";
181
+ return "other";
182
+ }
183
+ if (anchorNode.getType() === "paragraph") return "paragraph";
184
+ return "other";
200
185
  }
201
- const DEFAULT_MAX_VISIBLE_INSERT_ITEMS = 5;
202
- function ToolbarPlugin({
203
- className,
204
- maxVisibleInsertItems = DEFAULT_MAX_VISIBLE_INSERT_ITEMS,
205
- insertItemOrder
206
- }) {
207
- const [editor] = useLexicalComposerContext();
208
- const [state, setState] = useState(INITIAL_STATE);
209
- const [tooltipHandle] = useState(() => createTooltipHandle());
210
- const toolbarItems = useMemo(() => {
211
- const items = collectCommandItems(editor).filter(
212
- (item) => item.placement?.includes("toolbar") && item.group === "insert"
213
- );
214
- if (!insertItemOrder || insertItemOrder.length === 0) return items;
215
- return items.sort((a, b) => {
216
- const ai = insertItemOrder.indexOf(a.title);
217
- const bi = insertItemOrder.indexOf(b.title);
218
- return (ai === -1 ? Infinity : ai) - (bi === -1 ? Infinity : bi);
219
- });
220
- }, [editor, insertItemOrder]);
221
- const updateToolbar = useCallback(() => {
222
- const selection = $getSelection();
223
- if (!$isRangeSelection(selection)) return;
224
- const anchorNode = selection.anchor.getNode();
225
- let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
226
- const parent = e.getParent();
227
- return parent !== null && $isRootOrShadowRoot(parent);
228
- }) ?? anchorNode.getTopLevelElementOrThrow();
229
- if ($isListNode(element)) {
230
- const parentList = $findMatchingParent(anchorNode, (node) => $isListNode(node));
231
- if (parentList) {
232
- element = parentList;
233
- }
234
- }
235
- const blockType = getBlockType(element);
236
- const fontFamily = $getSelectionStyleValueForProperty(selection, "font-family", "");
237
- const elementFormat = $isElementNode(element) ? element.getFormatType() : "left";
238
- const isBold = selection.hasFormat("bold");
239
- const isItalic = selection.hasFormat("italic");
240
- const isUnderline = selection.hasFormat("underline");
241
- const isStrikethrough = selection.hasFormat("strikethrough");
242
- const isCode = selection.hasFormat("code");
243
- const isHighlight = selection.hasFormat("highlight");
244
- const isSpoiler = $selectionTouchesSpoiler(selection);
245
- setState((prev) => ({
246
- ...prev,
247
- blockType,
248
- fontFamily,
249
- elementFormat,
250
- isBold,
251
- isItalic,
252
- isUnderline,
253
- isStrikethrough,
254
- isCode,
255
- isHighlight,
256
- isSpoiler
257
- }));
258
- }, []);
259
- useEffect(() => {
260
- const unregisterUndo = editor.registerCommand(
261
- CAN_UNDO_COMMAND,
262
- (payload) => {
263
- setState((prev) => ({ ...prev, canUndo: payload }));
264
- return false;
265
- },
266
- COMMAND_PRIORITY_LOW
267
- );
268
- const unregisterRedo = editor.registerCommand(
269
- CAN_REDO_COMMAND,
270
- (payload) => {
271
- setState((prev) => ({ ...prev, canRedo: payload }));
272
- return false;
273
- },
274
- COMMAND_PRIORITY_LOW
275
- );
276
- const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {
277
- editorState.read(() => {
278
- updateToolbar();
279
- });
280
- });
281
- return () => {
282
- unregisterUndo();
283
- unregisterRedo();
284
- unregisterUpdate();
285
- };
286
- }, [editor, updateToolbar]);
287
- const applyFontFamily = useCallback(
288
- (value) => {
289
- editor.update(() => {
290
- const selection = $getSelection();
291
- if ($isRangeSelection(selection)) {
292
- $patchStyleText(selection, { "font-family": value || "" });
293
- }
294
- });
295
- },
296
- [editor]
297
- );
298
- const fontFamilyItems = useMemo(
299
- () => FONT_FAMILIES.map((def) => ({
300
- label: def.label,
301
- active: state.fontFamily === def.value,
302
- style: def.value ? { fontFamily: def.value } : void 0,
303
- onSelect: () => applyFontFamily(def.value)
304
- })),
305
- [state.fontFamily, applyFontFamily]
306
- );
307
- const headingItems = useMemo(
308
- () => [
309
- {
310
- label: "Text",
311
- icon: /* @__PURE__ */ jsx(Pilcrow, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
312
- active: state.blockType === "paragraph",
313
- onSelect: () => {
314
- editor.update(() => {
315
- const selection = $getSelection();
316
- if ($isRangeSelection(selection)) {
317
- $setBlocksType(selection, () => $createParagraphNode());
318
- }
319
- });
320
- }
321
- },
322
- {
323
- label: "Heading 1",
324
- icon: /* @__PURE__ */ jsx(Heading1, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
325
- active: state.blockType === "h1",
326
- onSelect: () => {
327
- editor.update(() => {
328
- const selection = $getSelection();
329
- if ($isRangeSelection(selection)) {
330
- $setBlocksType(selection, () => $createHeadingNode("h1"));
331
- }
332
- });
333
- }
334
- },
335
- {
336
- label: "Heading 2",
337
- icon: /* @__PURE__ */ jsx(Heading2, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
338
- active: state.blockType === "h2",
339
- onSelect: () => {
340
- editor.update(() => {
341
- const selection = $getSelection();
342
- if ($isRangeSelection(selection)) {
343
- $setBlocksType(selection, () => $createHeadingNode("h2"));
344
- }
345
- });
346
- }
347
- },
348
- {
349
- label: "Heading 3",
350
- icon: /* @__PURE__ */ jsx(Heading3, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
351
- active: state.blockType === "h3",
352
- onSelect: () => {
353
- editor.update(() => {
354
- const selection = $getSelection();
355
- if ($isRangeSelection(selection)) {
356
- $setBlocksType(selection, () => $createHeadingNode("h3"));
357
- }
358
- });
359
- }
360
- }
361
- ],
362
- [editor, state.blockType]
363
- );
364
- const containerClassName = className ? `${toolbarContainer} ${className}` : toolbarContainer;
365
- const h = tooltipHandle;
366
- return /* @__PURE__ */ jsxs(TooltipProvider, { delay: 300, children: [
367
- /* @__PURE__ */ jsx(TooltipRoot, { disableHoverablePopup: true, handle: tooltipHandle, children: ((props) => props.payload !== void 0 ? /* @__PURE__ */ jsxs(TooltipContent, { side: "bottom", sideOffset: 4, children: [
368
- props.payload.title,
369
- props.payload.shortcut && /* @__PURE__ */ jsx("span", { className: tooltipShortcut, children: props.payload.shortcut })
370
- ] }) : null) }),
371
- /* @__PURE__ */ jsx("div", { "aria-label": "Editor toolbar", className: containerClassName, role: "toolbar", children: /* @__PURE__ */ jsxs("div", { className: toolbarRow, children: [
372
- /* @__PURE__ */ jsx(
373
- ToolbarDropdown,
374
- {
375
- items: fontFamilyItems,
376
- label: getFontLabel(state.fontFamily),
377
- title: "Font family",
378
- tooltipHandle: h,
379
- triggerWidth: 76
380
- }
381
- ),
382
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
383
- /* @__PURE__ */ jsx(
384
- ToolbarDropdown,
385
- {
386
- items: headingItems,
387
- label: BLOCK_TYPE_LABELS[state.blockType] ?? "Text",
388
- title: "Block type",
389
- tooltipHandle: h,
390
- triggerWidth: 120
391
- }
392
- ),
393
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
394
- /* @__PURE__ */ jsx(
395
- ToolbarButton,
396
- {
397
- disabled: !state.canUndo,
398
- icon: /* @__PURE__ */ jsx(Undo, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
399
- shortcut: "Ctrl+Z",
400
- title: "Undo",
401
- tooltipHandle: h,
402
- onClick: () => editor.dispatchCommand(UNDO_COMMAND, void 0)
403
- }
404
- ),
405
- /* @__PURE__ */ jsx(
406
- ToolbarButton,
407
- {
408
- disabled: !state.canRedo,
409
- icon: /* @__PURE__ */ jsx(Redo, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
410
- shortcut: "Ctrl+Y",
411
- title: "Redo",
412
- tooltipHandle: h,
413
- onClick: () => editor.dispatchCommand(REDO_COMMAND, void 0)
414
- }
415
- ),
416
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
417
- /* @__PURE__ */ jsx(
418
- ToolbarButton,
419
- {
420
- active: state.isBold,
421
- icon: /* @__PURE__ */ jsx(Bold, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
422
- shortcut: "Ctrl+B",
423
- title: "Bold",
424
- tooltipHandle: h,
425
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold")
426
- }
427
- ),
428
- /* @__PURE__ */ jsx(
429
- ToolbarButton,
430
- {
431
- active: state.isItalic,
432
- icon: /* @__PURE__ */ jsx(Italic, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
433
- shortcut: "Ctrl+I",
434
- title: "Italic",
435
- tooltipHandle: h,
436
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic")
437
- }
438
- ),
439
- /* @__PURE__ */ jsx(
440
- ToolbarButton,
441
- {
442
- active: state.isUnderline,
443
- icon: /* @__PURE__ */ jsx(Underline, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
444
- shortcut: "Ctrl+U",
445
- title: "Underline",
446
- tooltipHandle: h,
447
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline")
448
- }
449
- ),
450
- /* @__PURE__ */ jsx(
451
- ToolbarButton,
452
- {
453
- active: state.isStrikethrough,
454
- icon: /* @__PURE__ */ jsx(Strikethrough, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
455
- title: "Strikethrough",
456
- tooltipHandle: h,
457
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough")
458
- }
459
- ),
460
- /* @__PURE__ */ jsx(
461
- ToolbarButton,
462
- {
463
- active: state.isCode,
464
- icon: /* @__PURE__ */ jsx(Code, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
465
- title: "Inline Code",
466
- tooltipHandle: h,
467
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code")
468
- }
469
- ),
470
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
471
- /* @__PURE__ */ jsx(
472
- ToolbarButton,
473
- {
474
- active: state.isHighlight,
475
- icon: /* @__PURE__ */ jsx(Highlighter, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
476
- title: "Highlight",
477
- tooltipHandle: h,
478
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "highlight")
479
- }
480
- ),
481
- /* @__PURE__ */ jsx(
482
- ToolbarButton,
483
- {
484
- active: state.isSpoiler,
485
- icon: /* @__PURE__ */ jsx(EyeOff, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
486
- title: "Spoiler",
487
- tooltipHandle: h,
488
- onClick: () => editor.update($toggleSpoilerSelection)
489
- }
490
- ),
491
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
492
- /* @__PURE__ */ jsx(
493
- ToolbarButton,
494
- {
495
- active: state.blockType === "bullet",
496
- icon: /* @__PURE__ */ jsx(List, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
497
- title: "Bulleted List",
498
- tooltipHandle: h,
499
- onClick: () => editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0)
500
- }
501
- ),
502
- /* @__PURE__ */ jsx(
503
- ToolbarButton,
504
- {
505
- active: state.blockType === "number",
506
- icon: /* @__PURE__ */ jsx(ListOrdered, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
507
- title: "Numbered List",
508
- tooltipHandle: h,
509
- onClick: () => editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0)
510
- }
511
- ),
512
- /* @__PURE__ */ jsx(
513
- ToolbarButton,
514
- {
515
- active: state.blockType === "check",
516
- icon: /* @__PURE__ */ jsx(ListChecks, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
517
- title: "Checklist",
518
- tooltipHandle: h,
519
- onClick: () => editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0)
520
- }
521
- ),
522
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
523
- /* @__PURE__ */ jsx(
524
- ToolbarButton,
525
- {
526
- active: state.elementFormat === "left" || state.elementFormat === "",
527
- icon: /* @__PURE__ */ jsx(AlignLeft, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
528
- title: "Align Left",
529
- tooltipHandle: h,
530
- onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "left")
531
- }
532
- ),
533
- /* @__PURE__ */ jsx(
534
- ToolbarButton,
535
- {
536
- active: state.elementFormat === "center",
537
- icon: /* @__PURE__ */ jsx(AlignCenter, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
538
- title: "Align Center",
539
- tooltipHandle: h,
540
- onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "center")
541
- }
542
- ),
543
- /* @__PURE__ */ jsx(
544
- ToolbarButton,
545
- {
546
- active: state.elementFormat === "right",
547
- icon: /* @__PURE__ */ jsx(AlignRight, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
548
- title: "Align Right",
549
- tooltipHandle: h,
550
- onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "right")
551
- }
552
- ),
553
- /* @__PURE__ */ jsx(
554
- ToolbarButton,
555
- {
556
- active: state.elementFormat === "justify",
557
- icon: /* @__PURE__ */ jsx(AlignJustify, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
558
- title: "Justify",
559
- tooltipHandle: h,
560
- onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "justify")
561
- }
562
- ),
563
- toolbarItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
564
- /* @__PURE__ */ jsx(ToolbarSeparator, {}),
565
- toolbarItems.slice(0, maxVisibleInsertItems).map((item) => /* @__PURE__ */ jsx(
566
- ToolbarButton,
567
- {
568
- icon: item.icon,
569
- shortcut: item.shortcut,
570
- title: item.title,
571
- tooltipHandle: h,
572
- onClick: () => item.onSelect(editor, "")
573
- },
574
- item.title
575
- )),
576
- toolbarItems.length > maxVisibleInsertItems && /* @__PURE__ */ jsxs(DropdownMenu, { modal: false, children: [
577
- /* @__PURE__ */ jsx(
578
- TooltipTrigger,
579
- {
580
- handle: h,
581
- payload: { title: "More" },
582
- render: /* @__PURE__ */ jsx(
583
- DropdownMenuTrigger,
584
- {
585
- className: toolbarButton,
586
- render: /* @__PURE__ */ jsx("button", { type: "button" })
587
- }
588
- ),
589
- children: /* @__PURE__ */ jsx(Ellipsis, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
590
- }
591
- ),
592
- /* @__PURE__ */ jsx(DropdownMenuContent, { positionMethod: "fixed", sideOffset: 4, children: toolbarItems.slice(maxVisibleInsertItems).map((item) => /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => item.onSelect(editor, ""), children: [
593
- item.icon && /* @__PURE__ */ jsx(
594
- "span",
595
- {
596
- style: {
597
- marginRight: 8,
598
- display: "inline-flex",
599
- transform: "scale(0.8)",
600
- transformOrigin: "left center"
601
- },
602
- children: item.icon
603
- }
604
- ),
605
- item.title
606
- ] }, item.title)) })
607
- ] })
608
- ] })
609
- ] }) })
610
- ] });
186
+ var DEFAULT_MAX_VISIBLE_INSERT_ITEMS = 5;
187
+ function ToolbarPlugin({ className, maxVisibleInsertItems = DEFAULT_MAX_VISIBLE_INSERT_ITEMS, insertItemOrder }) {
188
+ const [editor] = useLexicalComposerContext();
189
+ const [state, setState] = useState(INITIAL_STATE);
190
+ const [tooltipHandle] = useState(() => createTooltipHandle());
191
+ const toolbarItems = useMemo(() => {
192
+ const items = collectCommandItems(editor).filter((item) => item.placement?.includes("toolbar") && item.group === "insert");
193
+ if (!insertItemOrder || insertItemOrder.length === 0) return items;
194
+ return items.sort((a, b) => {
195
+ const ai = insertItemOrder.indexOf(a.title);
196
+ const bi = insertItemOrder.indexOf(b.title);
197
+ return (ai === -1 ? Infinity : ai) - (bi === -1 ? Infinity : bi);
198
+ });
199
+ }, [editor, insertItemOrder]);
200
+ const updateToolbar = useCallback(() => {
201
+ const selection = $getSelection();
202
+ if (!$isRangeSelection(selection)) return;
203
+ const anchorNode = selection.anchor.getNode();
204
+ let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
205
+ const parent = e.getParent();
206
+ return parent !== null && $isRootOrShadowRoot(parent);
207
+ }) ?? anchorNode.getTopLevelElementOrThrow();
208
+ if ($isListNode(element)) {
209
+ const parentList = $findMatchingParent(anchorNode, (node) => $isListNode(node));
210
+ if (parentList) element = parentList;
211
+ }
212
+ const blockType = getBlockType(element);
213
+ const fontFamily = $getSelectionStyleValueForProperty(selection, "font-family", "");
214
+ const elementFormat = $isElementNode(element) ? element.getFormatType() : "left";
215
+ const isBold = selection.hasFormat("bold");
216
+ const isItalic = selection.hasFormat("italic");
217
+ const isUnderline = selection.hasFormat("underline");
218
+ const isStrikethrough = selection.hasFormat("strikethrough");
219
+ const isCode = selection.hasFormat("code");
220
+ const isHighlight = selection.hasFormat("highlight");
221
+ const isSpoiler = $selectionTouchesSpoiler(selection);
222
+ setState((prev) => ({
223
+ ...prev,
224
+ blockType,
225
+ fontFamily,
226
+ elementFormat,
227
+ isBold,
228
+ isItalic,
229
+ isUnderline,
230
+ isStrikethrough,
231
+ isCode,
232
+ isHighlight,
233
+ isSpoiler
234
+ }));
235
+ }, []);
236
+ useEffect(() => {
237
+ const unregisterUndo = editor.registerCommand(CAN_UNDO_COMMAND, (payload) => {
238
+ setState((prev) => ({
239
+ ...prev,
240
+ canUndo: payload
241
+ }));
242
+ return false;
243
+ }, COMMAND_PRIORITY_LOW);
244
+ const unregisterRedo = editor.registerCommand(CAN_REDO_COMMAND, (payload) => {
245
+ setState((prev) => ({
246
+ ...prev,
247
+ canRedo: payload
248
+ }));
249
+ return false;
250
+ }, COMMAND_PRIORITY_LOW);
251
+ const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {
252
+ editorState.read(() => {
253
+ updateToolbar();
254
+ });
255
+ });
256
+ return () => {
257
+ unregisterUndo();
258
+ unregisterRedo();
259
+ unregisterUpdate();
260
+ };
261
+ }, [editor, updateToolbar]);
262
+ const applyFontFamily = useCallback((value) => {
263
+ editor.update(() => {
264
+ const selection = $getSelection();
265
+ if ($isRangeSelection(selection)) $patchStyleText(selection, { "font-family": value || "" });
266
+ });
267
+ }, [editor]);
268
+ const fontFamilyItems = useMemo(() => FONT_FAMILIES.map((def) => ({
269
+ label: def.label,
270
+ active: state.fontFamily === def.value,
271
+ style: def.value ? { fontFamily: def.value } : void 0,
272
+ onSelect: () => applyFontFamily(def.value)
273
+ })), [state.fontFamily, applyFontFamily]);
274
+ const headingItems = useMemo(() => [
275
+ {
276
+ label: "Text",
277
+ icon: /* @__PURE__ */ jsx(Pilcrow, {
278
+ size: ICON_SIZE,
279
+ strokeWidth: ICON_STROKE
280
+ }),
281
+ active: state.blockType === "paragraph",
282
+ onSelect: () => {
283
+ editor.update(() => {
284
+ const selection = $getSelection();
285
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createParagraphNode());
286
+ });
287
+ }
288
+ },
289
+ {
290
+ label: "Heading 1",
291
+ icon: /* @__PURE__ */ jsx(Heading1, {
292
+ size: ICON_SIZE,
293
+ strokeWidth: ICON_STROKE
294
+ }),
295
+ active: state.blockType === "h1",
296
+ onSelect: () => {
297
+ editor.update(() => {
298
+ const selection = $getSelection();
299
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createHeadingNode("h1"));
300
+ });
301
+ }
302
+ },
303
+ {
304
+ label: "Heading 2",
305
+ icon: /* @__PURE__ */ jsx(Heading2, {
306
+ size: ICON_SIZE,
307
+ strokeWidth: ICON_STROKE
308
+ }),
309
+ active: state.blockType === "h2",
310
+ onSelect: () => {
311
+ editor.update(() => {
312
+ const selection = $getSelection();
313
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createHeadingNode("h2"));
314
+ });
315
+ }
316
+ },
317
+ {
318
+ label: "Heading 3",
319
+ icon: /* @__PURE__ */ jsx(Heading3, {
320
+ size: ICON_SIZE,
321
+ strokeWidth: ICON_STROKE
322
+ }),
323
+ active: state.blockType === "h3",
324
+ onSelect: () => {
325
+ editor.update(() => {
326
+ const selection = $getSelection();
327
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createHeadingNode("h3"));
328
+ });
329
+ }
330
+ }
331
+ ], [editor, state.blockType]);
332
+ const containerClassName = className ? `${toolbarContainer} ${className}` : toolbarContainer;
333
+ const h = tooltipHandle;
334
+ return /* @__PURE__ */ jsxs(TooltipProvider, {
335
+ delay: 300,
336
+ children: [/* @__PURE__ */ jsx(TooltipRoot, {
337
+ disableHoverablePopup: true,
338
+ handle: tooltipHandle,
339
+ children: ((props) => props.payload !== void 0 ? /* @__PURE__ */ jsxs(TooltipContent, {
340
+ side: "bottom",
341
+ sideOffset: 4,
342
+ children: [props.payload.title, props.payload.shortcut && /* @__PURE__ */ jsx("span", {
343
+ className: "_1e1ersc8",
344
+ children: props.payload.shortcut
345
+ })]
346
+ }) : null)
347
+ }), /* @__PURE__ */ jsx("div", {
348
+ "aria-label": "Editor toolbar",
349
+ className: containerClassName,
350
+ role: "toolbar",
351
+ children: /* @__PURE__ */ jsxs("div", {
352
+ className: toolbarRow,
353
+ children: [
354
+ /* @__PURE__ */ jsx(ToolbarDropdown, {
355
+ items: fontFamilyItems,
356
+ label: getFontLabel(state.fontFamily),
357
+ title: "Font family",
358
+ tooltipHandle: h,
359
+ triggerWidth: 76
360
+ }),
361
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
362
+ /* @__PURE__ */ jsx(ToolbarDropdown, {
363
+ items: headingItems,
364
+ label: BLOCK_TYPE_LABELS[state.blockType] ?? "Text",
365
+ title: "Block type",
366
+ tooltipHandle: h,
367
+ triggerWidth: 120
368
+ }),
369
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
370
+ /* @__PURE__ */ jsx(ToolbarButton, {
371
+ disabled: !state.canUndo,
372
+ icon: /* @__PURE__ */ jsx(Undo, {
373
+ size: ICON_SIZE,
374
+ strokeWidth: ICON_STROKE
375
+ }),
376
+ shortcut: "Ctrl+Z",
377
+ title: "Undo",
378
+ tooltipHandle: h,
379
+ onClick: () => editor.dispatchCommand(UNDO_COMMAND, void 0)
380
+ }),
381
+ /* @__PURE__ */ jsx(ToolbarButton, {
382
+ disabled: !state.canRedo,
383
+ icon: /* @__PURE__ */ jsx(Redo, {
384
+ size: ICON_SIZE,
385
+ strokeWidth: ICON_STROKE
386
+ }),
387
+ shortcut: "Ctrl+Y",
388
+ title: "Redo",
389
+ tooltipHandle: h,
390
+ onClick: () => editor.dispatchCommand(REDO_COMMAND, void 0)
391
+ }),
392
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
393
+ /* @__PURE__ */ jsx(ToolbarButton, {
394
+ active: state.isBold,
395
+ icon: /* @__PURE__ */ jsx(Bold, {
396
+ size: ICON_SIZE,
397
+ strokeWidth: ICON_STROKE
398
+ }),
399
+ shortcut: "Ctrl+B",
400
+ title: "Bold",
401
+ tooltipHandle: h,
402
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold")
403
+ }),
404
+ /* @__PURE__ */ jsx(ToolbarButton, {
405
+ active: state.isItalic,
406
+ icon: /* @__PURE__ */ jsx(Italic, {
407
+ size: ICON_SIZE,
408
+ strokeWidth: ICON_STROKE
409
+ }),
410
+ shortcut: "Ctrl+I",
411
+ title: "Italic",
412
+ tooltipHandle: h,
413
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic")
414
+ }),
415
+ /* @__PURE__ */ jsx(ToolbarButton, {
416
+ active: state.isUnderline,
417
+ icon: /* @__PURE__ */ jsx(Underline, {
418
+ size: ICON_SIZE,
419
+ strokeWidth: ICON_STROKE
420
+ }),
421
+ shortcut: "Ctrl+U",
422
+ title: "Underline",
423
+ tooltipHandle: h,
424
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline")
425
+ }),
426
+ /* @__PURE__ */ jsx(ToolbarButton, {
427
+ active: state.isStrikethrough,
428
+ icon: /* @__PURE__ */ jsx(Strikethrough, {
429
+ size: ICON_SIZE,
430
+ strokeWidth: ICON_STROKE
431
+ }),
432
+ title: "Strikethrough",
433
+ tooltipHandle: h,
434
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough")
435
+ }),
436
+ /* @__PURE__ */ jsx(ToolbarButton, {
437
+ active: state.isCode,
438
+ icon: /* @__PURE__ */ jsx(Code, {
439
+ size: ICON_SIZE,
440
+ strokeWidth: ICON_STROKE
441
+ }),
442
+ title: "Inline Code",
443
+ tooltipHandle: h,
444
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code")
445
+ }),
446
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
447
+ /* @__PURE__ */ jsx(ToolbarButton, {
448
+ active: state.isHighlight,
449
+ icon: /* @__PURE__ */ jsx(Highlighter, {
450
+ size: ICON_SIZE,
451
+ strokeWidth: ICON_STROKE
452
+ }),
453
+ title: "Highlight",
454
+ tooltipHandle: h,
455
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "highlight")
456
+ }),
457
+ /* @__PURE__ */ jsx(ToolbarButton, {
458
+ active: state.isSpoiler,
459
+ icon: /* @__PURE__ */ jsx(EyeOff, {
460
+ size: ICON_SIZE,
461
+ strokeWidth: ICON_STROKE
462
+ }),
463
+ title: "Spoiler",
464
+ tooltipHandle: h,
465
+ onClick: () => editor.update($toggleSpoilerSelection)
466
+ }),
467
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
468
+ /* @__PURE__ */ jsx(ToolbarButton, {
469
+ active: state.blockType === "bullet",
470
+ icon: /* @__PURE__ */ jsx(List, {
471
+ size: ICON_SIZE,
472
+ strokeWidth: ICON_STROKE
473
+ }),
474
+ title: "Bulleted List",
475
+ tooltipHandle: h,
476
+ onClick: () => editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0)
477
+ }),
478
+ /* @__PURE__ */ jsx(ToolbarButton, {
479
+ active: state.blockType === "number",
480
+ icon: /* @__PURE__ */ jsx(ListOrdered, {
481
+ size: ICON_SIZE,
482
+ strokeWidth: ICON_STROKE
483
+ }),
484
+ title: "Numbered List",
485
+ tooltipHandle: h,
486
+ onClick: () => editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0)
487
+ }),
488
+ /* @__PURE__ */ jsx(ToolbarButton, {
489
+ active: state.blockType === "check",
490
+ icon: /* @__PURE__ */ jsx(ListChecks, {
491
+ size: ICON_SIZE,
492
+ strokeWidth: ICON_STROKE
493
+ }),
494
+ title: "Checklist",
495
+ tooltipHandle: h,
496
+ onClick: () => editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0)
497
+ }),
498
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
499
+ /* @__PURE__ */ jsx(ToolbarButton, {
500
+ active: state.elementFormat === "left" || state.elementFormat === "",
501
+ icon: /* @__PURE__ */ jsx(AlignLeft, {
502
+ size: ICON_SIZE,
503
+ strokeWidth: ICON_STROKE
504
+ }),
505
+ title: "Align Left",
506
+ tooltipHandle: h,
507
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "left")
508
+ }),
509
+ /* @__PURE__ */ jsx(ToolbarButton, {
510
+ active: state.elementFormat === "center",
511
+ icon: /* @__PURE__ */ jsx(AlignCenter, {
512
+ size: ICON_SIZE,
513
+ strokeWidth: ICON_STROKE
514
+ }),
515
+ title: "Align Center",
516
+ tooltipHandle: h,
517
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "center")
518
+ }),
519
+ /* @__PURE__ */ jsx(ToolbarButton, {
520
+ active: state.elementFormat === "right",
521
+ icon: /* @__PURE__ */ jsx(AlignRight, {
522
+ size: ICON_SIZE,
523
+ strokeWidth: ICON_STROKE
524
+ }),
525
+ title: "Align Right",
526
+ tooltipHandle: h,
527
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "right")
528
+ }),
529
+ /* @__PURE__ */ jsx(ToolbarButton, {
530
+ active: state.elementFormat === "justify",
531
+ icon: /* @__PURE__ */ jsx(AlignJustify, {
532
+ size: ICON_SIZE,
533
+ strokeWidth: ICON_STROKE
534
+ }),
535
+ title: "Justify",
536
+ tooltipHandle: h,
537
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "justify")
538
+ }),
539
+ toolbarItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
540
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
541
+ toolbarItems.slice(0, maxVisibleInsertItems).map((item) => /* @__PURE__ */ jsx(ToolbarButton, {
542
+ icon: item.icon,
543
+ shortcut: item.shortcut,
544
+ title: item.title,
545
+ tooltipHandle: h,
546
+ onClick: () => item.onSelect(editor, "")
547
+ }, item.title)),
548
+ toolbarItems.length > maxVisibleInsertItems && /* @__PURE__ */ jsxs(DropdownMenu, {
549
+ modal: false,
550
+ children: [/* @__PURE__ */ jsx(TooltipTrigger, {
551
+ handle: h,
552
+ payload: { title: "More" },
553
+ render: /* @__PURE__ */ jsx(DropdownMenuTrigger, {
554
+ className: "_1e1ersc2",
555
+ render: /* @__PURE__ */ jsx("button", { type: "button" })
556
+ }),
557
+ children: /* @__PURE__ */ jsx(Ellipsis, {
558
+ size: ICON_SIZE,
559
+ strokeWidth: ICON_STROKE
560
+ })
561
+ }), /* @__PURE__ */ jsx(DropdownMenuContent, {
562
+ positionMethod: "fixed",
563
+ sideOffset: 4,
564
+ children: toolbarItems.slice(maxVisibleInsertItems).map((item) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
565
+ onClick: () => item.onSelect(editor, ""),
566
+ children: [item.icon && /* @__PURE__ */ jsx("span", {
567
+ style: {
568
+ marginRight: 8,
569
+ display: "inline-flex",
570
+ transform: "scale(0.8)",
571
+ transformOrigin: "left center"
572
+ },
573
+ children: item.icon
574
+ }), item.title]
575
+ }, item.title))
576
+ })]
577
+ })
578
+ ] })
579
+ ]
580
+ })
581
+ })]
582
+ });
611
583
  }
612
- export {
613
- ToolbarPlugin
614
- };
584
+ //#endregion
585
+ export { ToolbarPlugin };