@haklex/rich-plugin-toolbar 0.0.56

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/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Innei
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+
24
+ Additional Terms and Conditions
25
+
26
+ ----------------
27
+
28
+ Use of this software is governed by the terms of MIT and, in addition, by the terms and conditions described in the additional file (ADDITIONAL_TERMS.md). By using this software, you agree to abide by these additional terms and conditions.
@@ -0,0 +1,13 @@
1
+ import { ReactNode } from 'react';
2
+ import { ToolbarTooltipHandle } from './types';
3
+ export interface ToolbarButtonProps {
4
+ icon: ReactNode;
5
+ title: string;
6
+ shortcut?: string;
7
+ active?: boolean;
8
+ disabled?: boolean;
9
+ onClick: () => void;
10
+ tooltipHandle?: ToolbarTooltipHandle;
11
+ }
12
+ export declare function ToolbarButton({ icon, title, shortcut, active, disabled, onClick, tooltipHandle, }: ToolbarButtonProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=ToolbarButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarButton.d.ts","sourceRoot":"","sources":["../src/ToolbarButton.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,oBAAoB,EAAyB,MAAM,SAAS,CAAA;AAE1E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,aAAa,CAAC,EAAE,oBAAoB,CAAA;CACrC;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,aAAa,GACd,EAAE,kBAAkB,2CAoCpB"}
@@ -0,0 +1,18 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ import { ToolbarTooltipHandle } from './types';
3
+ export interface ToolbarDropdownItem {
4
+ label: string;
5
+ icon?: ReactNode;
6
+ active?: boolean;
7
+ style?: CSSProperties;
8
+ onSelect: () => void;
9
+ }
10
+ export interface ToolbarDropdownProps {
11
+ label: string;
12
+ title: string;
13
+ items: ToolbarDropdownItem[];
14
+ triggerWidth?: number;
15
+ tooltipHandle?: ToolbarTooltipHandle;
16
+ }
17
+ export declare function ToolbarDropdown({ label, title, items, triggerWidth, tooltipHandle, }: ToolbarDropdownProps): import("react/jsx-runtime").JSX.Element;
18
+ //# sourceMappingURL=ToolbarDropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarDropdown.d.ts","sourceRoot":"","sources":["../src/ToolbarDropdown.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGrD,OAAO,KAAK,EAAE,oBAAoB,EAAyB,MAAM,SAAS,CAAA;AAE1E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,mBAAmB,EAAE,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,oBAAoB,CAAA;CACrC;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,KAAK,EACL,YAAY,EACZ,aAAa,GACd,EAAE,oBAAoB,2CAyEtB"}
@@ -0,0 +1,6 @@
1
+ import { ReactElement } from 'react';
2
+ export interface ToolbarPluginProps {
3
+ className?: string;
4
+ }
5
+ export declare function ToolbarPlugin({ className }: ToolbarPluginProps): ReactElement;
6
+ //# sourceMappingURL=ToolbarPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarPlugin.d.ts","sourceRoot":"","sources":["../src/ToolbarPlugin.tsx"],"names":[],"mappings":"AAyDA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAA;AAsHxD,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE,kBAAkB,GAAG,YAAY,CAqY7E"}
@@ -0,0 +1,2 @@
1
+ export declare function ToolbarSeparator(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=ToolbarSeparator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarSeparator.d.ts","sourceRoot":"","sources":["../src/ToolbarSeparator.tsx"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,4CAE/B"}
@@ -0,0 +1,3 @@
1
+ export type { ToolbarPluginProps } from './ToolbarPlugin';
2
+ export { ToolbarPlugin } from './ToolbarPlugin';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,566 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { collectCommandItems } from "@haklex/rich-editor";
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";
5
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
6
+ import { $createHeadingNode, $isHeadingNode } from "@lexical/rich-text";
7
+ import { $getSelectionStyleValueForProperty, $patchStyleText, $setBlocksType } from "@lexical/selection";
8
+ import { $findMatchingParent } from "@lexical/utils";
9
+ import { $getSelection, $isRangeSelection, $isRootOrShadowRoot, 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, List, ListOrdered, ListChecks, AlignLeft, AlignCenter, AlignRight, AlignJustify } from "lucide-react";
11
+ import { useState, useEffect, useCallback, useMemo } from "react";
12
+ var toolbarContainer = "_1e1ersc0";
13
+ var toolbarRow = "_1e1ersc1";
14
+ var toolbarButton = "_1e1ersc2";
15
+ var toolbarButtonActive = "_1e1ersc3";
16
+ var toolbarDropdownTrigger = "_1e1ersc4";
17
+ var toolbarDropdownTriggerChevron = "_1e1ersc5";
18
+ var toolbarSeparator = "_1e1ersc6";
19
+ 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
+ type: "button",
34
+ className: `${toolbarButton}${active ? ` ${toolbarButtonActive}` : ""}`,
35
+ disabled,
36
+ onMouseDown: (e) => {
37
+ e.preventDefault();
38
+ onClick();
39
+ },
40
+ "aria-label": title,
41
+ "aria-pressed": active
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
+ ] });
62
+ }
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
+ style: triggerStyle,
76
+ render: /* @__PURE__ */ jsx("button", { type: "button" })
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
+ ] });
128
+ }
129
+ function ToolbarSeparator() {
130
+ return /* @__PURE__ */ jsx("div", { className: toolbarSeparator });
131
+ }
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' }
148
+ ];
149
+ 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 "默认";
159
+ }
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"
169
+ };
170
+ const INITIAL_STATE = {
171
+ canUndo: false,
172
+ canRedo: false,
173
+ blockType: "paragraph",
174
+ fontFamily: "",
175
+ isBold: false,
176
+ isItalic: false,
177
+ isUnderline: false,
178
+ isStrikethrough: false,
179
+ isCode: false,
180
+ isHighlight: false
181
+ };
182
+ function getBlockType(anchorNode) {
183
+ if ($isHeadingNode(anchorNode)) {
184
+ const tag = anchorNode.getTag();
185
+ if (tag === "h1" || tag === "h2" || tag === "h3") return tag;
186
+ return "other";
187
+ }
188
+ if ($isListNode(anchorNode)) {
189
+ const listType = anchorNode.getListType();
190
+ if (listType === "bullet") return "bullet";
191
+ if (listType === "number") return "number";
192
+ if (listType === "check") return "check";
193
+ return "other";
194
+ }
195
+ const type = anchorNode.getType();
196
+ if (type === "paragraph") return "paragraph";
197
+ return "other";
198
+ }
199
+ function ToolbarPlugin({ className }) {
200
+ const [editor] = useLexicalComposerContext();
201
+ const [state, setState] = useState(INITIAL_STATE);
202
+ const [toolbarItems, setToolbarItems] = useState([]);
203
+ const [tooltipHandle] = useState(
204
+ () => createTooltipHandle()
205
+ );
206
+ useEffect(() => {
207
+ const items = collectCommandItems(editor).filter(
208
+ (item) => item.placement?.includes("toolbar") && item.group === "insert"
209
+ );
210
+ setToolbarItems(items);
211
+ }, [editor]);
212
+ const updateToolbar = useCallback(() => {
213
+ const selection = $getSelection();
214
+ if (!$isRangeSelection(selection)) return;
215
+ const anchorNode = selection.anchor.getNode();
216
+ let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
217
+ const parent = e.getParent();
218
+ return parent !== null && $isRootOrShadowRoot(parent);
219
+ }) ?? anchorNode.getTopLevelElementOrThrow();
220
+ if ($isListNode(element)) {
221
+ const parentList = $findMatchingParent(
222
+ anchorNode,
223
+ (node) => $isListNode(node)
224
+ );
225
+ if (parentList) {
226
+ element = parentList;
227
+ }
228
+ }
229
+ const blockType = getBlockType(element);
230
+ const fontFamily = $getSelectionStyleValueForProperty(
231
+ selection,
232
+ "font-family",
233
+ ""
234
+ );
235
+ setState((prev) => ({
236
+ ...prev,
237
+ blockType,
238
+ fontFamily,
239
+ isBold: selection.hasFormat("bold"),
240
+ isItalic: selection.hasFormat("italic"),
241
+ isUnderline: selection.hasFormat("underline"),
242
+ isStrikethrough: selection.hasFormat("strikethrough"),
243
+ isCode: selection.hasFormat("code"),
244
+ isHighlight: selection.hasFormat("highlight")
245
+ }));
246
+ }, []);
247
+ useEffect(() => {
248
+ const unregisterUndo = editor.registerCommand(
249
+ CAN_UNDO_COMMAND,
250
+ (payload) => {
251
+ setState((prev) => ({ ...prev, canUndo: payload }));
252
+ return false;
253
+ },
254
+ COMMAND_PRIORITY_LOW
255
+ );
256
+ const unregisterRedo = editor.registerCommand(
257
+ CAN_REDO_COMMAND,
258
+ (payload) => {
259
+ setState((prev) => ({ ...prev, canRedo: payload }));
260
+ return false;
261
+ },
262
+ COMMAND_PRIORITY_LOW
263
+ );
264
+ const unregisterUpdate = editor.registerUpdateListener(
265
+ ({ editorState }) => {
266
+ editorState.read(() => {
267
+ updateToolbar();
268
+ });
269
+ }
270
+ );
271
+ return () => {
272
+ unregisterUndo();
273
+ unregisterRedo();
274
+ unregisterUpdate();
275
+ };
276
+ }, [editor, updateToolbar]);
277
+ const applyFontFamily = useCallback(
278
+ (value) => {
279
+ editor.update(() => {
280
+ const selection = $getSelection();
281
+ if ($isRangeSelection(selection)) {
282
+ $patchStyleText(selection, { "font-family": value || "" });
283
+ }
284
+ });
285
+ },
286
+ [editor]
287
+ );
288
+ const fontFamilyItems = useMemo(
289
+ () => FONT_FAMILIES.map((def) => ({
290
+ label: def.label,
291
+ active: state.fontFamily === def.value,
292
+ style: def.value ? { fontFamily: def.value } : void 0,
293
+ onSelect: () => applyFontFamily(def.value)
294
+ })),
295
+ [state.fontFamily, applyFontFamily]
296
+ );
297
+ const headingItems = useMemo(
298
+ () => [
299
+ {
300
+ label: "Text",
301
+ icon: /* @__PURE__ */ jsx(Pilcrow, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
302
+ active: state.blockType === "paragraph",
303
+ onSelect: () => {
304
+ editor.update(() => {
305
+ const selection = $getSelection();
306
+ if ($isRangeSelection(selection)) {
307
+ $setBlocksType(selection, () => $createParagraphNode());
308
+ }
309
+ });
310
+ }
311
+ },
312
+ {
313
+ label: "Heading 1",
314
+ icon: /* @__PURE__ */ jsx(Heading1, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
315
+ active: state.blockType === "h1",
316
+ onSelect: () => {
317
+ editor.update(() => {
318
+ const selection = $getSelection();
319
+ if ($isRangeSelection(selection)) {
320
+ $setBlocksType(selection, () => $createHeadingNode("h1"));
321
+ }
322
+ });
323
+ }
324
+ },
325
+ {
326
+ label: "Heading 2",
327
+ icon: /* @__PURE__ */ jsx(Heading2, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
328
+ active: state.blockType === "h2",
329
+ onSelect: () => {
330
+ editor.update(() => {
331
+ const selection = $getSelection();
332
+ if ($isRangeSelection(selection)) {
333
+ $setBlocksType(selection, () => $createHeadingNode("h2"));
334
+ }
335
+ });
336
+ }
337
+ },
338
+ {
339
+ label: "Heading 3",
340
+ icon: /* @__PURE__ */ jsx(Heading3, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
341
+ active: state.blockType === "h3",
342
+ onSelect: () => {
343
+ editor.update(() => {
344
+ const selection = $getSelection();
345
+ if ($isRangeSelection(selection)) {
346
+ $setBlocksType(selection, () => $createHeadingNode("h3"));
347
+ }
348
+ });
349
+ }
350
+ }
351
+ ],
352
+ [editor, state.blockType]
353
+ );
354
+ const containerClassName = className ? `${toolbarContainer} ${className}` : toolbarContainer;
355
+ const h = tooltipHandle;
356
+ return /* @__PURE__ */ jsxs(TooltipProvider, { delay: 300, children: [
357
+ /* @__PURE__ */ jsx(TooltipRoot, { handle: tooltipHandle, disableHoverablePopup: true, children: (({ payload }) => payload !== void 0 ? /* @__PURE__ */ jsxs(TooltipContent, { side: "bottom", sideOffset: 4, children: [
358
+ payload.title,
359
+ payload.shortcut && /* @__PURE__ */ jsx("span", { className: tooltipShortcut, children: payload.shortcut })
360
+ ] }) : null) }),
361
+ /* @__PURE__ */ jsx(
362
+ "div",
363
+ {
364
+ className: containerClassName,
365
+ role: "toolbar",
366
+ "aria-label": "Editor toolbar",
367
+ children: /* @__PURE__ */ jsxs("div", { className: toolbarRow, children: [
368
+ /* @__PURE__ */ jsx(
369
+ ToolbarDropdown,
370
+ {
371
+ label: getFontLabel(state.fontFamily),
372
+ title: "Font family",
373
+ items: fontFamilyItems,
374
+ triggerWidth: 76,
375
+ tooltipHandle: h
376
+ }
377
+ ),
378
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
379
+ /* @__PURE__ */ jsx(
380
+ ToolbarDropdown,
381
+ {
382
+ label: BLOCK_TYPE_LABELS[state.blockType] ?? "Text",
383
+ title: "Block type",
384
+ items: headingItems,
385
+ triggerWidth: 120,
386
+ tooltipHandle: h
387
+ }
388
+ ),
389
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
390
+ /* @__PURE__ */ jsx(
391
+ ToolbarButton,
392
+ {
393
+ icon: /* @__PURE__ */ jsx(Undo, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
394
+ title: "Undo",
395
+ shortcut: "Ctrl+Z",
396
+ disabled: !state.canUndo,
397
+ onClick: () => editor.dispatchCommand(UNDO_COMMAND, void 0),
398
+ tooltipHandle: h
399
+ }
400
+ ),
401
+ /* @__PURE__ */ jsx(
402
+ ToolbarButton,
403
+ {
404
+ icon: /* @__PURE__ */ jsx(Redo, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
405
+ title: "Redo",
406
+ shortcut: "Ctrl+Y",
407
+ disabled: !state.canRedo,
408
+ onClick: () => editor.dispatchCommand(REDO_COMMAND, void 0),
409
+ tooltipHandle: h
410
+ }
411
+ ),
412
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
413
+ /* @__PURE__ */ jsx(
414
+ ToolbarButton,
415
+ {
416
+ icon: /* @__PURE__ */ jsx(Bold, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
417
+ title: "Bold",
418
+ shortcut: "Ctrl+B",
419
+ active: state.isBold,
420
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold"),
421
+ tooltipHandle: h
422
+ }
423
+ ),
424
+ /* @__PURE__ */ jsx(
425
+ ToolbarButton,
426
+ {
427
+ icon: /* @__PURE__ */ jsx(Italic, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
428
+ title: "Italic",
429
+ shortcut: "Ctrl+I",
430
+ active: state.isItalic,
431
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic"),
432
+ tooltipHandle: h
433
+ }
434
+ ),
435
+ /* @__PURE__ */ jsx(
436
+ ToolbarButton,
437
+ {
438
+ icon: /* @__PURE__ */ jsx(Underline, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
439
+ title: "Underline",
440
+ shortcut: "Ctrl+U",
441
+ active: state.isUnderline,
442
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline"),
443
+ tooltipHandle: h
444
+ }
445
+ ),
446
+ /* @__PURE__ */ jsx(
447
+ ToolbarButton,
448
+ {
449
+ icon: /* @__PURE__ */ jsx(Strikethrough, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
450
+ title: "Strikethrough",
451
+ active: state.isStrikethrough,
452
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough"),
453
+ tooltipHandle: h
454
+ }
455
+ ),
456
+ /* @__PURE__ */ jsx(
457
+ ToolbarButton,
458
+ {
459
+ icon: /* @__PURE__ */ jsx(Code, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
460
+ title: "Inline Code",
461
+ active: state.isCode,
462
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code"),
463
+ tooltipHandle: h
464
+ }
465
+ ),
466
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
467
+ /* @__PURE__ */ jsx(
468
+ ToolbarButton,
469
+ {
470
+ icon: /* @__PURE__ */ jsx(Highlighter, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
471
+ title: "Highlight",
472
+ active: state.isHighlight,
473
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "highlight"),
474
+ tooltipHandle: h
475
+ }
476
+ ),
477
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
478
+ /* @__PURE__ */ jsx(
479
+ ToolbarButton,
480
+ {
481
+ icon: /* @__PURE__ */ jsx(List, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
482
+ title: "Bulleted List",
483
+ active: state.blockType === "bullet",
484
+ onClick: () => editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0),
485
+ tooltipHandle: h
486
+ }
487
+ ),
488
+ /* @__PURE__ */ jsx(
489
+ ToolbarButton,
490
+ {
491
+ icon: /* @__PURE__ */ jsx(ListOrdered, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
492
+ title: "Numbered List",
493
+ active: state.blockType === "number",
494
+ onClick: () => editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0),
495
+ tooltipHandle: h
496
+ }
497
+ ),
498
+ /* @__PURE__ */ jsx(
499
+ ToolbarButton,
500
+ {
501
+ icon: /* @__PURE__ */ jsx(ListChecks, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
502
+ title: "Checklist",
503
+ active: state.blockType === "check",
504
+ onClick: () => editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0),
505
+ tooltipHandle: h
506
+ }
507
+ ),
508
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
509
+ /* @__PURE__ */ jsx(
510
+ ToolbarButton,
511
+ {
512
+ icon: /* @__PURE__ */ jsx(AlignLeft, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
513
+ title: "Align Left",
514
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "left"),
515
+ tooltipHandle: h
516
+ }
517
+ ),
518
+ /* @__PURE__ */ jsx(
519
+ ToolbarButton,
520
+ {
521
+ icon: /* @__PURE__ */ jsx(AlignCenter, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
522
+ title: "Align Center",
523
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "center"),
524
+ tooltipHandle: h
525
+ }
526
+ ),
527
+ /* @__PURE__ */ jsx(
528
+ ToolbarButton,
529
+ {
530
+ icon: /* @__PURE__ */ jsx(AlignRight, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
531
+ title: "Align Right",
532
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "right"),
533
+ tooltipHandle: h
534
+ }
535
+ ),
536
+ /* @__PURE__ */ jsx(
537
+ ToolbarButton,
538
+ {
539
+ icon: /* @__PURE__ */ jsx(AlignJustify, { size: ICON_SIZE, strokeWidth: ICON_STROKE }),
540
+ title: "Justify",
541
+ onClick: () => editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "justify"),
542
+ tooltipHandle: h
543
+ }
544
+ ),
545
+ toolbarItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
546
+ /* @__PURE__ */ jsx(ToolbarSeparator, {}),
547
+ toolbarItems.map((item) => /* @__PURE__ */ jsx(
548
+ ToolbarButton,
549
+ {
550
+ icon: item.icon,
551
+ title: item.title,
552
+ shortcut: item.shortcut,
553
+ onClick: () => item.onSelect(editor, ""),
554
+ tooltipHandle: h
555
+ },
556
+ item.title
557
+ ))
558
+ ] })
559
+ ] })
560
+ }
561
+ )
562
+ ] });
563
+ }
564
+ export {
565
+ ToolbarPlugin
566
+ };
@@ -0,0 +1 @@
1
+ :root{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}:root.dark{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._88yfio0{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._88yfio1{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.8;--rc-line-height-tight: 1.4;--rc-font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._88yfio2{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #a1a1aa;--rc-quote-bg: #fafafa;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: none;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 2px;--rc-space-sm: 4px;--rc-space-md: 10px;--rc-space-lg: 16px;--rc-space-xl: 20px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 14px;--rc-font-size-small: 12px;--rc-line-height: 1.5;--rc-line-height-tight: 1.3;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 3px;--rc-radius-md: 6px;--rc-radius-lg: 8px}.dark ._88yfio0,[data-theme=dark] ._88yfio0,.dark._88yfio0,[data-theme=dark]._88yfio0,.dark ._88yfio1,[data-theme=dark] ._88yfio1,.dark._88yfio1,[data-theme=dark]._88yfio1,.dark ._88yfio2,[data-theme=dark] ._88yfio2,.dark._88yfio2,[data-theme=dark]._88yfio2{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4)}._1e1ersc0{display:flex;flex-direction:column;gap:4px;border-bottom:1px solid var(--rc-border);background-color:var(--rc-bg)}._1e1ersc1{display:flex;flex-direction:row;align-items:center;gap:4px;flex-wrap:wrap;min-height:36px;max-width:var(--rc-max-width);margin:0 auto;padding:6px 16px}._1e1ersc2{position:relative;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:6px;color:var(--rc-text-secondary);cursor:pointer;padding:0;transition:color .15s,background-color .15s}._1e1ersc2:hover{background-color:var(--rc-fill-quaternary);color:var(--rc-text)}._1e1ersc2:active{background-color:var(--rc-fill-tertiary)}._1e1ersc2:disabled{opacity:.35;cursor:default;background-color:transparent;color:var(--rc-text-quaternary)}._1e1ersc2 svg{width:15px;height:15px;stroke-width:2}._1e1ersc3,._1e1ersc3:hover{color:var(--rc-accent);background-color:var(--rc-fill-tertiary)}._1e1ersc4{display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 10px;border:none;background:transparent;border-radius:6px;color:var(--rc-text-secondary);cursor:pointer;font-size:13px;font-weight:500;line-height:1;transition:color .15s,background-color .15s}._1e1ersc4:hover{background-color:var(--rc-fill-quaternary);color:var(--rc-text)}._1e1ersc5{margin-left:auto;display:inline-flex;flex-shrink:0}._1e1ersc6{width:1px;height:24px;background-color:var(--rc-border);margin-inline:6px;flex-shrink:0}._1e1ersc7{background-color:var(--rc-fill-tertiary);color:var(--rc-accent)}._1e1ersc8{font-size:11px;opacity:.7;margin-left:6px}
@@ -0,0 +1,10 @@
1
+ export declare const toolbarContainer: string;
2
+ export declare const toolbarRow: string;
3
+ export declare const toolbarButton: string;
4
+ export declare const toolbarButtonActive: string;
5
+ export declare const toolbarDropdownTrigger: string;
6
+ export declare const toolbarDropdownTriggerChevron: string;
7
+ export declare const toolbarSeparator: string;
8
+ export declare const toolbarDropdownItemActive: string;
9
+ export declare const tooltipShortcut: string;
10
+ //# sourceMappingURL=styles.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,QAM3B,CAAA;AAEF,eAAO,MAAM,UAAU,QAUrB,CAAA;AAEF,eAAO,MAAM,aAAa,QA6BxB,CAAA;AAQF,eAAO,MAAM,mBAAmB,QAO9B,CAAA;AAEF,eAAO,MAAM,sBAAsB,QAmBjC,CAAA;AAEF,eAAO,MAAM,6BAA6B,QAIxC,CAAA;AAEF,eAAO,MAAM,gBAAgB,QAM3B,CAAA;AAEF,eAAO,MAAM,yBAAyB,QAGpC,CAAA;AAEF,eAAO,MAAM,eAAe,QAI1B,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { createTooltipHandle } from '@haklex/rich-editor-ui';
2
+ export interface ToolbarTooltipPayload {
3
+ title: string;
4
+ shortcut?: string;
5
+ }
6
+ export type ToolbarTooltipHandle = ReturnType<typeof createTooltipHandle<ToolbarTooltipPayload>>;
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEjE,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAC3C,OAAO,mBAAmB,CAAC,qBAAqB,CAAC,CAClD,CAAA"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@haklex/rich-plugin-toolbar",
3
+ "version": "0.0.56",
4
+ "description": "Top toolbar plugin for rich editor",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.mjs",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./style.css": "./dist/rich-plugin-toolbar.css"
13
+ },
14
+ "main": "./dist/index.mjs",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "@haklex/rich-editor": "0.0.56",
20
+ "@haklex/rich-editor-ui": "0.0.56",
21
+ "@haklex/rich-style-token": "0.0.56"
22
+ },
23
+ "devDependencies": {
24
+ "@lexical/list": "^0.41.0",
25
+ "@lexical/react": "^0.41.0",
26
+ "@lexical/rich-text": "^0.41.0",
27
+ "@lexical/selection": "^0.41.0",
28
+ "@lexical/utils": "^0.41.0",
29
+ "@types/react": "^19.2.14",
30
+ "@types/react-dom": "^19.2.3",
31
+ "@vanilla-extract/css": "^1.18.0",
32
+ "@vanilla-extract/vite-plugin": "^5.1.4",
33
+ "lexical": "^0.41.0",
34
+ "lucide-react": "^0.575.0",
35
+ "react": "19.2.4",
36
+ "react-dom": "19.2.4",
37
+ "typescript": "^5.9.3",
38
+ "vite": "^7.3.1",
39
+ "vite-plugin-dts": "^4.5.4"
40
+ },
41
+ "peerDependencies": {
42
+ "@lexical/list": "^0.41.0",
43
+ "@lexical/react": "^0.41.0",
44
+ "@lexical/rich-text": "^0.41.0",
45
+ "@lexical/selection": "^0.41.0",
46
+ "@lexical/utils": "^0.41.0",
47
+ "lexical": "^0.41.0",
48
+ "lucide-react": "^0.574.0",
49
+ "react": ">=19",
50
+ "react-dom": ">=19"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "scripts": {
56
+ "build": "vite build",
57
+ "dev:build": "vite build --watch"
58
+ },
59
+ "types": "./dist/index.d.ts"
60
+ }