@qwanyx/ai-editor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/components/AIEditor.d.ts +15 -0
  2. package/dist/components/AIEditor.d.ts.map +1 -0
  3. package/dist/components/AIEditor.js +154 -0
  4. package/dist/components/AIToolbar.d.ts +22 -0
  5. package/dist/components/AIToolbar.d.ts.map +1 -0
  6. package/dist/components/AIToolbar.js +10 -0
  7. package/dist/components/EditorToolbar.d.ts +8 -0
  8. package/dist/components/EditorToolbar.d.ts.map +1 -0
  9. package/dist/components/EditorToolbar.js +241 -0
  10. package/dist/components/MarkdownPreview.d.ts +7 -0
  11. package/dist/components/MarkdownPreview.d.ts.map +1 -0
  12. package/dist/components/MarkdownPreview.js +40 -0
  13. package/dist/components/PromptModal.d.ts +9 -0
  14. package/dist/components/PromptModal.d.ts.map +1 -0
  15. package/dist/components/PromptModal.js +38 -0
  16. package/dist/components/RichTextEditor.d.ts +15 -0
  17. package/dist/components/RichTextEditor.d.ts.map +1 -0
  18. package/dist/components/RichTextEditor.js +253 -0
  19. package/dist/hooks/useAIEditor.d.ts +15 -0
  20. package/dist/hooks/useAIEditor.d.ts.map +1 -0
  21. package/dist/hooks/useAIEditor.js +46 -0
  22. package/dist/hooks/useSelection.d.ts +12 -0
  23. package/dist/hooks/useSelection.d.ts.map +1 -0
  24. package/dist/hooks/useSelection.js +45 -0
  25. package/dist/index.d.ts +15 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +14 -0
  28. package/dist/nodes/ImageLinkNode.d.ts +48 -0
  29. package/dist/nodes/ImageLinkNode.d.ts.map +1 -0
  30. package/dist/nodes/ImageLinkNode.js +157 -0
  31. package/dist/nodes/ImageNode.d.ts +62 -0
  32. package/dist/nodes/ImageNode.d.ts.map +1 -0
  33. package/dist/nodes/ImageNode.js +487 -0
  34. package/dist/nodes/LinkNode.d.ts +33 -0
  35. package/dist/nodes/LinkNode.d.ts.map +1 -0
  36. package/dist/nodes/LinkNode.js +108 -0
  37. package/dist/plugins/ImageLinkPlugin.d.ts +2 -0
  38. package/dist/plugins/ImageLinkPlugin.d.ts.map +1 -0
  39. package/dist/plugins/ImageLinkPlugin.js +112 -0
  40. package/dist/plugins/InsertObjectPlugin.d.ts +4 -0
  41. package/dist/plugins/InsertObjectPlugin.d.ts.map +1 -0
  42. package/dist/plugins/InsertObjectPlugin.js +464 -0
  43. package/dist/plugins/LinkPlugin.d.ts +2 -0
  44. package/dist/plugins/LinkPlugin.d.ts.map +1 -0
  45. package/dist/plugins/LinkPlugin.js +45 -0
  46. package/package.json +45 -0
