@haklex/rich-plugin-slash-menu 0.1.1 → 0.3.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,335 +1,393 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { INSERT_UNORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND } from "@lexical/list";
1
+ import { INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from "@lexical/list";
5
2
  import { INSERT_HORIZONTAL_RULE_COMMAND } from "@lexical/react/LexicalHorizontalRuleNode";
6
3
  import { $createHeadingNode, $createQuoteNode } from "@lexical/rich-text";
7
4
  import { $setBlocksType } from "@lexical/selection";
8
5
  import { INSERT_TABLE_COMMAND } from "@lexical/table";
9
- import { $getSelection, $isRangeSelection, $createParagraphNode } from "lexical";
10
- import { Type, Heading1, Heading2, Heading3, TextQuote, Minus, Table, List, ListOrdered, ListChecks } from "lucide-react";
11
- import { createElement, useEffect, useMemo, useState, useCallback, isValidElement } from "react";
12
- import { MenuOption, useBasicTypeaheadTriggerMatch, LexicalTypeaheadMenuPlugin } from "@lexical/react/LexicalTypeaheadMenuPlugin";
6
+ import { $createParagraphNode, $getSelection, $isRangeSelection } from "lexical";
7
+ import { Heading1, Heading2, Heading3, List, ListChecks, ListOrdered, Minus, Table, TextQuote, Type } from "lucide-react";
8
+ import { createElement, isValidElement, useCallback, useEffect, useMemo, useState } from "react";
9
+ import { LexicalTypeaheadMenuPlugin, MenuOption, useBasicTypeaheadTriggerMatch } from "@lexical/react/LexicalTypeaheadMenuPlugin";
10
+ import { autoUpdate, flip, offset, shift, useFloating } from "@floating-ui/react-dom";
13
11
  import { jsx, jsxs } from "react/jsx-runtime";
14
- import { useFloating, autoUpdate, offset, flip, shift } from "@floating-ui/react-dom";
15
12
  import { collectCommandItems } from "@haklex/rich-editor/commands";
16
13
  import { PortalThemeWrapper } from "@haklex/rich-style-token";
17
14
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
18
15
  import { createPortal } from "react-dom";
19
- class SlashMenuItem extends MenuOption {
20
- constructor(title, options) {
21
- super(title);
22
- __publicField(this, "title");
23
- __publicField(this, "icon");
24
- __publicField(this, "description");
25
- __publicField(this, "keywords");
26
- __publicField(this, "section");
27
- __publicField(this, "onSelect");
28
- this.title = title;
29
- this.icon = options.icon;
30
- this.description = options.description ?? "";
31
- this.keywords = options.keywords ?? [];
32
- this.section = options.section ?? "BASIC BLOCKS";
33
- this.onSelect = options.onSelect;
34
- }
16
+ //#region \0@oxc-project+runtime@0.127.0/helpers/typeof.js
17
+ function _typeof(o) {
18
+ "@babel/helpers - typeof";
19
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
20
+ return typeof o;
21
+ } : function(o) {
22
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
23
+ }, _typeof(o);
35
24
  }
36
- const SECTION_BASIC = "BASIC BLOCKS";
37
- const SECTION_LIST = "LISTS";
38
- const ICON_SIZE = 20;
25
+ //#endregion
26
+ //#region \0@oxc-project+runtime@0.127.0/helpers/toPrimitive.js
27
+ function toPrimitive(t, r) {
28
+ if ("object" != _typeof(t) || !t) return t;
29
+ var e = t[Symbol.toPrimitive];
30
+ if (void 0 !== e) {
31
+ var i = e.call(t, r || "default");
32
+ if ("object" != _typeof(i)) return i;
33
+ throw new TypeError("@@toPrimitive must return a primitive value.");
34
+ }
35
+ return ("string" === r ? String : Number)(t);
36
+ }
37
+ //#endregion
38
+ //#region \0@oxc-project+runtime@0.127.0/helpers/toPropertyKey.js
39
+ function toPropertyKey(t) {
40
+ var i = toPrimitive(t, "string");
41
+ return "symbol" == _typeof(i) ? i : i + "";
42
+ }
43
+ //#endregion
44
+ //#region \0@oxc-project+runtime@0.127.0/helpers/defineProperty.js
45
+ function _defineProperty(e, r, t) {
46
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
47
+ value: t,
48
+ enumerable: !0,
49
+ configurable: !0,
50
+ writable: !0
51
+ }) : e[r] = t, e;
52
+ }
53
+ //#endregion
54
+ //#region src/SlashMenuItem.ts
55
+ var SlashMenuItem = class extends MenuOption {
56
+ constructor(title, options) {
57
+ super(title);
58
+ _defineProperty(this, "title", void 0);
59
+ _defineProperty(this, "icon", void 0);
60
+ _defineProperty(this, "description", void 0);
61
+ _defineProperty(this, "keywords", void 0);
62
+ _defineProperty(this, "section", void 0);
63
+ _defineProperty(this, "onSelect", void 0);
64
+ this.title = title;
65
+ this.icon = options.icon;
66
+ this.description = options.description ?? "";
67
+ this.keywords = options.keywords ?? [];
68
+ this.section = options.section ?? "BASIC BLOCKS";
69
+ this.onSelect = options.onSelect;
70
+ }
71
+ };
72
+ //#endregion
73
+ //#region src/builtinItems.ts
74
+ var SECTION_BASIC = "BASIC BLOCKS";
75
+ var SECTION_LIST = "LISTS";
76
+ var ICON_SIZE = 20;
39
77
  function getBuiltinItems() {
40
- return [
41
- new SlashMenuItem("Text", {
42
- icon: createElement(Type, { size: ICON_SIZE }),
43
- description: "Plain text block",
44
- keywords: ["paragraph", "text", "plain"],
45
- section: SECTION_BASIC,
46
- onSelect: (editor) => {
47
- editor.update(() => {
48
- const selection = $getSelection();
49
- if ($isRangeSelection(selection)) {
50
- $setBlocksType(selection, () => $createParagraphNode());
51
- }
52
- });
53
- }
54
- }),
55
- new SlashMenuItem("Heading 1", {
56
- icon: createElement(Heading1, { size: ICON_SIZE }),
57
- description: "Large section heading",
58
- keywords: ["heading", "h1", "title"],
59
- section: SECTION_BASIC,
60
- onSelect: (editor) => {
61
- editor.update(() => {
62
- const selection = $getSelection();
63
- if ($isRangeSelection(selection)) {
64
- $setBlocksType(selection, () => $createHeadingNode("h1"));
65
- }
66
- });
67
- }
68
- }),
69
- new SlashMenuItem("Heading 2", {
70
- icon: createElement(Heading2, { size: ICON_SIZE }),
71
- description: "Medium section heading",
72
- keywords: ["heading", "h2", "subtitle"],
73
- section: SECTION_BASIC,
74
- onSelect: (editor) => {
75
- editor.update(() => {
76
- const selection = $getSelection();
77
- if ($isRangeSelection(selection)) {
78
- $setBlocksType(selection, () => $createHeadingNode("h2"));
79
- }
80
- });
81
- }
82
- }),
83
- new SlashMenuItem("Heading 3", {
84
- icon: createElement(Heading3, { size: ICON_SIZE }),
85
- description: "Small section heading",
86
- keywords: ["heading", "h3"],
87
- section: SECTION_BASIC,
88
- onSelect: (editor) => {
89
- editor.update(() => {
90
- const selection = $getSelection();
91
- if ($isRangeSelection(selection)) {
92
- $setBlocksType(selection, () => $createHeadingNode("h3"));
93
- }
94
- });
95
- }
96
- }),
97
- new SlashMenuItem("Quote", {
98
- icon: createElement(TextQuote, { size: ICON_SIZE }),
99
- description: "Capture a quote",
100
- keywords: ["quote", "blockquote"],
101
- section: SECTION_BASIC,
102
- onSelect: (editor) => {
103
- editor.update(() => {
104
- const selection = $getSelection();
105
- if (!$isRangeSelection(selection)) return;
106
- const anchorNode = selection.anchor.getNode();
107
- const element = anchorNode.getTopLevelElementOrThrow();
108
- const quoteNode = $createQuoteNode();
109
- const paragraph = $createParagraphNode();
110
- paragraph.append(...element.getChildren());
111
- quoteNode.append(paragraph);
112
- element.replace(quoteNode);
113
- paragraph.selectEnd();
114
- });
115
- }
116
- }),
117
- new SlashMenuItem("Divider", {
118
- icon: createElement(Minus, { size: ICON_SIZE }),
119
- description: "Visual separator",
120
- keywords: ["divider", "hr", "rule", "separator"],
121
- section: SECTION_BASIC,
122
- onSelect: (editor) => {
123
- editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, void 0);
124
- }
125
- }),
126
- new SlashMenuItem("Table", {
127
- icon: createElement(Table, { size: ICON_SIZE }),
128
- description: "Add a table",
129
- keywords: ["table", "grid"],
130
- section: SECTION_BASIC,
131
- onSelect: (editor) => {
132
- editor.dispatchCommand(INSERT_TABLE_COMMAND, {
133
- columns: "3",
134
- rows: "3",
135
- includeHeaders: true
136
- });
137
- }
138
- }),
139
- new SlashMenuItem("Bulleted List", {
140
- icon: createElement(List, { size: ICON_SIZE }),
141
- description: "Unordered list",
142
- keywords: ["list", "bullet", "unordered"],
143
- section: SECTION_LIST,
144
- onSelect: (editor) => {
145
- editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
146
- }
147
- }),
148
- new SlashMenuItem("Numbered List", {
149
- icon: createElement(ListOrdered, { size: ICON_SIZE }),
150
- description: "Ordered list with numbers",
151
- keywords: ["list", "ordered", "number"],
152
- section: SECTION_LIST,
153
- onSelect: (editor) => {
154
- editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
155
- }
156
- }),
157
- new SlashMenuItem("To-do List", {
158
- icon: createElement(ListChecks, { size: ICON_SIZE }),
159
- description: "Track tasks with checkboxes",
160
- keywords: ["task", "todo", "checkbox", "checklist"],
161
- section: SECTION_LIST,
162
- onSelect: (editor) => {
163
- editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0);
164
- }
165
- })
166
- ];
78
+ return [
79
+ new SlashMenuItem("Text", {
80
+ icon: createElement(Type, { size: ICON_SIZE }),
81
+ description: "Plain text block",
82
+ keywords: [
83
+ "paragraph",
84
+ "text",
85
+ "plain"
86
+ ],
87
+ section: SECTION_BASIC,
88
+ onSelect: (editor) => {
89
+ editor.update(() => {
90
+ const selection = $getSelection();
91
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createParagraphNode());
92
+ });
93
+ }
94
+ }),
95
+ new SlashMenuItem("Heading 1", {
96
+ icon: createElement(Heading1, { size: ICON_SIZE }),
97
+ description: "Large section heading",
98
+ keywords: [
99
+ "heading",
100
+ "h1",
101
+ "title"
102
+ ],
103
+ section: SECTION_BASIC,
104
+ onSelect: (editor) => {
105
+ editor.update(() => {
106
+ const selection = $getSelection();
107
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createHeadingNode("h1"));
108
+ });
109
+ }
110
+ }),
111
+ new SlashMenuItem("Heading 2", {
112
+ icon: createElement(Heading2, { size: ICON_SIZE }),
113
+ description: "Medium section heading",
114
+ keywords: [
115
+ "heading",
116
+ "h2",
117
+ "subtitle"
118
+ ],
119
+ section: SECTION_BASIC,
120
+ onSelect: (editor) => {
121
+ editor.update(() => {
122
+ const selection = $getSelection();
123
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createHeadingNode("h2"));
124
+ });
125
+ }
126
+ }),
127
+ new SlashMenuItem("Heading 3", {
128
+ icon: createElement(Heading3, { size: ICON_SIZE }),
129
+ description: "Small section heading",
130
+ keywords: ["heading", "h3"],
131
+ section: SECTION_BASIC,
132
+ onSelect: (editor) => {
133
+ editor.update(() => {
134
+ const selection = $getSelection();
135
+ if ($isRangeSelection(selection)) $setBlocksType(selection, () => $createHeadingNode("h3"));
136
+ });
137
+ }
138
+ }),
139
+ new SlashMenuItem("Quote", {
140
+ icon: createElement(TextQuote, { size: ICON_SIZE }),
141
+ description: "Capture a quote",
142
+ keywords: ["quote", "blockquote"],
143
+ section: SECTION_BASIC,
144
+ onSelect: (editor) => {
145
+ editor.update(() => {
146
+ const selection = $getSelection();
147
+ if (!$isRangeSelection(selection)) return;
148
+ const element = selection.anchor.getNode().getTopLevelElementOrThrow();
149
+ const quoteNode = $createQuoteNode();
150
+ const paragraph = $createParagraphNode();
151
+ paragraph.append(...element.getChildren());
152
+ quoteNode.append(paragraph);
153
+ element.replace(quoteNode);
154
+ paragraph.selectEnd();
155
+ });
156
+ }
157
+ }),
158
+ new SlashMenuItem("Divider", {
159
+ icon: createElement(Minus, { size: ICON_SIZE }),
160
+ description: "Visual separator",
161
+ keywords: [
162
+ "divider",
163
+ "hr",
164
+ "rule",
165
+ "separator"
166
+ ],
167
+ section: SECTION_BASIC,
168
+ onSelect: (editor) => {
169
+ editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, void 0);
170
+ }
171
+ }),
172
+ new SlashMenuItem("Table", {
173
+ icon: createElement(Table, { size: ICON_SIZE }),
174
+ description: "Add a table",
175
+ keywords: ["table", "grid"],
176
+ section: SECTION_BASIC,
177
+ onSelect: (editor) => {
178
+ editor.dispatchCommand(INSERT_TABLE_COMMAND, {
179
+ columns: "3",
180
+ rows: "3",
181
+ includeHeaders: true
182
+ });
183
+ }
184
+ }),
185
+ new SlashMenuItem("Bulleted List", {
186
+ icon: createElement(List, { size: ICON_SIZE }),
187
+ description: "Unordered list",
188
+ keywords: [
189
+ "list",
190
+ "bullet",
191
+ "unordered"
192
+ ],
193
+ section: SECTION_LIST,
194
+ onSelect: (editor) => {
195
+ editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
196
+ }
197
+ }),
198
+ new SlashMenuItem("Numbered List", {
199
+ icon: createElement(ListOrdered, { size: ICON_SIZE }),
200
+ description: "Ordered list with numbers",
201
+ keywords: [
202
+ "list",
203
+ "ordered",
204
+ "number"
205
+ ],
206
+ section: SECTION_LIST,
207
+ onSelect: (editor) => {
208
+ editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
209
+ }
210
+ }),
211
+ new SlashMenuItem("To-do List", {
212
+ icon: createElement(ListChecks, { size: ICON_SIZE }),
213
+ description: "Track tasks with checkboxes",
214
+ keywords: [
215
+ "task",
216
+ "todo",
217
+ "checkbox",
218
+ "checklist"
219
+ ],
220
+ section: SECTION_LIST,
221
+ onSelect: (editor) => {
222
+ editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0);
223
+ }
224
+ })
225
+ ];
167
226
  }
