@haklex/rich-plugin-floating-toolbar 0.0.65 → 0.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -13
- package/dist/FloatingToolbarPlugin.d.ts.map +1 -1
- package/dist/index.mjs +40 -79
- package/package.json +19 -14
package/README.md
CHANGED
|
@@ -1,30 +1,59 @@
|
|
|
1
1
|
# @haklex/rich-plugin-floating-toolbar
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Floating toolbar plugin that appears on text selection for inline formatting.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @haklex/rich-plugin-floating-toolbar
|
|
8
|
+
pnpm add @haklex/rich-plugin-floating-toolbar
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Peer Dependencies
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
| Package | Version |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `@lexical/link` | `^0.41.0` |
|
|
16
|
+
| `@lexical/react` | `^0.41.0` |
|
|
17
|
+
| `@lexical/selection` | `^0.41.0` |
|
|
18
|
+
| `lexical` | `^0.41.0` |
|
|
19
|
+
| `lucide-react` | `^0.574.0` |
|
|
20
|
+
| `react` | `>= 19` |
|
|
21
|
+
| `react-dom` | `>= 19` |
|
|
16
22
|
|
|
17
|
-
##
|
|
23
|
+
## Usage
|
|
18
24
|
|
|
19
25
|
```tsx
|
|
20
26
|
import { FloatingToolbarPlugin } from '@haklex/rich-plugin-floating-toolbar'
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
import '@haklex/rich-plugin-floating-toolbar/style.css'
|
|
28
|
+
|
|
29
|
+
function Editor() {
|
|
30
|
+
return (
|
|
31
|
+
<RichEditor>
|
|
32
|
+
<FloatingToolbarPlugin />
|
|
33
|
+
</RichEditor>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
26
36
|
```
|
|
27
37
|
|
|
38
|
+
When the user selects text, a floating toolbar appears near the selection with inline formatting controls such as bold, italic, underline, strikethrough, code, and link insertion.
|
|
39
|
+
|
|
40
|
+
## Exports
|
|
41
|
+
|
|
42
|
+
| Export | Type | Description |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| `FloatingToolbarPlugin` | Component | Main plugin component to render inside `RichEditor` |
|
|
45
|
+
|
|
46
|
+
## Sub-path Exports
|
|
47
|
+
|
|
48
|
+
| Path | Description |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `@haklex/rich-plugin-floating-toolbar` | Plugin component |
|
|
51
|
+
| `@haklex/rich-plugin-floating-toolbar/style.css` | Stylesheet |
|
|
52
|
+
|
|
53
|
+
## Part of Haklex
|
|
54
|
+
|
|
55
|
+
This package is part of the [Haklex](../../README.md) rich editor ecosystem.
|
|
56
|
+
|
|
28
57
|
## License
|
|
29
58
|
|
|
30
59
|
MIT
|
|
@@ -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":"AAgCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AA6L1C,wBAAgB,qBAAqB,IAAI,YAAY,GAAG,IAAI,CA6f3D"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { $createRubyNode, $isRubyNode } from "@haklex/rich-editor";
|
|
2
|
+
import { $createRubyNode, $isRubyNode } from "@haklex/rich-editor/nodes";
|
|
3
3
|
import { ColorPicker } from "@haklex/rich-editor-ui";
|
|
4
4
|
import { usePortalTheme, usePortalContainer, vars } from "@haklex/rich-style-token";
|
|
5
5
|
import { TOGGLE_LINK_COMMAND, $isLinkNode, $isAutoLinkNode } from "@lexical/link";
|
|
@@ -108,32 +108,24 @@ function computePosition(nativeSelection, toolbar2, container) {
|
|
|
108
108
|
const offsetY = containerRect?.top ?? 0;
|
|
109
109
|
const availableWidth = containerRect?.width ?? window.innerWidth;
|
|
110
110
|
const rawLeft = rect.left - offsetX + rect.width / 2 - toolbarWidth / 2;
|
|
111
|
-
const clampedLeft = Math.max(
|
|
112
|
-
8,
|
|
113
|
-
Math.min(rawLeft, availableWidth - toolbarWidth - 8)
|
|
114
|
-
);
|
|
111
|
+
const clampedLeft = Math.max(8, Math.min(rawLeft, availableWidth - toolbarWidth - 8));
|
|
115
112
|
return {
|
|
116
113
|
top: rect.top - offsetY - toolbarHeight - 10,
|
|
117
114
|
left: clampedLeft
|
|
118
115
|
};
|
|
119
116
|
}
|
|
120
|
-
function ToolbarButton({
|
|
121
|
-
active,
|
|
122
|
-
onClick,
|
|
123
|
-
ariaLabel,
|
|
124
|
-
children
|
|
125
|
-
}) {
|
|
117
|
+
function ToolbarButton({ active, onClick, ariaLabel, children }) {
|
|
126
118
|
return /* @__PURE__ */ jsxs(
|
|
127
119
|
"button",
|
|
128
120
|
{
|
|
129
|
-
|
|
121
|
+
"aria-label": ariaLabel,
|
|
122
|
+
"aria-pressed": active,
|
|
130
123
|
className: `${btn}${active ? ` ${btnActive}` : ""}`,
|
|
124
|
+
type: "button",
|
|
131
125
|
onMouseDown: (e) => {
|
|
132
126
|
e.preventDefault();
|
|
133
127
|
onClick();
|
|
134
128
|
},
|
|
135
|
-
"aria-label": ariaLabel,
|
|
136
|
-
"aria-pressed": active,
|
|
137
129
|
children: [
|
|
138
130
|
children,
|
|
139
131
|
active && /* @__PURE__ */ jsx("span", { className: btnIndicator })
|
|
@@ -144,7 +136,7 @@ function ToolbarButton({
|
|
|
144
136
|
const ICON_SIZE = 15;
|
|
145
137
|
const ICON_STROKE = 2;
|
|
146
138
|
function extractCssVarName(value) {
|
|
147
|
-
const match = value.match(/^var\((--[
|
|
139
|
+
const match = value.match(/^var\((--[^\s),]+)(?:,[^)]+)?\)$/);
|
|
148
140
|
return match?.[1] ?? null;
|
|
149
141
|
}
|
|
150
142
|
function collectThemeVarNames(contract, output) {
|
|
@@ -205,13 +197,11 @@ function FloatingToolbarPlugin() {
|
|
|
205
197
|
},
|
|
206
198
|
COMMAND_PRIORITY_LOW
|
|
207
199
|
);
|
|
208
|
-
const unregisterUpdate = editor.registerUpdateListener(
|
|
209
|
-
(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
);
|
|
200
|
+
const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {
|
|
201
|
+
editorState.read(() => {
|
|
202
|
+
updateToolbar();
|
|
203
|
+
});
|
|
204
|
+
});
|
|
215
205
|
return () => {
|
|
216
206
|
unregisterCommand();
|
|
217
207
|
unregisterUpdate();
|
|
@@ -269,9 +259,7 @@ function FloatingToolbarPlugin() {
|
|
|
269
259
|
return isEffectiveLinkNode(parent) || isEffectiveLinkNode(node);
|
|
270
260
|
});
|
|
271
261
|
if (hasLink) {
|
|
272
|
-
for (const autoLinkNode of collectSelectedActiveAutoLinkNodes(
|
|
273
|
-
selection
|
|
274
|
-
)) {
|
|
262
|
+
for (const autoLinkNode of collectSelectedActiveAutoLinkNodes(selection)) {
|
|
275
263
|
autoLinkNode.setIsUnlinked(true);
|
|
276
264
|
autoLinkNode.markDirty();
|
|
277
265
|
}
|
|
@@ -430,10 +418,7 @@ function FloatingToolbarPlugin() {
|
|
|
430
418
|
const availW = containerRect?.width ?? window.innerWidth;
|
|
431
419
|
const editorWidth = editorEl.offsetWidth;
|
|
432
420
|
const rawLeft = rect.left - oX + rect.width / 2 - editorWidth / 2;
|
|
433
|
-
const clampedLeft = Math.max(
|
|
434
|
-
8,
|
|
435
|
-
Math.min(rawLeft, availW - editorWidth - 8)
|
|
436
|
-
);
|
|
421
|
+
const clampedLeft = Math.max(8, Math.min(rawLeft, availW - editorWidth - 8));
|
|
437
422
|
editorEl.style.top = `${rect.bottom - oY + 8}px`;
|
|
438
423
|
editorEl.style.left = `${clampedLeft}px`;
|
|
439
424
|
};
|
|
@@ -450,18 +435,18 @@ function FloatingToolbarPlugin() {
|
|
|
450
435
|
/* @__PURE__ */ jsxs(
|
|
451
436
|
"div",
|
|
452
437
|
{
|
|
453
|
-
|
|
438
|
+
"aria-label": "Text formatting",
|
|
454
439
|
className: toolbarClassName,
|
|
440
|
+
ref: toolbarRef,
|
|
455
441
|
role: "toolbar",
|
|
456
|
-
"aria-label": "Text formatting",
|
|
457
442
|
style: { position: "fixed", zIndex: 50 },
|
|
458
443
|
children: [
|
|
459
444
|
/* @__PURE__ */ jsx(
|
|
460
445
|
ToolbarButton,
|
|
461
446
|
{
|
|
462
447
|
active: state.isBold,
|
|
463
|
-
onClick: () => handleFormat("bold"),
|
|
464
448
|
ariaLabel: "Bold",
|
|
449
|
+
onClick: () => handleFormat("bold"),
|
|
465
450
|
children: /* @__PURE__ */ jsx(Bold, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
466
451
|
}
|
|
467
452
|
),
|
|
@@ -469,8 +454,8 @@ function FloatingToolbarPlugin() {
|
|
|
469
454
|
ToolbarButton,
|
|
470
455
|
{
|
|
471
456
|
active: state.isItalic,
|
|
472
|
-
onClick: () => handleFormat("italic"),
|
|
473
457
|
ariaLabel: "Italic",
|
|
458
|
+
onClick: () => handleFormat("italic"),
|
|
474
459
|
children: /* @__PURE__ */ jsx(Italic, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
475
460
|
}
|
|
476
461
|
),
|
|
@@ -478,8 +463,8 @@ function FloatingToolbarPlugin() {
|
|
|
478
463
|
ToolbarButton,
|
|
479
464
|
{
|
|
480
465
|
active: state.isUnderline,
|
|
481
|
-
onClick: () => handleFormat("underline"),
|
|
482
466
|
ariaLabel: "Underline",
|
|
467
|
+
onClick: () => handleFormat("underline"),
|
|
483
468
|
children: /* @__PURE__ */ jsx(Underline, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
484
469
|
}
|
|
485
470
|
),
|
|
@@ -487,8 +472,8 @@ function FloatingToolbarPlugin() {
|
|
|
487
472
|
ToolbarButton,
|
|
488
473
|
{
|
|
489
474
|
active: state.isStrikethrough,
|
|
490
|
-
onClick: () => handleFormat("strikethrough"),
|
|
491
475
|
ariaLabel: "Strikethrough",
|
|
476
|
+
onClick: () => handleFormat("strikethrough"),
|
|
492
477
|
children: /* @__PURE__ */ jsx(Strikethrough, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
493
478
|
}
|
|
494
479
|
),
|
|
@@ -496,8 +481,8 @@ function FloatingToolbarPlugin() {
|
|
|
496
481
|
ToolbarButton,
|
|
497
482
|
{
|
|
498
483
|
active: state.isSuperscript,
|
|
499
|
-
onClick: () => handleFormat("superscript"),
|
|
500
484
|
ariaLabel: "Superscript",
|
|
485
|
+
onClick: () => handleFormat("superscript"),
|
|
501
486
|
children: /* @__PURE__ */ jsx(Superscript, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
502
487
|
}
|
|
503
488
|
),
|
|
@@ -505,8 +490,8 @@ function FloatingToolbarPlugin() {
|
|
|
505
490
|
ToolbarButton,
|
|
506
491
|
{
|
|
507
492
|
active: state.isSubscript,
|
|
508
|
-
onClick: () => handleFormat("subscript"),
|
|
509
493
|
ariaLabel: "Subscript",
|
|
494
|
+
onClick: () => handleFormat("subscript"),
|
|
510
495
|
children: /* @__PURE__ */ jsx(Subscript, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
511
496
|
}
|
|
512
497
|
),
|
|
@@ -515,8 +500,8 @@ function FloatingToolbarPlugin() {
|
|
|
515
500
|
ToolbarButton,
|
|
516
501
|
{
|
|
517
502
|
active: state.isCode,
|
|
518
|
-
onClick: () => handleFormat("code"),
|
|
519
503
|
ariaLabel: "Code",
|
|
504
|
+
onClick: () => handleFormat("code"),
|
|
520
505
|
children: /* @__PURE__ */ jsx(Code, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
521
506
|
}
|
|
522
507
|
),
|
|
@@ -524,37 +509,15 @@ function FloatingToolbarPlugin() {
|
|
|
524
509
|
ToolbarButton,
|
|
525
510
|
{
|
|
526
511
|
active: state.isHighlight,
|
|
527
|
-
onClick: () => handleFormat("highlight"),
|
|
528
512
|
ariaLabel: "Highlight",
|
|
513
|
+
onClick: () => handleFormat("highlight"),
|
|
529
514
|
children: /* @__PURE__ */ jsx(Highlighter, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
530
515
|
}
|
|
531
516
|
),
|
|
532
|
-
/* @__PURE__ */ jsx(
|
|
533
|
-
|
|
534
|
-
{
|
|
535
|
-
active: state.isLink,
|
|
536
|
-
onClick: handleLink,
|
|
537
|
-
ariaLabel: "Link",
|
|
538
|
-
children: /* @__PURE__ */ jsx(Link, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
539
|
-
}
|
|
540
|
-
),
|
|
541
|
-
/* @__PURE__ */ jsx(
|
|
542
|
-
ToolbarButton,
|
|
543
|
-
{
|
|
544
|
-
active: state.isRuby,
|
|
545
|
-
onClick: handleRuby,
|
|
546
|
-
ariaLabel: "Ruby annotation",
|
|
547
|
-
children: /* @__PURE__ */ jsx(Languages, { size: ICON_SIZE, strokeWidth: ICON_STROKE })
|
|
548
|
-
}
|
|
549
|
-
),
|
|
517
|
+
/* @__PURE__ */ jsx(ToolbarButton, { active: state.isLink, ariaLabel: "Link", onClick: handleLink, children: /* @__PURE__ */ jsx(Link, { size: ICON_SIZE, strokeWidth: ICON_STROKE }) }),
|
|
518
|
+
/* @__PURE__ */ jsx(ToolbarButton, { active: state.isRuby, ariaLabel: "Ruby annotation", onClick: handleRuby, children: /* @__PURE__ */ jsx(Languages, { size: ICON_SIZE, strokeWidth: ICON_STROKE }) }),
|
|
550
519
|
/* @__PURE__ */ jsx("span", { className: separator }),
|
|
551
|
-
/* @__PURE__ */ jsx(
|
|
552
|
-
ColorPicker,
|
|
553
|
-
{
|
|
554
|
-
currentColor: state.fontColor || "inherit",
|
|
555
|
-
onSelect: handleColor
|
|
556
|
-
}
|
|
557
|
-
)
|
|
520
|
+
/* @__PURE__ */ jsx(ColorPicker, { currentColor: state.fontColor || "inherit", onSelect: handleColor })
|
|
558
521
|
]
|
|
559
522
|
}
|
|
560
523
|
),
|
|
@@ -564,8 +527,8 @@ function FloatingToolbarPlugin() {
|
|
|
564
527
|
/* @__PURE__ */ jsxs(
|
|
565
528
|
"div",
|
|
566
529
|
{
|
|
567
|
-
ref: rubyEditorRef,
|
|
568
530
|
className: rubyEditorClassName,
|
|
531
|
+
ref: rubyEditorRef,
|
|
569
532
|
style: { position: "fixed", zIndex: 51 },
|
|
570
533
|
children: [
|
|
571
534
|
/* @__PURE__ */ jsxs("div", { className: rubyPreview, children: [
|
|
@@ -576,12 +539,11 @@ function FloatingToolbarPlugin() {
|
|
|
576
539
|
/* @__PURE__ */ jsx(
|
|
577
540
|
"input",
|
|
578
541
|
{
|
|
579
|
-
ref: rubyInputRef,
|
|
580
542
|
className: rubyInput,
|
|
543
|
+
placeholder: "读音",
|
|
544
|
+
ref: rubyInputRef,
|
|
581
545
|
value: rubyEdit.reading,
|
|
582
|
-
onChange: (e) => setRubyEdit(
|
|
583
|
-
(prev) => prev ? { ...prev, reading: e.target.value } : null
|
|
584
|
-
),
|
|
546
|
+
onChange: (e) => setRubyEdit((prev) => prev ? { ...prev, reading: e.target.value } : null),
|
|
585
547
|
onKeyDown: (e) => {
|
|
586
548
|
if (e.key === "Enter") {
|
|
587
549
|
e.preventDefault();
|
|
@@ -591,34 +553,33 @@ function FloatingToolbarPlugin() {
|
|
|
591
553
|
e.preventDefault();
|
|
592
554
|
handleRubyCancel();
|
|
593
555
|
}
|
|
594
|
-
}
|
|
595
|
-
placeholder: "读音"
|
|
556
|
+
}
|
|
596
557
|
}
|
|
597
558
|
),
|
|
598
559
|
/* @__PURE__ */ jsx(
|
|
599
560
|
"button",
|
|
600
561
|
{
|
|
601
|
-
|
|
562
|
+
"aria-label": "Confirm",
|
|
602
563
|
className: rubyActionBtn,
|
|
564
|
+
style: { color: "#22c55e" },
|
|
565
|
+
type: "button",
|
|
603
566
|
onMouseDown: (e) => {
|
|
604
567
|
e.preventDefault();
|
|
605
568
|
handleRubyConfirm();
|
|
606
569
|
},
|
|
607
|
-
style: { color: "#22c55e" },
|
|
608
|
-
"aria-label": "Confirm",
|
|
609
570
|
children: /* @__PURE__ */ jsx(Check, { size: 14, strokeWidth: ICON_STROKE })
|
|
610
571
|
}
|
|
611
572
|
),
|
|
612
573
|
/* @__PURE__ */ jsx(
|
|
613
574
|
"button",
|
|
614
575
|
{
|
|
615
|
-
|
|
576
|
+
"aria-label": "Cancel",
|
|
616
577
|
className: rubyActionBtn,
|
|
578
|
+
type: "button",
|
|
617
579
|
onMouseDown: (e) => {
|
|
618
580
|
e.preventDefault();
|
|
619
581
|
handleRubyCancel();
|
|
620
582
|
},
|
|
621
|
-
"aria-label": "Cancel",
|
|
622
583
|
children: /* @__PURE__ */ jsx(X, { size: 14, strokeWidth: ICON_STROKE })
|
|
623
584
|
}
|
|
624
585
|
),
|
|
@@ -626,14 +587,14 @@ function FloatingToolbarPlugin() {
|
|
|
626
587
|
/* @__PURE__ */ jsx(
|
|
627
588
|
"button",
|
|
628
589
|
{
|
|
629
|
-
|
|
590
|
+
"aria-label": "Delete ruby",
|
|
630
591
|
className: rubyActionBtn,
|
|
592
|
+
style: { color: "#ef4444" },
|
|
593
|
+
type: "button",
|
|
631
594
|
onMouseDown: (e) => {
|
|
632
595
|
e.preventDefault();
|
|
633
596
|
handleRubyDelete();
|
|
634
597
|
},
|
|
635
|
-
style: { color: "#ef4444" },
|
|
636
|
-
"aria-label": "Delete ruby",
|
|
637
598
|
children: /* @__PURE__ */ jsx(Trash2, { size: 14, strokeWidth: ICON_STROKE })
|
|
638
599
|
}
|
|
639
600
|
)
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-plugin-floating-toolbar",
|
|
3
|
-
"
|
|
4
|
-
"version": "0.0.65",
|
|
3
|
+
"version": "0.0.67",
|
|
5
4
|
"description": "Floating toolbar plugin",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Innei/haklex.git",
|
|
8
|
+
"directory": "packages/rich-plugin-floating-toolbar"
|
|
9
|
+
},
|
|
6
10
|
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
7
12
|
"exports": {
|
|
8
13
|
".": {
|
|
9
14
|
"import": "./dist/index.mjs",
|
|
@@ -15,19 +20,10 @@
|
|
|
15
20
|
"files": [
|
|
16
21
|
"dist"
|
|
17
22
|
],
|
|
18
|
-
"peerDependencies": {
|
|
19
|
-
"@lexical/link": "^0.41.0",
|
|
20
|
-
"@lexical/react": "^0.41.0",
|
|
21
|
-
"@lexical/selection": "^0.41.0",
|
|
22
|
-
"lexical": "^0.41.0",
|
|
23
|
-
"lucide-react": "^0.574.0",
|
|
24
|
-
"react": ">=19",
|
|
25
|
-
"react-dom": ">=19"
|
|
26
|
-
},
|
|
27
23
|
"dependencies": {
|
|
28
|
-
"@haklex/rich-editor
|
|
29
|
-
"@haklex/rich-editor": "0.0.
|
|
30
|
-
"@haklex/rich-style-token": "0.0.
|
|
24
|
+
"@haklex/rich-editor": "0.0.67",
|
|
25
|
+
"@haklex/rich-editor-ui": "0.0.67",
|
|
26
|
+
"@haklex/rich-style-token": "0.0.67"
|
|
31
27
|
},
|
|
32
28
|
"devDependencies": {
|
|
33
29
|
"@lexical/link": "^0.41.0",
|
|
@@ -45,6 +41,15 @@
|
|
|
45
41
|
"vite": "^7.3.1",
|
|
46
42
|
"vite-plugin-dts": "^4.5.4"
|
|
47
43
|
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@lexical/link": "^0.41.0",
|
|
46
|
+
"@lexical/react": "^0.41.0",
|
|
47
|
+
"@lexical/selection": "^0.41.0",
|
|
48
|
+
"lexical": "^0.41.0",
|
|
49
|
+
"lucide-react": "^0.574.0",
|
|
50
|
+
"react": ">=19",
|
|
51
|
+
"react-dom": ">=19"
|
|
52
|
+
},
|
|
48
53
|
"publishConfig": {
|
|
49
54
|
"access": "public"
|
|
50
55
|
},
|