luxe-edit 0.1.4 → 0.1.6
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 +125 -21
- package/dist/index.css +127 -4
- package/dist/index.d.mts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# luxe-edit
|
|
2
2
|
|
|
3
|
-
A beautiful, customizable rich text editor for React built on Lexical with customizable toolbars and floating toolbar support.
|
|
3
|
+
A beautiful, customizable rich text editor for React built on [Lexical](https://lexical.dev/) with customizable toolbars and floating toolbar support.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
🌐 **[View Live Demo →](https://luxe-tools.github.io/luxe-edit/)**
|
|
5
|
+
**[Live Demo →](https://luxe-tools.github.io/luxe-edit/)**
|
|
8
6
|
|
|
9
7
|
## Installation
|
|
10
8
|
|
|
@@ -23,31 +21,137 @@ import { LuxeEditor } from 'luxe-edit';
|
|
|
23
21
|
import 'luxe-edit/index.css';
|
|
24
22
|
|
|
25
23
|
function App() {
|
|
24
|
+
return <LuxeEditor initialConfig={{ namespace: 'MyEditor' }} />;
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Props
|
|
29
|
+
|
|
30
|
+
| Prop | Type | Default | Description |
|
|
31
|
+
|------|------|---------|-------------|
|
|
32
|
+
| `initialConfig` | `Partial<InitialConfigType>` | required | Lexical editor config (namespace, theme, etc.) |
|
|
33
|
+
| `initialJSON` | `any` | — | Pre-load editor with saved JSON state |
|
|
34
|
+
| `showToolbar` | `boolean` | `true` | Show/hide the top toolbar |
|
|
35
|
+
| `showFloatingToolbar` | `boolean` | `true` | Show/hide the floating selection toolbar |
|
|
36
|
+
| `toolbarItems` | `ToolbarItem[]` | see below | Customize top toolbar buttons |
|
|
37
|
+
| `floatingToolbarItems` | `ToolbarItem[]` | same as `toolbarItems` | Customize floating toolbar buttons |
|
|
38
|
+
| `onChange` | `(editorState, editor) => void` | — | Called whenever the editor content changes |
|
|
39
|
+
| `ignoreInitialChange` | `boolean` | `true` | Skip `onChange` on initial mount |
|
|
40
|
+
| `children` | `ReactNode` | — | Render extra Lexical plugins inside the composer |
|
|
41
|
+
|
|
42
|
+
## Toolbar Items
|
|
43
|
+
|
|
44
|
+
The `toolbarItems` and `floatingToolbarItems` props accept an array of `ToolbarItem` objects.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
type ToolbarItemType =
|
|
48
|
+
| 'undo' | 'redo' | 'divider'
|
|
49
|
+
| 'bold' | 'italic' | 'underline' | 'strikethrough'
|
|
50
|
+
| 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6'
|
|
51
|
+
| 'paragraph' | 'headingDropdown'
|
|
52
|
+
| 'alignLeft' | 'alignCenter' | 'alignRight' | 'alignJustify'
|
|
53
|
+
| 'textColor' | 'backgroundColor'
|
|
54
|
+
| 'link' | 'fullscreen';
|
|
55
|
+
|
|
56
|
+
interface ToolbarItem {
|
|
57
|
+
type: ToolbarItemType;
|
|
58
|
+
label?: string; // Custom label
|
|
59
|
+
icon?: React.ReactNode; // Custom icon
|
|
60
|
+
color?: string; // Default color for textColor/backgroundColor (e.g. '#ff0000')
|
|
61
|
+
colors?: string[]; // Custom color palette for color picker
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Default toolbar:**
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const defaultToolbarItems = [
|
|
69
|
+
{ type: 'undo' },
|
|
70
|
+
{ type: 'redo' },
|
|
71
|
+
{ type: 'divider' },
|
|
72
|
+
{ type: 'bold' },
|
|
73
|
+
{ type: 'italic' },
|
|
74
|
+
{ type: 'underline' },
|
|
75
|
+
{ type: 'strikethrough' },
|
|
76
|
+
{ type: 'divider' },
|
|
77
|
+
{ type: 'headingDropdown' },
|
|
78
|
+
{ type: 'divider' },
|
|
79
|
+
{ type: 'link' },
|
|
80
|
+
];
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Examples
|
|
84
|
+
|
|
85
|
+
### Save and restore content
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { useState } from 'react';
|
|
89
|
+
import { LuxeEditor, getEditorJSON } from 'luxe-edit';
|
|
90
|
+
import 'luxe-edit/index.css';
|
|
91
|
+
|
|
92
|
+
function App() {
|
|
93
|
+
const [savedJSON, setSavedJSON] = useState(null);
|
|
94
|
+
|
|
26
95
|
return (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
namespace: 'MyEditor'
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
96
|
+
<>
|
|
97
|
+
<LuxeEditor
|
|
98
|
+
initialConfig={{ namespace: 'MyEditor' }}
|
|
99
|
+
initialJSON={savedJSON}
|
|
100
|
+
onChange={(editorState) => {
|
|
101
|
+
setSavedJSON(getEditorJSON(editorState));
|
|
102
|
+
}}
|
|
103
|
+
/>
|
|
104
|
+
<button onClick={() => console.log(savedJSON)}>Log JSON</button>
|
|
105
|
+
</>
|
|
33
106
|
);
|
|
34
107
|
}
|
|
35
108
|
```
|
|
36
109
|
|
|
37
|
-
|
|
110
|
+
### Custom toolbar
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
<LuxeEditor
|
|
114
|
+
initialConfig={{ namespace: 'MyEditor' }}
|
|
115
|
+
toolbarItems={[
|
|
116
|
+
{ type: 'bold' },
|
|
117
|
+
{ type: 'italic' },
|
|
118
|
+
{ type: 'divider' },
|
|
119
|
+
{ type: 'textColor', colors: ['#000000', '#ef4444', '#3b82f6'] },
|
|
120
|
+
{ type: 'headingDropdown' },
|
|
121
|
+
{ type: 'fullscreen' },
|
|
122
|
+
]}
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Disable floating toolbar
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
<LuxeEditor
|
|
130
|
+
initialConfig={{ namespace: 'MyEditor' }}
|
|
131
|
+
showFloatingToolbar={false}
|
|
132
|
+
/>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Get plain text or markdown
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
import { getEditorText, getEditorFormattedText } from 'luxe-edit';
|
|
38
139
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- ✅ Customizable toolbars
|
|
45
|
-
- ✅ Floating toolbar
|
|
46
|
-
- ✅ TypeScript support
|
|
140
|
+
onChange={(editorState) => {
|
|
141
|
+
const plain = getEditorText(editorState); // Plain text
|
|
142
|
+
const markdown = getEditorFormattedText(editorState); // Markdown-style text
|
|
143
|
+
}}
|
|
144
|
+
```
|
|
47
145
|
|
|
48
|
-
##
|
|
146
|
+
## Utility Functions
|
|
49
147
|
|
|
50
|
-
|
|
148
|
+
| Function | Signature | Description |
|
|
149
|
+
|----------|-----------|-------------|
|
|
150
|
+
| `getEditorJSON` | `(editorState) => any` | Serialized JSON — store in a database and reload with `initialJSON` |
|
|
151
|
+
| `getEditorText` | `(editorState) => string` | Plain text content |
|
|
152
|
+
| `getEditorFormattedText` | `(editorState) => string` | Markdown-formatted text |
|
|
153
|
+
| `getEditorDOM` | `(editor) => string` | Raw HTML from the editor DOM |
|
|
154
|
+
| `getEditorTree` | `(json) => any` | Debug tree structure from JSON |
|
|
51
155
|
|
|
52
156
|
## License
|
|
53
157
|
|
package/dist/index.css
CHANGED
|
@@ -1,19 +1,45 @@
|
|
|
1
|
-
|
|
1
|
+
/* Light theme (default) */
|
|
2
|
+
:root, [data-luxe-theme="light"] {
|
|
2
3
|
--luxe-primary: #3b82f6;
|
|
3
4
|
--luxe-border: #e5e7eb;
|
|
4
5
|
--luxe-bg: #ffffff;
|
|
6
|
+
--luxe-text: #111827;
|
|
7
|
+
--luxe-placeholder: #9ca3af;
|
|
8
|
+
--luxe-toolbar-bg: #f9fafb;
|
|
9
|
+
--luxe-toolbar-border: #e5e7eb;
|
|
10
|
+
--luxe-toolbar-btn-hover: #f3f4f6;
|
|
11
|
+
--luxe-toolbar-btn-active: #e5e7eb;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Dark theme */
|
|
15
|
+
[data-luxe-theme="dark"] {
|
|
16
|
+
--luxe-primary: #60a5fa;
|
|
17
|
+
--luxe-border: #374151;
|
|
18
|
+
--luxe-bg: #1f2937;
|
|
19
|
+
--luxe-text: #f9fafb;
|
|
20
|
+
--luxe-placeholder: #6b7280;
|
|
21
|
+
--luxe-toolbar-bg: #111827;
|
|
22
|
+
--luxe-toolbar-border: #374151;
|
|
23
|
+
--luxe-toolbar-btn-hover: #374151;
|
|
24
|
+
--luxe-toolbar-btn-active: #4b5563;
|
|
5
25
|
}
|
|
6
26
|
|
|
7
27
|
.luxe-editor-container {
|
|
8
28
|
border: 1px solid var(--luxe-border);
|
|
9
29
|
border-radius: 8px;
|
|
10
30
|
background: var(--luxe-bg);
|
|
31
|
+
color: var(--luxe-text);
|
|
11
32
|
padding: 1rem;
|
|
12
33
|
}
|
|
13
|
-
|
|
34
|
+
|
|
14
35
|
.luxe-input {
|
|
15
36
|
min-height: 200px;
|
|
16
37
|
outline: none;
|
|
38
|
+
color: var(--luxe-text);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.luxe-placeholder {
|
|
42
|
+
color: var(--luxe-placeholder);
|
|
17
43
|
}
|
|
18
44
|
|
|
19
45
|
.luxe-bold { font-weight: bold; }
|
|
@@ -103,14 +129,111 @@
|
|
|
103
129
|
padding: 0;
|
|
104
130
|
}
|
|
105
131
|
|
|
132
|
+
/* Floating toolbar — needs its own theme vars since it's portaled to body */
|
|
133
|
+
.luxe-floating-toolbar {
|
|
134
|
+
--luxe-bg: #ffffff;
|
|
135
|
+
--luxe-border: #e5e7eb;
|
|
136
|
+
--luxe-text: #111827;
|
|
137
|
+
--luxe-toolbar-bg: #ffffff;
|
|
138
|
+
--luxe-toolbar-border: #e5e7eb;
|
|
139
|
+
--luxe-toolbar-btn-hover: #f3f4f6;
|
|
140
|
+
--luxe-toolbar-btn-active: #e5e7eb;
|
|
141
|
+
background: var(--luxe-toolbar-bg);
|
|
142
|
+
border: 1px solid var(--luxe-toolbar-border);
|
|
143
|
+
color: var(--luxe-text);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.luxe-floating-toolbar[data-luxe-theme="dark"] {
|
|
147
|
+
--luxe-bg: #1f2937;
|
|
148
|
+
--luxe-border: #374151;
|
|
149
|
+
--luxe-text: #f9fafb;
|
|
150
|
+
--luxe-toolbar-bg: #111827;
|
|
151
|
+
--luxe-toolbar-border: #374151;
|
|
152
|
+
--luxe-toolbar-btn-hover: #374151;
|
|
153
|
+
--luxe-toolbar-btn-active: #4b5563;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* Toolbar */
|
|
157
|
+
.luxe-toolbar {
|
|
158
|
+
background: var(--luxe-toolbar-bg);
|
|
159
|
+
border-bottom: 1px solid var(--luxe-toolbar-border);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.luxe-toolbar-divider {
|
|
163
|
+
background: var(--luxe-toolbar-border);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* Toolbar buttons */
|
|
167
|
+
.luxe-toolbar-btn {
|
|
168
|
+
background: transparent;
|
|
169
|
+
color: var(--luxe-text);
|
|
170
|
+
border: none;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.luxe-toolbar-btn:hover:not(:disabled) {
|
|
175
|
+
background: var(--luxe-toolbar-btn-hover);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.luxe-toolbar-btn.luxe-active {
|
|
179
|
+
background: var(--luxe-toolbar-btn-active);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.luxe-toolbar-btn:disabled {
|
|
183
|
+
opacity: 0.5;
|
|
184
|
+
cursor: not-allowed;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Select-style buttons (heading dropdown, color picker trigger) */
|
|
188
|
+
.luxe-toolbar-select-btn {
|
|
189
|
+
background: var(--luxe-bg);
|
|
190
|
+
border: 1px solid var(--luxe-border);
|
|
191
|
+
color: var(--luxe-text);
|
|
192
|
+
cursor: pointer;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.luxe-toolbar-select-btn:hover {
|
|
196
|
+
background: var(--luxe-toolbar-btn-hover);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Dropdown / popup panels */
|
|
200
|
+
.luxe-toolbar-panel {
|
|
201
|
+
background: var(--luxe-bg);
|
|
202
|
+
border: 1px solid var(--luxe-border);
|
|
203
|
+
color: var(--luxe-text);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.luxe-toolbar-panel-item {
|
|
207
|
+
background: transparent;
|
|
208
|
+
color: var(--luxe-text);
|
|
209
|
+
border: none;
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
width: 100%;
|
|
212
|
+
text-align: left;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.luxe-toolbar-panel-item:hover {
|
|
216
|
+
background: var(--luxe-toolbar-btn-hover);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.luxe-toolbar-panel-item.luxe-active {
|
|
220
|
+
background: var(--luxe-toolbar-btn-active);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.luxe-toolbar-input {
|
|
224
|
+
background: var(--luxe-bg);
|
|
225
|
+
border: 1px solid var(--luxe-border);
|
|
226
|
+
color: var(--luxe-text);
|
|
227
|
+
}
|
|
228
|
+
|
|
106
229
|
/* Link styles */
|
|
107
230
|
.luxe-input a {
|
|
108
|
-
color:
|
|
231
|
+
color: var(--luxe-primary);
|
|
109
232
|
text-decoration: underline;
|
|
110
233
|
cursor: pointer;
|
|
111
234
|
}
|
|
112
235
|
|
|
113
236
|
.luxe-input a:hover {
|
|
114
|
-
|
|
237
|
+
opacity: 0.8;
|
|
115
238
|
text-decoration: underline;
|
|
116
239
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -16,8 +16,9 @@ interface ToolbarItem {
|
|
|
16
16
|
interface FloatingToolbarPluginProps {
|
|
17
17
|
enabled?: boolean;
|
|
18
18
|
items?: ToolbarItem[];
|
|
19
|
+
colorScheme?: 'light' | 'dark';
|
|
19
20
|
}
|
|
20
|
-
declare function FloatingToolbarPlugin({ enabled, items }: FloatingToolbarPluginProps): React.ReactPortal | null;
|
|
21
|
+
declare function FloatingToolbarPlugin({ enabled, items, colorScheme, }: FloatingToolbarPluginProps): React.ReactPortal | null;
|
|
21
22
|
|
|
22
23
|
interface ToolbarProps {
|
|
23
24
|
items: ToolbarItem[];
|
|
@@ -46,17 +47,34 @@ declare function getEditorDOM(editor: any): string;
|
|
|
46
47
|
* Convert JSON to tree structure for display
|
|
47
48
|
*/
|
|
48
49
|
declare function getEditorTree(json: any): any;
|
|
50
|
+
/**
|
|
51
|
+
* Extract plain text from a stored Lexical JSON object.
|
|
52
|
+
* No editor instance or DOM required — works anywhere (server, utility, etc.)
|
|
53
|
+
*/
|
|
54
|
+
declare function getTextFromJSON(json: any): string;
|
|
55
|
+
/**
|
|
56
|
+
* Convert a stored Lexical JSON object to an HTML string.
|
|
57
|
+
* Useful for rendering editor content in read-only views without mounting the editor.
|
|
58
|
+
* Note: runs in a browser-like environment; on the server use a DOM shim (e.g. jsdom).
|
|
59
|
+
*/
|
|
60
|
+
declare function getHTMLFromJSON(json: any): string;
|
|
49
61
|
|
|
50
62
|
interface LuxeEditorProps {
|
|
51
63
|
initialConfig: Partial<InitialConfigType>;
|
|
64
|
+
/**
|
|
65
|
+
* Optional initial editor content as a serialized Lexical editor state (JSON).
|
|
66
|
+
* This is ideal for loading content from a database for editing.
|
|
67
|
+
*/
|
|
68
|
+
initialJSON?: any;
|
|
52
69
|
showFloatingToolbar?: boolean;
|
|
53
70
|
showToolbar?: boolean;
|
|
54
71
|
toolbarItems?: ToolbarItem[];
|
|
55
72
|
floatingToolbarItems?: ToolbarItem[];
|
|
56
73
|
onChange?: (editorState: EditorState, editor: LexicalEditor) => void;
|
|
57
74
|
ignoreInitialChange?: boolean;
|
|
75
|
+
colorScheme?: 'light' | 'dark';
|
|
58
76
|
children?: React__default.ReactNode;
|
|
59
77
|
}
|
|
60
|
-
declare function LuxeEditor({ initialConfig, showFloatingToolbar, showToolbar, toolbarItems, floatingToolbarItems, onChange, ignoreInitialChange, children }: LuxeEditorProps): react_jsx_runtime.JSX.Element;
|
|
78
|
+
declare function LuxeEditor({ initialConfig, initialJSON, showFloatingToolbar, showToolbar, toolbarItems, floatingToolbarItems, onChange, ignoreInitialChange, colorScheme, children }: LuxeEditorProps): react_jsx_runtime.JSX.Element;
|
|
61
79
|
|
|
62
|
-
export { FloatingToolbarPlugin, LuxeEditor, type LuxeEditorProps, Toolbar, type ToolbarItem, type ToolbarItemType, getEditorDOM, getEditorFormattedText, getEditorJSON, getEditorText, getEditorTree };
|
|
80
|
+
export { FloatingToolbarPlugin, LuxeEditor, type LuxeEditorProps, Toolbar, type ToolbarItem, type ToolbarItemType, getEditorDOM, getEditorFormattedText, getEditorJSON, getEditorText, getEditorTree, getHTMLFromJSON, getTextFromJSON };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,8 +16,9 @@ interface ToolbarItem {
|
|
|
16
16
|
interface FloatingToolbarPluginProps {
|
|
17
17
|
enabled?: boolean;
|
|
18
18
|
items?: ToolbarItem[];
|
|
19
|
+
colorScheme?: 'light' | 'dark';
|
|
19
20
|
}
|
|
20
|
-
declare function FloatingToolbarPlugin({ enabled, items }: FloatingToolbarPluginProps): React.ReactPortal | null;
|
|
21
|
+
declare function FloatingToolbarPlugin({ enabled, items, colorScheme, }: FloatingToolbarPluginProps): React.ReactPortal | null;
|
|
21
22
|
|
|
22
23
|
interface ToolbarProps {
|
|
23
24
|
items: ToolbarItem[];
|
|
@@ -46,17 +47,34 @@ declare function getEditorDOM(editor: any): string;
|
|
|
46
47
|
* Convert JSON to tree structure for display
|
|
47
48
|
*/
|
|
48
49
|
declare function getEditorTree(json: any): any;
|
|
50
|
+
/**
|
|
51
|
+
* Extract plain text from a stored Lexical JSON object.
|
|
52
|
+
* No editor instance or DOM required — works anywhere (server, utility, etc.)
|
|
53
|
+
*/
|
|
54
|
+
declare function getTextFromJSON(json: any): string;
|
|
55
|
+
/**
|
|
56
|
+
* Convert a stored Lexical JSON object to an HTML string.
|
|
57
|
+
* Useful for rendering editor content in read-only views without mounting the editor.
|
|
58
|
+
* Note: runs in a browser-like environment; on the server use a DOM shim (e.g. jsdom).
|
|
59
|
+
*/
|
|
60
|
+
declare function getHTMLFromJSON(json: any): string;
|
|
49
61
|
|
|
50
62
|
interface LuxeEditorProps {
|
|
51
63
|
initialConfig: Partial<InitialConfigType>;
|
|
64
|
+
/**
|
|
65
|
+
* Optional initial editor content as a serialized Lexical editor state (JSON).
|
|
66
|
+
* This is ideal for loading content from a database for editing.
|
|
67
|
+
*/
|
|
68
|
+
initialJSON?: any;
|
|
52
69
|
showFloatingToolbar?: boolean;
|
|
53
70
|
showToolbar?: boolean;
|
|
54
71
|
toolbarItems?: ToolbarItem[];
|
|
55
72
|
floatingToolbarItems?: ToolbarItem[];
|
|
56
73
|
onChange?: (editorState: EditorState, editor: LexicalEditor) => void;
|
|
57
74
|
ignoreInitialChange?: boolean;
|
|
75
|
+
colorScheme?: 'light' | 'dark';
|
|
58
76
|
children?: React__default.ReactNode;
|
|
59
77
|
}
|
|
60
|
-
declare function LuxeEditor({ initialConfig, showFloatingToolbar, showToolbar, toolbarItems, floatingToolbarItems, onChange, ignoreInitialChange, children }: LuxeEditorProps): react_jsx_runtime.JSX.Element;
|
|
78
|
+
declare function LuxeEditor({ initialConfig, initialJSON, showFloatingToolbar, showToolbar, toolbarItems, floatingToolbarItems, onChange, ignoreInitialChange, colorScheme, children }: LuxeEditorProps): react_jsx_runtime.JSX.Element;
|
|
61
79
|
|
|
62
|
-
export { FloatingToolbarPlugin, LuxeEditor, type LuxeEditorProps, Toolbar, type ToolbarItem, type ToolbarItemType, getEditorDOM, getEditorFormattedText, getEditorJSON, getEditorText, getEditorTree };
|
|
80
|
+
export { FloatingToolbarPlugin, LuxeEditor, type LuxeEditorProps, Toolbar, type ToolbarItem, type ToolbarItemType, getEditorDOM, getEditorFormattedText, getEditorJSON, getEditorText, getEditorTree, getHTMLFromJSON, getTextFromJSON };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
"use strict";var ve=Object.create;var j=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Ne=Object.getPrototypeOf,Le=Object.prototype.hasOwnProperty;var Ie=(e,r)=>{for(var o in r)j(e,o,{get:r[o],enumerable:!0})},te=(e,r,o,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let l of Ee(r))!Le.call(e,l)&&l!==o&&j(e,l,{get:()=>r[l],enumerable:!(t=ke(r,l))||t.enumerable});return e};var we=(e,r,o)=>(o=e!=null?ve(Ne(e)):{},te(r||!e||!e.__esModule?j(o,"default",{value:e,enumerable:!0}):o,e)),Re=e=>te(j({},"__esModule",{value:!0}),e);var Pe={};Ie(Pe,{FloatingToolbarPlugin:()=>X,LuxeEditor:()=>Ke,Toolbar:()=>J,getEditorDOM:()=>ce,getEditorFormattedText:()=>de,getEditorJSON:()=>le,getEditorText:()=>se,getEditorTree:()=>pe});module.exports=Re(Pe);var _=we(require("react")),ge=require("@lexical/react/LexicalComposer"),fe=require("@lexical/react/LexicalRichTextPlugin"),he=require("@lexical/react/LexicalContentEditable"),be=require("@lexical/react/LexicalHistoryPlugin"),me=require("@lexical/react/LexicalErrorBoundary"),xe=require("@lexical/react/LexicalLinkPlugin"),ye=require("@lexical/rich-text"),q=require("@lexical/link"),Y=require("lexical"),Te=require("@lexical/react/LexicalComposerContext");var re=require("@lexical/react/LexicalComposerContext"),v=require("lexical"),V=require("@lexical/selection"),G=require("@lexical/rich-text"),D=require("react"),ie=require("react-dom");var oe=require("@lexical/react/LexicalComposerContext"),ne=require("@lexical/utils"),a=require("lexical"),Z=require("@lexical/selection"),W=require("@lexical/rich-text"),F=require("@lexical/link"),b=require("react"),p=require("react/jsx-runtime"),Q=["#000000","#ffffff","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#808080","#800000","#008000","#000080","#808000","#800080","#008080"];function B(e){return{undo:"\u21B6",redo:"\u21B7",divider:"",bold:"B",italic:"I",underline:"U",strikethrough:"S",heading1:"H1",heading2:"H2",heading3:"H3",heading4:"H4",heading5:"H5",heading6:"H6",paragraph:"P",alignLeft:"\u2B05",alignCenter:"\u2B0C",alignRight:"\u27A1",alignJustify:"\u2B0C",textColor:"A",backgroundColor:"\u2B1B",fullscreen:"\u26F6",headingDropdown:"Normal",link:"\u{1F517}"}[e]||e}function Se(){return(0,p.jsx)("div",{style:{width:"1px",height:"24px",background:"#e5e7eb",margin:"0 4px"}})}function Me({item:e,onAction:r}){let[o,t]=(0,b.useState)(!1),l=(0,b.useRef)(null),s=e.colors||Q;return(0,b.useEffect)(()=>{let i=u=>{l.current&&!l.current.contains(u.target)&&t(!1)};if(o)return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[o]),e.color?(0,p.jsx)("button",{onClick:()=>r(e,e.color),title:`${e.type==="textColor"?"Text":"Background"} Color: ${e.color}`,style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:e.type==="backgroundColor"?e.color:"white",color:e.type==="textColor"?e.color:"#000",cursor:"pointer",borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center"},children:e.icon||B(e.type)}):(0,p.jsxs)("div",{style:{position:"relative"},ref:l,children:[(0,p.jsxs)("button",{onClick:()=>t(!o),title:`${e.type==="textColor"?"Text":"Background"} Color`,style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:[e.icon||(0,p.jsx)("span",{style:{display:"block",width:"20px",height:"20px",background:e.type==="backgroundColor"?"linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%)":"currentColor",backgroundSize:e.type==="backgroundColor"?"8px 8px":"auto",backgroundPosition:e.type==="backgroundColor"?"0 0, 0 4px, 4px -4px, -4px 0px":"auto"},children:e.type==="textColor"&&(0,p.jsx)("span",{style:{color:"#000",fontSize:"12px"},children:"A"})}),(0,p.jsx)("span",{style:{marginLeft:"4px",fontSize:"10px"},children:"\u25BC"})]}),o&&(0,p.jsxs)("div",{style:{position:"absolute",top:"100%",left:0,marginTop:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"8px",display:"grid",gridTemplateColumns:"repeat(5, 1fr)",gap:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"160px"},children:[s.map(i=>(0,p.jsxs)("button",{onClick:()=>{r(e,i),t(!1)},title:i,style:{width:"24px",height:"24px",borderRadius:"4px",border:e.type==="textColor"?`3px solid ${i}`:"1px solid #e5e7eb",background:e.type==="backgroundColor"?i:"white",color:e.type==="textColor"?"#000":"inherit",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"12px",fontWeight:"bold",position:"relative"},children:[e.type==="textColor"&&(0,p.jsx)("span",{style:{color:i,fontSize:"14px",fontWeight:"bold",lineHeight:"1"},children:"A"}),e.type==="backgroundColor"&&i==="#ffffff"&&(0,p.jsx)("span",{style:{color:"#000",fontSize:"10px",border:"1px solid #ccc",width:"12px",height:"12px",display:"block"},children:"\u25A1"})]},i)),(0,p.jsx)("input",{type:"color",onChange:i=>{r(e,i.target.value),t(!1)},style:{gridColumn:"1 / -1",width:"100%",height:"32px",border:"1px solid #e5e7eb",borderRadius:"4px",cursor:"pointer"}})]})]})}function $e({item:e,onAction:r,currentBlockType:o="paragraph"}){let[t,l]=(0,b.useState)(!1),s=(0,b.useRef)(null);(0,b.useEffect)(()=>{let g=n=>{s.current&&!s.current.contains(n.target)&&l(!1)};if(t)return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[t]);let i=()=>o==="paragraph"?"Normal":o.startsWith("h")?`Heading ${o.replace("h","")}`:"Normal",u=g=>{r(e,void 0,g),l(!1)},h=[{value:"paragraph",label:"Normal"},{value:"h1",label:"Heading 1"},{value:"h2",label:"Heading 2"},{value:"h3",label:"Heading 3"},{value:"h4",label:"Heading 4"},{value:"h5",label:"Heading 5"},{value:"h6",label:"Heading 6"}];return(0,p.jsxs)("div",{style:{position:"relative"},ref:s,children:[(0,p.jsxs)("button",{onClick:()=>l(!t),title:"Heading",style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",minWidth:"100px",height:"32px",display:"flex",alignItems:"center",justifyContent:"space-between",position:"relative",fontSize:o==="paragraph"?"14px":o==="h1"?"20px":o==="h2"?"18px":o==="h3"?"16px":"14px",fontWeight:o!=="paragraph"?"bold":"normal"},children:[(0,p.jsx)("span",{children:e.label||i()}),(0,p.jsx)("span",{style:{marginLeft:"8px",fontSize:"10px"},children:"\u25BC"})]}),t&&(0,p.jsx)("div",{style:{position:"absolute",top:"100%",left:0,marginTop:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"150px"},children:h.map(g=>(0,p.jsx)("button",{onClick:()=>u(g.value),style:{width:"100%",padding:"8px 12px",border:"none",background:o===g.value?"#e5e7eb":"transparent",cursor:"pointer",borderRadius:"4px",textAlign:"left",fontSize:g.value==="paragraph"?"14px":g.value==="h1"?"20px":g.value==="h2"?"18px":g.value==="h3"?"16px":"14px",fontWeight:g.value!=="paragraph"?"bold":"normal",display:"flex",alignItems:"center"},onMouseEnter:n=>{o!==g.value&&(n.currentTarget.style.background="#f3f4f6")},onMouseLeave:n=>{o!==g.value?n.currentTarget.style.background="transparent":n.currentTarget.style.background="#e5e7eb"},children:g.label},g.value))})]})}function He({item:e,onAction:r,editor:o}){let[t,l]=(0,b.useState)(!1),[s,i]=(0,b.useState)(""),[u,h]=(0,b.useState)(!1),g=(0,b.useRef)(null),n=(0,b.useRef)(null);(0,b.useEffect)(()=>{let d=()=>{o.getEditorState().read(()=>{let H=(0,a.$getSelection)();if((0,a.$isRangeSelection)(H)){let E=H.getNodes(),w=null;for(let N of E){let c=N.getParent();for(;c!==null;){if((0,F.$isLinkNode)(c)){w=c;break}c=c.getParent()}if(w)break}w&&(0,F.$isLinkNode)(w)?(h(!0),i(w.getURL())):(h(!1),i(""))}else h(!1),i("")})},y=o.registerUpdateListener(()=>{d()}),x=o.registerCommand(a.SELECTION_CHANGE_COMMAND,()=>(d(),!1),a.COMMAND_PRIORITY_LOW);return d(),()=>{y(),x()}},[o]),(0,b.useEffect)(()=>{let d=y=>{g.current&&!g.current.contains(y.target)&&l(!1)};if(t)return document.addEventListener("mousedown",d),setTimeout(()=>n.current?.focus(),0),()=>document.removeEventListener("mousedown",d)},[t,u,s]);let m=()=>{if(!s.trim()){o.dispatchCommand(F.TOGGLE_LINK_COMMAND,null),l(!1),i("");return}let d=s.trim();!d.startsWith("http://")&&!d.startsWith("https://")&&!d.startsWith("mailto:")&&!d.startsWith("#")&&!d.startsWith("/")&&(d="https://"+d),o.dispatchCommand(F.TOGGLE_LINK_COMMAND,d),l(!1),i("")},f=()=>{o.dispatchCommand(F.TOGGLE_LINK_COMMAND,null),l(!1),i("")},T=d=>{d.key==="Enter"?(d.preventDefault(),m()):d.key==="Escape"&&(l(!1),i(""))};return(0,p.jsxs)("div",{style:{position:"relative"},ref:g,children:[(0,p.jsx)("button",{onClick:()=>{l(!t)},title:u?"Edit Link":"Insert Link",style:{padding:"6px 12px",border:"none",background:u?"#e5e7eb":"transparent",cursor:"pointer",borderRadius:"4px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},onMouseEnter:d=>{u||(d.currentTarget.style.background="#f3f4f6")},onMouseLeave:d=>{u?d.currentTarget.style.background="#e5e7eb":d.currentTarget.style.background="transparent"},children:e.icon||B(e.type)}),t&&(0,p.jsxs)("div",{style:{position:"absolute",top:"100%",left:0,marginTop:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"12px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"300px"},children:[(0,p.jsx)("input",{ref:n,type:"text",placeholder:"Enter URL (e.g., https://example.com)",value:s,onChange:d=>i(d.target.value),onKeyDown:T,style:{width:"100%",padding:"8px",border:"1px solid #e5e7eb",borderRadius:"4px",fontSize:"14px",marginBottom:"8px"}}),(0,p.jsxs)("div",{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[u&&(0,p.jsx)("button",{onClick:f,style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px",color:"#dc2626"},children:"Remove"}),(0,p.jsx)("button",{onClick:()=>l(!1),style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px"},children:"Cancel"}),(0,p.jsx)("button",{onClick:m,style:{padding:"6px 12px",border:"none",background:"#3b82f6",color:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px"},children:u?"Update":"Insert"})]})]})]})}function Oe({item:e,active:r=!1,disabled:o=!1,onAction:t,currentBlockType:l}){let i=e.type.startsWith("heading")&&e.type!=="headingDropdown"?parseInt(e.type.replace("heading","")):null,u=e.label||B(e.type);return e.type==="divider"?(0,p.jsx)(Se,{}):e.type==="headingDropdown"?(0,p.jsx)($e,{item:e,onAction:t,currentBlockType:l}):e.type==="textColor"||e.type==="backgroundColor"?(0,p.jsx)(Me,{item:e,onAction:t}):(0,p.jsx)("button",{onClick:()=>t(e),disabled:o,title:e.type.charAt(0).toUpperCase()+e.type.slice(1).replace(/([A-Z])/g," $1").trim(),style:{padding:"6px 12px",border:"none",background:r?"#e5e7eb":"transparent",cursor:o?"not-allowed":"pointer",borderRadius:"4px",fontWeight:e.type==="bold"?"bold":"normal",fontStyle:e.type==="italic"?"italic":"normal",textDecoration:e.type==="underline"?"underline":e.type==="strikethrough"?"line-through":"none",fontSize:i?`${18-i*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s",opacity:o?.5:1},onMouseEnter:h=>{!o&&!r&&(h.currentTarget.style.background="#f3f4f6")},onMouseLeave:h=>{r?h.currentTarget.style.background="#e5e7eb":h.currentTarget.style.background="transparent"},children:e.icon||u})}function J({items:e,onFullscreenToggle:r,isFullscreen:o=!1}){let[t]=(0,oe.useLexicalComposerContext)(),[l,s]=(0,b.useState)(!1),[i,u]=(0,b.useState)(!1),[h,g]=(0,b.useState)(!1),[n,m]=(0,b.useState)(!1),[f,T]=(0,b.useState)(!1),[d,y]=(0,b.useState)(!1),[x,H]=(0,b.useState)("paragraph"),E=(0,b.useCallback)(()=>{let c=(0,a.$getSelection)();if((0,a.$isRangeSelection)(c)){g(c.hasFormat("bold")),m(c.hasFormat("italic")),T(c.hasFormat("underline")),y(c.hasFormat("strikethrough"));let R=c.anchor.getNode(),S=R.getKey()==="root"?R:R.getTopLevelElementOrThrow(),C=S.getKey();if(t.getElementByKey(C)!==null){let I=(0,W.$isHeadingNode)(S)?S.getTag():S.getType();H(I)}}},[t]);(0,b.useEffect)(()=>(0,ne.mergeRegister)(t.registerUpdateListener(({editorState:c})=>{c.read(()=>{E()})}),t.registerCommand(a.SELECTION_CHANGE_COMMAND,()=>(E(),!1),a.COMMAND_PRIORITY_LOW),t.registerCommand(a.CAN_UNDO_COMMAND,c=>(s(c),!1),a.COMMAND_PRIORITY_LOW),t.registerCommand(a.CAN_REDO_COMMAND,c=>(u(c),!1),a.COMMAND_PRIORITY_LOW)),[t,E]);let w=(0,b.useCallback)((c,R,S)=>{let{type:C}=c;if(C==="fullscreen"){r?.();return}if(C==="undo"){t.dispatchCommand(a.UNDO_COMMAND,void 0);return}if(C==="redo"){t.dispatchCommand(a.REDO_COMMAND,void 0);return}if(C==="textColor"&&R){t.update(()=>{let L=(0,a.$getSelection)();(0,a.$isRangeSelection)(L)&&(0,Z.$patchStyleText)(L,{color:R})});return}if(C==="backgroundColor"&&R){t.update(()=>{let L=(0,a.$getSelection)();(0,a.$isRangeSelection)(L)&&(0,Z.$patchStyleText)(L,{"background-color":R})});return}if(C==="bold"||C==="italic"||C==="underline"||C==="strikethrough"){t.dispatchCommand(a.FORMAT_TEXT_COMMAND,C);return}if(C==="alignLeft"){t.dispatchCommand(a.FORMAT_ELEMENT_COMMAND,"left");return}if(C==="alignCenter"){t.dispatchCommand(a.FORMAT_ELEMENT_COMMAND,"center");return}if(C==="alignRight"){t.dispatchCommand(a.FORMAT_ELEMENT_COMMAND,"right");return}if(C==="alignJustify"){t.dispatchCommand(a.FORMAT_ELEMENT_COMMAND,"justify");return}if(C==="headingDropdown"&&S){if(S==="paragraph")t.update(()=>{let L=(0,a.$getSelection)();if((0,a.$isRangeSelection)(L)){let I=L.anchor.getNode(),k=I.getKey()==="root"?I:I.getTopLevelElementOrThrow(),M=k.getKey();if(t.getElementByKey(M)!==null&&(0,W.$isHeadingNode)(k)&&(0,a.$isElementNode)(k)){let A=(0,a.$createParagraphNode)(),P=k.getChildren();A.append(...P),k.replace(A),A.selectEnd()}}});else{let L=S;t.update(()=>{let I=(0,a.$getSelection)();if((0,a.$isRangeSelection)(I)){let k=I.anchor.getNode(),M=k.getKey()==="root"?k:k.getTopLevelElementOrThrow(),K=M.getKey();if(t.getElementByKey(K)!==null&&(0,a.$isElementNode)(M)){let P=(0,W.$createHeadingNode)(L),z=M.getChildren();P.append(...z),M.replace(P),P.selectEnd()}}})}return}if(C.startsWith("heading")&&C!=="headingDropdown"){let I=`h${parseInt(C.replace("heading",""))}`;t.update(()=>{let k=(0,a.$getSelection)();if((0,a.$isRangeSelection)(k)){let M=k.anchor.getNode(),K=M.getKey()==="root"?M:M.getTopLevelElementOrThrow(),A=K.getKey();if(t.getElementByKey(A)!==null&&(0,a.$isElementNode)(K)){let z=(0,W.$createHeadingNode)(I),Ce=K.getChildren();z.append(...Ce),K.replace(z),z.selectEnd()}}});return}if(C==="paragraph"){t.update(()=>{let L=(0,a.$getSelection)();if((0,a.$isRangeSelection)(L)){let I=L.anchor.getNode(),k=I.getKey()==="root"?I:I.getTopLevelElementOrThrow(),M=k.getKey();if(t.getElementByKey(M)!==null&&(0,W.$isHeadingNode)(k)&&(0,a.$isElementNode)(k)){let A=(0,a.$createParagraphNode)(),P=k.getChildren();A.append(...P),k.replace(A),A.selectEnd()}}});return}},[t,r]),N=c=>{switch(c){case"undo":return{disabled:!l};case"redo":return{disabled:!i};case"bold":return{active:h};case"italic":return{active:n};case"underline":return{active:f};case"strikethrough":return{active:d};case"fullscreen":return{active:o};case"heading1":return{active:x==="h1"};case"heading2":return{active:x==="h2"};case"heading3":return{active:x==="h3"};case"heading4":return{active:x==="h4"};case"heading5":return{active:x==="h5"};case"heading6":return{active:x==="h6"};case"paragraph":return{active:x==="paragraph"};default:return{}}};return(0,p.jsx)("div",{className:"luxe-toolbar",style:{display:"flex",gap:"4px",alignItems:"center",background:"white",borderBottom:"1px solid #e5e7eb",borderRadius:"8px 8px 0 0",padding:"8px",flexWrap:"wrap"},children:e.map((c,R)=>{let S=N(c.type);return c.type==="link"?(0,p.jsx)(He,{item:c,onAction:w,editor:t},`${c.type}-${R}`):(0,p.jsx)(Oe,{item:c,active:S.active,disabled:S.disabled,onAction:w,currentBlockType:x},`${c.type}-${R}`)})})}var U=require("react/jsx-runtime"),Ae=[{type:"bold"},{type:"italic"},{type:"underline"}];function De(e){let r=["bold","italic","underline","strikethrough","textColor","backgroundColor"];return e.filter(o=>r.includes(o.type))}function X({enabled:e=!0,items:r}){let o=r?De(r).slice(0,4):Ae,[t]=(0,re.useLexicalComposerContext)(),[l,s]=(0,D.useState)(null),[i,u]=(0,D.useState)(null);(0,D.useEffect)(()=>{let n=t.getRootElement();n&&u(n)},[t]);let h=(0,D.useCallback)(()=>{if(!i)return;let n=window.getSelection();if(!n||n.rangeCount===0||n.isCollapsed){s(null);return}try{let m=n.getRangeAt(0);if(!i.contains(m.commonAncestorContainer)){s(null);return}let f=m.getBoundingClientRect();f&&f.width>0&&f.height>0?t.getEditorState().read(()=>{let T=(0,v.$getSelection)();T&&(0,v.$isRangeSelection)(T)&&!T.isCollapsed()?s({x:f.left+f.width/2,y:f.top-40}):s(null)}):s(null)}catch{s(null)}},[t,i]);(0,D.useEffect)(()=>{if(!i)return;let n=t.registerUpdateListener(()=>{setTimeout(()=>h(),10)});return()=>{n()}},[t,i,h]),(0,D.useEffect)(()=>{let n=()=>{setTimeout(()=>h(),50)},m=()=>{setTimeout(()=>h(),50)},f=()=>{setTimeout(()=>h(),50)};return document.addEventListener("mouseup",n),document.addEventListener("keyup",m),document.addEventListener("selectionchange",f),()=>{document.removeEventListener("mouseup",n),document.removeEventListener("keyup",m),document.removeEventListener("selectionchange",f)}},[h]);let g=(0,D.useCallback)((n,m)=>{let{type:f}=n;if(f==="textColor"&&m){t.update(()=>{let T=(0,v.$getSelection)();(0,v.$isRangeSelection)(T)&&(0,V.$patchStyleText)(T,{color:m})});return}if(f==="backgroundColor"&&m){t.update(()=>{let T=(0,v.$getSelection)();(0,v.$isRangeSelection)(T)&&(0,V.$patchStyleText)(T,{"background-color":m})});return}if(f==="bold"||f==="italic"||f==="underline"||f==="strikethrough"){t.dispatchCommand(v.FORMAT_TEXT_COMMAND,f);return}if(f.startsWith("heading")){let d=`h${parseInt(f.replace("heading",""))}`;t.update(()=>{let y=(0,v.$getSelection)();if((0,v.$isRangeSelection)(y)){let x=y.anchor.getNode(),H=x.getKey()==="root"?x:x.getTopLevelElementOrThrow(),E=H.getKey();if(t.getElementByKey(E)!==null&&(0,v.$isElementNode)(H)){let N=(0,G.$createHeadingNode)(d),c=H.getChildren();N.append(...c),H.replace(N),N.selectEnd()}}});return}if(f==="paragraph"){t.update(()=>{let T=(0,v.$getSelection)();if((0,v.$isRangeSelection)(T)){let d=T.anchor.getNode(),y=d.getKey()==="root"?d:d.getTopLevelElementOrThrow(),x=y.getKey();if(t.getElementByKey(x)!==null&&(0,G.$isHeadingNode)(y)&&(0,v.$isElementNode)(y)){let E=(0,v.$createParagraphNode)(),w=y.getChildren();E.append(...w),y.replace(E),E.selectEnd()}}});return}},[t]);return!e||!o||o.length===0||!l?null:(0,ie.createPortal)((0,U.jsx)("div",{className:"luxe-floating-toolbar",style:{position:"fixed",top:`${l.y}px`,left:`${l.x}px`,transform:"translateX(-50%)",display:"flex",gap:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3},children:o.map((n,m)=>{let f=n.label||B(n.type),d=n.type.startsWith("heading")?parseInt(n.type.replace("heading","")):null;if(n.type==="textColor"||n.type==="backgroundColor"){let y=n.colors||Q.slice(0,6);return(0,U.jsx)("div",{style:{display:"flex",gap:"2px"},children:n.color?(0,U.jsx)("button",{onClick:()=>g(n,n.color),title:`${n.type==="textColor"?"Text":"Background"} Color`,style:{padding:"4px 8px",border:"1px solid #e5e7eb",background:n.type==="backgroundColor"?n.color:"white",color:n.type==="textColor"?n.color:"#000",cursor:"pointer",borderRadius:"4px",minWidth:"28px",height:"28px"},children:n.type==="textColor"?"A":"\u25A0"}):y.map(x=>(0,U.jsx)("button",{onClick:()=>g(n,x),title:x,style:{width:"24px",height:"24px",border:n.type==="textColor"?`3px solid ${x}`:"1px solid #e5e7eb",background:n.type==="backgroundColor"?x:"white",color:n.type==="textColor"?"#000":"inherit",cursor:"pointer",borderRadius:"3px",fontSize:"10px",display:"flex",alignItems:"center",justifyContent:"center"},children:n.type==="textColor"&&(0,U.jsx)("span",{style:{color:x,fontSize:"12px",fontWeight:"bold",lineHeight:"1"},children:"A"})},x))},`${n.type}-${m}`)}return(0,U.jsx)("button",{onClick:()=>g(n),title:n.type.charAt(0).toUpperCase()+n.type.slice(1),style:{padding:"6px 12px",border:"none",background:"transparent",cursor:"pointer",borderRadius:"4px",fontWeight:n.type==="bold"?"bold":"normal",fontStyle:n.type==="italic"?"italic":"normal",textDecoration:n.type==="underline"?"underline":n.type==="strikethrough"?"line-through":"none",fontSize:d?`${18-d*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},onMouseEnter:y=>{y.currentTarget.style.background="#f3f4f6"},onMouseLeave:y=>{y.currentTarget.style.background="transparent"},children:n.icon||f},`${n.type}-${m}`)})}),document.body)}var O=require("lexical"),ae=require("@lexical/rich-text");function le(e){return e.toJSON()}function se(e){let r="";return e.read(()=>{r=(0,O.$getRoot)().getTextContent()}),r}function ee(e,r){let o=(r&1)!==0,t=(r&2)!==0,l=(r&4)!==0,s=(r&8)!==0;return o&&t?e=`***${e}***`:o?e=`**${e}**`:t&&(e=`*${e}*`),l&&(e=`__${e}__`),s&&(e=`~~${e}~~`),e}function de(e){let r="";return e.read(()=>{let t=(0,O.$getRoot)().getChildren(),l=s=>{let i="";if((0,ae.$isHeadingNode)(s)){let u=s.getTag(),h=parseInt(u.replace("h","")),g="#".repeat(h),n=s.getChildren(),m="";for(let f of n)(0,O.$isTextNode)(f)?m+=ee(f.getTextContent(),f.getFormat()):(0,O.$isElementNode)(f)&&(m+=l(f));i+=`${g} ${m}
|
|
2
|
+
"use strict";var Se=Object.create;var j=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var He=Object.getPrototypeOf,$e=Object.prototype.hasOwnProperty;var Me=(e,n)=>{for(var o in n)j(e,o,{get:n[o],enumerable:!0})},ae=(e,n,o,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of we(n))!$e.call(e,r)&&r!==o&&j(e,r,{get:()=>n[r],enumerable:!(t=Re(n,r))||t.enumerable});return e};var Oe=(e,n,o)=>(o=e!=null?Se(He(e)):{},ae(n||!e||!e.__esModule?j(o,"default",{value:e,enumerable:!0}):o,e)),Ae=e=>ae(j({},"__esModule",{value:!0}),e);var Ge={};Me(Ge,{FloatingToolbarPlugin:()=>q,LuxeEditor:()=>je,Toolbar:()=>G,getEditorDOM:()=>fe,getEditorFormattedText:()=>ge,getEditorJSON:()=>pe,getEditorText:()=>ue,getEditorTree:()=>he,getHTMLFromJSON:()=>be,getTextFromJSON:()=>xe});module.exports=Ae(Ge);var z=Oe(require("react")),Te=require("@lexical/react/LexicalComposer"),Ce=require("@lexical/react/LexicalRichTextPlugin"),ve=require("@lexical/react/LexicalContentEditable"),Ne=require("@lexical/react/LexicalHistoryPlugin"),Ee=require("@lexical/react/LexicalErrorBoundary"),ke=require("@lexical/react/LexicalLinkPlugin"),Le=require("@lexical/rich-text"),Q=require("@lexical/link"),V=require("lexical"),re=require("@lexical/react/LexicalComposerContext");var se=require("@lexical/react/LexicalComposerContext"),N=require("lexical"),oe=require("@lexical/selection"),X=require("@lexical/rich-text"),A=require("react"),de=require("react-dom");var le=require("@lexical/react/LexicalComposerContext"),ie=require("@lexical/utils"),i=require("lexical"),ee=require("@lexical/selection"),P=require("@lexical/rich-text"),W=require("@lexical/link"),h=require("react"),g=require("react/jsx-runtime"),te=["#000000","#ffffff","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#808080","#800000","#008000","#000080","#808000","#800080","#008080"];function J(e){return{undo:"\u21B6",redo:"\u21B7",divider:"",bold:"B",italic:"I",underline:"U",strikethrough:"S",heading1:"H1",heading2:"H2",heading3:"H3",heading4:"H4",heading5:"H5",heading6:"H6",paragraph:"P",alignLeft:"\u2B05",alignCenter:"\u2B0C",alignRight:"\u27A1",alignJustify:"\u2B0C",textColor:"A",backgroundColor:"\u2B1B",fullscreen:"\u26F6",headingDropdown:"Normal",link:"\u{1F517}"}[e]||e}function De(){return(0,g.jsx)("div",{className:"luxe-toolbar-divider",style:{width:"1px",height:"24px",margin:"0 4px"}})}function Ke({item:e,onAction:n}){let[o,t]=(0,h.useState)(!1),r=(0,h.useRef)(null),s=e.colors||te;return(0,h.useEffect)(()=>{let l=p=>{r.current&&!r.current.contains(p.target)&&t(!1)};if(o)return document.addEventListener("mousedown",l),()=>document.removeEventListener("mousedown",l)},[o]),e.color?(0,g.jsx)("button",{onClick:()=>n(e,e.color),title:`${e.type==="textColor"?"Text":"Background"} Color: ${e.color}`,className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",background:e.type==="backgroundColor"?e.color:void 0,color:e.type==="textColor"?e.color:void 0,borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center"},children:e.icon||J(e.type)}):(0,g.jsxs)("div",{style:{position:"relative"},ref:r,children:[(0,g.jsxs)("button",{onClick:()=>t(!o),title:`${e.type==="textColor"?"Text":"Background"} Color`,className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:[e.icon||(0,g.jsx)("span",{style:{display:"block",width:"20px",height:"20px",background:e.type==="backgroundColor"?"linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%)":"currentColor",backgroundSize:e.type==="backgroundColor"?"8px 8px":"auto",backgroundPosition:e.type==="backgroundColor"?"0 0, 0 4px, 4px -4px, -4px 0px":"auto"},children:e.type==="textColor"&&(0,g.jsx)("span",{style:{fontSize:"12px"},children:"A"})}),(0,g.jsx)("span",{style:{marginLeft:"4px",fontSize:"10px"},children:"\u25BC"})]}),o&&(0,g.jsxs)("div",{className:"luxe-toolbar-panel",style:{position:"absolute",top:"100%",left:0,marginTop:"4px",borderRadius:"6px",padding:"8px",display:"grid",gridTemplateColumns:"repeat(5, 1fr)",gap:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"160px"},children:[s.map(l=>(0,g.jsxs)("button",{onClick:()=>{n(e,l),t(!1)},title:l,style:{width:"24px",height:"24px",borderRadius:"4px",border:e.type==="textColor"?`3px solid ${l}`:"1px solid #e5e7eb",background:e.type==="backgroundColor"?l:"white",color:e.type==="textColor"?"#000":"inherit",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"12px",fontWeight:"bold",position:"relative"},children:[e.type==="textColor"&&(0,g.jsx)("span",{style:{color:l,fontSize:"14px",fontWeight:"bold",lineHeight:"1"},children:"A"}),e.type==="backgroundColor"&&l==="#ffffff"&&(0,g.jsx)("span",{style:{color:"#000",fontSize:"10px",border:"1px solid #ccc",width:"12px",height:"12px",display:"block"},children:"\u25A1"})]},l)),(0,g.jsx)("input",{type:"color",onChange:l=>{n(e,l.target.value),t(!1)},className:"luxe-toolbar-input",style:{gridColumn:"1 / -1",width:"100%",height:"32px",borderRadius:"4px",cursor:"pointer"}})]})]})}function Fe({item:e,onAction:n,currentBlockType:o="paragraph"}){let[t,r]=(0,h.useState)(!1),s=(0,h.useRef)(null);(0,h.useEffect)(()=>{let u=y=>{s.current&&!s.current.contains(y.target)&&r(!1)};if(t)return document.addEventListener("mousedown",u),()=>document.removeEventListener("mousedown",u)},[t]);let l=()=>o==="paragraph"?"Normal":o.startsWith("h")?`Heading ${o.replace("h","")}`:"Normal",p=u=>{n(e,void 0,u),r(!1)},b=[{value:"paragraph",label:"Normal"},{value:"h1",label:"Heading 1"},{value:"h2",label:"Heading 2"},{value:"h3",label:"Heading 3"},{value:"h4",label:"Heading 4"},{value:"h5",label:"Heading 5"},{value:"h6",label:"Heading 6"}];return(0,g.jsxs)("div",{style:{position:"relative"},ref:s,children:[(0,g.jsxs)("button",{onClick:()=>r(!t),title:"Heading",className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",minWidth:"100px",height:"32px",display:"flex",alignItems:"center",justifyContent:"space-between",position:"relative",fontSize:o==="paragraph"?"14px":o==="h1"?"20px":o==="h2"?"18px":o==="h3"?"16px":"14px",fontWeight:o!=="paragraph"?"bold":"normal"},children:[(0,g.jsx)("span",{children:e.label||l()}),(0,g.jsx)("span",{style:{marginLeft:"8px",fontSize:"10px"},children:"\u25BC"})]}),t&&(0,g.jsx)("div",{className:"luxe-toolbar-panel",style:{position:"absolute",top:"100%",left:0,marginTop:"4px",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"150px"},children:b.map(u=>(0,g.jsx)("button",{onClick:()=>p(u.value),className:`luxe-toolbar-panel-item${o===u.value?" luxe-active":""}`,style:{padding:"8px 12px",borderRadius:"4px",fontSize:u.value==="paragraph"?"14px":u.value==="h1"?"20px":u.value==="h2"?"18px":u.value==="h3"?"16px":"14px",fontWeight:u.value!=="paragraph"?"bold":"normal",display:"flex",alignItems:"center"},children:u.label},u.value))})]})}function Pe({item:e,onAction:n,editor:o}){let[t,r]=(0,h.useState)(!1),[s,l]=(0,h.useState)(""),[p,b]=(0,h.useState)(!1),u=(0,h.useRef)(null),y=(0,h.useRef)(null);(0,h.useEffect)(()=>{let d=()=>{o.getEditorState().read(()=>{let C=(0,i.$getSelection)();if((0,i.$isRangeSelection)(C)){let w=C.getNodes(),v=null;for(let D of w){let c=D.getParent();for(;c!==null;){if((0,W.$isLinkNode)(c)){v=c;break}c=c.getParent()}if(v)break}v&&(0,W.$isLinkNode)(v)?(b(!0),l(v.getURL())):(b(!1),l(""))}else b(!1),l("")})},k=o.registerUpdateListener(()=>{d()}),x=o.registerCommand(i.SELECTION_CHANGE_COMMAND,()=>(d(),!1),i.COMMAND_PRIORITY_LOW);return d(),()=>{k(),x()}},[o]),(0,h.useEffect)(()=>{let d=k=>{u.current&&!u.current.contains(k.target)&&r(!1)};if(t)return document.addEventListener("mousedown",d),setTimeout(()=>y.current?.focus(),0),()=>document.removeEventListener("mousedown",d)},[t,p,s]);let a=()=>{if(!s.trim()){o.dispatchCommand(W.TOGGLE_LINK_COMMAND,null),r(!1),l("");return}let d=s.trim();!d.startsWith("http://")&&!d.startsWith("https://")&&!d.startsWith("mailto:")&&!d.startsWith("#")&&!d.startsWith("/")&&(d="https://"+d),o.dispatchCommand(W.TOGGLE_LINK_COMMAND,d),r(!1),l("")},m=()=>{o.dispatchCommand(W.TOGGLE_LINK_COMMAND,null),r(!1),l("")},f=d=>{d.key==="Enter"?(d.preventDefault(),a()):d.key==="Escape"&&(r(!1),l(""))};return(0,g.jsxs)("div",{style:{position:"relative"},ref:u,children:[(0,g.jsx)("button",{onClick:()=>r(!t),title:p?"Edit Link":"Insert Link",className:`luxe-toolbar-btn${p?" luxe-active":""}`,style:{padding:"6px 12px",borderRadius:"4px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},children:e.icon||J(e.type)}),t&&(0,g.jsxs)("div",{className:"luxe-toolbar-panel",style:{position:"absolute",top:"100%",left:0,marginTop:"4px",borderRadius:"6px",padding:"12px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"300px"},children:[(0,g.jsx)("input",{ref:y,type:"text",placeholder:"Enter URL (e.g., https://example.com)",value:s,onChange:d=>l(d.target.value),onKeyDown:f,className:"luxe-toolbar-input",style:{width:"100%",padding:"8px",borderRadius:"4px",fontSize:"14px",marginBottom:"8px",boxSizing:"border-box"}}),(0,g.jsxs)("div",{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[p&&(0,g.jsx)("button",{onClick:m,className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",fontSize:"14px",color:"#dc2626"},children:"Remove"}),(0,g.jsx)("button",{onClick:()=>r(!1),className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",fontSize:"14px"},children:"Cancel"}),(0,g.jsx)("button",{onClick:a,style:{padding:"6px 12px",border:"none",background:"var(--luxe-primary)",color:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px"},children:p?"Update":"Insert"})]})]})]})}function We({item:e,active:n=!1,disabled:o=!1,onAction:t,currentBlockType:r}){let l=e.type.startsWith("heading")&&e.type!=="headingDropdown"?parseInt(e.type.replace("heading","")):null,p=e.label||J(e.type);return e.type==="divider"?(0,g.jsx)(De,{}):e.type==="headingDropdown"?(0,g.jsx)(Fe,{item:e,onAction:t,currentBlockType:r}):e.type==="textColor"||e.type==="backgroundColor"?(0,g.jsx)(Ke,{item:e,onAction:t}):(0,g.jsx)("button",{onClick:()=>t(e),disabled:o,title:e.type.charAt(0).toUpperCase()+e.type.slice(1).replace(/([A-Z])/g," $1").trim(),className:`luxe-toolbar-btn${n?" luxe-active":""}`,style:{padding:"6px 12px",borderRadius:"4px",fontWeight:e.type==="bold"?"bold":"normal",fontStyle:e.type==="italic"?"italic":"normal",textDecoration:e.type==="underline"?"underline":e.type==="strikethrough"?"line-through":"none",fontSize:l?`${18-l*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},children:e.icon||p})}function G({items:e,onFullscreenToggle:n,isFullscreen:o=!1}){let[t]=(0,le.useLexicalComposerContext)(),[r,s]=(0,h.useState)(!1),[l,p]=(0,h.useState)(!1),[b,u]=(0,h.useState)(!1),[y,a]=(0,h.useState)(!1),[m,f]=(0,h.useState)(!1),[d,k]=(0,h.useState)(!1),[x,C]=(0,h.useState)("paragraph"),w=(0,h.useCallback)(()=>{let c=(0,i.$getSelection)();if((0,i.$isRangeSelection)(c)){u(c.hasFormat("bold")),a(c.hasFormat("italic")),f(c.hasFormat("underline")),k(c.hasFormat("strikethrough"));let S=c.anchor.getNode(),M=S.getKey()==="root"?S:S.getTopLevelElementOrThrow(),T=M.getKey();if(t.getElementByKey(T)!==null){let I=(0,P.$isHeadingNode)(M)?M.getTag():M.getType();C(I)}}},[t]);(0,h.useEffect)(()=>(0,ie.mergeRegister)(t.registerUpdateListener(({editorState:c})=>{c.read(()=>{w()})}),t.registerCommand(i.SELECTION_CHANGE_COMMAND,()=>(w(),!1),i.COMMAND_PRIORITY_LOW),t.registerCommand(i.CAN_UNDO_COMMAND,c=>(s(c),!1),i.COMMAND_PRIORITY_LOW),t.registerCommand(i.CAN_REDO_COMMAND,c=>(p(c),!1),i.COMMAND_PRIORITY_LOW)),[t,w]);let v=(0,h.useCallback)((c,S,M)=>{let{type:T}=c;if(T==="fullscreen"){n?.();return}if(T==="undo"){t.dispatchCommand(i.UNDO_COMMAND,void 0);return}if(T==="redo"){t.dispatchCommand(i.REDO_COMMAND,void 0);return}if(T==="textColor"&&S){t.update(()=>{let L=(0,i.$getSelection)();(0,i.$isRangeSelection)(L)&&(0,ee.$patchStyleText)(L,{color:S})});return}if(T==="backgroundColor"&&S){t.update(()=>{let L=(0,i.$getSelection)();(0,i.$isRangeSelection)(L)&&(0,ee.$patchStyleText)(L,{"background-color":S})});return}if(T==="bold"||T==="italic"||T==="underline"||T==="strikethrough"){t.dispatchCommand(i.FORMAT_TEXT_COMMAND,T);return}if(T==="alignLeft"){t.dispatchCommand(i.FORMAT_ELEMENT_COMMAND,"left");return}if(T==="alignCenter"){t.dispatchCommand(i.FORMAT_ELEMENT_COMMAND,"center");return}if(T==="alignRight"){t.dispatchCommand(i.FORMAT_ELEMENT_COMMAND,"right");return}if(T==="alignJustify"){t.dispatchCommand(i.FORMAT_ELEMENT_COMMAND,"justify");return}if(T==="headingDropdown"&&M){if(M==="paragraph")t.update(()=>{let L=(0,i.$getSelection)();if((0,i.$isRangeSelection)(L)){let I=L.anchor.getNode(),E=I.getKey()==="root"?I:I.getTopLevelElementOrThrow(),H=E.getKey();if(t.getElementByKey(H)!==null&&(0,P.$isHeadingNode)(E)&&(0,i.$isElementNode)(E)){let O=(0,i.$createParagraphNode)(),F=E.getChildren();O.append(...F),E.replace(O),O.selectEnd()}}});else{let L=M;t.update(()=>{let I=(0,i.$getSelection)();if((0,i.$isRangeSelection)(I)){let E=I.anchor.getNode(),H=E.getKey()==="root"?E:E.getTopLevelElementOrThrow(),K=H.getKey();if(t.getElementByKey(K)!==null&&(0,i.$isElementNode)(H)){let F=(0,P.$createHeadingNode)(L),B=H.getChildren();F.append(...B),H.replace(F),F.selectEnd()}}})}return}if(T.startsWith("heading")&&T!=="headingDropdown"){let I=`h${parseInt(T.replace("heading",""))}`;t.update(()=>{let E=(0,i.$getSelection)();if((0,i.$isRangeSelection)(E)){let H=E.anchor.getNode(),K=H.getKey()==="root"?H:H.getTopLevelElementOrThrow(),O=K.getKey();if(t.getElementByKey(O)!==null&&(0,i.$isElementNode)(K)){let B=(0,P.$createHeadingNode)(I),Ie=K.getChildren();B.append(...Ie),K.replace(B),B.selectEnd()}}});return}if(T==="paragraph"){t.update(()=>{let L=(0,i.$getSelection)();if((0,i.$isRangeSelection)(L)){let I=L.anchor.getNode(),E=I.getKey()==="root"?I:I.getTopLevelElementOrThrow(),H=E.getKey();if(t.getElementByKey(H)!==null&&(0,P.$isHeadingNode)(E)&&(0,i.$isElementNode)(E)){let O=(0,i.$createParagraphNode)(),F=E.getChildren();O.append(...F),E.replace(O),O.selectEnd()}}});return}},[t,n]),D=c=>{switch(c){case"undo":return{disabled:!r};case"redo":return{disabled:!l};case"bold":return{active:b};case"italic":return{active:y};case"underline":return{active:m};case"strikethrough":return{active:d};case"fullscreen":return{active:o};case"heading1":return{active:x==="h1"};case"heading2":return{active:x==="h2"};case"heading3":return{active:x==="h3"};case"heading4":return{active:x==="h4"};case"heading5":return{active:x==="h5"};case"heading6":return{active:x==="h6"};case"paragraph":return{active:x==="paragraph"};default:return{}}};return(0,g.jsx)("div",{className:"luxe-toolbar",style:{display:"flex",gap:"4px",alignItems:"center",borderRadius:"8px 8px 0 0",padding:"8px",flexWrap:"wrap"},children:e.map((c,S)=>{let M=D(c.type);return c.type==="link"?(0,g.jsx)(Pe,{item:c,onAction:v,editor:t},`${c.type}-${S}`):(0,g.jsx)(We,{item:c,active:M.active,disabled:M.disabled,onAction:v,currentBlockType:x},`${c.type}-${S}`)})})}var U=require("react/jsx-runtime"),Ue=[{type:"bold"},{type:"italic"},{type:"underline"}];function ze(e){let n=["bold","italic","underline","strikethrough","textColor","backgroundColor"];return e.filter(o=>n.includes(o.type))}function q({enabled:e=!0,items:n,colorScheme:o}){let t=n?ze(n).slice(0,4):Ue,[r]=(0,se.useLexicalComposerContext)(),[s,l]=(0,A.useState)(null),[p,b]=(0,A.useState)(null);(0,A.useEffect)(()=>{let a=r.getRootElement();a&&b(a)},[r]);let u=(0,A.useCallback)(()=>{if(!p)return;let a=window.getSelection();if(!a||a.rangeCount===0||a.isCollapsed){l(null);return}try{let m=a.getRangeAt(0);if(!p.contains(m.commonAncestorContainer)){l(null);return}let f=m.getBoundingClientRect();f&&f.width>0&&f.height>0?r.getEditorState().read(()=>{let d=(0,N.$getSelection)();d&&(0,N.$isRangeSelection)(d)&&!d.isCollapsed()?l({x:f.left+f.width/2,y:f.top-40}):l(null)}):l(null)}catch{l(null)}},[r,p]);(0,A.useEffect)(()=>{if(!p)return;let a=r.registerUpdateListener(()=>{setTimeout(()=>u(),10)});return()=>{a()}},[r,p,u]),(0,A.useEffect)(()=>{let a=()=>{setTimeout(()=>u(),50)},m=()=>{setTimeout(()=>u(),50)},f=()=>{setTimeout(()=>u(),50)};return document.addEventListener("mouseup",a),document.addEventListener("keyup",m),document.addEventListener("selectionchange",f),()=>{document.removeEventListener("mouseup",a),document.removeEventListener("keyup",m),document.removeEventListener("selectionchange",f)}},[u]);let y=(0,A.useCallback)((a,m)=>{let{type:f}=a;if(f==="textColor"&&m){r.update(()=>{let d=(0,N.$getSelection)();(0,N.$isRangeSelection)(d)&&(0,oe.$patchStyleText)(d,{color:m})});return}if(f==="backgroundColor"&&m){r.update(()=>{let d=(0,N.$getSelection)();(0,N.$isRangeSelection)(d)&&(0,oe.$patchStyleText)(d,{"background-color":m})});return}if(f==="bold"||f==="italic"||f==="underline"||f==="strikethrough"){r.dispatchCommand(N.FORMAT_TEXT_COMMAND,f);return}if(f.startsWith("heading")){let k=`h${parseInt(f.replace("heading",""))}`;r.update(()=>{let x=(0,N.$getSelection)();if((0,N.$isRangeSelection)(x)){let C=x.anchor.getNode(),w=C.getKey()==="root"?C:C.getTopLevelElementOrThrow(),v=w.getKey();if(r.getElementByKey(v)!==null&&(0,N.$isElementNode)(w)){let c=(0,X.$createHeadingNode)(k),S=w.getChildren();c.append(...S),w.replace(c),c.selectEnd()}}});return}if(f==="paragraph"){r.update(()=>{let d=(0,N.$getSelection)();if((0,N.$isRangeSelection)(d)){let k=d.anchor.getNode(),x=k.getKey()==="root"?k:k.getTopLevelElementOrThrow(),C=x.getKey();if(r.getElementByKey(C)!==null&&(0,X.$isHeadingNode)(x)&&(0,N.$isElementNode)(x)){let v=(0,N.$createParagraphNode)(),D=x.getChildren();v.append(...D),x.replace(v),v.selectEnd()}}});return}},[r]);return!e||!t||t.length===0||!s?null:(0,de.createPortal)((0,U.jsx)("div",{className:"luxe-floating-toolbar","data-luxe-theme":o,style:{position:"fixed",top:`${s.y}px`,left:`${s.x}px`,transform:"translateX(-50%)",display:"flex",gap:"4px",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3},children:t.map((a,m)=>{let f=a.label||J(a.type),k=a.type.startsWith("heading")?parseInt(a.type.replace("heading","")):null;if(a.type==="textColor"||a.type==="backgroundColor"){let x=a.colors||te.slice(0,6);return(0,U.jsx)("div",{style:{display:"flex",gap:"2px"},children:a.color?(0,U.jsx)("button",{onClick:()=>y(a,a.color),title:`${a.type==="textColor"?"Text":"Background"} Color`,className:"luxe-toolbar-select-btn",style:{padding:"4px 8px",background:a.type==="backgroundColor"?a.color:void 0,color:a.type==="textColor"?a.color:void 0,borderRadius:"4px",minWidth:"28px",height:"28px"},children:a.type==="textColor"?"A":"\u25A0"}):x.map(C=>(0,U.jsx)("button",{onClick:()=>y(a,C),title:C,style:{width:"24px",height:"24px",border:a.type==="textColor"?`3px solid ${C}`:"1px solid #e5e7eb",background:a.type==="backgroundColor"?C:void 0,cursor:"pointer",borderRadius:"3px",fontSize:"10px",display:"flex",alignItems:"center",justifyContent:"center"},children:a.type==="textColor"&&(0,U.jsx)("span",{style:{color:C,fontSize:"12px",fontWeight:"bold",lineHeight:"1"},children:"A"})},C))},`${a.type}-${m}`)}return(0,U.jsx)("button",{onClick:()=>y(a),title:a.type.charAt(0).toUpperCase()+a.type.slice(1),className:"luxe-toolbar-btn",style:{padding:"6px 12px",borderRadius:"4px",fontWeight:a.type==="bold"?"bold":"normal",fontStyle:a.type==="italic"?"italic":"normal",textDecoration:a.type==="underline"?"underline":a.type==="strikethrough"?"line-through":"none",fontSize:k?`${18-k*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},children:a.icon||f},`${a.type}-${m}`)})}),document.body)}var _=require("lexical"),$=require("lexical"),Y=require("@lexical/rich-text"),Z=require("@lexical/link"),ce=require("@lexical/html");function pe(e){return e.toJSON()}function ue(e){let n="";return e.read(()=>{n=(0,$.$getRoot)().getTextContent()}),n}function ne(e,n){let o=(n&1)!==0,t=(n&2)!==0,r=(n&4)!==0,s=(n&8)!==0;return o&&t?e=`***${e}***`:o?e=`**${e}**`:t&&(e=`*${e}*`),r&&(e=`__${e}__`),s&&(e=`~~${e}~~`),e}function ge(e){let n="";return e.read(()=>{let t=(0,$.$getRoot)().getChildren(),r=s=>{let l="";if((0,Y.$isHeadingNode)(s)){let p=s.getTag(),b=parseInt(p.replace("h","")),u="#".repeat(b),y=s.getChildren(),a="";for(let m of y)(0,$.$isTextNode)(m)?a+=ne(m.getTextContent(),m.getFormat()):(0,$.$isElementNode)(m)&&(a+=r(m));l+=`${u} ${a}
|
|
3
3
|
|
|
4
|
-
`}else if((0
|
|
4
|
+
`}else if((0,$.$isElementNode)(s)){let p=s.getChildren(),b="";for(let y of p)(0,$.$isTextNode)(y)?b+=ne(y.getTextContent(),y.getFormat()):(0,$.$isElementNode)(y)&&(b+=r(y));let u=s.getType();u==="paragraph"?l+=b+`
|
|
5
5
|
|
|
6
|
-
`:
|
|
6
|
+
`:l+=b}else(0,$.$isTextNode)(s)&&(l+=ne(s.getTextContent(),s.getFormat()));return l};for(let s of t)n+=r(s)}),n.trim()}function fe(e){if(!e)return"";try{let n=e.getRootElement();if(!n)return"";let o=n.querySelector('[contenteditable="true"]');if(o)return(o.innerHTML||"").trim()||"";if(n.hasAttribute("contenteditable")&&n.getAttribute("contenteditable")==="true")return n.innerHTML||"";let t=Array.from(n.children).filter(r=>{let s=r.id||"",l=r.className||"";return!s.includes("toolbar")&&!l.includes("toolbar")});if(t.length>0){for(let r of t)if(r.hasAttribute("contenteditable"))return r.innerHTML||"";return t[0].innerHTML||""}return n.innerHTML||""}catch(n){return console.error("Error getting editor DOM:",n),""}}function he(e){if(!e||!e.root)return null;let n=(o,t=0)=>{if(!o)return null;let r=o.type||"unknown",s=o.key||"",l=o.children||[],p={type:r,key:s,depth:t,children:[]};return o.tag&&(p.tag=o.tag),o.format!==void 0&&(p.format=o.format),o.text&&(p.text=o.text.substring(0,50)+(o.text.length>50?"...":"")),o.style&&(p.style=o.style),o.indent&&(p.indent=o.indent),o.direction&&(p.direction=o.direction),Array.isArray(l)&&(p.children=l.map(b=>n(b,t+1)).filter(Boolean)),p};return n(e.root)}var _e=[Y.HeadingNode,_.ParagraphNode,_.TextNode,Z.LinkNode,Z.AutoLinkNode];function me(){return(0,_.createEditor)({namespace:"luxe-headless",nodes:_e,onError:()=>{}})}function xe(e){if(!e)return"";try{let o=me().parseEditorState(e),t="";return o.read(()=>{t=(0,$.$getRoot)().getTextContent()}),t}catch{return""}}function be(e){if(!e)return"";try{let n=me(),o=n.parseEditorState(e),t="";return o.read(()=>{t=(0,ce.$generateHtmlFromNodes)(n,null)}),t}catch{return""}}var R=require("react/jsx-runtime"),ye={paragraph:"luxe-paragraph",heading:{h1:"luxe-heading-h1",h2:"luxe-heading-h2",h3:"luxe-heading-h3",h4:"luxe-heading-h4",h5:"luxe-heading-h5",h6:"luxe-heading-h6"},text:{bold:"luxe-bold",italic:"luxe-italic",underline:"luxe-underline",strikethrough:"luxe-strikethrough"}};function Be({onChange:e,ignoreInitialChange:n}){let[o]=(0,re.useLexicalComposerContext)(),t=z.default.useRef(!0);return z.default.useEffect(()=>o.registerUpdateListener(({editorState:r,prevEditorState:s})=>{if(n&&t.current&&s.isEmpty()){t.current=!1;return}t.current=!1,e(r,o)}),[o,e,n]),null}function Je({initialJSON:e}){let[n]=(0,re.useLexicalComposerContext)(),o=z.default.useRef(!1);return z.default.useEffect(()=>{if(!(!e||o.current))try{let t=n.parseEditorState(e);n.setEditorState(t),o.current=!0}catch(t){console.error("LuxeEditor: Failed to parse initialJSON",t)}},[n,e]),null}function je({initialConfig:e,initialJSON:n,showFloatingToolbar:o=!0,showToolbar:t=!0,toolbarItems:r,floatingToolbarItems:s,onChange:l,ignoreInitialChange:p=!0,colorScheme:b,children:u}){let[y,a]=z.default.useState(!1),m=[Le.HeadingNode,V.ParagraphNode,V.TextNode,Q.LinkNode,Q.AutoLinkNode],f=e.theme?{...ye,...e.theme}:ye,{theme:d,...k}=e,x=k.onUpdate,C={namespace:"LuxeEditor",theme:f,nodes:m,onError:c=>console.error(c),onUpdate:x,...k},v=r||[{type:"undo"},{type:"redo"},{type:"divider"},{type:"bold"},{type:"italic"},{type:"underline"},{type:"strikethrough"},{type:"divider"},{type:"headingDropdown"},{type:"divider"},{type:"link"}],D=z.default.useCallback(()=>{a(c=>!c)},[]);return(0,R.jsx)(Te.LexicalComposer,{initialConfig:C,children:(0,R.jsxs)("div",{className:`luxe-editor-container ${y?"luxe-editor-fullscreen":""}`,"data-luxe-theme":b,children:[t&&v&&v.length>0&&(0,R.jsx)(G,{items:v,onFullscreenToggle:D,isFullscreen:y}),(0,R.jsx)(Ce.RichTextPlugin,{contentEditable:(0,R.jsx)(ve.ContentEditable,{className:"luxe-input"}),placeholder:(0,R.jsx)("div",{className:"luxe-placeholder",children:"Start writing..."}),ErrorBoundary:Ee.LexicalErrorBoundary}),(0,R.jsx)(Ne.HistoryPlugin,{}),(0,R.jsx)(ke.LinkPlugin,{}),l&&(0,R.jsx)(Be,{onChange:l,ignoreInitialChange:p}),n&&(0,R.jsx)(Je,{initialJSON:n}),o&&(0,R.jsx)(q,{enabled:!0,items:s||v,colorScheme:b}),u]})})}0&&(module.exports={FloatingToolbarPlugin,LuxeEditor,Toolbar,getEditorDOM,getEditorFormattedText,getEditorJSON,getEditorText,getEditorTree,getHTMLFromJSON,getTextFromJSON});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import B from"react";import{LexicalComposer as ze}from"@lexical/react/LexicalComposer";import{RichTextPlugin as Be}from"@lexical/react/LexicalRichTextPlugin";import{ContentEditable as je}from"@lexical/react/LexicalContentEditable";import{HistoryPlugin as Je}from"@lexical/react/LexicalHistoryPlugin";import{LexicalErrorBoundary as Ge}from"@lexical/react/LexicalErrorBoundary";import{LinkPlugin as Xe}from"@lexical/react/LexicalLinkPlugin";import{HeadingNode as qe}from"@lexical/rich-text";import{LinkNode as Ye,AutoLinkNode as Ze}from"@lexical/link";import{ParagraphNode as Qe,TextNode as Ve}from"lexical";import{useLexicalComposerContext as et}from"@lexical/react/LexicalComposerContext";import{useLexicalComposerContext as Re}from"@lexical/react/LexicalComposerContext";import{$getSelection as _,$isRangeSelection as z,FORMAT_TEXT_COMMAND as Se,$createParagraphNode as Me,$isElementNode as ce}from"lexical";import{$patchStyleText as pe}from"@lexical/selection";import{$createHeadingNode as $e,$isHeadingNode as He}from"@lexical/rich-text";import{useCallback as ue,useEffect as V,useState as ge}from"react";import{createPortal as Oe}from"react-dom";import{useLexicalComposerContext as me}from"@lexical/react/LexicalComposerContext";import{mergeRegister as xe}from"@lexical/utils";import{$getSelection as D,$isRangeSelection as K,$createParagraphNode as re,$isElementNode as j,CAN_REDO_COMMAND as ye,CAN_UNDO_COMMAND as Te,COMMAND_PRIORITY_LOW as G,FORMAT_ELEMENT_COMMAND as J,FORMAT_TEXT_COMMAND as Ce,REDO_COMMAND as ve,SELECTION_CHANGE_COMMAND as de,UNDO_COMMAND as ke}from"lexical";import{$patchStyleText as ie}from"@lexical/selection";import{$createHeadingNode as ae,$isHeadingNode as q}from"@lexical/rich-text";import{$isLinkNode as le,TOGGLE_LINK_COMMAND as Y}from"@lexical/link";import{useCallback as se,useEffect as F,useState as R,useRef as X}from"react";import{jsx as b,jsxs as $}from"react/jsx-runtime";var Z=["#000000","#ffffff","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#808080","#800000","#008000","#000080","#808000","#800080","#008080"];function U(e){return{undo:"\u21B6",redo:"\u21B7",divider:"",bold:"B",italic:"I",underline:"U",strikethrough:"S",heading1:"H1",heading2:"H2",heading3:"H3",heading4:"H4",heading5:"H5",heading6:"H6",paragraph:"P",alignLeft:"\u2B05",alignCenter:"\u2B0C",alignRight:"\u27A1",alignJustify:"\u2B0C",textColor:"A",backgroundColor:"\u2B1B",fullscreen:"\u26F6",headingDropdown:"Normal",link:"\u{1F517}"}[e]||e}function Ee(){return b("div",{style:{width:"1px",height:"24px",background:"#e5e7eb",margin:"0 4px"}})}function Ne({item:e,onAction:i}){let[n,t]=R(!1),l=X(null),a=e.colors||Z;return F(()=>{let r=c=>{l.current&&!l.current.contains(c.target)&&t(!1)};if(n)return document.addEventListener("mousedown",r),()=>document.removeEventListener("mousedown",r)},[n]),e.color?b("button",{onClick:()=>i(e,e.color),title:`${e.type==="textColor"?"Text":"Background"} Color: ${e.color}`,style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:e.type==="backgroundColor"?e.color:"white",color:e.type==="textColor"?e.color:"#000",cursor:"pointer",borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center"},children:e.icon||U(e.type)}):$("div",{style:{position:"relative"},ref:l,children:[$("button",{onClick:()=>t(!n),title:`${e.type==="textColor"?"Text":"Background"} Color`,style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:[e.icon||b("span",{style:{display:"block",width:"20px",height:"20px",background:e.type==="backgroundColor"?"linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%)":"currentColor",backgroundSize:e.type==="backgroundColor"?"8px 8px":"auto",backgroundPosition:e.type==="backgroundColor"?"0 0, 0 4px, 4px -4px, -4px 0px":"auto"},children:e.type==="textColor"&&b("span",{style:{color:"#000",fontSize:"12px"},children:"A"})}),b("span",{style:{marginLeft:"4px",fontSize:"10px"},children:"\u25BC"})]}),n&&$("div",{style:{position:"absolute",top:"100%",left:0,marginTop:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"8px",display:"grid",gridTemplateColumns:"repeat(5, 1fr)",gap:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"160px"},children:[a.map(r=>$("button",{onClick:()=>{i(e,r),t(!1)},title:r,style:{width:"24px",height:"24px",borderRadius:"4px",border:e.type==="textColor"?`3px solid ${r}`:"1px solid #e5e7eb",background:e.type==="backgroundColor"?r:"white",color:e.type==="textColor"?"#000":"inherit",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"12px",fontWeight:"bold",position:"relative"},children:[e.type==="textColor"&&b("span",{style:{color:r,fontSize:"14px",fontWeight:"bold",lineHeight:"1"},children:"A"}),e.type==="backgroundColor"&&r==="#ffffff"&&b("span",{style:{color:"#000",fontSize:"10px",border:"1px solid #ccc",width:"12px",height:"12px",display:"block"},children:"\u25A1"})]},r)),b("input",{type:"color",onChange:r=>{i(e,r.target.value),t(!1)},style:{gridColumn:"1 / -1",width:"100%",height:"32px",border:"1px solid #e5e7eb",borderRadius:"4px",cursor:"pointer"}})]})]})}function Le({item:e,onAction:i,currentBlockType:n="paragraph"}){let[t,l]=R(!1),a=X(null);F(()=>{let p=o=>{a.current&&!a.current.contains(o.target)&&l(!1)};if(t)return document.addEventListener("mousedown",p),()=>document.removeEventListener("mousedown",p)},[t]);let r=()=>n==="paragraph"?"Normal":n.startsWith("h")?`Heading ${n.replace("h","")}`:"Normal",c=p=>{i(e,void 0,p),l(!1)},g=[{value:"paragraph",label:"Normal"},{value:"h1",label:"Heading 1"},{value:"h2",label:"Heading 2"},{value:"h3",label:"Heading 3"},{value:"h4",label:"Heading 4"},{value:"h5",label:"Heading 5"},{value:"h6",label:"Heading 6"}];return $("div",{style:{position:"relative"},ref:a,children:[$("button",{onClick:()=>l(!t),title:"Heading",style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",minWidth:"100px",height:"32px",display:"flex",alignItems:"center",justifyContent:"space-between",position:"relative",fontSize:n==="paragraph"?"14px":n==="h1"?"20px":n==="h2"?"18px":n==="h3"?"16px":"14px",fontWeight:n!=="paragraph"?"bold":"normal"},children:[b("span",{children:e.label||r()}),b("span",{style:{marginLeft:"8px",fontSize:"10px"},children:"\u25BC"})]}),t&&b("div",{style:{position:"absolute",top:"100%",left:0,marginTop:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"150px"},children:g.map(p=>b("button",{onClick:()=>c(p.value),style:{width:"100%",padding:"8px 12px",border:"none",background:n===p.value?"#e5e7eb":"transparent",cursor:"pointer",borderRadius:"4px",textAlign:"left",fontSize:p.value==="paragraph"?"14px":p.value==="h1"?"20px":p.value==="h2"?"18px":p.value==="h3"?"16px":"14px",fontWeight:p.value!=="paragraph"?"bold":"normal",display:"flex",alignItems:"center"},onMouseEnter:o=>{n!==p.value&&(o.currentTarget.style.background="#f3f4f6")},onMouseLeave:o=>{n!==p.value?o.currentTarget.style.background="transparent":o.currentTarget.style.background="#e5e7eb"},children:p.label},p.value))})]})}function Ie({item:e,onAction:i,editor:n}){let[t,l]=R(!1),[a,r]=R(""),[c,g]=R(!1),p=X(null),o=X(null);F(()=>{let s=()=>{n.getEditorState().read(()=>{let S=D();if(K(S)){let C=S.getNodes(),N=null;for(let v of C){let d=v.getParent();for(;d!==null;){if(le(d)){N=d;break}d=d.getParent()}if(N)break}N&&le(N)?(g(!0),r(N.getURL())):(g(!1),r(""))}else g(!1),r("")})},m=n.registerUpdateListener(()=>{s()}),h=n.registerCommand(de,()=>(s(),!1),G);return s(),()=>{m(),h()}},[n]),F(()=>{let s=m=>{p.current&&!p.current.contains(m.target)&&l(!1)};if(t)return document.addEventListener("mousedown",s),setTimeout(()=>o.current?.focus(),0),()=>document.removeEventListener("mousedown",s)},[t,c,a]);let f=()=>{if(!a.trim()){n.dispatchCommand(Y,null),l(!1),r("");return}let s=a.trim();!s.startsWith("http://")&&!s.startsWith("https://")&&!s.startsWith("mailto:")&&!s.startsWith("#")&&!s.startsWith("/")&&(s="https://"+s),n.dispatchCommand(Y,s),l(!1),r("")},u=()=>{n.dispatchCommand(Y,null),l(!1),r("")},x=s=>{s.key==="Enter"?(s.preventDefault(),f()):s.key==="Escape"&&(l(!1),r(""))};return $("div",{style:{position:"relative"},ref:p,children:[b("button",{onClick:()=>{l(!t)},title:c?"Edit Link":"Insert Link",style:{padding:"6px 12px",border:"none",background:c?"#e5e7eb":"transparent",cursor:"pointer",borderRadius:"4px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},onMouseEnter:s=>{c||(s.currentTarget.style.background="#f3f4f6")},onMouseLeave:s=>{c?s.currentTarget.style.background="#e5e7eb":s.currentTarget.style.background="transparent"},children:e.icon||U(e.type)}),t&&$("div",{style:{position:"absolute",top:"100%",left:0,marginTop:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"12px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"300px"},children:[b("input",{ref:o,type:"text",placeholder:"Enter URL (e.g., https://example.com)",value:a,onChange:s=>r(s.target.value),onKeyDown:x,style:{width:"100%",padding:"8px",border:"1px solid #e5e7eb",borderRadius:"4px",fontSize:"14px",marginBottom:"8px"}}),$("div",{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[c&&b("button",{onClick:u,style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px",color:"#dc2626"},children:"Remove"}),b("button",{onClick:()=>l(!1),style:{padding:"6px 12px",border:"1px solid #e5e7eb",background:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px"},children:"Cancel"}),b("button",{onClick:f,style:{padding:"6px 12px",border:"none",background:"#3b82f6",color:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px"},children:c?"Update":"Insert"})]})]})]})}function we({item:e,active:i=!1,disabled:n=!1,onAction:t,currentBlockType:l}){let r=e.type.startsWith("heading")&&e.type!=="headingDropdown"?parseInt(e.type.replace("heading","")):null,c=e.label||U(e.type);return e.type==="divider"?b(Ee,{}):e.type==="headingDropdown"?b(Le,{item:e,onAction:t,currentBlockType:l}):e.type==="textColor"||e.type==="backgroundColor"?b(Ne,{item:e,onAction:t}):b("button",{onClick:()=>t(e),disabled:n,title:e.type.charAt(0).toUpperCase()+e.type.slice(1).replace(/([A-Z])/g," $1").trim(),style:{padding:"6px 12px",border:"none",background:i?"#e5e7eb":"transparent",cursor:n?"not-allowed":"pointer",borderRadius:"4px",fontWeight:e.type==="bold"?"bold":"normal",fontStyle:e.type==="italic"?"italic":"normal",textDecoration:e.type==="underline"?"underline":e.type==="strikethrough"?"line-through":"none",fontSize:r?`${18-r*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s",opacity:n?.5:1},onMouseEnter:g=>{!n&&!i&&(g.currentTarget.style.background="#f3f4f6")},onMouseLeave:g=>{i?g.currentTarget.style.background="#e5e7eb":g.currentTarget.style.background="transparent"},children:e.icon||c})}function Q({items:e,onFullscreenToggle:i,isFullscreen:n=!1}){let[t]=me(),[l,a]=R(!1),[r,c]=R(!1),[g,p]=R(!1),[o,f]=R(!1),[u,x]=R(!1),[s,m]=R(!1),[h,S]=R("paragraph"),C=se(()=>{let d=D();if(K(d)){p(d.hasFormat("bold")),f(d.hasFormat("italic")),x(d.hasFormat("underline")),m(d.hasFormat("strikethrough"));let L=d.anchor.getNode(),I=L.getKey()==="root"?L:L.getTopLevelElementOrThrow(),y=I.getKey();if(t.getElementByKey(y)!==null){let E=q(I)?I.getTag():I.getType();S(E)}}},[t]);F(()=>xe(t.registerUpdateListener(({editorState:d})=>{d.read(()=>{C()})}),t.registerCommand(de,()=>(C(),!1),G),t.registerCommand(Te,d=>(a(d),!1),G),t.registerCommand(ye,d=>(c(d),!1),G)),[t,C]);let N=se((d,L,I)=>{let{type:y}=d;if(y==="fullscreen"){i?.();return}if(y==="undo"){t.dispatchCommand(ke,void 0);return}if(y==="redo"){t.dispatchCommand(ve,void 0);return}if(y==="textColor"&&L){t.update(()=>{let k=D();K(k)&&ie(k,{color:L})});return}if(y==="backgroundColor"&&L){t.update(()=>{let k=D();K(k)&&ie(k,{"background-color":L})});return}if(y==="bold"||y==="italic"||y==="underline"||y==="strikethrough"){t.dispatchCommand(Ce,y);return}if(y==="alignLeft"){t.dispatchCommand(J,"left");return}if(y==="alignCenter"){t.dispatchCommand(J,"center");return}if(y==="alignRight"){t.dispatchCommand(J,"right");return}if(y==="alignJustify"){t.dispatchCommand(J,"justify");return}if(y==="headingDropdown"&&I){if(I==="paragraph")t.update(()=>{let k=D();if(K(k)){let E=k.anchor.getNode(),T=E.getKey()==="root"?E:E.getTopLevelElementOrThrow(),w=T.getKey();if(t.getElementByKey(w)!==null&&q(T)&&j(T)){let M=re(),A=T.getChildren();M.append(...A),T.replace(M),M.selectEnd()}}});else{let k=I;t.update(()=>{let E=D();if(K(E)){let T=E.anchor.getNode(),w=T.getKey()==="root"?T:T.getTopLevelElementOrThrow(),O=w.getKey();if(t.getElementByKey(O)!==null&&j(w)){let A=ae(k),W=w.getChildren();A.append(...W),w.replace(A),A.selectEnd()}}})}return}if(y.startsWith("heading")&&y!=="headingDropdown"){let E=`h${parseInt(y.replace("heading",""))}`;t.update(()=>{let T=D();if(K(T)){let w=T.anchor.getNode(),O=w.getKey()==="root"?w:w.getTopLevelElementOrThrow(),M=O.getKey();if(t.getElementByKey(M)!==null&&j(O)){let W=ae(E),be=O.getChildren();W.append(...be),O.replace(W),W.selectEnd()}}});return}if(y==="paragraph"){t.update(()=>{let k=D();if(K(k)){let E=k.anchor.getNode(),T=E.getKey()==="root"?E:E.getTopLevelElementOrThrow(),w=T.getKey();if(t.getElementByKey(w)!==null&&q(T)&&j(T)){let M=re(),A=T.getChildren();M.append(...A),T.replace(M),M.selectEnd()}}});return}},[t,i]),v=d=>{switch(d){case"undo":return{disabled:!l};case"redo":return{disabled:!r};case"bold":return{active:g};case"italic":return{active:o};case"underline":return{active:u};case"strikethrough":return{active:s};case"fullscreen":return{active:n};case"heading1":return{active:h==="h1"};case"heading2":return{active:h==="h2"};case"heading3":return{active:h==="h3"};case"heading4":return{active:h==="h4"};case"heading5":return{active:h==="h5"};case"heading6":return{active:h==="h6"};case"paragraph":return{active:h==="paragraph"};default:return{}}};return b("div",{className:"luxe-toolbar",style:{display:"flex",gap:"4px",alignItems:"center",background:"white",borderBottom:"1px solid #e5e7eb",borderRadius:"8px 8px 0 0",padding:"8px",flexWrap:"wrap"},children:e.map((d,L)=>{let I=v(d.type);return d.type==="link"?b(Ie,{item:d,onAction:N,editor:t},`${d.type}-${L}`):b(we,{item:d,active:I.active,disabled:I.disabled,onAction:N,currentBlockType:h},`${d.type}-${L}`)})})}import{jsx as P}from"react/jsx-runtime";var Ae=[{type:"bold"},{type:"italic"},{type:"underline"}];function De(e){let i=["bold","italic","underline","strikethrough","textColor","backgroundColor"];return e.filter(n=>i.includes(n.type))}function ee({enabled:e=!0,items:i}){let n=i?De(i).slice(0,4):Ae,[t]=Re(),[l,a]=ge(null),[r,c]=ge(null);V(()=>{let o=t.getRootElement();o&&c(o)},[t]);let g=ue(()=>{if(!r)return;let o=window.getSelection();if(!o||o.rangeCount===0||o.isCollapsed){a(null);return}try{let f=o.getRangeAt(0);if(!r.contains(f.commonAncestorContainer)){a(null);return}let u=f.getBoundingClientRect();u&&u.width>0&&u.height>0?t.getEditorState().read(()=>{let x=_();x&&z(x)&&!x.isCollapsed()?a({x:u.left+u.width/2,y:u.top-40}):a(null)}):a(null)}catch{a(null)}},[t,r]);V(()=>{if(!r)return;let o=t.registerUpdateListener(()=>{setTimeout(()=>g(),10)});return()=>{o()}},[t,r,g]),V(()=>{let o=()=>{setTimeout(()=>g(),50)},f=()=>{setTimeout(()=>g(),50)},u=()=>{setTimeout(()=>g(),50)};return document.addEventListener("mouseup",o),document.addEventListener("keyup",f),document.addEventListener("selectionchange",u),()=>{document.removeEventListener("mouseup",o),document.removeEventListener("keyup",f),document.removeEventListener("selectionchange",u)}},[g]);let p=ue((o,f)=>{let{type:u}=o;if(u==="textColor"&&f){t.update(()=>{let x=_();z(x)&&pe(x,{color:f})});return}if(u==="backgroundColor"&&f){t.update(()=>{let x=_();z(x)&&pe(x,{"background-color":f})});return}if(u==="bold"||u==="italic"||u==="underline"||u==="strikethrough"){t.dispatchCommand(Se,u);return}if(u.startsWith("heading")){let s=`h${parseInt(u.replace("heading",""))}`;t.update(()=>{let m=_();if(z(m)){let h=m.anchor.getNode(),S=h.getKey()==="root"?h:h.getTopLevelElementOrThrow(),C=S.getKey();if(t.getElementByKey(C)!==null&&ce(S)){let v=$e(s),d=S.getChildren();v.append(...d),S.replace(v),v.selectEnd()}}});return}if(u==="paragraph"){t.update(()=>{let x=_();if(z(x)){let s=x.anchor.getNode(),m=s.getKey()==="root"?s:s.getTopLevelElementOrThrow(),h=m.getKey();if(t.getElementByKey(h)!==null&&He(m)&&ce(m)){let C=Me(),N=m.getChildren();C.append(...N),m.replace(C),C.selectEnd()}}});return}},[t]);return!e||!n||n.length===0||!l?null:Oe(P("div",{className:"luxe-floating-toolbar",style:{position:"fixed",top:`${l.y}px`,left:`${l.x}px`,transform:"translateX(-50%)",display:"flex",gap:"4px",background:"white",border:"1px solid #e5e7eb",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3},children:n.map((o,f)=>{let u=o.label||U(o.type),s=o.type.startsWith("heading")?parseInt(o.type.replace("heading","")):null;if(o.type==="textColor"||o.type==="backgroundColor"){let m=o.colors||Z.slice(0,6);return P("div",{style:{display:"flex",gap:"2px"},children:o.color?P("button",{onClick:()=>p(o,o.color),title:`${o.type==="textColor"?"Text":"Background"} Color`,style:{padding:"4px 8px",border:"1px solid #e5e7eb",background:o.type==="backgroundColor"?o.color:"white",color:o.type==="textColor"?o.color:"#000",cursor:"pointer",borderRadius:"4px",minWidth:"28px",height:"28px"},children:o.type==="textColor"?"A":"\u25A0"}):m.map(h=>P("button",{onClick:()=>p(o,h),title:h,style:{width:"24px",height:"24px",border:o.type==="textColor"?`3px solid ${h}`:"1px solid #e5e7eb",background:o.type==="backgroundColor"?h:"white",color:o.type==="textColor"?"#000":"inherit",cursor:"pointer",borderRadius:"3px",fontSize:"10px",display:"flex",alignItems:"center",justifyContent:"center"},children:o.type==="textColor"&&P("span",{style:{color:h,fontSize:"12px",fontWeight:"bold",lineHeight:"1"},children:"A"})},h))},`${o.type}-${f}`)}return P("button",{onClick:()=>p(o),title:o.type.charAt(0).toUpperCase()+o.type.slice(1),style:{padding:"6px 12px",border:"none",background:"transparent",cursor:"pointer",borderRadius:"4px",fontWeight:o.type==="bold"?"bold":"normal",fontStyle:o.type==="italic"?"italic":"normal",textDecoration:o.type==="underline"?"underline":o.type==="strikethrough"?"line-through":"none",fontSize:s?`${18-s*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},onMouseEnter:m=>{m.currentTarget.style.background="#f3f4f6"},onMouseLeave:m=>{m.currentTarget.style.background="transparent"},children:o.icon||u},`${o.type}-${f}`)})}),document.body)}import{$getRoot as fe,$isElementNode as te,$isTextNode as oe}from"lexical";import{$isHeadingNode as Ke}from"@lexical/rich-text";function Pe(e){return e.toJSON()}function We(e){let i="";return e.read(()=>{i=fe().getTextContent()}),i}function ne(e,i){let n=(i&1)!==0,t=(i&2)!==0,l=(i&4)!==0,a=(i&8)!==0;return n&&t?e=`***${e}***`:n?e=`**${e}**`:t&&(e=`*${e}*`),l&&(e=`__${e}__`),a&&(e=`~~${e}~~`),e}function Fe(e){let i="";return e.read(()=>{let t=fe().getChildren(),l=a=>{let r="";if(Ke(a)){let c=a.getTag(),g=parseInt(c.replace("h","")),p="#".repeat(g),o=a.getChildren(),f="";for(let u of o)oe(u)?f+=ne(u.getTextContent(),u.getFormat()):te(u)&&(f+=l(u));r+=`${p} ${f}
|
|
2
|
+
import P from"react";import{LexicalComposer as tt}from"@lexical/react/LexicalComposer";import{RichTextPlugin as ot}from"@lexical/react/LexicalRichTextPlugin";import{ContentEditable as nt}from"@lexical/react/LexicalContentEditable";import{HistoryPlugin as rt}from"@lexical/react/LexicalHistoryPlugin";import{LexicalErrorBoundary as at}from"@lexical/react/LexicalErrorBoundary";import{LinkPlugin as lt}from"@lexical/react/LexicalLinkPlugin";import{HeadingNode as it}from"@lexical/rich-text";import{LinkNode as st,AutoLinkNode as dt}from"@lexical/link";import{ParagraphNode as ct,TextNode as pt}from"lexical";import{useLexicalComposerContext as xe}from"@lexical/react/LexicalComposerContext";import{useLexicalComposerContext as He}from"@lexical/react/LexicalComposerContext";import{$getSelection as _,$isRangeSelection as B,FORMAT_TEXT_COMMAND as $e,$createParagraphNode as Me,$isElementNode as pe}from"lexical";import{$patchStyleText as ue}from"@lexical/selection";import{$createHeadingNode as Oe,$isHeadingNode as Ae}from"@lexical/rich-text";import{useCallback as ge,useEffect as V,useState as fe}from"react";import{createPortal as De}from"react-dom";import{useLexicalComposerContext as ye}from"@lexical/react/LexicalComposerContext";import{mergeRegister as Te}from"@lexical/utils";import{$getSelection as D,$isRangeSelection as K,$createParagraphNode as ae,$isElementNode as J,CAN_REDO_COMMAND as Ce,CAN_UNDO_COMMAND as ve,COMMAND_PRIORITY_LOW as G,FORMAT_ELEMENT_COMMAND as j,FORMAT_TEXT_COMMAND as Ne,REDO_COMMAND as Ee,SELECTION_CHANGE_COMMAND as ce,UNDO_COMMAND as ke}from"lexical";import{$patchStyleText as le}from"@lexical/selection";import{$createHeadingNode as ie,$isHeadingNode as q}from"@lexical/rich-text";import{$isLinkNode as se,TOGGLE_LINK_COMMAND as Y}from"@lexical/link";import{useCallback as de,useEffect as U,useState as S,useRef as X}from"react";import{jsx as f,jsxs as $}from"react/jsx-runtime";var Z=["#000000","#ffffff","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#808080","#800000","#008000","#000080","#808000","#800080","#008080"];function z(e){return{undo:"\u21B6",redo:"\u21B7",divider:"",bold:"B",italic:"I",underline:"U",strikethrough:"S",heading1:"H1",heading2:"H2",heading3:"H3",heading4:"H4",heading5:"H5",heading6:"H6",paragraph:"P",alignLeft:"\u2B05",alignCenter:"\u2B0C",alignRight:"\u27A1",alignJustify:"\u2B0C",textColor:"A",backgroundColor:"\u2B1B",fullscreen:"\u26F6",headingDropdown:"Normal",link:"\u{1F517}"}[e]||e}function Le(){return f("div",{className:"luxe-toolbar-divider",style:{width:"1px",height:"24px",margin:"0 4px"}})}function Ie({item:e,onAction:r}){let[o,t]=S(!1),a=X(null),i=e.colors||Z;return U(()=>{let l=c=>{a.current&&!a.current.contains(c.target)&&t(!1)};if(o)return document.addEventListener("mousedown",l),()=>document.removeEventListener("mousedown",l)},[o]),e.color?f("button",{onClick:()=>r(e,e.color),title:`${e.type==="textColor"?"Text":"Background"} Color: ${e.color}`,className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",background:e.type==="backgroundColor"?e.color:void 0,color:e.type==="textColor"?e.color:void 0,borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center"},children:e.icon||z(e.type)}):$("div",{style:{position:"relative"},ref:a,children:[$("button",{onClick:()=>t(!o),title:`${e.type==="textColor"?"Text":"Background"} Color`,className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",minWidth:"40px",height:"32px",display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:[e.icon||f("span",{style:{display:"block",width:"20px",height:"20px",background:e.type==="backgroundColor"?"linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%)":"currentColor",backgroundSize:e.type==="backgroundColor"?"8px 8px":"auto",backgroundPosition:e.type==="backgroundColor"?"0 0, 0 4px, 4px -4px, -4px 0px":"auto"},children:e.type==="textColor"&&f("span",{style:{fontSize:"12px"},children:"A"})}),f("span",{style:{marginLeft:"4px",fontSize:"10px"},children:"\u25BC"})]}),o&&$("div",{className:"luxe-toolbar-panel",style:{position:"absolute",top:"100%",left:0,marginTop:"4px",borderRadius:"6px",padding:"8px",display:"grid",gridTemplateColumns:"repeat(5, 1fr)",gap:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"160px"},children:[i.map(l=>$("button",{onClick:()=>{r(e,l),t(!1)},title:l,style:{width:"24px",height:"24px",borderRadius:"4px",border:e.type==="textColor"?`3px solid ${l}`:"1px solid #e5e7eb",background:e.type==="backgroundColor"?l:"white",color:e.type==="textColor"?"#000":"inherit",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"12px",fontWeight:"bold",position:"relative"},children:[e.type==="textColor"&&f("span",{style:{color:l,fontSize:"14px",fontWeight:"bold",lineHeight:"1"},children:"A"}),e.type==="backgroundColor"&&l==="#ffffff"&&f("span",{style:{color:"#000",fontSize:"10px",border:"1px solid #ccc",width:"12px",height:"12px",display:"block"},children:"\u25A1"})]},l)),f("input",{type:"color",onChange:l=>{r(e,l.target.value),t(!1)},className:"luxe-toolbar-input",style:{gridColumn:"1 / -1",width:"100%",height:"32px",borderRadius:"4px",cursor:"pointer"}})]})]})}function Se({item:e,onAction:r,currentBlockType:o="paragraph"}){let[t,a]=S(!1),i=X(null);U(()=>{let p=x=>{i.current&&!i.current.contains(x.target)&&a(!1)};if(t)return document.addEventListener("mousedown",p),()=>document.removeEventListener("mousedown",p)},[t]);let l=()=>o==="paragraph"?"Normal":o.startsWith("h")?`Heading ${o.replace("h","")}`:"Normal",c=p=>{r(e,void 0,p),a(!1)},m=[{value:"paragraph",label:"Normal"},{value:"h1",label:"Heading 1"},{value:"h2",label:"Heading 2"},{value:"h3",label:"Heading 3"},{value:"h4",label:"Heading 4"},{value:"h5",label:"Heading 5"},{value:"h6",label:"Heading 6"}];return $("div",{style:{position:"relative"},ref:i,children:[$("button",{onClick:()=>a(!t),title:"Heading",className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",minWidth:"100px",height:"32px",display:"flex",alignItems:"center",justifyContent:"space-between",position:"relative",fontSize:o==="paragraph"?"14px":o==="h1"?"20px":o==="h2"?"18px":o==="h3"?"16px":"14px",fontWeight:o!=="paragraph"?"bold":"normal"},children:[f("span",{children:e.label||l()}),f("span",{style:{marginLeft:"8px",fontSize:"10px"},children:"\u25BC"})]}),t&&f("div",{className:"luxe-toolbar-panel",style:{position:"absolute",top:"100%",left:0,marginTop:"4px",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"150px"},children:m.map(p=>f("button",{onClick:()=>c(p.value),className:`luxe-toolbar-panel-item${o===p.value?" luxe-active":""}`,style:{padding:"8px 12px",borderRadius:"4px",fontSize:p.value==="paragraph"?"14px":p.value==="h1"?"20px":p.value==="h2"?"18px":p.value==="h3"?"16px":"14px",fontWeight:p.value!=="paragraph"?"bold":"normal",display:"flex",alignItems:"center"},children:p.label},p.value))})]})}function Re({item:e,onAction:r,editor:o}){let[t,a]=S(!1),[i,l]=S(""),[c,m]=S(!1),p=X(null),x=X(null);U(()=>{let s=()=>{o.getEditorState().read(()=>{let y=D();if(K(y)){let L=y.getNodes(),T=null;for(let M of L){let d=M.getParent();for(;d!==null;){if(se(d)){T=d;break}d=d.getParent()}if(T)break}T&&se(T)?(m(!0),l(T.getURL())):(m(!1),l(""))}else m(!1),l("")})},v=o.registerUpdateListener(()=>{s()}),h=o.registerCommand(ce,()=>(s(),!1),G);return s(),()=>{v(),h()}},[o]),U(()=>{let s=v=>{p.current&&!p.current.contains(v.target)&&a(!1)};if(t)return document.addEventListener("mousedown",s),setTimeout(()=>x.current?.focus(),0),()=>document.removeEventListener("mousedown",s)},[t,c,i]);let n=()=>{if(!i.trim()){o.dispatchCommand(Y,null),a(!1),l("");return}let s=i.trim();!s.startsWith("http://")&&!s.startsWith("https://")&&!s.startsWith("mailto:")&&!s.startsWith("#")&&!s.startsWith("/")&&(s="https://"+s),o.dispatchCommand(Y,s),a(!1),l("")},g=()=>{o.dispatchCommand(Y,null),a(!1),l("")},u=s=>{s.key==="Enter"?(s.preventDefault(),n()):s.key==="Escape"&&(a(!1),l(""))};return $("div",{style:{position:"relative"},ref:p,children:[f("button",{onClick:()=>a(!t),title:c?"Edit Link":"Insert Link",className:`luxe-toolbar-btn${c?" luxe-active":""}`,style:{padding:"6px 12px",borderRadius:"4px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},children:e.icon||z(e.type)}),t&&$("div",{className:"luxe-toolbar-panel",style:{position:"absolute",top:"100%",left:0,marginTop:"4px",borderRadius:"6px",padding:"12px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3,minWidth:"300px"},children:[f("input",{ref:x,type:"text",placeholder:"Enter URL (e.g., https://example.com)",value:i,onChange:s=>l(s.target.value),onKeyDown:u,className:"luxe-toolbar-input",style:{width:"100%",padding:"8px",borderRadius:"4px",fontSize:"14px",marginBottom:"8px",boxSizing:"border-box"}}),$("div",{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[c&&f("button",{onClick:g,className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",fontSize:"14px",color:"#dc2626"},children:"Remove"}),f("button",{onClick:()=>a(!1),className:"luxe-toolbar-select-btn",style:{padding:"6px 12px",borderRadius:"4px",fontSize:"14px"},children:"Cancel"}),f("button",{onClick:n,style:{padding:"6px 12px",border:"none",background:"var(--luxe-primary)",color:"white",cursor:"pointer",borderRadius:"4px",fontSize:"14px"},children:c?"Update":"Insert"})]})]})]})}function we({item:e,active:r=!1,disabled:o=!1,onAction:t,currentBlockType:a}){let l=e.type.startsWith("heading")&&e.type!=="headingDropdown"?parseInt(e.type.replace("heading","")):null,c=e.label||z(e.type);return e.type==="divider"?f(Le,{}):e.type==="headingDropdown"?f(Se,{item:e,onAction:t,currentBlockType:a}):e.type==="textColor"||e.type==="backgroundColor"?f(Ie,{item:e,onAction:t}):f("button",{onClick:()=>t(e),disabled:o,title:e.type.charAt(0).toUpperCase()+e.type.slice(1).replace(/([A-Z])/g," $1").trim(),className:`luxe-toolbar-btn${r?" luxe-active":""}`,style:{padding:"6px 12px",borderRadius:"4px",fontWeight:e.type==="bold"?"bold":"normal",fontStyle:e.type==="italic"?"italic":"normal",textDecoration:e.type==="underline"?"underline":e.type==="strikethrough"?"line-through":"none",fontSize:l?`${18-l*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},children:e.icon||c})}function Q({items:e,onFullscreenToggle:r,isFullscreen:o=!1}){let[t]=ye(),[a,i]=S(!1),[l,c]=S(!1),[m,p]=S(!1),[x,n]=S(!1),[g,u]=S(!1),[s,v]=S(!1),[h,y]=S("paragraph"),L=de(()=>{let d=D();if(K(d)){p(d.hasFormat("bold")),n(d.hasFormat("italic")),u(d.hasFormat("underline")),v(d.hasFormat("strikethrough"));let k=d.anchor.getNode(),R=k.getKey()==="root"?k:k.getTopLevelElementOrThrow(),b=R.getKey();if(t.getElementByKey(b)!==null){let E=q(R)?R.getTag():R.getType();y(E)}}},[t]);U(()=>Te(t.registerUpdateListener(({editorState:d})=>{d.read(()=>{L()})}),t.registerCommand(ce,()=>(L(),!1),G),t.registerCommand(ve,d=>(i(d),!1),G),t.registerCommand(Ce,d=>(c(d),!1),G)),[t,L]);let T=de((d,k,R)=>{let{type:b}=d;if(b==="fullscreen"){r?.();return}if(b==="undo"){t.dispatchCommand(ke,void 0);return}if(b==="redo"){t.dispatchCommand(Ee,void 0);return}if(b==="textColor"&&k){t.update(()=>{let N=D();K(N)&&le(N,{color:k})});return}if(b==="backgroundColor"&&k){t.update(()=>{let N=D();K(N)&&le(N,{"background-color":k})});return}if(b==="bold"||b==="italic"||b==="underline"||b==="strikethrough"){t.dispatchCommand(Ne,b);return}if(b==="alignLeft"){t.dispatchCommand(j,"left");return}if(b==="alignCenter"){t.dispatchCommand(j,"center");return}if(b==="alignRight"){t.dispatchCommand(j,"right");return}if(b==="alignJustify"){t.dispatchCommand(j,"justify");return}if(b==="headingDropdown"&&R){if(R==="paragraph")t.update(()=>{let N=D();if(K(N)){let E=N.anchor.getNode(),C=E.getKey()==="root"?E:E.getTopLevelElementOrThrow(),I=C.getKey();if(t.getElementByKey(I)!==null&&q(C)&&J(C)){let w=ae(),A=C.getChildren();w.append(...A),C.replace(w),w.selectEnd()}}});else{let N=R;t.update(()=>{let E=D();if(K(E)){let C=E.anchor.getNode(),I=C.getKey()==="root"?C:C.getTopLevelElementOrThrow(),O=I.getKey();if(t.getElementByKey(O)!==null&&J(I)){let A=ie(N),W=I.getChildren();A.append(...W),I.replace(A),A.selectEnd()}}})}return}if(b.startsWith("heading")&&b!=="headingDropdown"){let E=`h${parseInt(b.replace("heading",""))}`;t.update(()=>{let C=D();if(K(C)){let I=C.anchor.getNode(),O=I.getKey()==="root"?I:I.getTopLevelElementOrThrow(),w=O.getKey();if(t.getElementByKey(w)!==null&&J(O)){let W=ie(E),be=O.getChildren();W.append(...be),O.replace(W),W.selectEnd()}}});return}if(b==="paragraph"){t.update(()=>{let N=D();if(K(N)){let E=N.anchor.getNode(),C=E.getKey()==="root"?E:E.getTopLevelElementOrThrow(),I=C.getKey();if(t.getElementByKey(I)!==null&&q(C)&&J(C)){let w=ae(),A=C.getChildren();w.append(...A),C.replace(w),w.selectEnd()}}});return}},[t,r]),M=d=>{switch(d){case"undo":return{disabled:!a};case"redo":return{disabled:!l};case"bold":return{active:m};case"italic":return{active:x};case"underline":return{active:g};case"strikethrough":return{active:s};case"fullscreen":return{active:o};case"heading1":return{active:h==="h1"};case"heading2":return{active:h==="h2"};case"heading3":return{active:h==="h3"};case"heading4":return{active:h==="h4"};case"heading5":return{active:h==="h5"};case"heading6":return{active:h==="h6"};case"paragraph":return{active:h==="paragraph"};default:return{}}};return f("div",{className:"luxe-toolbar",style:{display:"flex",gap:"4px",alignItems:"center",borderRadius:"8px 8px 0 0",padding:"8px",flexWrap:"wrap"},children:e.map((d,k)=>{let R=M(d.type);return d.type==="link"?f(Re,{item:d,onAction:T,editor:t},`${d.type}-${k}`):f(we,{item:d,active:R.active,disabled:R.disabled,onAction:T,currentBlockType:h},`${d.type}-${k}`)})})}import{jsx as F}from"react/jsx-runtime";var Ke=[{type:"bold"},{type:"italic"},{type:"underline"}];function Fe(e){let r=["bold","italic","underline","strikethrough","textColor","backgroundColor"];return e.filter(o=>r.includes(o.type))}function ee({enabled:e=!0,items:r,colorScheme:o}){let t=r?Fe(r).slice(0,4):Ke,[a]=He(),[i,l]=fe(null),[c,m]=fe(null);V(()=>{let n=a.getRootElement();n&&m(n)},[a]);let p=ge(()=>{if(!c)return;let n=window.getSelection();if(!n||n.rangeCount===0||n.isCollapsed){l(null);return}try{let g=n.getRangeAt(0);if(!c.contains(g.commonAncestorContainer)){l(null);return}let u=g.getBoundingClientRect();u&&u.width>0&&u.height>0?a.getEditorState().read(()=>{let s=_();s&&B(s)&&!s.isCollapsed()?l({x:u.left+u.width/2,y:u.top-40}):l(null)}):l(null)}catch{l(null)}},[a,c]);V(()=>{if(!c)return;let n=a.registerUpdateListener(()=>{setTimeout(()=>p(),10)});return()=>{n()}},[a,c,p]),V(()=>{let n=()=>{setTimeout(()=>p(),50)},g=()=>{setTimeout(()=>p(),50)},u=()=>{setTimeout(()=>p(),50)};return document.addEventListener("mouseup",n),document.addEventListener("keyup",g),document.addEventListener("selectionchange",u),()=>{document.removeEventListener("mouseup",n),document.removeEventListener("keyup",g),document.removeEventListener("selectionchange",u)}},[p]);let x=ge((n,g)=>{let{type:u}=n;if(u==="textColor"&&g){a.update(()=>{let s=_();B(s)&&ue(s,{color:g})});return}if(u==="backgroundColor"&&g){a.update(()=>{let s=_();B(s)&&ue(s,{"background-color":g})});return}if(u==="bold"||u==="italic"||u==="underline"||u==="strikethrough"){a.dispatchCommand($e,u);return}if(u.startsWith("heading")){let v=`h${parseInt(u.replace("heading",""))}`;a.update(()=>{let h=_();if(B(h)){let y=h.anchor.getNode(),L=y.getKey()==="root"?y:y.getTopLevelElementOrThrow(),T=L.getKey();if(a.getElementByKey(T)!==null&&pe(L)){let d=Oe(v),k=L.getChildren();d.append(...k),L.replace(d),d.selectEnd()}}});return}if(u==="paragraph"){a.update(()=>{let s=_();if(B(s)){let v=s.anchor.getNode(),h=v.getKey()==="root"?v:v.getTopLevelElementOrThrow(),y=h.getKey();if(a.getElementByKey(y)!==null&&Ae(h)&&pe(h)){let T=Me(),M=h.getChildren();T.append(...M),h.replace(T),T.selectEnd()}}});return}},[a]);return!e||!t||t.length===0||!i?null:De(F("div",{className:"luxe-floating-toolbar","data-luxe-theme":o,style:{position:"fixed",top:`${i.y}px`,left:`${i.x}px`,transform:"translateX(-50%)",display:"flex",gap:"4px",borderRadius:"6px",padding:"4px",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1)",zIndex:1e3},children:t.map((n,g)=>{let u=n.label||z(n.type),v=n.type.startsWith("heading")?parseInt(n.type.replace("heading","")):null;if(n.type==="textColor"||n.type==="backgroundColor"){let h=n.colors||Z.slice(0,6);return F("div",{style:{display:"flex",gap:"2px"},children:n.color?F("button",{onClick:()=>x(n,n.color),title:`${n.type==="textColor"?"Text":"Background"} Color`,className:"luxe-toolbar-select-btn",style:{padding:"4px 8px",background:n.type==="backgroundColor"?n.color:void 0,color:n.type==="textColor"?n.color:void 0,borderRadius:"4px",minWidth:"28px",height:"28px"},children:n.type==="textColor"?"A":"\u25A0"}):h.map(y=>F("button",{onClick:()=>x(n,y),title:y,style:{width:"24px",height:"24px",border:n.type==="textColor"?`3px solid ${y}`:"1px solid #e5e7eb",background:n.type==="backgroundColor"?y:void 0,cursor:"pointer",borderRadius:"3px",fontSize:"10px",display:"flex",alignItems:"center",justifyContent:"center"},children:n.type==="textColor"&&F("span",{style:{color:y,fontSize:"12px",fontWeight:"bold",lineHeight:"1"},children:"A"})},y))},`${n.type}-${g}`)}return F("button",{onClick:()=>x(n),title:n.type.charAt(0).toUpperCase()+n.type.slice(1),className:"luxe-toolbar-btn",style:{padding:"6px 12px",borderRadius:"4px",fontWeight:n.type==="bold"?"bold":"normal",fontStyle:n.type==="italic"?"italic":"normal",textDecoration:n.type==="underline"?"underline":n.type==="strikethrough"?"line-through":"none",fontSize:v?`${18-v*2}px`:"14px",minWidth:"32px",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},children:n.icon||u},`${n.type}-${g}`)})}),document.body)}import{createEditor as Pe,ParagraphNode as We,TextNode as Ue}from"lexical";import{$getRoot as re,$isElementNode as te,$isTextNode as oe}from"lexical";import{$isHeadingNode as ze,HeadingNode as _e}from"@lexical/rich-text";import{LinkNode as Be,AutoLinkNode as Je}from"@lexical/link";import{$generateHtmlFromNodes as je}from"@lexical/html";function Ge(e){return e.toJSON()}function Xe(e){let r="";return e.read(()=>{r=re().getTextContent()}),r}function ne(e,r){let o=(r&1)!==0,t=(r&2)!==0,a=(r&4)!==0,i=(r&8)!==0;return o&&t?e=`***${e}***`:o?e=`**${e}**`:t&&(e=`*${e}*`),a&&(e=`__${e}__`),i&&(e=`~~${e}~~`),e}function qe(e){let r="";return e.read(()=>{let t=re().getChildren(),a=i=>{let l="";if(ze(i)){let c=i.getTag(),m=parseInt(c.replace("h","")),p="#".repeat(m),x=i.getChildren(),n="";for(let g of x)oe(g)?n+=ne(g.getTextContent(),g.getFormat()):te(g)&&(n+=a(g));l+=`${p} ${n}
|
|
3
3
|
|
|
4
|
-
`}else if(te(
|
|
4
|
+
`}else if(te(i)){let c=i.getChildren(),m="";for(let x of c)oe(x)?m+=ne(x.getTextContent(),x.getFormat()):te(x)&&(m+=a(x));let p=i.getType();p==="paragraph"?l+=m+`
|
|
5
5
|
|
|
6
|
-
`:
|
|
6
|
+
`:l+=m}else oe(i)&&(l+=ne(i.getTextContent(),i.getFormat()));return l};for(let i of t)r+=a(i)}),r.trim()}function Ye(e){if(!e)return"";try{let r=e.getRootElement();if(!r)return"";let o=r.querySelector('[contenteditable="true"]');if(o)return(o.innerHTML||"").trim()||"";if(r.hasAttribute("contenteditable")&&r.getAttribute("contenteditable")==="true")return r.innerHTML||"";let t=Array.from(r.children).filter(a=>{let i=a.id||"",l=a.className||"";return!i.includes("toolbar")&&!l.includes("toolbar")});if(t.length>0){for(let a of t)if(a.hasAttribute("contenteditable"))return a.innerHTML||"";return t[0].innerHTML||""}return r.innerHTML||""}catch(r){return console.error("Error getting editor DOM:",r),""}}function Ze(e){if(!e||!e.root)return null;let r=(o,t=0)=>{if(!o)return null;let a=o.type||"unknown",i=o.key||"",l=o.children||[],c={type:a,key:i,depth:t,children:[]};return o.tag&&(c.tag=o.tag),o.format!==void 0&&(c.format=o.format),o.text&&(c.text=o.text.substring(0,50)+(o.text.length>50?"...":"")),o.style&&(c.style=o.style),o.indent&&(c.indent=o.indent),o.direction&&(c.direction=o.direction),Array.isArray(l)&&(c.children=l.map(m=>r(m,t+1)).filter(Boolean)),c};return r(e.root)}var Qe=[_e,We,Ue,Be,Je];function he(){return Pe({namespace:"luxe-headless",nodes:Qe,onError:()=>{}})}function Ve(e){if(!e)return"";try{let o=he().parseEditorState(e),t="";return o.read(()=>{t=re().getTextContent()}),t}catch{return""}}function et(e){if(!e)return"";try{let r=he(),o=r.parseEditorState(e),t="";return o.read(()=>{t=je(r,null)}),t}catch{return""}}import{jsx as H,jsxs as ft}from"react/jsx-runtime";var me={paragraph:"luxe-paragraph",heading:{h1:"luxe-heading-h1",h2:"luxe-heading-h2",h3:"luxe-heading-h3",h4:"luxe-heading-h4",h5:"luxe-heading-h5",h6:"luxe-heading-h6"},text:{bold:"luxe-bold",italic:"luxe-italic",underline:"luxe-underline",strikethrough:"luxe-strikethrough"}};function ut({onChange:e,ignoreInitialChange:r}){let[o]=xe(),t=P.useRef(!0);return P.useEffect(()=>o.registerUpdateListener(({editorState:a,prevEditorState:i})=>{if(r&&t.current&&i.isEmpty()){t.current=!1;return}t.current=!1,e(a,o)}),[o,e,r]),null}function gt({initialJSON:e}){let[r]=xe(),o=P.useRef(!1);return P.useEffect(()=>{if(!(!e||o.current))try{let t=r.parseEditorState(e);r.setEditorState(t),o.current=!0}catch(t){console.error("LuxeEditor: Failed to parse initialJSON",t)}},[r,e]),null}function ro({initialConfig:e,initialJSON:r,showFloatingToolbar:o=!0,showToolbar:t=!0,toolbarItems:a,floatingToolbarItems:i,onChange:l,ignoreInitialChange:c=!0,colorScheme:m,children:p}){let[x,n]=P.useState(!1),g=[it,ct,pt,st,dt],u=e.theme?{...me,...e.theme}:me,{theme:s,...v}=e,h=v.onUpdate,y={namespace:"LuxeEditor",theme:u,nodes:g,onError:d=>console.error(d),onUpdate:h,...v},T=a||[{type:"undo"},{type:"redo"},{type:"divider"},{type:"bold"},{type:"italic"},{type:"underline"},{type:"strikethrough"},{type:"divider"},{type:"headingDropdown"},{type:"divider"},{type:"link"}],M=P.useCallback(()=>{n(d=>!d)},[]);return H(tt,{initialConfig:y,children:ft("div",{className:`luxe-editor-container ${x?"luxe-editor-fullscreen":""}`,"data-luxe-theme":m,children:[t&&T&&T.length>0&&H(Q,{items:T,onFullscreenToggle:M,isFullscreen:x}),H(ot,{contentEditable:H(nt,{className:"luxe-input"}),placeholder:H("div",{className:"luxe-placeholder",children:"Start writing..."}),ErrorBoundary:at}),H(rt,{}),H(lt,{}),l&&H(ut,{onChange:l,ignoreInitialChange:c}),r&&H(gt,{initialJSON:r}),o&&H(ee,{enabled:!0,items:i||T,colorScheme:m}),p]})})}export{ee as FloatingToolbarPlugin,ro as LuxeEditor,Q as Toolbar,Ye as getEditorDOM,qe as getEditorFormattedText,Ge as getEditorJSON,Xe as getEditorText,Ze as getEditorTree,et as getHTMLFromJSON,Ve as getTextFromJSON};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "luxe-edit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "A beautiful, customizable rich text editor for React built on Lexical with customizable toolbars and floating toolbar support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@lexical/code": "^0.39.0",
|
|
53
|
+
"@lexical/html": "^0.39.0",
|
|
53
54
|
"@lexical/link": "^0.39.0",
|
|
54
55
|
"@lexical/list": "^0.39.0",
|
|
55
56
|
"@lexical/react": "^0.39.0",
|