227
+ //#endregion
228
+ //#region src/styles.css.ts
168
229
  var slashMenu = "qolrkf0";
169
230
  var slashMenuSectionWrapper = "qolrkf1";
170
- var slashMenuSectionDivider = "qolrkf2";
171
231
  var slashMenuSection = "qolrkf3";
172
232
  var slashMenuItems = "qolrkf4";
173
233
  var slashMenuItem = "qolrkf5";
174
234
  var slashMenuItemIcon = "qolrkf6";
175
235
  var slashMenuItemText = "qolrkf7";
176
236
  var slashMenuItemTitle = "qolrkf8";
177
- var slashMenuItemDescription = "qolrkf9";
178
237
  var slashMenuEmpty = "qolrkfa";
238
+ //#endregion
239
+ //#region src/SlashMenuList.tsx
179
240
  function groupBySection(options) {
180
- const groups = [];
181
- const seen = /* @__PURE__ */ new Map();
182
- options.forEach((item, index) => {
183
- const label = item.section;
184
- let group = seen.get(label);
185
- if (!group) {
186
- group = { label, items: [] };
187
- seen.set(label, group);
188
- groups.push(group);
189
- }
190
- group.items.push({ item, globalIndex: index });
191
- });
192
- return groups;
241
+ const groups = [];
242
+ const seen = /* @__PURE__ */ new Map();
243
+ options.forEach((item, index) => {
244
+ const label = item.section;
245
+ let group = seen.get(label);
246
+ if (!group) {
247
+ group = {
248
+ label,
249
+ items: []
250
+ };
251
+ seen.set(label, group);
252
+ groups.push(group);
253
+ }
254
+ group.items.push({
255
+ item,
256
+ globalIndex: index
257
+ });
258
+ });
259
+ return groups;
193
260
  }