@@ -0,0 +1,62 @@
1
+ import { DecoratorNode, DOMConversionMap, DOMExportOutput, LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical';
2
+ import React from 'react';
3
+ export type ImageFloatType = 'none' | 'left' | 'right';
4
+ export interface ImagePayload {
5
+ src: string;
6
+ altText?: string;
7
+ width?: number;
8
+ height?: number;
9
+ copyright?: string;
10
+ photographer?: string;
11
+ comment?: string;
12
+ float?: ImageFloatType;
13
+ }
14
+ export type SerializedImageNode = Spread<{
15
+ src: string;
16
+ altText: string;
17
+ width?: number;
18
+ height?: number;
19
+ copyright?: string;
20
+ photographer?: string;
21
+ comment?: string;
22
+ float?: ImageFloatType;
23
+ }, SerializedLexicalNode>;
24
+ export declare class ImageNode extends DecoratorNode<React.ReactElement> {
25
+ __src: string;
26
+ __altText: string;
27
+ __width?: number;
28
+ __height?: number;
29
+ __copyright?: string;
30
+ __photographer?: string;
31
+ __comment?: string;
32
+ __float?: ImageFloatType;
33
+ static getType(): string;
34
+ static clone(node: ImageNode): ImageNode;
35
+ constructor(src: string, altText?: string, width?: number, height?: number, copyright?: string, photographer?: string, comment?: string, float?: ImageFloatType, key?: NodeKey);
36
+ createDOM(): HTMLElement;
37
+ updateDOM(): false;
38
+ setSrc(src: string): void;
39
+ getSrc(): string;
40
+ setAltText(altText: string): void;
41
+ getAltText(): string;
42
+ setWidth(width: number | undefined): void;
43
+ setHeight(height: number | undefined): void;
44
+ getWidth(): number | undefined;
45
+ getHeight(): number | undefined;
46
+ setCopyright(copyright: string | undefined): void;
47
+ getCopyright(): string | undefined;
48
+ setPhotographer(photographer: string | undefined): void;
49
+ getPhotographer(): string | undefined;
50
+ setComment(comment: string | undefined): void;
51
+ getComment(): string | undefined;
52
+ setFloat(float: ImageFloatType | undefined): void;
53
+ getFloat(): ImageFloatType | undefined;
54
+ static importJSON(serializedNode: SerializedImageNode): ImageNode;
55
+ exportJSON(): SerializedImageNode;
56
+ exportDOM(): DOMExportOutput;
57
+ static importDOM(): DOMConversionMap | null;
58
+ decorate(): React.ReactElement;
59
+ }
60
+ export declare function $createImageNode(payload: ImagePayload): ImageNode;
61
+ export declare function $isImageNode(node: LexicalNode | null | undefined): node is ImageNode;
62
+ //# sourceMappingURL=ImageNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageNode.d.ts","sourceRoot":"","sources":["../../src/nodes/ImageNode.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,487 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { DecoratorNode, $getNodeByKey, } from 'lexical';
4
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
5
+ import { useCallback, useRef, useState, useEffect } from 'react';
6
+ function ImageComponent({ src, altText, width, height, copyright: initialCopyright, photographer: initialPhotographer, comment: initialComment, float: initialFloat, nodeKey, }) {
7
+ const [editor] = useLexicalComposerContext();
8
+ const containerRef = useRef(null);
9
+ const imageRef = useRef(null);
10
+ const [isSelected, setIsSelected] = useState(false);
11
+ const [isResizing, setIsResizing] = useState(false);
12
+ const [showMetadataEditor, setShowMetadataEditor] = useState(false);
13
+ const [showFullscreen, setShowFullscreen] = useState(false);
14
+ const [currentWidth, setCurrentWidth] = useState(width);
15
+ // Local state for display (updated after save)
16
+ const [displayCopyright, setDisplayCopyright] = useState(initialCopyright);
17
+ const [displayPhotographer, setDisplayPhotographer] = useState(initialPhotographer);
18
+ const [displayComment, setDisplayComment] = useState(initialComment);
19
+ const [displayFloat, setDisplayFloat] = useState(initialFloat || 'none');
20
+ // Edit form state
21
+ const [editSrc, setEditSrc] = useState('');
22
+ const [editAltText, setEditAltText] = useState('');
23
+ const [editCopyright, setEditCopyright] = useState('');
24
+ const [editPhotographer, setEditPhotographer] = useState('');
25
+ const [editComment, setEditComment] = useState('');
26
+ const [editFloat, setEditFloat] = useState('none');
27
+ const startX = useRef(0);
28
+ const startWidth = useRef(0);
29
+ // Handle click to select
30
+ const handleClick = useCallback((e) => {
31
+ e.stopPropagation();
32
+ setIsSelected(true);
33
+ }, []);
34
+ // Click outside to deselect
35
+ useEffect(() => {
36
+ const handleClickOutside = (e) => {
37
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
38
+ setIsSelected(false);
39
+ }
40
+ };
41
+ document.addEventListener('mousedown', handleClickOutside);
42
+ return () => document.removeEventListener('mousedown', handleClickOutside);
43
+ }, []);
44
+ // Handle resize start
45
+ const handleResizeStart = useCallback((e) => {
46
+ e.preventDefault();
47
+ e.stopPropagation();
48
+ setIsResizing(true);
49
+ startX.current = e.clientX;
50
+ startWidth.current = imageRef.current?.offsetWidth || currentWidth || 300;
51
+ }, [currentWidth]);
52
+ // Handle resize move
53
+ useEffect(() => {
54
+ if (!isResizing)
55
+ return;
56
+ const handleMouseMove = (e) => {
57
+ const diff = e.clientX - startX.current;
58
+ const newWidth = Math.max(50, startWidth.current + diff);
59
+ setCurrentWidth(newWidth);
60
+ };
61
+ const handleMouseUp = () => {
62
+ setIsResizing(false);
63
+ editor.update(() => {
64
+ const node = $getNodeByKey(nodeKey);
65
+ if (node && $isImageNode(node)) {
66
+ node.setWidth(currentWidth);
67
+ }
68
+ });
69
+ };
70
+ document.addEventListener('mousemove', handleMouseMove);
71
+ document.addEventListener('mouseup', handleMouseUp);
72
+ return () => {
73
+ document.removeEventListener('mousemove', handleMouseMove);
74
+ document.removeEventListener('mouseup', handleMouseUp);
75
+ };
76
+ }, [isResizing, editor, nodeKey, currentWidth]);
77
+ // Open metadata editor
78
+ const openMetadataEditor = useCallback(() => {
79
+ // Use props for src/altText (always current)
80
+ setEditSrc(src);
81
+ setEditAltText(altText);
82
+ // Read other values from node
83
+ editor.getEditorState().read(() => {
84
+ const node = $getNodeByKey(nodeKey);
85
+ if (node && $isImageNode(node)) {
86
+ setEditCopyright(node.getCopyright() || '');
87
+ setEditPhotographer(node.getPhotographer() || '');
88
+ setEditComment(node.getComment() || '');
89
+ setEditFloat(node.getFloat() || 'none');
90
+ }
91
+ });
92
+ setShowMetadataEditor(true);
93
+ }, [editor, nodeKey, src, altText]);
94
+ // Save metadata
95
+ const saveMetadata = useCallback(() => {
96
+ editor.update(() => {
97
+ const node = $getNodeByKey(nodeKey);
98
+ if (node && $isImageNode(node)) {
99
+ if (editSrc)
100
+ node.setSrc(editSrc);
101
+ node.setAltText(editAltText);
102
+ node.setCopyright(editCopyright || undefined);
103
+ node.setPhotographer(editPhotographer || undefined);
104
+ node.setComment(editComment || undefined);
105
+ node.setFloat(editFloat);
106
+ }
107
+ });
108
+ // Update display state
109
+ setDisplayCopyright(editCopyright || undefined);
110
+ setDisplayPhotographer(editPhotographer || undefined);
111
+ setDisplayComment(editComment || undefined);
112
+ setDisplayFloat(editFloat);
113
+ setShowMetadataEditor(false);
114
+ }, [editor, nodeKey, editSrc, editAltText, editCopyright, editPhotographer, editComment, editFloat]);
115
+ // Get float styles
116
+ const getFloatStyles = () => {
117
+ if (displayFloat === 'left') {
118
+ return { float: 'left', marginRight: '16px', marginBottom: '8px' };
119
+ }
120
+ if (displayFloat === 'right') {
121
+ return { float: 'right', marginLeft: '16px', marginBottom: '8px' };
122
+ }
123
+ return { margin: '8px 0' };
124
+ };
125
+ return (_jsxs("span", { ref: containerRef, style: {
126
+ display: 'inline-block',
127
+ position: 'relative',
128
+ ...getFloatStyles(),
129
+ }, onClick: handleClick, children: [_jsx("img", { ref: imageRef, src: src, alt: altText, title: displayComment || undefined, style: {
130
+ maxWidth: '100%',
131
+ height: 'auto',
132
+ width: currentWidth ? `${currentWidth}px` : 'auto',
133
+ display: 'block',
134
+ borderRadius: '4px',
135
+ outline: isSelected ? '2px solid #3b82f6' : 'none',
136
+ cursor: 'pointer',
137
+ }, draggable: false }), (displayCopyright || displayPhotographer) && (_jsxs("div", { style: {
138
+ position: 'absolute',
139
+ bottom: '6px',
140
+ left: '6px',
141
+ color: 'white',
142
+ fontSize: '9px',
143
+ display: 'flex',
144
+ flexDirection: 'column',
145
+ gap: '2px',
146
+ textShadow: '0 1px 3px rgba(0,0,0,0.8), 0 0 8px rgba(0,0,0,0.5)',
147
+ }, children: [displayCopyright && (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: '2px' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '10px' }, children: "copyright" }), displayCopyright] })), displayPhotographer && (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: '2px' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '10px' }, children: "photo_camera" }), displayPhotographer] }))] })), isSelected && (_jsx("button", { onClick: (e) => {
148
+ e.stopPropagation();
149
+ openMetadataEditor();
150
+ }, style: {
151
+ position: 'absolute',
152
+ top: '-6px',
153
+ right: '50px',
154
+ width: '24px',
155
+ height: '24px',
156
+ backgroundColor: '#3b82f6',
157
+ border: '2px solid white',
158
+ borderRadius: '4px',
159
+ cursor: 'pointer',
160
+ display: 'flex',
161
+ alignItems: 'center',
162
+ justifyContent: 'center',
163
+ boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
164
+ }, title: "Modifier les m\u00E9tadonn\u00E9es", children: _jsx("span", { className: "material-icons", style: { fontSize: '14px', color: 'white' }, children: "edit" }) })), isSelected && (_jsx("button", { onClick: (e) => {
165
+ e.stopPropagation();
166
+ setShowFullscreen(true);
167
+ }, style: {
168
+ position: 'absolute',
169
+ top: '-6px',
170
+ right: '20px',
171
+ width: '24px',
172
+ height: '24px',
173
+ backgroundColor: '#3b82f6',
174
+ border: '2px solid white',
175
+ borderRadius: '4px',
176
+ cursor: 'pointer',
177
+ display: 'flex',
178
+ alignItems: 'center',
179
+ justifyContent: 'center',
180
+ boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
181
+ }, title: "Voir en plein \u00E9cran", children: _jsx("span", { className: "material-icons", style: { fontSize: '14px', color: 'white' }, children: "fullscreen" }) })), isSelected && (_jsx("div", { onMouseDown: handleResizeStart, style: {
182
+ position: 'absolute',
183
+ right: '-6px',
184
+ bottom: '-6px',
185
+ width: '12px',
186
+ height: '12px',
187
+ backgroundColor: '#3b82f6',
188
+ borderRadius: '2px',
189
+ cursor: 'se-resize',
190
+ border: '2px solid white',
191
+ boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
192
+ } })), showMetadataEditor && (_jsx("div", { style: {
193
+ position: 'fixed',
194
+ inset: 0,
195
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
196
+ display: 'flex',
197
+ alignItems: 'center',
198
+ justifyContent: 'center',
199
+ zIndex: 100000,
200
+ }, onClick: () => setShowMetadataEditor(false), children: _jsxs("div", { onClick: (e) => e.stopPropagation(), style: {
201
+ backgroundColor: 'white',
202
+ borderRadius: '12px',
203
+ padding: '24px',
204
+ boxShadow: '0 25px 50px rgba(0,0,0,0.25)',
205
+ minWidth: '360px',
206
+ maxWidth: '450px',
207
+ }, children: [_jsx("h3", { style: { margin: '0 0 20px 0', fontSize: '18px', fontWeight: 600, color: '#111827' }, children: "Propri\u00E9t\u00E9s de l'image" }), _jsxs("div", { style: { marginBottom: '16px' }, children: [_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "link" }), "URL de l'image"] }), _jsx("input", { type: "url", value: editSrc, onChange: (e) => setEditSrc(e.target.value), placeholder: "https://example.com/image.jpg", style: {
208
+ width: '100%',
209
+ padding: '10px 12px',
210
+ border: '1px solid #d1d5db',
211
+ borderRadius: '8px',
212
+ fontSize: '14px',
213
+ boxSizing: 'border-box',
214
+ outline: 'none',
215
+ }, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), _jsxs("div", { style: { marginBottom: '16px' }, children: [_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "description" }), "Texte alternatif"] }), _jsx("input", { type: "text", value: editAltText, onChange: (e) => setEditAltText(e.target.value), placeholder: "Description de l'image", style: {
216
+ width: '100%',
217
+ padding: '10px 12px',
218
+ border: '1px solid #d1d5db',
219
+ borderRadius: '8px',
220
+ fontSize: '14px',
221
+ boxSizing: 'border-box',
222
+ outline: 'none',
223
+ }, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), _jsx("hr", { style: { border: 'none', borderTop: '1px solid #e5e7eb', margin: '20px 0' } }), _jsxs("div", { style: { marginBottom: '16px' }, children: [_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "photo_camera" }), "Photographe"] }), _jsx("input", { type: "text", value: editPhotographer, onChange: (e) => setEditPhotographer(e.target.value), placeholder: "Nom du photographe", autoFocus: true, style: {
224
+ width: '100%',
225
+ padding: '10px 12px',
226
+ border: '1px solid #d1d5db',
227
+ borderRadius: '8px',
228
+ fontSize: '14px',
229
+ boxSizing: 'border-box',
230
+ outline: 'none',
231
+ }, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), _jsxs("div", { style: { marginBottom: '16px' }, children: [_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "copyright" }), "Copyright"] }), _jsx("input", { type: "text", value: editCopyright, onChange: (e) => setEditCopyright(e.target.value), placeholder: "Ex: \u00A9 2024 Nom", style: {
232
+ width: '100%',
233
+ padding: '10px 12px',
234
+ border: '1px solid #d1d5db',
235
+ borderRadius: '8px',
236
+ fontSize: '14px',
237
+ boxSizing: 'border-box',
238
+ outline: 'none',
239
+ }, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), _jsxs("div", { style: { marginBottom: '16px' }, children: [_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "chat" }), "Commentaire (tooltip)"] }), _jsx("textarea", { value: editComment, onChange: (e) => setEditComment(e.target.value), placeholder: "Commentaire affich\u00E9 au survol de l'image", rows: 3, style: {
240
+ width: '100%',
241
+ padding: '10px 12px',
242
+ border: '1px solid #d1d5db',
243
+ borderRadius: '8px',
244
+ fontSize: '14px',
245
+ resize: 'vertical',
246
+ boxSizing: 'border-box',
247
+ outline: 'none',
248
+ fontFamily: 'inherit',
249
+ }, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), _jsxs("div", { style: { marginBottom: '24px' }, children: [_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "wrap_text" }), "Habillage du texte"] }), _jsxs("div", { style: { display: 'flex', gap: '8px', width: '100%' }, children: [_jsx("button", { type: "button", onClick: () => setEditFloat('none'), style: {
250
+ flex: 1,
251
+ minWidth: 0,
252
+ padding: '12px',
253
+ border: '1px solid',
254
+ borderColor: editFloat === 'none' ? '#3b82f6' : '#d1d5db',
255
+ backgroundColor: editFloat === 'none' ? '#eff6ff' : 'white',
256
+ color: editFloat === 'none' ? '#1d4ed8' : '#374151',
257
+ borderRadius: '6px',
258
+ cursor: 'pointer',
259
+ display: 'flex',
260
+ flexDirection: 'column',
261
+ alignItems: 'center',
262
+ justifyContent: 'center',
263
+ gap: '4px',
264
+ }, title: "Aucun habillage", children: _jsx("span", { className: "material-icons", style: { fontSize: '24px' }, children: "image" }) }), _jsx("button", { type: "button", onClick: () => setEditFloat('left'), style: {
265
+ flex: 1,
266
+ minWidth: 0,
267
+ padding: '12px',
268
+ border: '1px solid',
269
+ borderColor: editFloat === 'left' ? '#3b82f6' : '#d1d5db',
270
+ backgroundColor: editFloat === 'left' ? '#eff6ff' : 'white',
271
+ color: editFloat === 'left' ? '#1d4ed8' : '#374151',
272
+ borderRadius: '6px',
273
+ cursor: 'pointer',
274
+ display: 'flex',
275
+ flexDirection: 'column',
276
+ alignItems: 'center',
277
+ justifyContent: 'center',
278
+ gap: '4px',
279
+ }, title: "Image \u00E0 gauche", children: _jsx("span", { className: "material-icons", style: { fontSize: '24px' }, children: "west" }) }), _jsx("button", { type: "button", onClick: () => setEditFloat('right'), style: {
280
+ flex: 1,
281
+ minWidth: 0,
282
+ padding: '12px',
283
+ border: '1px solid',
284
+ borderColor: editFloat === 'right' ? '#3b82f6' : '#d1d5db',
285
+ backgroundColor: editFloat === 'right' ? '#eff6ff' : 'white',
286
+ color: editFloat === 'right' ? '#1d4ed8' : '#374151',
287
+ borderRadius: '6px',
288
+ cursor: 'pointer',
289
+ display: 'flex',
290
+ flexDirection: 'column',
291
+ alignItems: 'center',
292
+ justifyContent: 'center',
293
+ gap: '4px',
294
+ }, title: "Image \u00E0 droite", children: _jsx("span", { className: "material-icons", style: { fontSize: '24px' }, children: "east" }) })] })] }), _jsxs("div", { style: { display: 'flex', gap: '12px', justifyContent: 'flex-end' }, children: [_jsx("button", { onClick: () => setShowMetadataEditor(false), style: {
295
+ padding: '10px 20px',
296
+ border: '1px solid #d1d5db',
297
+ backgroundColor: 'white',
298
+ borderRadius: '8px',
299
+ fontSize: '14px',
300
+ fontWeight: 500,
301
+ cursor: 'pointer',
302
+ color: '#374151',
303
+ }, children: "Annuler" }), _jsx("button", { onClick: saveMetadata, style: {
304
+ padding: '10px 20px',
305
+ border: 'none',
306
+ backgroundColor: '#3b82f6',
307
+ color: 'white',
308
+ borderRadius: '8px',
309
+ fontSize: '14px',
310
+ fontWeight: 500,
311
+ cursor: 'pointer',
312
+ }, children: "Enregistrer" })] })] }) })), showFullscreen && (_jsxs("div", { style: {
313
+ position: 'fixed',
314
+ inset: 0,
315
+ backgroundColor: 'rgba(0, 0, 0, 0.9)',
316
+ display: 'flex',
317
+ alignItems: 'center',
318
+ justifyContent: 'center',
319
+ zIndex: 100000,
320
+ cursor: 'pointer',
321
+ }, onClick: () => setShowFullscreen(false), children: [_jsx("button", { onClick: () => setShowFullscreen(false), style: {
322
+ position: 'absolute',
323
+ top: '20px',
324
+ right: '20px',
325
+ width: '40px',
326
+ height: '40px',
327
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
328
+ border: 'none',
329
+ borderRadius: '50%',
330
+ cursor: 'pointer',
331
+ display: 'flex',
332
+ alignItems: 'center',
333
+ justifyContent: 'center',
334
+ transition: 'background-color 0.2s',
335
+ }, onMouseEnter: (e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)', onMouseLeave: (e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)', title: "Fermer", children: _jsx("span", { className: "material-icons", style: { fontSize: '24px', color: 'white' }, children: "close" }) }), _jsx("img", { src: src, alt: altText, style: {
336
+ maxWidth: '95vw',
337
+ maxHeight: '95vh',
338
+ objectFit: 'contain',
339
+ borderRadius: '4px',
340
+ boxShadow: '0 25px 50px rgba(0,0,0,0.5)',
341
+ }, onClick: (e) => e.stopPropagation() }), (displayCopyright || displayPhotographer || displayComment) && (_jsxs("div", { style: {
342
+ position: 'absolute',
343
+ bottom: '20px',
344
+ left: '50%',
345
+ transform: 'translateX(-50%)',
346
+ color: 'white',
347
+ fontSize: '14px',
348
+ textAlign: 'center',
349
+ textShadow: '0 2px 4px rgba(0,0,0,0.8)',
350
+ maxWidth: '80vw',
351
+ }, children: [displayComment && (_jsx("div", { style: { marginBottom: '8px', fontSize: '16px' }, children: displayComment })), _jsxs("div", { style: { display: 'flex', gap: '16px', justifyContent: 'center', fontSize: '12px', opacity: 0.8 }, children: [displayCopyright && (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '14px' }, children: "copyright" }), displayCopyright] })), displayPhotographer && (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [_jsx("span", { className: "material-icons", style: { fontSize: '14px' }, children: "photo_camera" }), displayPhotographer] }))] })] }))] }))] }));
352
+ }
353
+ export class ImageNode extends DecoratorNode {
354
+ static getType() {
355
+ return 'image';
356
+ }
357
+ static clone(node) {
358
+ return new ImageNode(node.__src, node.__altText, node.__width, node.__height, node.__copyright, node.__photographer, node.__comment, node.__float, node.__key);
359
+ }
360
+ constructor(src, altText = '', width, height, copyright, photographer, comment, float, key) {
361
+ super(key);
362
+ this.__src = src;
363
+ this.__altText = altText;
364
+ this.__width = width;
365
+ this.__height = height;
366
+ this.__copyright = copyright;
367
+ this.__photographer = photographer;
368
+ this.__comment = comment;
369
+ this.__float = float;
370
+ }
371
+ createDOM() {
372
+ const span = document.createElement('span');
373
+ span.style.display = 'block';
374
+ return span;
375
+ }
376
+ updateDOM() {
377
+ return false;
378
+ }
379
+ setSrc(src) {
380
+ const writable = this.getWritable();
381
+ writable.__src = src;
382
+ }
383
+ getSrc() {
384
+ return this.__src;
385
+ }
386
+ setAltText(altText) {
387
+ const writable = this.getWritable();
388
+ writable.__altText = altText;
389
+ }
390
+ getAltText() {
391
+ return this.__altText;
392
+ }
393
+ setWidth(width) {
394
+ const writable = this.getWritable();
395
+ writable.__width = width;
396
+ }
397
+ setHeight(height) {
398
+ const writable = this.getWritable();
399
+ writable.__height = height;
400
+ }
401
+ getWidth() {
402
+ return this.__width;
403
+ }
404
+ getHeight() {
405
+ return this.__height;
406
+ }
407
+ setCopyright(copyright) {
408
+ const writable = this.getWritable();
409
+ writable.__copyright = copyright;
410
+ }
411
+ getCopyright() {
412
+ return this.__copyright;
413
+ }
414
+ setPhotographer(photographer) {
415
+ const writable = this.getWritable();
416
+ writable.__photographer = photographer;
417
+ }
418
+ getPhotographer() {
419
+ return this.__photographer;
420
+ }
421
+ setComment(comment) {
422
+ const writable = this.getWritable();
423
+ writable.__comment = comment;
424
+ }
425
+ getComment() {
426
+ return this.__comment;
427
+ }
428
+ setFloat(float) {
429
+ const writable = this.getWritable();
430
+ writable.__float = float;
431
+ }
432
+ getFloat() {
433
+ return this.__float;
434
+ }
435
+ static importJSON(serializedNode) {
436
+ const { src, altText, width, height, copyright, photographer, comment, float } = serializedNode;
437
+ return $createImageNode({ src, altText, width, height, copyright, photographer, comment, float });
438
+ }
439
+ exportJSON() {
440
+ return {
441
+ type: 'image',
442
+ version: 1,
443
+ src: this.__src,
444
+ altText: this.__altText,
445
+ width: this.__width,
446
+ height: this.__height,
447
+ copyright: this.__copyright,
448
+ photographer: this.__photographer,
449
+ comment: this.__comment,
450
+ float: this.__float,
451
+ };
452
+ }
453
+ exportDOM() {
454
+ const img = document.createElement('img');
455
+ img.src = this.__src;
456
+ img.alt = this.__altText;
457
+ if (this.__width)
458
+ img.width = this.__width;
459
+ if (this.__height)
460
+ img.height = this.__height;
461
+ return { element: img };
462
+ }
463
+ static importDOM() {
464
+ return {
465
+ img: () => ({
466
+ conversion: (domNode) => {
467
+ const img = domNode;
468
+ const src = img.src;
469
+ const altText = img.alt || '';
470
+ const width = img.width || undefined;
471
+ const height = img.height || undefined;
472
+ return { node: $createImageNode({ src, altText, width, height }) };
473
+ },
474
+ priority: 0,
475
+ }),
476
+ };
477
+ }
478
+ decorate() {
479
+ return (_jsx(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, copyright: this.__copyright, photographer: this.__photographer, comment: this.__comment, float: this.__float, nodeKey: this.__key }));
480
+ }
481
+ }
482
+ export function $createImageNode(payload) {
483
+ return new ImageNode(payload.src, payload.altText || '', payload.width, payload.height, payload.copyright, payload.photographer, payload.comment, payload.float);
484
+ }
485
+ export function $isImageNode(node) {
486
+ return node instanceof ImageNode;
487
+ }
@@ -0,0 +1,33 @@
1
+ import { ElementNode, LexicalNode, NodeKey, RangeSelection, SerializedElementNode, Spread } from 'lexical';
2
+ export interface SimpleLinkPayload {
3
+ url: string;
4
+ title?: string;
5
+ }
6
+ export type SerializedSimpleLinkNode = Spread<{
7
+ url: string;
8
+ title?: string;
9
+ }, SerializedElementNode>;
10
+ export declare class SimpleLinkNode extends ElementNode {
11
+ __url: string;
12
+ __title?: string;
13
+ static getType(): string;
14
+ static clone(node: SimpleLinkNode): SimpleLinkNode;
15
+ constructor(url: string, title?: string, key?: NodeKey);
16
+ createDOM(): HTMLElement;
17
+ updateDOM(prevNode: SimpleLinkNode, dom: HTMLAnchorElement): boolean;
18
+ getUrl(): string;
19
+ setUrl(url: string): void;
20
+ getTitle(): string | undefined;
21
+ setTitle(title: string | undefined): void;
22
+ static importJSON(serializedNode: SerializedSimpleLinkNode): SimpleLinkNode;
23
+ exportJSON(): SerializedSimpleLinkNode;
24
+ canInsertTextBefore(): boolean;
25
+ canInsertTextAfter(): boolean;
26
+ canBeEmpty(): boolean;
27
+ isInline(): boolean;
28
+ extractWithChild(): boolean;
29
+ }
30
+ export declare function $createSimpleLinkNode(payload: SimpleLinkPayload): SimpleLinkNode;
31
+ export declare function $isSimpleLinkNode(node: LexicalNode | null | undefined): node is SimpleLinkNode;
32
+ export declare function $wrapSelectionInSimpleLink(selection: RangeSelection, url: string, title?: string): void;
33
+ //# sourceMappingURL=LinkNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkNode.d.ts","sourceRoot":"","sources":["../../src/nodes/LinkNode.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,WAAW,EACX,WAAW,EACX,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAC3C;IACE,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,EACD,qBAAqB,CACtB,CAAA;AAED,qBAAa,cAAe,SAAQ,WAAW;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc;gBAItC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAMtD,SAAS,IAAI,WAAW;IAcxB,SAAS,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO;IAcpE,MAAM,IAAI,MAAM;IAIhB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKzC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,wBAAwB,GAAG,cAAc;IAW3E,UAAU,IAAI,wBAAwB;IAUtC,mBAAmB,IAAI,OAAO;IAI9B,kBAAkB,IAAI,OAAO;IAI7B,UAAU,IAAI,OAAO;IAIrB,QAAQ,IAAI,OAAO;IAInB,gBAAgB,IAAI,OAAO;CAG5B;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAEhF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,cAAc,CAE9F;AAGD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,cAAc,EACzB,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAYN"}