@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":"
|
|
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,
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
263
|
+
return isEffectiveLinkNode(parent) || isEffectiveLinkNode(node);
|
|
207
264
|
});
|
|
208
265
|
if (hasLink) {
|
|
209
|
-
|
|
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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
{
|
|
316
|
-
|
|
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
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
{
|
|
326
|
-
|
|
327
|
-
|
|
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
|
-
|
|
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}
|
package/dist/styles.css.d.ts
CHANGED
|
@@ -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
|
package/dist/styles.css.d.ts.map
CHANGED
|
@@ -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.
|
|
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
|
|
20
|
-
"@haklex/rich-
|
|
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",
|