194
- function SlashMenuList({
195
- anchorElement,
196
- options,
197
- selectedIndex,
198
- selectOptionAndCleanUp,
199
- setHighlightedIndex
200
- }) {
201
- const { refs, floatingStyles } = useFloating({
202
- placement: "bottom-start",
203
- strategy: "absolute",
204
- middleware: [
205
- offset(8),
206
- flip({
207
- fallbackPlacements: ["top-start"],
208
- padding: 8
209
- }),
210
- shift({
211
- padding: 8
212
- })
213
- ],
214
- whileElementsMounted: autoUpdate
215
- });
216
- useEffect(() => {
217
- refs.setReference(anchorElement);
218
- }, [anchorElement, refs]);
219
- const sections = useMemo(() => groupBySection(options), [options]);
220
- if (options.length === 0) {
221
- return /* @__PURE__ */ jsx("div", { className: slashMenu, ref: refs.setFloating, style: floatingStyles, children: /* @__PURE__ */ jsx("div", { className: slashMenuEmpty, children: "No matching commands" }) });
222
- }
223
- return /* @__PURE__ */ jsx("ul", { className: slashMenu, ref: refs.setFloating, role: "listbox", style: floatingStyles, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs("li", { className: slashMenuSectionWrapper, role: "presentation", children: [
224
- sectionIndex > 0 && /* @__PURE__ */ jsx("div", { className: slashMenuSectionDivider }),
225
- /* @__PURE__ */ jsx("div", { className: slashMenuSection, children: section.label }),
226
- /* @__PURE__ */ jsx("ul", { className: slashMenuItems, role: "group", children: section.items.map(({ item, globalIndex }) => /* @__PURE__ */ jsxs(
227
- "li",
228
- {
229
- "aria-selected": globalIndex === selectedIndex,
230
- className: slashMenuItem,
231
- ref: item.setRefElement,
232
- role: "option",
233
- tabIndex: -1,
234
- onClick: () => selectOptionAndCleanUp(item),
235
- onMouseEnter: () => setHighlightedIndex(globalIndex),
236
- children: [
237
- /* @__PURE__ */ jsx("span", { className: slashMenuItemIcon, children: item.icon }),
238
- /* @__PURE__ */ jsxs("span", { className: slashMenuItemText, children: [
239
- /* @__PURE__ */ jsx("span", { className: slashMenuItemTitle, children: item.title }),
240
- item.description && /* @__PURE__ */ jsx("span", { className: slashMenuItemDescription, children: item.description })
241
- ] })
242
- ]
243
- },
244
- item.key
245
- )) })
246
- ] }, section.label)) });
261
+ function SlashMenuList({ anchorElement, options, selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) {
262
+ const { refs, floatingStyles } = useFloating({
263
+ placement: "bottom-start",
264
+ strategy: "absolute",
265
+ middleware: [
266
+ offset(8),
267
+ flip({
268
+ fallbackPlacements: ["top-start"],
269
+ padding: 8
270
+ }),
271
+ shift({ padding: 8 })
272
+ ],
273
+ whileElementsMounted: autoUpdate
274
+ });
275
+ useEffect(() => {
276
+ refs.setReference(anchorElement);
277
+ }, [anchorElement, refs]);
278
+ const sections = useMemo(() => groupBySection(options), [options]);
279
+ if (options.length === 0) return /* @__PURE__ */ jsx("div", {
280
+ className: slashMenu,
281
+ ref: refs.setFloating,
282
+ style: floatingStyles,
283
+ children: /* @__PURE__ */ jsx("div", {
284
+ className: slashMenuEmpty,
285
+ children: "No matching commands"
286
+ })
287
+ });
288
+ return /* @__PURE__ */ jsx("ul", {
289
+ className: slashMenu,
290
+ ref: refs.setFloating,
291
+ role: "listbox",
292
+ style: floatingStyles,
293
+ children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs("li", {
294
+ className: slashMenuSectionWrapper,
295
+ role: "presentation",
296
+ children: [
297
+ sectionIndex > 0 && /* @__PURE__ */ jsx("div", { className: "qolrkf2" }),
298
+ /* @__PURE__ */ jsx("div", {
299
+ className: slashMenuSection,
300
+ children: section.label
301
+ }),
302
+ /* @__PURE__ */ jsx("ul", {
303
+ className: slashMenuItems,
304
+ role: "group",
305
+ children: section.items.map(({ item, globalIndex }) => /* @__PURE__ */ jsxs("li", {
306
+ "aria-selected": globalIndex === selectedIndex,
307
+ className: slashMenuItem,
308
+ ref: item.setRefElement,
309
+ role: "option",
310
+ tabIndex: -1,
311
+ onClick: () => selectOptionAndCleanUp(item),
312
+ onMouseEnter: () => setHighlightedIndex(globalIndex),
313
+ children: [/* @__PURE__ */ jsx("span", {
314
+ className: slashMenuItemIcon,
315
+ children: item.icon
316
+ }), /* @__PURE__ */ jsxs("span", {
317
+ className: slashMenuItemText,
318
+ children: [/* @__PURE__ */ jsx("span", {
319
+ className: slashMenuItemTitle,
320
+ children: item.title
321
+ }), item.description && /* @__PURE__ */ jsx("span", {
322
+ className: "qolrkf9",
323
+ children: item.description
324
+ })]
325
+ })]
326
+ }, item.key))
327
+ })
328
+ ]
329
+ }, section.label))
330
+ });
247
331
  }
