@qwanyx/ai-editor 1.2.0 → 1.3.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.
- package/dist/components/AIEditor.js +37 -34
- package/dist/components/AIToolbar.js +13 -7
- package/dist/components/EditorToolbar.js +85 -82
- package/dist/components/MarkdownPreview.js +8 -5
- package/dist/components/PromptModal.js +13 -10
- package/dist/components/RichTextEditor.d.ts.map +1 -1
- package/dist/components/RichTextEditor.js +92 -55
- package/dist/components/RichTextViewer.d.ts.map +1 -1
- package/dist/components/RichTextViewer.js +33 -29
- package/dist/context/EditorModeContext.d.ts +12 -0
- package/dist/context/EditorModeContext.d.ts.map +1 -0
- package/dist/context/EditorModeContext.js +15 -0
- package/dist/hooks/useAIEditor.js +17 -14
- package/dist/hooks/useSelection.js +9 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -10
- package/dist/nodes/ImageLinkNode.js +17 -10
- package/dist/nodes/ImageNode.d.ts.map +1 -1
- package/dist/nodes/ImageNode.js +84 -69
- package/dist/nodes/LinkNode.js +13 -6
- package/dist/plugins/ImageLinkPlugin.d.ts.map +1 -1
- package/dist/plugins/ImageLinkPlugin.js +46 -38
- package/dist/plugins/InsertObjectPlugin.js +74 -70
- package/dist/plugins/LinkPlugin.js +16 -13
- package/package.json +2 -3
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
'use client';
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ImageLinkNode = void 0;
|
|
5
|
+
exports.$createImageLinkNode = $createImageLinkNode;
|
|
6
|
+
exports.$isImageLinkNode = $isImageLinkNode;
|
|
7
|
+
exports.$wrapSelectionInImageLink = $wrapSelectionInImageLink;
|
|
8
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
|
+
const lexical_1 = require("lexical");
|
|
4
10
|
// Fullscreen modal component for the image link
|
|
5
11
|
function ImageLinkFullscreen({ url, altText, onClose, }) {
|
|
6
|
-
return (
|
|
12
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
7
13
|
position: 'fixed',
|
|
8
14
|
inset: 0,
|
|
9
15
|
backgroundColor: 'rgba(0, 0, 0, 0.9)',
|
|
@@ -12,7 +18,7 @@ function ImageLinkFullscreen({ url, altText, onClose, }) {
|
|
|
12
18
|
justifyContent: 'center',
|
|
13
19
|
zIndex: 100000,
|
|
14
20
|
cursor: 'pointer',
|
|
15
|
-
}, onClick: onClose, children: [
|
|
21
|
+
}, onClick: onClose, children: [(0, jsx_runtime_1.jsx)("button", { onClick: onClose, style: {
|
|
16
22
|
position: 'absolute',
|
|
17
23
|
top: '20px',
|
|
18
24
|
right: '20px',
|
|
@@ -26,7 +32,7 @@ function ImageLinkFullscreen({ url, altText, onClose, }) {
|
|
|
26
32
|
alignItems: 'center',
|
|
27
33
|
justifyContent: 'center',
|
|
28
34
|
transition: 'background-color 0.2s',
|
|
29
|
-
}, 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:
|
|
35
|
+
}, 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: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '24px', color: 'white' }, children: "close" }) }), (0, jsx_runtime_1.jsx)("img", { src: url, alt: altText || '', style: {
|
|
30
36
|
maxWidth: '95vw',
|
|
31
37
|
maxHeight: '95vh',
|
|
32
38
|
objectFit: 'contain',
|
|
@@ -34,7 +40,7 @@ function ImageLinkFullscreen({ url, altText, onClose, }) {
|
|
|
34
40
|
boxShadow: '0 25px 50px rgba(0,0,0,0.5)',
|
|
35
41
|
}, onClick: (e) => e.stopPropagation() })] }));
|
|
36
42
|
}
|
|
37
|
-
|
|
43
|
+
class ImageLinkNode extends lexical_1.ElementNode {
|
|
38
44
|
static getType() {
|
|
39
45
|
return 'image-link';
|
|
40
46
|
}
|
|
@@ -137,14 +143,15 @@ export class ImageLinkNode extends ElementNode {
|
|
|
137
143
|
return true;
|
|
138
144
|
}
|
|
139
145
|
}
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
exports.ImageLinkNode = ImageLinkNode;
|
|
147
|
+
function $createImageLinkNode(payload) {
|
|
148
|
+
return (0, lexical_1.$applyNodeReplacement)(new ImageLinkNode(payload.url, payload.altText, payload.copyright, payload.photographer, payload.comment));
|
|
142
149
|
}
|
|
143
|
-
|
|
150
|
+
function $isImageLinkNode(node) {
|
|
144
151
|
return node instanceof ImageLinkNode;
|
|
145
152
|
}
|
|
146
153
|
// Helper to wrap selection in an image link
|
|
147
|
-
|
|
154
|
+
function $wrapSelectionInImageLink(selection, url, altText, copyright, photographer, comment) {
|
|
148
155
|
const nodes = selection.extract();
|
|
149
156
|
const imageLinkNode = $createImageLinkNode({ url, altText, copyright, photographer, comment });
|
|
150
157
|
if (nodes.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageNode.d.ts","sourceRoot":"","sources":["../../src/nodes/ImageNode.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,MAAM,EAEP,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAmD,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"ImageNode.d.ts","sourceRoot":"","sources":["../../src/nodes/ImageNode.tsx"],"names":[],"mappings":"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"}
|
package/dist/nodes/ImageNode.js
CHANGED
|
@@ -1,38 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
'use client';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ImageNode = void 0;
|
|
5
|
+
exports.$createImageNode = $createImageNode;
|
|
6
|
+
exports.$isImageNode = $isImageNode;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const lexical_1 = require("lexical");
|
|
9
|
+
const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext");
|
|
10
|
+
const react_1 = require("react");
|
|
11
|
+
const EditorModeContext_1 = require("../context/EditorModeContext");
|
|
6
12
|
function ImageComponent({ src, altText, width, height, copyright: initialCopyright, photographer: initialPhotographer, comment: initialComment, float: initialFloat, nodeKey, }) {
|
|
7
|
-
const [editor] = useLexicalComposerContext();
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const [
|
|
12
|
-
const [
|
|
13
|
-
const [
|
|
14
|
-
const [
|
|
13
|
+
const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
|
|
14
|
+
const { isViewer } = (0, EditorModeContext_1.useEditorMode)();
|
|
15
|
+
const containerRef = (0, react_1.useRef)(null);
|
|
16
|
+
const imageRef = (0, react_1.useRef)(null);
|
|
17
|
+
const [isSelected, setIsSelected] = (0, react_1.useState)(false);
|
|
18
|
+
const [isHovered, setIsHovered] = (0, react_1.useState)(false);
|
|
19
|
+
const [isResizing, setIsResizing] = (0, react_1.useState)(false);
|
|
20
|
+
const [showMetadataEditor, setShowMetadataEditor] = (0, react_1.useState)(false);
|
|
21
|
+
const [showFullscreen, setShowFullscreen] = (0, react_1.useState)(false);
|
|
22
|
+
const [currentWidth, setCurrentWidth] = (0, react_1.useState)(width);
|
|
15
23
|
// 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');
|
|
24
|
+
const [displayCopyright, setDisplayCopyright] = (0, react_1.useState)(initialCopyright);
|
|
25
|
+
const [displayPhotographer, setDisplayPhotographer] = (0, react_1.useState)(initialPhotographer);
|
|
26
|
+
const [displayComment, setDisplayComment] = (0, react_1.useState)(initialComment);
|
|
27
|
+
const [displayFloat, setDisplayFloat] = (0, react_1.useState)(initialFloat || 'none');
|
|
20
28
|
// 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) => {
|
|
29
|
+
const [editSrc, setEditSrc] = (0, react_1.useState)('');
|
|
30
|
+
const [editAltText, setEditAltText] = (0, react_1.useState)('');
|
|
31
|
+
const [editCopyright, setEditCopyright] = (0, react_1.useState)('');
|
|
32
|
+
const [editPhotographer, setEditPhotographer] = (0, react_1.useState)('');
|
|
33
|
+
const [editComment, setEditComment] = (0, react_1.useState)('');
|
|
34
|
+
const [editFloat, setEditFloat] = (0, react_1.useState)('none');
|
|
35
|
+
const startX = (0, react_1.useRef)(0);
|
|
36
|
+
const startWidth = (0, react_1.useRef)(0);
|
|
37
|
+
// Handle click to select (or open fullscreen in viewer mode)
|
|
38
|
+
const handleClick = (0, react_1.useCallback)((e) => {
|
|
31
39
|
e.stopPropagation();
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
if (isViewer) {
|
|
41
|
+
// In viewer mode, click opens fullscreen directly
|
|
42
|
+
setShowFullscreen(true);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
setIsSelected(true);
|
|
46
|
+
}
|
|
47
|
+
}, [isViewer]);
|
|
34
48
|
// Click outside to deselect
|
|
35
|
-
useEffect(() => {
|
|
49
|
+
(0, react_1.useEffect)(() => {
|
|
36
50
|
const handleClickOutside = (e) => {
|
|
37
51
|
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
38
52
|
setIsSelected(false);
|
|
@@ -42,7 +56,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
42
56
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
43
57
|
}, []);
|
|
44
58
|
// Handle resize start
|
|
45
|
-
const handleResizeStart = useCallback((e) => {
|
|
59
|
+
const handleResizeStart = (0, react_1.useCallback)((e) => {
|
|
46
60
|
e.preventDefault();
|
|
47
61
|
e.stopPropagation();
|
|
48
62
|
setIsResizing(true);
|
|
@@ -50,7 +64,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
50
64
|
startWidth.current = imageRef.current?.offsetWidth || currentWidth || 300;
|
|
51
65
|
}, [currentWidth]);
|
|
52
66
|
// Handle resize move
|
|
53
|
-
useEffect(() => {
|
|
67
|
+
(0, react_1.useEffect)(() => {
|
|
54
68
|
if (!isResizing)
|
|
55
69
|
return;
|
|
56
70
|
const handleMouseMove = (e) => {
|
|
@@ -61,7 +75,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
61
75
|
const handleMouseUp = () => {
|
|
62
76
|
setIsResizing(false);
|
|
63
77
|
editor.update(() => {
|
|
64
|
-
const node =
|
|
78
|
+
const node = (0, lexical_1.$getNodeByKey)(nodeKey);
|
|
65
79
|
if (node && $isImageNode(node)) {
|
|
66
80
|
node.setWidth(currentWidth);
|
|
67
81
|
}
|
|
@@ -75,13 +89,13 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
75
89
|
};
|
|
76
90
|
}, [isResizing, editor, nodeKey, currentWidth]);
|
|
77
91
|
// Open metadata editor
|
|
78
|
-
const openMetadataEditor = useCallback(() => {
|
|
92
|
+
const openMetadataEditor = (0, react_1.useCallback)(() => {
|
|
79
93
|
// Use props for src/altText (always current)
|
|
80
94
|
setEditSrc(src);
|
|
81
95
|
setEditAltText(altText);
|
|
82
96
|
// Read other values from node
|
|
83
97
|
editor.getEditorState().read(() => {
|
|
84
|
-
const node =
|
|
98
|
+
const node = (0, lexical_1.$getNodeByKey)(nodeKey);
|
|
85
99
|
if (node && $isImageNode(node)) {
|
|
86
100
|
setEditCopyright(node.getCopyright() || '');
|
|
87
101
|
setEditPhotographer(node.getPhotographer() || '');
|
|
@@ -92,9 +106,9 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
92
106
|
setShowMetadataEditor(true);
|
|
93
107
|
}, [editor, nodeKey, src, altText]);
|
|
94
108
|
// Save metadata
|
|
95
|
-
const saveMetadata = useCallback(() => {
|
|
109
|
+
const saveMetadata = (0, react_1.useCallback)(() => {
|
|
96
110
|
editor.update(() => {
|
|
97
|
-
const node =
|
|
111
|
+
const node = (0, lexical_1.$getNodeByKey)(nodeKey);
|
|
98
112
|
if (node && $isImageNode(node)) {
|
|
99
113
|
if (editSrc)
|
|
100
114
|
node.setSrc(editSrc);
|
|
@@ -122,19 +136,19 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
122
136
|
}
|
|
123
137
|
return { margin: '8px 0' };
|
|
124
138
|
};
|
|
125
|
-
return (
|
|
139
|
+
return ((0, jsx_runtime_1.jsxs)("span", { ref: containerRef, style: {
|
|
126
140
|
display: 'inline-block',
|
|
127
141
|
position: 'relative',
|
|
128
142
|
...getFloatStyles(),
|
|
129
|
-
}, onClick: handleClick, children: [
|
|
143
|
+
}, onClick: handleClick, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [(0, jsx_runtime_1.jsx)("img", { ref: imageRef, src: src, alt: altText, title: displayComment || undefined, style: {
|
|
130
144
|
maxWidth: '100%',
|
|
131
145
|
height: 'auto',
|
|
132
146
|
width: currentWidth ? `${currentWidth}px` : 'auto',
|
|
133
147
|
display: 'block',
|
|
134
148
|
borderRadius: '4px',
|
|
135
|
-
outline: isSelected ? '2px solid #3b82f6' : 'none',
|
|
149
|
+
outline: !isViewer && isSelected ? '2px solid #3b82f6' : 'none',
|
|
136
150
|
cursor: 'pointer',
|
|
137
|
-
}, draggable: false }), (displayCopyright || displayPhotographer) && (
|
|
151
|
+
}, draggable: false }), (displayCopyright || displayPhotographer) && ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
138
152
|
position: 'absolute',
|
|
139
153
|
bottom: '6px',
|
|
140
154
|
left: '6px',
|
|
@@ -144,7 +158,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
144
158
|
flexDirection: 'column',
|
|
145
159
|
gap: '2px',
|
|
146
160
|
textShadow: '0 1px 3px rgba(0,0,0,0.8), 0 0 8px rgba(0,0,0,0.5)',
|
|
147
|
-
}, children: [displayCopyright && (
|
|
161
|
+
}, children: [displayCopyright && ((0, jsx_runtime_1.jsxs)("span", { style: { display: 'flex', alignItems: 'center', gap: '2px' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '10px' }, children: "copyright" }), displayCopyright] })), displayPhotographer && ((0, jsx_runtime_1.jsxs)("span", { style: { display: 'flex', alignItems: 'center', gap: '2px' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '10px' }, children: "photo_camera" }), displayPhotographer] }))] })), !isViewer && isSelected && ((0, jsx_runtime_1.jsx)("button", { onClick: (e) => {
|
|
148
162
|
e.stopPropagation();
|
|
149
163
|
openMetadataEditor();
|
|
150
164
|
}, style: {
|
|
@@ -161,24 +175,24 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
161
175
|
alignItems: 'center',
|
|
162
176
|
justifyContent: 'center',
|
|
163
177
|
boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
|
|
164
|
-
}, title: "Modifier les m\u00E9tadonn\u00E9es", children:
|
|
178
|
+
}, title: "Modifier les m\u00E9tadonn\u00E9es", children: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '14px', color: 'white' }, children: "edit" }) })), ((!isViewer && isSelected) || (isViewer && isHovered)) && ((0, jsx_runtime_1.jsx)("button", { onClick: (e) => {
|
|
165
179
|
e.stopPropagation();
|
|
166
180
|
setShowFullscreen(true);
|
|
167
181
|
}, style: {
|
|
168
182
|
position: 'absolute',
|
|
169
|
-
top: '-6px',
|
|
170
|
-
right: '20px',
|
|
183
|
+
top: isViewer ? '8px' : '-6px',
|
|
184
|
+
right: isViewer ? '8px' : '20px',
|
|
171
185
|
width: '24px',
|
|
172
186
|
height: '24px',
|
|
173
|
-
backgroundColor: '#3b82f6',
|
|
174
|
-
border: '2px solid white',
|
|
175
|
-
borderRadius: '4px',
|
|
187
|
+
backgroundColor: isViewer ? 'rgba(0, 0, 0, 0.6)' : '#3b82f6',
|
|
188
|
+
border: isViewer ? 'none' : '2px solid white',
|
|
189
|
+
borderRadius: isViewer ? '50%' : '4px',
|
|
176
190
|
cursor: 'pointer',
|
|
177
191
|
display: 'flex',
|
|
178
192
|
alignItems: 'center',
|
|
179
193
|
justifyContent: 'center',
|
|
180
194
|
boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
|
|
181
|
-
}, title: "Voir en plein \u00E9cran", children:
|
|
195
|
+
}, title: "Voir en plein \u00E9cran", children: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '14px', color: 'white' }, children: "fullscreen" }) })), !isViewer && isSelected && ((0, jsx_runtime_1.jsx)("div", { onMouseDown: handleResizeStart, style: {
|
|
182
196
|
position: 'absolute',
|
|
183
197
|
right: '-6px',
|
|
184
198
|
bottom: '-6px',
|
|
@@ -189,7 +203,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
189
203
|
cursor: 'se-resize',
|
|
190
204
|
border: '2px solid white',
|
|
191
205
|
boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
|
|
192
|
-
} })), showMetadataEditor && (
|
|
206
|
+
} })), showMetadataEditor && ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
193
207
|
position: 'fixed',
|
|
194
208
|
inset: 0,
|
|
195
209
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
@@ -197,14 +211,14 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
197
211
|
alignItems: 'center',
|
|
198
212
|
justifyContent: 'center',
|
|
199
213
|
zIndex: 100000,
|
|
200
|
-
}, onClick: () => setShowMetadataEditor(false), children:
|
|
214
|
+
}, onClick: () => setShowMetadataEditor(false), children: (0, jsx_runtime_1.jsxs)("div", { onClick: (e) => e.stopPropagation(), style: {
|
|
201
215
|
backgroundColor: 'white',
|
|
202
216
|
borderRadius: '12px',
|
|
203
217
|
padding: '24px',
|
|
204
218
|
boxShadow: '0 25px 50px rgba(0,0,0,0.25)',
|
|
205
219
|
minWidth: '360px',
|
|
206
220
|
maxWidth: '450px',
|
|
207
|
-
}, children: [
|
|
221
|
+
}, children: [(0, jsx_runtime_1.jsx)("h3", { style: { margin: '0 0 20px 0', fontSize: '18px', fontWeight: 600, color: '#111827' }, children: "Propri\u00E9t\u00E9s de l'image" }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '16px' }, children: [(0, jsx_runtime_1.jsxs)("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "link" }), "URL de l'image"] }), (0, jsx_runtime_1.jsx)("input", { type: "url", value: editSrc, onChange: (e) => setEditSrc(e.target.value), placeholder: "https://example.com/image.jpg", style: {
|
|
208
222
|
width: '100%',
|
|
209
223
|
padding: '10px 12px',
|
|
210
224
|
border: '1px solid #d1d5db',
|
|
@@ -212,7 +226,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
212
226
|
fontSize: '14px',
|
|
213
227
|
boxSizing: 'border-box',
|
|
214
228
|
outline: 'none',
|
|
215
|
-
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }),
|
|
229
|
+
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '16px' }, children: [(0, jsx_runtime_1.jsxs)("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "description" }), "Texte alternatif"] }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: editAltText, onChange: (e) => setEditAltText(e.target.value), placeholder: "Description de l'image", style: {
|
|
216
230
|
width: '100%',
|
|
217
231
|
padding: '10px 12px',
|
|
218
232
|
border: '1px solid #d1d5db',
|
|
@@ -220,7 +234,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
220
234
|
fontSize: '14px',
|
|
221
235
|
boxSizing: 'border-box',
|
|
222
236
|
outline: 'none',
|
|
223
|
-
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }),
|
|
237
|
+
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), (0, jsx_runtime_1.jsx)("hr", { style: { border: 'none', borderTop: '1px solid #e5e7eb', margin: '20px 0' } }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '16px' }, children: [(0, jsx_runtime_1.jsxs)("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "photo_camera" }), "Photographe"] }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: editPhotographer, onChange: (e) => setEditPhotographer(e.target.value), placeholder: "Nom du photographe", autoFocus: true, style: {
|
|
224
238
|
width: '100%',
|
|
225
239
|
padding: '10px 12px',
|
|
226
240
|
border: '1px solid #d1d5db',
|
|
@@ -228,7 +242,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
228
242
|
fontSize: '14px',
|
|
229
243
|
boxSizing: 'border-box',
|
|
230
244
|
outline: 'none',
|
|
231
|
-
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }),
|
|
245
|
+
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '16px' }, children: [(0, jsx_runtime_1.jsxs)("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "copyright" }), "Copyright"] }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: editCopyright, onChange: (e) => setEditCopyright(e.target.value), placeholder: "Ex: \u00A9 2024 Nom", style: {
|
|
232
246
|
width: '100%',
|
|
233
247
|
padding: '10px 12px',
|
|
234
248
|
border: '1px solid #d1d5db',
|
|
@@ -236,7 +250,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
236
250
|
fontSize: '14px',
|
|
237
251
|
boxSizing: 'border-box',
|
|
238
252
|
outline: 'none',
|
|
239
|
-
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }),
|
|
253
|
+
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '16px' }, children: [(0, jsx_runtime_1.jsxs)("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "chat" }), "Commentaire (tooltip)"] }), (0, jsx_runtime_1.jsx)("textarea", { value: editComment, onChange: (e) => setEditComment(e.target.value), placeholder: "Commentaire affich\u00E9 au survol de l'image", rows: 3, style: {
|
|
240
254
|
width: '100%',
|
|
241
255
|
padding: '10px 12px',
|
|
242
256
|
border: '1px solid #d1d5db',
|
|
@@ -246,7 +260,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
246
260
|
boxSizing: 'border-box',
|
|
247
261
|
outline: 'none',
|
|
248
262
|
fontFamily: 'inherit',
|
|
249
|
-
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }),
|
|
263
|
+
}, onFocus: (e) => e.target.style.borderColor = '#3b82f6', onBlur: (e) => e.target.style.borderColor = '#d1d5db' })] }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: '24px' }, children: [(0, jsx_runtime_1.jsxs)("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: '#374151' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '18px', color: '#6b7280' }, children: "wrap_text" }), "Habillage du texte"] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '8px', width: '100%' }, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setEditFloat('none'), style: {
|
|
250
264
|
flex: 1,
|
|
251
265
|
minWidth: 0,
|
|
252
266
|
padding: '12px',
|
|
@@ -261,7 +275,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
261
275
|
alignItems: 'center',
|
|
262
276
|
justifyContent: 'center',
|
|
263
277
|
gap: '4px',
|
|
264
|
-
}, title: "Aucun habillage", children:
|
|
278
|
+
}, title: "Aucun habillage", children: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '24px' }, children: "image" }) }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setEditFloat('left'), style: {
|
|
265
279
|
flex: 1,
|
|
266
280
|
minWidth: 0,
|
|
267
281
|
padding: '12px',
|
|
@@ -276,7 +290,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
276
290
|
alignItems: 'center',
|
|
277
291
|
justifyContent: 'center',
|
|
278
292
|
gap: '4px',
|
|
279
|
-
}, title: "Image \u00E0 gauche", children:
|
|
293
|
+
}, title: "Image \u00E0 gauche", children: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '24px' }, children: "west" }) }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setEditFloat('right'), style: {
|
|
280
294
|
flex: 1,
|
|
281
295
|
minWidth: 0,
|
|
282
296
|
padding: '12px',
|
|
@@ -291,7 +305,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
291
305
|
alignItems: 'center',
|
|
292
306
|
justifyContent: 'center',
|
|
293
307
|
gap: '4px',
|
|
294
|
-
}, title: "Image \u00E0 droite", children:
|
|
308
|
+
}, title: "Image \u00E0 droite", children: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '24px' }, children: "east" }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '12px', justifyContent: 'flex-end' }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowMetadataEditor(false), style: {
|
|
295
309
|
padding: '10px 20px',
|
|
296
310
|
border: '1px solid #d1d5db',
|
|
297
311
|
backgroundColor: 'white',
|
|
@@ -300,7 +314,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
300
314
|
fontWeight: 500,
|
|
301
315
|
cursor: 'pointer',
|
|
302
316
|
color: '#374151',
|
|
303
|
-
}, children: "Annuler" }),
|
|
317
|
+
}, children: "Annuler" }), (0, jsx_runtime_1.jsx)("button", { onClick: saveMetadata, style: {
|
|
304
318
|
padding: '10px 20px',
|
|
305
319
|
border: 'none',
|
|
306
320
|
backgroundColor: '#3b82f6',
|
|
@@ -309,7 +323,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
309
323
|
fontSize: '14px',
|
|
310
324
|
fontWeight: 500,
|
|
311
325
|
cursor: 'pointer',
|
|
312
|
-
}, children: "Enregistrer" })] })] }) })), showFullscreen && (
|
|
326
|
+
}, children: "Enregistrer" })] })] }) })), showFullscreen && ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
313
327
|
position: 'fixed',
|
|
314
328
|
inset: 0,
|
|
315
329
|
backgroundColor: 'rgba(0, 0, 0, 0.9)',
|
|
@@ -318,7 +332,7 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
318
332
|
justifyContent: 'center',
|
|
319
333
|
zIndex: 100000,
|
|
320
334
|
cursor: 'pointer',
|
|
321
|
-
}, onClick: () => setShowFullscreen(false), children: [
|
|
335
|
+
}, onClick: () => setShowFullscreen(false), children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowFullscreen(false), style: {
|
|
322
336
|
position: 'absolute',
|
|
323
337
|
top: '20px',
|
|
324
338
|
right: '20px',
|
|
@@ -332,13 +346,13 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
332
346
|
alignItems: 'center',
|
|
333
347
|
justifyContent: 'center',
|
|
334
348
|
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:
|
|
349
|
+
}, 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: (0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '24px', color: 'white' }, children: "close" }) }), (0, jsx_runtime_1.jsx)("img", { src: src, alt: altText, style: {
|
|
336
350
|
maxWidth: '95vw',
|
|
337
351
|
maxHeight: '95vh',
|
|
338
352
|
objectFit: 'contain',
|
|
339
353
|
borderRadius: '4px',
|
|
340
354
|
boxShadow: '0 25px 50px rgba(0,0,0,0.5)',
|
|
341
|
-
}, onClick: (e) => e.stopPropagation() }), (displayCopyright || displayPhotographer || displayComment) && (
|
|
355
|
+
}, onClick: (e) => e.stopPropagation() }), (displayCopyright || displayPhotographer || displayComment) && ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
342
356
|
position: 'absolute',
|
|
343
357
|
bottom: '20px',
|
|
344
358
|
left: '50%',
|
|
@@ -348,9 +362,9 @@ function ImageComponent({ src, altText, width, height, copyright: initialCopyrig
|
|
|
348
362
|
textAlign: 'center',
|
|
349
363
|
textShadow: '0 2px 4px rgba(0,0,0,0.8)',
|
|
350
364
|
maxWidth: '80vw',
|
|
351
|
-
}, children: [displayComment && (
|
|
365
|
+
}, children: [displayComment && ((0, jsx_runtime_1.jsx)("div", { style: { marginBottom: '8px', fontSize: '16px' }, children: displayComment })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '16px', justifyContent: 'center', fontSize: '12px', opacity: 0.8 }, children: [displayCopyright && ((0, jsx_runtime_1.jsxs)("span", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '14px' }, children: "copyright" }), displayCopyright] })), displayPhotographer && ((0, jsx_runtime_1.jsxs)("span", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [(0, jsx_runtime_1.jsx)("span", { className: "material-icons", style: { fontSize: '14px' }, children: "photo_camera" }), displayPhotographer] }))] })] }))] }))] }));
|
|
352
366
|
}
|
|
353
|
-
|
|
367
|
+
class ImageNode extends lexical_1.DecoratorNode {
|
|
354
368
|
static getType() {
|
|
355
369
|
return 'image';
|
|
356
370
|
}
|
|
@@ -476,12 +490,13 @@ export class ImageNode extends DecoratorNode {
|
|
|
476
490
|
};
|
|
477
491
|
}
|
|
478
492
|
decorate() {
|
|
479
|
-
return (
|
|
493
|
+
return ((0, jsx_runtime_1.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
494
|
}
|
|
481
495
|
}
|
|
482
|
-
|
|
496
|
+
exports.ImageNode = ImageNode;
|
|
497
|
+
function $createImageNode(payload) {
|
|
483
498
|
return new ImageNode(payload.src, payload.altText || '', payload.width, payload.height, payload.copyright, payload.photographer, payload.comment, payload.float);
|
|
484
499
|
}
|
|
485
|
-
|
|
500
|
+
function $isImageNode(node) {
|
|
486
501
|
return node instanceof ImageNode;
|
|
487
502
|
}
|
package/dist/nodes/LinkNode.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
'use client';
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.SimpleLinkNode = void 0;
|
|
5
|
+
exports.$createSimpleLinkNode = $createSimpleLinkNode;
|
|
6
|
+
exports.$isSimpleLinkNode = $isSimpleLinkNode;
|
|
7
|
+
exports.$wrapSelectionInSimpleLink = $wrapSelectionInSimpleLink;
|
|
8
|
+
const lexical_1 = require("lexical");
|
|
9
|
+
class SimpleLinkNode extends lexical_1.ElementNode {
|
|
4
10
|
static getType() {
|
|
5
11
|
return 'simple-link';
|
|
6
12
|
}
|
|
@@ -88,14 +94,15 @@ export class SimpleLinkNode extends ElementNode {
|
|
|
88
94
|
return true;
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
exports.SimpleLinkNode = SimpleLinkNode;
|
|
98
|
+
function $createSimpleLinkNode(payload) {
|
|
99
|
+
return (0, lexical_1.$applyNodeReplacement)(new SimpleLinkNode(payload.url, payload.title));
|
|
93
100
|
}
|
|
94
|
-
|
|
101
|
+
function $isSimpleLinkNode(node) {
|
|
95
102
|
return node instanceof SimpleLinkNode;
|
|
96
103
|
}
|
|
97
104
|
// Helper to wrap selection in a link
|
|
98
|
-
|
|
105
|
+
function $wrapSelectionInSimpleLink(selection, url, title) {
|
|
99
106
|
const nodes = selection.extract();
|
|
100
107
|
const linkNode = $createSimpleLinkNode({ url, title });
|
|
101
108
|
if (nodes.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageLinkPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/ImageLinkPlugin.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImageLinkPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/ImageLinkPlugin.tsx"],"names":[],"mappings":"AAwIA,wBAAgB,eAAe,4CAiF9B"}
|