@haklex/rich-plugin-floating-toolbar 0.0.43 → 0.0.45

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.
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingToolbarPlugin.d.ts","sourceRoot":"","sources":["../src/FloatingToolbarPlugin.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AA0IzC,wBAAgB,qBAAqB,IAAI,YAAY,GAAG,IAAI,CAuP3D"}
1
+ {"version":3,"file":"FloatingToolbarPlugin.d.ts","sourceRoot":"","sources":["../src/FloatingToolbarPlugin.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAkMzC,wBAAgB,qBAAqB,IAAI,YAAY,GAAG,IAAI,CAghB3D"}
package/dist/index.mjs CHANGED
@@ -1,18 +1,47 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { $createRubyNode, $isRubyNode } from "@haklex/rich-editor";
2
3
  import { ColorPicker } from "@haklex/rich-editor-ui";
3
4
  import { usePortalTheme, vars } from "@haklex/rich-style-token";
4
- import { $isLinkNode, TOGGLE_LINK_COMMAND } from "@lexical/link";
5
+ import { TOGGLE_LINK_COMMAND, $isLinkNode, $isAutoLinkNode } from "@lexical/link";
5
6
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
6
7
  import { $patchStyleText, $getSelectionStyleValueForProperty } from "@lexical/selection";
7
- import { $getSelection, $isRangeSelection, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_LOW, FORMAT_TEXT_COMMAND } from "lexical";
8
- import { Bold, Italic, Underline, Strikethrough, Superscript, Subscript, Code, Highlighter, Link } from "lucide-react";
8
+ import { $getSelection, $isRangeSelection, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_LOW, FORMAT_TEXT_COMMAND, $createTextNode, $getNodeByKey } from "lexical";
9
+ import { Bold, Italic, Underline, Strikethrough, Superscript, Subscript, Code, Highlighter, Link, Languages, Check, X, Trash2 } from "lucide-react";
9
10
  import { useRef, useState, useCallback, useEffect } from "react";
10
11
  import { createPortal } from "react-dom";
11
12
  var toolbar = "_1m6axz71";
12
13
  var btn = "_1m6axz72";
13
14
  var btnActive = "_1m6axz73";
14
15
  var btnIndicator = "_1m6axz74";
15
- var separator = "_1m6axz75";
16
+ var rubyEditor = "_1m6axz75";
17
+ var rubyPreview = "_1m6axz76";
18
+ var rubyPreviewReading = "_1m6axz77";
19
+ var rubyPreviewBase = "_1m6axz78";
20
+ var rubyInputRow = "_1m6axz79";
21
+ var rubyInput = "_1m6axz7a";
22
+ var rubyActionBtn = "_1m6axz7b";
23
+ var rubyHint = "_1m6axz7c";
24
+ var separator = "_1m6axz7d";
25
+ function isEffectiveLinkNode(node) {
26
+ if (!$isLinkNode(node)) return false;
27
+ return !$isAutoLinkNode(node) || !node.getIsUnlinked();
28
+ }
29
+ function isRegularLinkNode(node) {
30
+ return $isLinkNode(node) && !$isAutoLinkNode(node);
31
+ }
32
+ function collectSelectedActiveAutoLinkNodes(selection) {
33
+ const autoLinkNodes = /* @__PURE__ */ new Map();
34
+ for (const node of selection.getNodes()) {
35
+ if ($isAutoLinkNode(node) && !node.getIsUnlinked()) {
36
+ autoLinkNodes.set(node.getKey(), node);
37
+ }
38
+ const parent = node.getParent();
39
+ if ($isAutoLinkNode(parent) && !parent.getIsUnlinked()) {
40
+ autoLinkNodes.set(parent.getKey(), parent);
41
+ }
42
+ }
43
+ return Array.from(autoLinkNodes.values());
44
+ }
16
45
  const INITIAL_STATE = {
17
46
  isBold: false,
18
47
  isItalic: false,
@@ -23,14 +52,36 @@ const INITIAL_STATE = {
23
52
  isCode: false,
24
53
  isHighlight: false,
25
54
  isLink: false,
55
+ isRuby: false,
26
56
  fontColor: ""
27
57
  };
58
+ function findRubyAncestor(node) {
59
+ let current = node;
60
+ while (current) {
61
+ if ($isRubyNode(current)) {
62
+ return current;
63
+ }
64
+ current = current.getParent();
65
+ }
66
+ return null;
67
+ }
68
+ function getSelectedRubyNodes(nodes) {
69
+ const rubyNodes = /* @__PURE__ */ new Map();
70
+ for (const node of nodes) {
71
+ const rubyNode = findRubyAncestor(node);
72
+ if (rubyNode) {
73
+ rubyNodes.set(rubyNode.getKey(), rubyNode);
74
+ }
75
+ }
76
+ return Array.from(rubyNodes.values());
77
+ }
28
78
  function getSelectionState(selection) {
29
79
  const nodes = selection.getNodes();
30
80
  const hasLink = nodes.some((node) => {
31
81
  const parent = node.getParent();
32
- return $isLinkNode(parent) || $isLinkNode(node);
82
+ return isEffectiveLinkNode(parent) || isEffectiveLinkNode(node);
33
83
  });
84
+ const hasRuby = getSelectedRubyNodes(nodes).length > 0;
34
85
  return {
35
86
  isBold: selection.hasFormat("bold"),
36
87
  isItalic: selection.hasFormat("italic"),
@@ -41,6 +92,7 @@ function getSelectionState(selection) {
41
92
  isCode: selection.hasFormat("code"),
42
93
  isHighlight: selection.hasFormat("highlight"),
43
94
  isLink: hasLink,
95
+ isRuby: hasRuby,
44
96
  fontColor: $getSelectionStyleValueForProperty(selection, "color", "")
45
97
  };
46
98
  }
@@ -110,6 +162,11 @@ function FloatingToolbarPlugin() {
110
162
  const toolbarRef = useRef(null);
111
163
  const [visible, setVisible] = useState(false);
112
164
  const [state, setState] = useState(INITIAL_STATE);
165
+ const [rubyEdit, setRubyEdit] = useState(null);
166
+ const rubyEditorRef = useRef(null);
167
+ const rubyInputRef = useRef(null);
168
+ const rubyEditRef = useRef(rubyEdit);
169
+ rubyEditRef.current = rubyEdit;
113
170
  const updateToolbar = useCallback(() => {
114
171
  const selection = $getSelection();
115
172
  if (!$isRangeSelection(selection) || selection.isCollapsed()) {
@@ -197,16 +254,28 @@ function FloatingToolbarPlugin() {
197
254
  [editor]
198
255
  );
199
256
  const handleLink = useCallback(() => {
200
- editor.getEditorState().read(() => {
257
+ editor.update(() => {
201
258
  const selection = $getSelection();
202
259
  if (!$isRangeSelection(selection)) return;
203
260
  const nodes = selection.getNodes();
204
261
  const hasLink = nodes.some((node) => {
205
262
  const parent = node.getParent();
206
- return $isLinkNode(parent) || $isLinkNode(node);
263
+ return isEffectiveLinkNode(parent) || isEffectiveLinkNode(node);
207
264
  });
208
265
  if (hasLink) {
209
- editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
266
+ for (const autoLinkNode of collectSelectedActiveAutoLinkNodes(
267
+ selection
268
+ )) {
269
+ autoLinkNode.setIsUnlinked(true);
270
+ autoLinkNode.markDirty();
271
+ }
272
+ const hasRegularLink = nodes.some((node) => {
273
+ const parent = node.getParent();
274
+ return isRegularLinkNode(parent) || isRegularLinkNode(node);
275
+ });
276
+ if (hasRegularLink) {
277
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
278
+ }
210
279
  } else {
211
280
  const text = selection.getTextContent();
212
281
  const url = /^https?:\/\//.test(text) ? text : "";
@@ -225,113 +294,346 @@ function FloatingToolbarPlugin() {
225
294
  },
226
295
  [editor]
227
296
  );
228
- if (!visible) return null;
229
- const toolbarClassName = portalClassName ? `${toolbar} ${portalClassName}` : toolbar;
230
- return createPortal(
231
- /* @__PURE__ */ jsxs(
232
- "div",
233
- {
234
- ref: toolbarRef,
235
- className: toolbarClassName,
236
- role: "toolbar",
237
- "aria-label": "Text formatting",
238
- style: { position: "fixed", zIndex: 50 },
239
- children: [
240
- /* @__PURE__ */ jsx(
241
- ToolbarButton,
242
- {
243
- active: state.isBold,
244
- onClick: () => handleFormat("bold"),
245
- ariaLabel: "Bold",
246
- children: /* @__PURE__ */ jsx(Bold, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
247
- }
248
- ),
249
- /* @__PURE__ */ jsx(
250
- ToolbarButton,
251
- {
252
- active: state.isItalic,
253
- onClick: () => handleFormat("italic"),
254
- ariaLabel: "Italic",
255
- children: /* @__PURE__ */ jsx(Italic, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
256
- }
257
- ),
258
- /* @__PURE__ */ jsx(
259
- ToolbarButton,
260
- {
261
- active: state.isUnderline,
262
- onClick: () => handleFormat("underline"),
263
- ariaLabel: "Underline",
264
- children: /* @__PURE__ */ jsx(Underline, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
265
- }
266
- ),
267
- /* @__PURE__ */ jsx(
268
- ToolbarButton,
269
- {
270
- active: state.isStrikethrough,
271
- onClick: () => handleFormat("strikethrough"),
272
- ariaLabel: "Strikethrough",
273
- children: /* @__PURE__ */ jsx(Strikethrough, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
274
- }
275
- ),
276
- /* @__PURE__ */ jsx(
277
- ToolbarButton,
278
- {
279
- active: state.isSuperscript,
280
- onClick: () => handleFormat("superscript"),
281
- ariaLabel: "Superscript",
282
- children: /* @__PURE__ */ jsx(Superscript, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
283
- }
284
- ),
285
- /* @__PURE__ */ jsx(
286
- ToolbarButton,
287
- {
288
- active: state.isSubscript,
289
- onClick: () => handleFormat("subscript"),
290
- ariaLabel: "Subscript",
291
- children: /* @__PURE__ */ jsx(Subscript, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
292
- }
293
- ),
294
- /* @__PURE__ */ jsx("span", { className: separator }),
295
- /* @__PURE__ */ jsx(
296
- ToolbarButton,
297
- {
298
- active: state.isCode,
299
- onClick: () => handleFormat("code"),
300
- ariaLabel: "Code",
301
- children: /* @__PURE__ */ jsx(Code, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
302
- }
303
- ),
304
- /* @__PURE__ */ jsx(
305
- ToolbarButton,
306
- {
307
- active: state.isHighlight,
308
- onClick: () => handleFormat("highlight"),
309
- ariaLabel: "Highlight",
310
- children: /* @__PURE__ */ jsx(Highlighter, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
311
- }
312
- ),
313
- /* @__PURE__ */ jsx(
314
- ToolbarButton,
315
- {
316
- active: state.isLink,
317
- onClick: handleLink,
318
- ariaLabel: "Link",
319
- children: /* @__PURE__ */ jsx(Link, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
297
+ const handleRuby = useCallback(() => {
298
+ editor.update(() => {
299
+ const selection = $getSelection();
300
+ if (!$isRangeSelection(selection)) return;
301
+ const nodes = selection.getNodes();
302
+ const rubyNodes = getSelectedRubyNodes(nodes);
303
+ if (rubyNodes.length > 0) {
304
+ const rubyNode = rubyNodes[0];
305
+ if (!rubyNode) return;
306
+ setRubyEdit({
307
+ nodeKey: rubyNode.getKey(),
308
+ reading: rubyNode.getReading(),
309
+ baseText: rubyNode.getTextContent(),
310
+ isNew: false
311
+ });
312
+ } else {
313
+ const text = selection.getTextContent();
314
+ if (!text.trim()) return;
315
+ selection.removeText();
316
+ const rubyNode = $createRubyNode("");
317
+ rubyNode.append($createTextNode(text));
318
+ const freshSelection = $getSelection();
319
+ if ($isRangeSelection(freshSelection)) {
320
+ freshSelection.insertNodes([rubyNode]);
321
+ }
322
+ setRubyEdit({
323
+ nodeKey: rubyNode.getKey(),
324
+ reading: "",
325
+ baseText: text,
326
+ isNew: true
327
+ });
328
+ }
329
+ });
330
+ }, [editor]);
331
+ const handleRubyConfirm = useCallback(() => {
332
+ const edit = rubyEditRef.current;
333
+ if (!edit) return;
334
+ editor.update(() => {
335
+ const node = $getNodeByKey(edit.nodeKey);
336
+ if ($isRubyNode(node)) {
337
+ node.setReading(edit.reading);
338
+ }
339
+ });
340
+ setRubyEdit(null);
341
+ }, [editor]);
342
+ const handleRubyCancel = useCallback(() => {
343
+ const edit = rubyEditRef.current;
344
+ if (!edit) return;
345
+ if (edit.isNew) {
346
+ editor.update(() => {
347
+ const node = $getNodeByKey(edit.nodeKey);
348
+ if ($isRubyNode(node)) {
349
+ const children = node.getChildren();
350
+ for (const child of children) {
351
+ node.insertBefore(child);
352
+ }
353
+ node.remove();
354
+ }
355
+ });
356
+ }
357
+ setRubyEdit(null);
358
+ }, [editor]);
359
+ const handleRubyDelete = useCallback(() => {
360
+ const edit = rubyEditRef.current;
361
+ if (!edit) return;
362
+ editor.update(() => {
363
+ const node = $getNodeByKey(edit.nodeKey);
364
+ if ($isRubyNode(node)) {
365
+ const children = node.getChildren();
366
+ for (const child of children) {
367
+ node.insertBefore(child);
368
+ }
369
+ node.remove();
370
+ }
371
+ });
372
+ setRubyEdit(null);
373
+ }, [editor]);
374
+ const isRubyEditing = rubyEdit !== null;
375
+ useEffect(() => {
376
+ if (!isRubyEditing) return;
377
+ const handleClickOutside = (e) => {
378
+ const currentEdit = rubyEditRef.current;
379
+ if (!currentEdit) return;
380
+ if (rubyEditorRef.current && !rubyEditorRef.current.contains(e.target)) {
381
+ if (currentEdit.reading.trim()) {
382
+ editor.update(() => {
383
+ const node = $getNodeByKey(currentEdit.nodeKey);
384
+ if ($isRubyNode(node)) {
385
+ node.setReading(currentEdit.reading);
320
386
  }
321
- ),
322
- /* @__PURE__ */ jsx("span", { className: separator }),
323
- /* @__PURE__ */ jsx(
324
- ColorPicker,
325
- {
326
- currentColor: state.fontColor || "inherit",
327
- onSelect: handleColor
387
+ });
388
+ } else if (currentEdit.isNew) {
389
+ editor.update(() => {
390
+ const node = $getNodeByKey(currentEdit.nodeKey);
391
+ if ($isRubyNode(node)) {
392
+ const children = node.getChildren();
393
+ for (const child of children) {
394
+ node.insertBefore(child);
395
+ }
396
+ node.remove();
328
397
  }
329
- )
330
- ]
398
+ });
399
+ }
400
+ setRubyEdit(null);
331
401
  }
402
+ };
403
+ const timer = setTimeout(() => {
404
+ document.addEventListener("mousedown", handleClickOutside);
405
+ }, 0);
406
+ return () => {
407
+ clearTimeout(timer);
408
+ document.removeEventListener("mousedown", handleClickOutside);
409
+ };
410
+ }, [editor, isRubyEditing]);
411
+ useEffect(() => {
412
+ if (!rubyEdit || !rubyEditorRef.current) return;
413
+ const positionEditor = () => {
414
+ const editorEl = rubyEditorRef.current;
415
+ if (!editorEl) return;
416
+ applyThemeVars(editorEl);
417
+ const rubyDom = editor.getElementByKey(rubyEdit.nodeKey);
418
+ if (!rubyDom) return;
419
+ const rect = rubyDom.getBoundingClientRect();
420
+ const editorWidth = editorEl.offsetWidth;
421
+ const rawLeft = rect.left + rect.width / 2 - editorWidth / 2;
422
+ const clampedLeft = Math.max(
423
+ 8,
424
+ Math.min(rawLeft, window.innerWidth - editorWidth - 8)
425
+ );
426
+ editorEl.style.top = `${rect.bottom + 8}px`;
427
+ editorEl.style.left = `${clampedLeft}px`;
428
+ };
429
+ requestAnimationFrame(positionEditor);
430
+ requestAnimationFrame(() => {
431
+ rubyInputRef.current?.focus();
432
+ });
433
+ }, [applyThemeVars, editor, rubyEdit]);
434
+ if (!visible && !rubyEdit) return null;
435
+ const toolbarClassName = portalClassName ? `${toolbar} ${portalClassName}` : toolbar;
436
+ const rubyEditorClassName = portalClassName ? `${rubyEditor} ${portalClassName}` : rubyEditor;
437
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
438
+ visible && !rubyEdit && createPortal(
439
+ /* @__PURE__ */ jsxs(
440
+ "div",
441
+ {
442
+ ref: toolbarRef,
443
+ className: toolbarClassName,
444
+ role: "toolbar",
445
+ "aria-label": "Text formatting",
446
+ style: { position: "fixed", zIndex: 50 },
447
+ children: [
448
+ /* @__PURE__ */ jsx(
449
+ ToolbarButton,
450
+ {
451
+ active: state.isBold,
452
+ onClick: () => handleFormat("bold"),
453
+ ariaLabel: "Bold",
454
+ children: /* @__PURE__ */ jsx(Bold, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
455
+ }
456
+ ),
457
+ /* @__PURE__ */ jsx(
458
+ ToolbarButton,
459
+ {
460
+ active: state.isItalic,
461
+ onClick: () => handleFormat("italic"),
462
+ ariaLabel: "Italic",
463
+ children: /* @__PURE__ */ jsx(Italic, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
464
+ }
465
+ ),
466
+ /* @__PURE__ */ jsx(
467
+ ToolbarButton,
468
+ {
469
+ active: state.isUnderline,
470
+ onClick: () => handleFormat("underline"),
471
+ ariaLabel: "Underline",
472
+ children: /* @__PURE__ */ jsx(Underline, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
473
+ }
474
+ ),
475
+ /* @__PURE__ */ jsx(
476
+ ToolbarButton,
477
+ {
478
+ active: state.isStrikethrough,
479
+ onClick: () => handleFormat("strikethrough"),
480
+ ariaLabel: "Strikethrough",
481
+ children: /* @__PURE__ */ jsx(Strikethrough, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
482
+ }
483
+ ),
484
+ /* @__PURE__ */ jsx(
485
+ ToolbarButton,
486
+ {
487
+ active: state.isSuperscript,
488
+ onClick: () => handleFormat("superscript"),
489
+ ariaLabel: "Superscript",
490
+ children: /* @__PURE__ */ jsx(Superscript, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
491
+ }
492
+ ),
493
+ /* @__PURE__ */ jsx(
494
+ ToolbarButton,
495
+ {
496
+ active: state.isSubscript,
497
+ onClick: () => handleFormat("subscript"),
498
+ ariaLabel: "Subscript",
499
+ children: /* @__PURE__ */ jsx(Subscript, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
500
+ }
501
+ ),
502
+ /* @__PURE__ */ jsx("span", { className: separator }),
503
+ /* @__PURE__ */ jsx(
504
+ ToolbarButton,
505
+ {
506
+ active: state.isCode,
507
+ onClick: () => handleFormat("code"),
508
+ ariaLabel: "Code",
509
+ children: /* @__PURE__ */ jsx(Code, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
510
+ }
511
+ ),
512
+ /* @__PURE__ */ jsx(
513
+ ToolbarButton,
514
+ {
515
+ active: state.isHighlight,
516
+ onClick: () => handleFormat("highlight"),
517
+ ariaLabel: "Highlight",
518
+ children: /* @__PURE__ */ jsx(Highlighter, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
519
+ }
520
+ ),
521
+ /* @__PURE__ */ jsx(
522
+ ToolbarButton,
523
+ {
524
+ active: state.isLink,
525
+ onClick: handleLink,
526
+ ariaLabel: "Link",
527
+ children: /* @__PURE__ */ jsx(Link, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
528
+ }
529
+ ),
530
+ /* @__PURE__ */ jsx(
531
+ ToolbarButton,
532
+ {
533
+ active: state.isRuby,
534
+ onClick: handleRuby,
535
+ ariaLabel: "Ruby annotation",
536
+ children: /* @__PURE__ */ jsx(Languages, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
537
+ }
538
+ ),
539
+ /* @__PURE__ */ jsx("span", { className: separator }),
540
+ /* @__PURE__ */ jsx(
541
+ ColorPicker,
542
+ {
543
+ currentColor: state.fontColor || "inherit",
544
+ onSelect: handleColor
545
+ }
546
+ )
547
+ ]
548
+ }
549
+ ),
550
+ document.body
332
551
  ),
333
- document.body
334
- );
552
+ rubyEdit && createPortal(
553
+ /* @__PURE__ */ jsxs(
554
+ "div",
555
+ {
556
+ ref: rubyEditorRef,
557
+ className: rubyEditorClassName,
558
+ style: { position: "fixed", zIndex: 51 },
559
+ children: [
560
+ /* @__PURE__ */ jsxs("div", { className: rubyPreview, children: [
561
+ /* @__PURE__ */ jsx("span", { className: rubyPreviewReading, children: rubyEdit.reading || " " }),
562
+ /* @__PURE__ */ jsx("span", { className: rubyPreviewBase, children: rubyEdit.baseText })
563
+ ] }),
564
+ /* @__PURE__ */ jsxs("div", { className: rubyInputRow, children: [
565
+ /* @__PURE__ */ jsx(
566
+ "input",
567
+ {
568
+ ref: rubyInputRef,
569
+ className: rubyInput,
570
+ value: rubyEdit.reading,
571
+ onChange: (e) => setRubyEdit(
572
+ (prev) => prev ? { ...prev, reading: e.target.value } : null
573
+ ),
574
+ onKeyDown: (e) => {
575
+ if (e.key === "Enter") {
576
+ e.preventDefault();
577
+ handleRubyConfirm();
578
+ }
579
+ if (e.key === "Escape") {
580
+ e.preventDefault();
581
+ handleRubyCancel();
582
+ }
583
+ },
584
+ placeholder: "读音"
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsx(
588
+ "button",
589
+ {
590
+ type: "button",
591
+ className: rubyActionBtn,
592
+ onMouseDown: (e) => {
593
+ e.preventDefault();
594
+ handleRubyConfirm();
595
+ },
596
+ style: { color: "#22c55e" },
597
+ "aria-label": "Confirm",
598
+ children: /* @__PURE__ */ jsx(Check, { size: 14, strokeWidth: ICON_STROKE })
599
+ }
600
+ ),
601
+ /* @__PURE__ */ jsx(
602
+ "button",
603
+ {
604
+ type: "button",
605
+ className: rubyActionBtn,
606
+ onMouseDown: (e) => {
607
+ e.preventDefault();
608
+ handleRubyCancel();
609
+ },
610
+ "aria-label": "Cancel",
611
+ children: /* @__PURE__ */ jsx(X, { size: 14, strokeWidth: ICON_STROKE })
612
+ }
613
+ ),
614
+ /* @__PURE__ */ jsx("span", { className: separator }),
615
+ /* @__PURE__ */ jsx(
616
+ "button",
617
+ {
618
+ type: "button",
619
+ className: rubyActionBtn,
620
+ onMouseDown: (e) => {
621
+ e.preventDefault();
622
+ handleRubyDelete();
623
+ },
624
+ style: { color: "#ef4444" },
625
+ "aria-label": "Delete ruby",
626
+ children: /* @__PURE__ */ jsx(Trash2, { size: 14, strokeWidth: ICON_STROKE })
627
+ }
628
+ )
629
+ ] }),
630
+ /* @__PURE__ */ jsx("span", { className: rubyHint, children: "Enter 保存 / Esc 取消" })
631
+ ]
632
+ }
633
+ ),
634
+ document.body
635
+ )
636
+ ] });
335
637
  }
336
638
  export {
337
639
  FloatingToolbarPlugin
@@ -1 +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-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-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}._11h7prk0{--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-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}._11h7prk1{--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-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}._11h7prk2{--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-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 ._11h7prk0,[data-theme=dark] ._11h7prk0,.dark._11h7prk0,[data-theme=dark]._11h7prk0,.dark ._11h7prk1,[data-theme=dark] ._11h7prk1,.dark._11h7prk1,[data-theme=dark]._11h7prk1,.dark ._11h7prk2,[data-theme=dark] ._11h7prk2,.dark._11h7prk2,[data-theme=dark]._11h7prk2{--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-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)}@keyframes _1m6axz70{0%{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}._1m6axz71{display:flex;align-items:center;gap:2px;padding:4px 6px;border-radius:12px;border:1px solid var(--rc-border);background-color:color-mix(in srgb,var(--rc-bg) 95%,transparent);backdrop-filter:blur(8px);box-shadow:var(--rc-shadow-top-bar);animation:_1m6axz70 .15s ease-out}._1m6axz72{position:relative;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:none;border-radius:8px;color:var(--rc-text-secondary);cursor:pointer;padding:0;transition:color .1s,background-color .1s}._1m6axz72:hover{color:var(--rc-text);background-color:color-mix(in srgb,var(--rc-text) 4%,transparent)}._1m6axz73{color:var(--rc-text);background-color:color-mix(in srgb,var(--rc-text) 6%,transparent)}._1m6axz74{position:absolute;bottom:2px;left:50%;transform:translate(-50%);height:2px;width:14px;border-radius:1px;background-color:var(--rc-text)}._1m6axz75{width:1px;height:20px;background-color:var(--rc-border);margin-inline:2px;flex-shrink:0}
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-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-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}._11h7prk0{--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-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}._11h7prk1{--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-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}._11h7prk2{--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-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 ._11h7prk0,[data-theme=dark] ._11h7prk0,.dark._11h7prk0,[data-theme=dark]._11h7prk0,.dark ._11h7prk1,[data-theme=dark] ._11h7prk1,.dark._11h7prk1,[data-theme=dark]._11h7prk1,.dark ._11h7prk2,[data-theme=dark] ._11h7prk2,.dark._11h7prk2,[data-theme=dark]._11h7prk2{--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-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)}@keyframes _1m6axz70{0%{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}._1m6axz71{display:flex;align-items:center;gap:2px;padding:4px 6px;border-radius:12px;border:1px solid var(--rc-border);background-color:color-mix(in srgb,var(--rc-bg) 95%,transparent);backdrop-filter:blur(8px);box-shadow:var(--rc-shadow-top-bar);animation:_1m6axz70 .15s ease-out}._1m6axz72{position:relative;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:none;border-radius:8px;color:var(--rc-text-secondary);cursor:pointer;padding:0;transition:color .1s,background-color .1s}._1m6axz72:hover{color:var(--rc-text);background-color:color-mix(in srgb,var(--rc-text) 4%,transparent)}._1m6axz73{color:var(--rc-text);background-color:color-mix(in srgb,var(--rc-text) 6%,transparent)}._1m6axz74{position:absolute;bottom:2px;left:50%;transform:translate(-50%);height:2px;width:14px;border-radius:1px;background-color:var(--rc-text)}._1m6axz75{display:flex;flex-direction:column;align-items:center;gap:8px;padding:12px 16px;border-radius:12px;border:1px solid var(--rc-border);background-color:color-mix(in srgb,var(--rc-bg) 95%,transparent);backdrop-filter:blur(8px);box-shadow:var(--rc-shadow-top-bar);animation:_1m6axz70 .15s ease-out;min-width:240px}._1m6axz76{display:flex;flex-direction:column;align-items:center;gap:2px;padding:4px 16px 8px}._1m6axz77{font-size:12px;color:var(--rc-text-secondary);line-height:1.2}._1m6axz78{font-size:20px;font-weight:600;line-height:1.3}._1m6axz79{display:flex;align-items:center;gap:6px;width:100%}._1m6axz7a{flex:1;padding:6px 10px;border-radius:8px;border:1.5px solid var(--rc-border);background-color:transparent;color:var(--rc-text);font-size:14px;outline:none;line-height:1.4}._1m6axz7a:focus{border-color:var(--rc-text)}._1m6axz7b{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:none;border-radius:6px;color:var(--rc-text-secondary);cursor:pointer;padding:0;transition:color .1s,background-color .1s}._1m6axz7b:hover{background-color:color-mix(in srgb,var(--rc-text) 6%,transparent)}._1m6axz7c{font-size:11px;color:var(--rc-text-secondary);opacity:.7}._1m6axz7d{width:1px;height:20px;background-color:var(--rc-border);margin-inline:2px;flex-shrink:0}
@@ -2,5 +2,13 @@ export declare const toolbar: string;
2
2
  export declare const btn: string;
3
3
  export declare const btnActive: string;
4
4
  export declare const btnIndicator: string;
5
+ export declare const rubyEditor: string;
6
+ export declare const rubyPreview: string;
7
+ export declare const rubyPreviewReading: string;
8
+ export declare const rubyPreviewBase: string;
9
+ export declare const rubyInputRow: string;
10
+ export declare const rubyInput: string;
11
+ export declare const rubyActionBtn: string;
12
+ export declare const rubyHint: string;
5
13
  export declare const separator: string;
6
14
  //# sourceMappingURL=styles.css.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,OAAO,QAWlB,CAAA;AAEF,eAAO,MAAM,GAAG,QAkBd,CAAA;AAEF,eAAO,MAAM,SAAS,QAGpB,CAAA;AAEF,eAAO,MAAM,YAAY,QASvB,CAAA;AAEF,eAAO,MAAM,SAAS,QAMpB,CAAA"}
1
+ {"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,OAAO,QAWlB,CAAA;AAEF,eAAO,MAAM,GAAG,QAkBd,CAAA;AAEF,eAAO,MAAM,SAAS,QAGpB,CAAA;AAEF,eAAO,MAAM,YAAY,QASvB,CAAA;AAEF,eAAO,MAAM,UAAU,QAarB,CAAA;AAEF,eAAO,MAAM,WAAW,QAMtB,CAAA;AAEF,eAAO,MAAM,kBAAkB,QAI7B,CAAA;AAEF,eAAO,MAAM,eAAe,QAI1B,CAAA;AAEF,eAAO,MAAM,YAAY,QAKvB,CAAA;AAEF,eAAO,MAAM,SAAS,QAepB,CAAA;AAEF,eAAO,MAAM,aAAa,QAgBxB,CAAA;AAEF,eAAO,MAAM,QAAQ,QAInB,CAAA;AAEF,eAAO,MAAM,SAAS,QAMpB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haklex/rich-plugin-floating-toolbar",
3
- "version": "0.0.43",
3
+ "version": "0.0.45",
4
4
  "description": "Floating toolbar plugin",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -16,8 +16,9 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@haklex/rich-editor-ui": "0.0.43",
20
- "@haklex/rich-style-token": "0.0.43"
19
+ "@haklex/rich-editor": "0.0.45",
20
+ "@haklex/rich-editor-ui": "0.0.45",
21
+ "@haklex/rich-style-token": "0.0.45"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@lexical/link": "^0.41.0",