332
+ //#endregion
333
+ //#region src/SlashMenuPlugin.tsx
248
334
  function collectNodeSlashItems(editor) {
249
- const configs = collectCommandItems(editor);
250
- return configs.filter((c) => !c.placement || c.placement.includes("slash")).map(
251
- (c) => new SlashMenuItem(c.title, {
252
- description: c.description,
253
- icon: isValidElement(c.icon) ? c.icon : void 0,
254
- keywords: c.keywords,
255
- section: c.section,
256
- onSelect: c.onSelect
257
- })
258
- );
335
+ return collectCommandItems(editor).filter((c) => !c.placement || c.placement.includes("slash")).map((c) => new SlashMenuItem(c.title, {
336
+ description: c.description,
337
+ icon: isValidElement(c.icon) ? c.icon : void 0,
338
+ keywords: c.keywords,
339
+ section: c.section,
340
+ onSelect: c.onSelect
341
+ }));
259
342
  }
260
343
  function filterItems(query, items) {
261
- if (!query) return items;
262
- const lower = query.toLowerCase();
263
- return items.filter((item) => {
264
- if (item.title.toLowerCase().includes(lower)) return true;
265
- return item.keywords.some((kw) => kw.toLowerCase().includes(lower));
266
- });
344
+ if (!query) return items;
345
+ const lower = query.toLowerCase();
346
+ return items.filter((item) => {
347
+ if (item.title.toLowerCase().includes(lower)) return true;
348
+ return item.keywords.some((kw) => kw.toLowerCase().includes(lower));
349
+ });
267
350
  }
268
351
  function SlashMenuPlugin({ items, extraItems, triggerChar = "/" }) {
269
- const [editor] = useLexicalComposerContext();
270
- const [queryString, setQueryString] = useState(null);
271
- const allItems = useMemo(() => {
272
- if (items) return items;
273
- const builtins = getBuiltinItems();
274
- const nodeItems = collectNodeSlashItems(editor);
275
- const combined = [...builtins, ...nodeItems];
276
- return extraItems ? [...combined, ...extraItems] : combined;
277
- }, [items, extraItems, editor]);
278
- const filteredItems = useMemo(
279
- () => filterItems(queryString ?? "", allItems),
280
- [queryString, allItems]
281
- );
282
- const checkForTriggerMatch = useBasicTypeaheadTriggerMatch(triggerChar, {
283
- minLength: 0
284
- });
285
- const onSelectOption = useCallback(
286
- (option, textNodeContainingQuery, closeMenu, matchingString) => {
287
- editor.update(() => {
288
- if (textNodeContainingQuery) {
289
- const selection = $getSelection();
290
- if ($isRangeSelection(selection)) {
291
- textNodeContainingQuery.remove();
292
- }
293
- }
294
- });
295
- closeMenu();
296
- option.onSelect(editor, matchingString);
297
- },
298
- [editor]
299
- );
300
- return /* @__PURE__ */ jsx(
301
- LexicalTypeaheadMenuPlugin,
302
- {
303
- options: filteredItems,
304
- triggerFn: checkForTriggerMatch,
305
- menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => {
306
- const anchorElement = anchorElementRef.current;
307
- if (!anchorElement || filteredItems.length === 0) {
308
- return null;
309
- }
310
- return createPortal(
311
- /* @__PURE__ */ jsx(PortalThemeWrapper, { children: /* @__PURE__ */ jsx(
312
- SlashMenuList,
313
- {
314
- anchorElement,
315
- options: filteredItems,
316
- selectOptionAndCleanUp,
317
- selectedIndex,
318
- setHighlightedIndex
319
- }
320
- ) }),
321
- anchorElement
322
- );
323
- },
324
- onQueryChange: setQueryString,
325
- onSelectOption
326
- }
327
- );
352
+ const [editor] = useLexicalComposerContext();
353
+ const [queryString, setQueryString] = useState(null);
354
+ const allItems = useMemo(() => {
355
+ if (items) return items;
356
+ const builtins = getBuiltinItems();
357
+ const nodeItems = collectNodeSlashItems(editor);
358
+ const combined = [...builtins, ...nodeItems];
359
+ return extraItems ? [...combined, ...extraItems] : combined;
360
+ }, [
361
+ items,
362
+ extraItems,
363
+ editor
364
+ ]);
365
+ const filteredItems = useMemo(() => filterItems(queryString ?? "", allItems), [queryString, allItems]);
366
+ return /* @__PURE__ */ jsx(LexicalTypeaheadMenuPlugin, {
367
+ options: filteredItems,
368
+ triggerFn: useBasicTypeaheadTriggerMatch(triggerChar, { minLength: 0 }),
369
+ menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => {
370
+ const anchorElement = anchorElementRef.current;
371
+ if (!anchorElement || filteredItems.length === 0) return null;
372
+ return createPortal(/* @__PURE__ */ jsx(PortalThemeWrapper, { children: /* @__PURE__ */ jsx(SlashMenuList, {
373
+ anchorElement,
374
+ options: filteredItems,
375
+ selectOptionAndCleanUp,
376
+ selectedIndex,
377
+ setHighlightedIndex
378
+ }) }), anchorElement);
379
+ },
380
+ onQueryChange: setQueryString,
381
+ onSelectOption: useCallback((option, textNodeContainingQuery, closeMenu, matchingString) => {
382
+ editor.update(() => {
383
+ if (textNodeContainingQuery) {
384
+ if ($isRangeSelection($getSelection())) textNodeContainingQuery.remove();
385
+ }
386
+ });
387
+ closeMenu();
388
+ option.onSelect(editor, matchingString);
389
+ }, [editor])
390
+ });
328
391
  }
329
- export {
330
- SlashMenuItem,
331
- SlashMenuList,
332
- SlashMenuPlugin,
333
- collectNodeSlashItems,
334
- getBuiltinItems
335
- };
392
+ //#endregion
393
+ export { SlashMenuItem, SlashMenuList, SlashMenuPlugin, collectNodeSlashItems, getBuiltinItems };
@@ -1 +1,2 @@
1
- :root{--rc-text: #000;--rc-text-secondary: #262626;--rc-text-tertiary: #737373;--rc-text-quaternary: #a3a3a3;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f5f5f5;--rc-fill: #e8e8e8;--rc-fill-secondary: #eeeeee;--rc-fill-tertiary: #f5f5f5;--rc-fill-quaternary: #fafafa;--rc-border: #f5f5f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #404040;--rc-code-bg: #f5f5f5;--rc-hr-border: #e5e5e5;--rc-quote-border: #2563eb;--rc-quote-bg: #f5f5f5;--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-family-kai: "楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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: #a3a3a3;--rc-text-tertiary: #737373;--rc-text-quaternary: #525252;--rc-bg: #0a0a0a;--rc-bg-secondary: #171717;--rc-bg-tertiary: #262626;--rc-fill: #2a2a2a;--rc-fill-secondary: #222222;--rc-fill-tertiary: #1a1a1a;--rc-fill-quaternary: #141414;--rc-border: #262626;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #d4d4d4;--rc-code-bg: #262626;--rc-hr-border: #262626;--rc-quote-border: #60a5fa;--rc-quote-bg: #262626;--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-family-kai: "楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}[data-theme=dark]{--rc-text: #fafafa;--rc-text-secondary: #a3a3a3;--rc-text-tertiary: #737373;--rc-text-quaternary: #525252;--rc-bg: #0a0a0a;--rc-bg-secondary: #171717;--rc-bg-tertiary: #262626;--rc-fill: #2a2a2a;--rc-fill-secondary: #222222;--rc-fill-tertiary: #1a1a1a;--rc-fill-quaternary: #141414;--rc-border: #262626;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #d4d4d4;--rc-code-bg: #262626;--rc-hr-border: #262626;--rc-quote-border: #60a5fa;--rc-quote-bg: #262626;--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-family-kai: "楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}._1m14pjb0{--rc-text: #000;--rc-text-secondary: #262626;--rc-text-tertiary: #737373;--rc-text-quaternary: #a3a3a3;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f5f5f5;--rc-fill: #e8e8e8;--rc-fill-secondary: #eeeeee;--rc-fill-tertiary: #f5f5f5;--rc-fill-quaternary: #fafafa;--rc-border: #f5f5f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #404040;--rc-code-bg: #f5f5f5;--rc-hr-border: #e5e5e5;--rc-quote-border: #2563eb;--rc-quote-bg: #f5f5f5;--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-family-kai: "楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}._1m14pjb1{--rc-text: #000;--rc-text-secondary: #262626;--rc-text-tertiary: #737373;--rc-text-quaternary: #a3a3a3;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f5f5f5;--rc-fill: #e8e8e8;--rc-fill-secondary: #eeeeee;--rc-fill-tertiary: #f5f5f5;--rc-fill-quaternary: #fafafa;--rc-border: #f5f5f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #404040;--rc-code-bg: #f5f5f5;--rc-hr-border: #e5e5e5;--rc-quote-border: #2563eb;--rc-quote-bg: #f5f5f5;--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-family-kai: "楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}._1m14pjb2{--rc-text: #000;--rc-text-secondary: #262626;--rc-text-tertiary: #737373;--rc-text-quaternary: #a3a3a3;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f5f5f5;--rc-fill: #e8e8e8;--rc-fill-secondary: #eeeeee;--rc-fill-tertiary: #f5f5f5;--rc-fill-quaternary: #fafafa;--rc-border: #f5f5f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #404040;--rc-code-bg: #f5f5f5;--rc-hr-border: #e5e5e5;--rc-quote-border: #a3a3a3;--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-family-kai: "楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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: 12px}.dark ._1m14pjb0,[data-theme=dark] ._1m14pjb0,.dark._1m14pjb0,[data-theme=dark]._1m14pjb0,.dark ._1m14pjb1,[data-theme=dark] ._1m14pjb1,.dark._1m14pjb1,[data-theme=dark]._1m14pjb1,.dark ._1m14pjb2,[data-theme=dark] ._1m14pjb2,.dark._1m14pjb2,[data-theme=dark]._1m14pjb2{--rc-text: #fafafa;--rc-text-secondary: #a3a3a3;--rc-text-tertiary: #737373;--rc-text-quaternary: #525252;--rc-bg: #0a0a0a;--rc-bg-secondary: #171717;--rc-bg-tertiary: #262626;--rc-fill: #2a2a2a;--rc-fill-secondary: #222222;--rc-fill-tertiary: #1a1a1a;--rc-fill-quaternary: #141414;--rc-border: #262626;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #d4d4d4;--rc-code-bg: #262626;--rc-hr-border: #262626;--rc-quote-border: #60a5fa;--rc-quote-bg: #262626;--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)}.qolrkf0{position:absolute;top:0;left:0;width:288px;max-height:384px;overflow-y:auto;overflow-x:hidden;font-family:var(--rc-font-family-sans);background:var(--rc-bg);border:1px solid var(--rc-border);border-radius:var(--rc-radius-lg);box-shadow:var(--rc-shadow-menu);list-style:none;margin:0;padding:0}.qolrkf0::-webkit-scrollbar{width:5px}.qolrkf0::-webkit-scrollbar-track{background:transparent}.qolrkf0::-webkit-scrollbar-thumb{background:var(--rc-text-quaternary);border-radius:3px}.qolrkf2{height:1px;background:var(--rc-border);opacity:.5}.qolrkf3{position:sticky;top:0;z-index:10;padding:8px 12px;font-size:11px;font-weight:500;letter-spacing:.05em;text-transform:uppercase;color:var(--rc-text-tertiary);user-select:none;background:var(--rc-bg)}.qolrkf4{padding:4px 0;list-style:none;margin:0}.qolrkf5{display:flex;align-items:center;gap:12px;padding:8px 12px;margin:0 4px;border-radius:var(--rc-radius-md);cursor:pointer;transition:background 75ms ease;color:var(--rc-text)}.qolrkf5:hover,.qolrkf5[aria-selected=true]{background:var(--rc-fill)}.qolrkf6{width:36px;height:36px;display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;border-radius:6px;background:var(--rc-bg-tertiary);border:1px solid transparent;color:var(--rc-text-tertiary);line-height:1;transition:background 75ms ease,border-color 75ms ease}.qolrkf5[aria-selected=true] .qolrkf6{background:var(--rc-bg);border-color:var(--rc-border)}.qolrkf7{display:flex;flex-direction:column;min-width:0;flex:1;gap:2px}.qolrkf8{font-size:14px;font-weight:500;line-height:1.3;color:var(--rc-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qolrkf9{font-size:12px;line-height:1.3;color:var(--rc-text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.qolrkfa{padding:32px 12px;color:var(--rc-text-quaternary);font-size:13px;text-align:center}@supports (backdrop-filter: blur(8px)){.qolrkf3{background:color-mix(in srgb,var(--rc-bg) 92%,transparent);backdrop-filter:blur(8px)}}
1
+ :root{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--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-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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,[data-theme=dark]{--rc-text:#fafafa;--rc-text-secondary:#a3a3a3;--rc-text-tertiary:#737373;--rc-text-quaternary:#525252;--rc-bg:#0a0a0a;--rc-bg-secondary:#171717;--rc-bg-tertiary:#262626;--rc-fill:#2a2a2a;--rc-fill-secondary:#222;--rc-fill-tertiary:#1a1a1a;--rc-fill-quaternary:#141414;--rc-border:#262626;--rc-accent:#60a5fa;--rc-accent-light:#60a5fa20;--rc-link:#60a5fa;--rc-code-text:#d4d4d4;--rc-code-bg:#262626;--rc-hr-border:#262626;--rc-quote-border:#60a5fa;--rc-quote-bg:#262626;--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 #00000073, 0 2px 8px #0000004d;--rc-shadow-modal:0 10px 15px -3px #0006, 0 4px 6px -4px #00000059;--rc-shadow-menu:0 1px 4px #00000040, 0 4px 16px #0006;--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-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}._1m14pjb0{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--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-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}._1m14pjb1{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--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-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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}._1m14pjb2{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#a3a3a3;--rc-quote-bg:#fafafa;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:none;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--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-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", 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:12px}.dark ._1m14pjb0,[data-theme=dark] ._1m14pjb0,.dark._1m14pjb0,[data-theme=dark]._1m14pjb0,.dark ._1m14pjb1,[data-theme=dark] ._1m14pjb1,.dark._1m14pjb1,[data-theme=dark]._1m14pjb1,.dark ._1m14pjb2,[data-theme=dark] ._1m14pjb2,.dark._1m14pjb2,[data-theme=dark]._1m14pjb2{--rc-text:#fafafa;--rc-text-secondary:#a3a3a3;--rc-text-tertiary:#737373;--rc-text-quaternary:#525252;--rc-bg:#0a0a0a;--rc-bg-secondary:#171717;--rc-bg-tertiary:#262626;--rc-fill:#2a2a2a;--rc-fill-secondary:#222;--rc-fill-tertiary:#1a1a1a;--rc-fill-quaternary:#141414;--rc-border:#262626;--rc-accent:#60a5fa;--rc-accent-light:#60a5fa20;--rc-link:#60a5fa;--rc-code-text:#d4d4d4;--rc-code-bg:#262626;--rc-hr-border:#262626;--rc-quote-border:#60a5fa;--rc-quote-bg:#262626;--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 #00000073, 0 2px 8px #0000004d;--rc-shadow-modal:0 10px 15px -3px #0006, 0 4px 6px -4px #00000059;--rc-shadow-menu:0 1px 4px #00000040, 0 4px 16px #0006}.qolrkf0{width:288px;max-height:384px;font-family:var(--rc-font-family-sans);background:var(--rc-bg);border:1px solid var(--rc-border);border-radius:var(--rc-radius-lg);box-shadow:var(--rc-shadow-menu);margin:0;padding:0;list-style:none;position:absolute;top:0;left:0;overflow:hidden auto}.qolrkf0::-webkit-scrollbar{width:5px}.qolrkf0::-webkit-scrollbar-track{background:0 0}.qolrkf0::-webkit-scrollbar-thumb{background:var(--rc-text-quaternary);border-radius:3px}.qolrkf2{background:var(--rc-border);opacity:.5;height:1px}.qolrkf3{z-index:10;letter-spacing:.05em;text-transform:uppercase;color:var(--rc-text-tertiary);-webkit-user-select:none;user-select:none;background:var(--rc-bg);padding:8px 12px;font-size:11px;font-weight:500;position:sticky;top:0}.qolrkf4{margin:0;padding:4px 0;list-style:none}.qolrkf5{border-radius:var(--rc-radius-md);cursor:pointer;color:var(--rc-text);align-items:center;gap:12px;margin:0 4px;padding:8px 12px;transition:background 75ms;display:flex}.qolrkf5:hover,.qolrkf5[aria-selected=true]{background:var(--rc-fill)}.qolrkf6{background:var(--rc-bg-tertiary);width:36px;height:36px;color:var(--rc-text-tertiary);border:1px solid #0000;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;font-size:16px;line-height:1;transition:background 75ms,border-color 75ms;display:flex}.qolrkf5[aria-selected=true] .qolrkf6{background:var(--rc-bg);border-color:var(--rc-border)}.qolrkf7{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.qolrkf8{color:var(--rc-text);text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:1.3;overflow:hidden}.qolrkf9{color:var(--rc-text-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:12px;line-height:1.3;overflow:hidden}.qolrkfa{color:var(--rc-text-quaternary);text-align:center;padding:32px 12px;font-size:13px}@supports ((-webkit-backdrop-filter:blur(8px)) or (backdrop-filter:blur(8px))){.qolrkf3{background:color-mix(in srgb, var(--rc-bg) 92%, transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}}
2
+ /*$vite$:1*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haklex/rich-plugin-slash-menu",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Slash command menu plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,34 +22,34 @@
22
22
  ],
23
23
  "dependencies": {
24
24
  "@floating-ui/react-dom": "^2.1.8",
25
- "@haklex/rich-editor": "0.1.1",
26
- "@haklex/rich-style-token": "0.1.1"
25
+ "@haklex/rich-editor": "0.3.0",
26
+ "@haklex/rich-style-token": "0.3.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@lexical/list": "^0.43.0",
30
- "@lexical/react": "^0.43.0",
31
- "@lexical/rich-text": "^0.43.0",
32
- "@lexical/selection": "^0.43.0",
33
- "@lexical/table": "^0.43.0",
29
+ "@lexical/list": "^0.44.0",
30
+ "@lexical/react": "^0.44.0",
31
+ "@lexical/rich-text": "^0.44.0",
32
+ "@lexical/selection": "^0.44.0",
33
+ "@lexical/table": "^0.44.0",
34
34
  "@types/react": "^19.2.14",
35
35
  "@types/react-dom": "^19.2.3",
36
- "@vanilla-extract/css": "^1.18.0",
37
- "@vanilla-extract/vite-plugin": "^5.1.4",
38
- "lexical": "^0.43.0",
39
- "lucide-react": "^1.0.0",
40
- "react": "19.2.4",
41
- "react-dom": "19.2.4",
36
+ "@vanilla-extract/css": "^1.20.1",
37
+ "@vanilla-extract/vite-plugin": "^5.2.2",
38
+ "lexical": "^0.44.0",
39
+ "lucide-react": "^1.12.0",
40
+ "react": "19.2.5",
41
+ "react-dom": "19.2.5",
42
42
  "typescript": "^5.9.3",
43
- "vite": "^7.3.1",
43
+ "vite": "^8.0.10",
44
44
  "vite-plugin-dts": "^4.5.4"
45
45
  },
46
46
  "peerDependencies": {
47
- "@lexical/list": "^0.43.0",
48
- "@lexical/react": "^0.43.0",
49
- "@lexical/rich-text": "^0.43.0",
50
- "@lexical/selection": "^0.43.0",
51
- "@lexical/table": "^0.43.0",
52
- "lexical": "^0.43.0",
47
+ "@lexical/list": "^0.44.0",
48
+ "@lexical/react": "^0.44.0",
49
+ "@lexical/rich-text": "^0.44.0",
50
+ "@lexical/selection": "^0.44.0",
51
+ "@lexical/table": "^0.44.0",
52
+ "lexical": "^0.44.0",
53
53
  "lucide-react": "^1.0.0",
54
54
  "react": ">=19",
55
55
  "react-dom": ">=19"