@qwanyx/ai-editor 1.3.13 → 1.4.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/PageEditor.d.ts +10 -0
  2. package/dist/components/PageEditor.d.ts.map +1 -0
  3. package/dist/components/PageEditor.js +294 -0
  4. package/dist/components/PageViewer.d.ts +8 -0
  5. package/dist/components/PageViewer.d.ts.map +1 -0
  6. package/dist/components/PageViewer.js +38 -0
  7. package/dist/components/RichTextEditor.d.ts +5 -1
  8. package/dist/components/RichTextEditor.d.ts.map +1 -1
  9. package/dist/components/RichTextEditor.js +11 -2
  10. package/dist/components/RichTextViewer.d.ts +3 -1
  11. package/dist/components/RichTextViewer.d.ts.map +1 -1
  12. package/dist/components/RichTextViewer.js +7 -2
  13. package/dist/components/Section.d.ts +10 -0
  14. package/dist/components/Section.d.ts.map +1 -0
  15. package/dist/components/Section.js +117 -0
  16. package/dist/components/SmartEditor.d.ts +58 -0
  17. package/dist/components/SmartEditor.d.ts.map +1 -0
  18. package/dist/components/SmartEditor.js +123 -0
  19. package/dist/context/PageContext.d.ts +35 -0
  20. package/dist/context/PageContext.d.ts.map +1 -0
  21. package/dist/context/PageContext.js +277 -0
  22. package/dist/index.d.ts +17 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +54 -1
  25. package/dist/layouts/OgilvyLayout.d.ts +5 -0
  26. package/dist/layouts/OgilvyLayout.d.ts.map +1 -0
  27. package/dist/layouts/OgilvyLayout.js +301 -0
  28. package/dist/layouts/RichTextLayout.d.ts +7 -0
  29. package/dist/layouts/RichTextLayout.d.ts.map +1 -0
  30. package/dist/layouts/RichTextLayout.js +47 -0
  31. package/dist/layouts/index.d.ts +30 -0
  32. package/dist/layouts/index.d.ts.map +1 -0
  33. package/dist/layouts/index.js +71 -0
  34. package/dist/types/index.d.ts +5 -0
  35. package/dist/types/index.d.ts.map +1 -0
  36. package/dist/types/index.js +20 -0
  37. package/dist/types/page.d.ts +151 -0
  38. package/dist/types/page.d.ts.map +1 -0
  39. package/dist/types/page.js +54 -0
  40. package/dist/utils/format.d.ts +71 -0
  41. package/dist/utils/format.d.ts.map +1 -0
  42. package/dist/utils/format.js +190 -0
  43. package/dist/utils/index.d.ts +5 -0
  44. package/dist/utils/index.d.ts.map +1 -0
  45. package/dist/utils/index.js +20 -0
  46. package/package.json +1 -1
@@ -0,0 +1,301 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createDefaultOgilvyContent = createDefaultOgilvyContent;
5
+ exports.OgilvyLayout = OgilvyLayout;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const react_1 = require("react");
8
+ const page_1 = require("../types/page");
9
+ const index_1 = require("./index");
10
+ const RichTextEditor_1 = require("../components/RichTextEditor");
11
+ const RichTextViewer_1 = require("../components/RichTextViewer");
12
+ // ============================================
13
+ // Styles
14
+ // ============================================
15
+ const styles = {
16
+ container: {
17
+ display: 'flex',
18
+ flexDirection: 'column',
19
+ gap: '1.5rem',
20
+ fontFamily: 'Georgia, serif',
21
+ },
22
+ imageContainer: {
23
+ width: '100%',
24
+ position: 'relative',
25
+ },
26
+ image: {
27
+ width: '100%',
28
+ height: 'auto',
29
+ display: 'block',
30
+ },
31
+ imagePlaceholder: {
32
+ width: '100%',
33
+ aspectRatio: '16/9',
34
+ backgroundColor: '#f0f0f0',
35
+ display: 'flex',
36
+ alignItems: 'center',
37
+ justifyContent: 'center',
38
+ color: '#999',
39
+ fontSize: '1rem',
40
+ cursor: 'pointer',
41
+ border: '2px dashed #ccc',
42
+ borderRadius: '4px',
43
+ },
44
+ legend: {
45
+ fontSize: '0.85rem',
46
+ color: '#666',
47
+ marginTop: '0.5rem',
48
+ fontStyle: 'italic',
49
+ },
50
+ titleContainer: {
51
+ textAlign: 'center',
52
+ },
53
+ title: {
54
+ fontSize: '2.5rem',
55
+ fontWeight: 700,
56
+ margin: 0,
57
+ lineHeight: 1.2,
58
+ },
59
+ titleInput: {
60
+ fontSize: '2.5rem',
61
+ fontWeight: 700,
62
+ margin: 0,
63
+ lineHeight: 1.2,
64
+ border: 'none',
65
+ outline: 'none',
66
+ width: '100%',
67
+ textAlign: 'center',
68
+ fontFamily: 'inherit',
69
+ backgroundColor: 'transparent',
70
+ },
71
+ subtitle: {
72
+ fontSize: '1.25rem',
73
+ fontWeight: 400,
74
+ color: '#555',
75
+ margin: '0.5rem 0 0 0',
76
+ fontStyle: 'italic',
77
+ },
78
+ subtitleInput: {
79
+ fontSize: '1.25rem',
80
+ fontWeight: 400,
81
+ color: '#555',
82
+ margin: '0.5rem 0 0 0',
83
+ fontStyle: 'italic',
84
+ border: 'none',
85
+ outline: 'none',
86
+ width: '100%',
87
+ textAlign: 'center',
88
+ fontFamily: 'inherit',
89
+ backgroundColor: 'transparent',
90
+ },
91
+ columnsContainer: {
92
+ display: 'grid',
93
+ gap: '2rem',
94
+ },
95
+ column: {
96
+ lineHeight: 1.7,
97
+ fontSize: '1rem',
98
+ textAlign: 'justify',
99
+ },
100
+ dropCap: {
101
+ float: 'left',
102
+ fontSize: '3em',
103
+ lineHeight: 1,
104
+ marginRight: '0.1em',
105
+ marginTop: '0.1em',
106
+ },
107
+ footnote: {
108
+ fontSize: '0.85rem',
109
+ color: '#666',
110
+ borderTop: '1px solid #ddd',
111
+ paddingTop: '1rem',
112
+ marginTop: '1rem',
113
+ },
114
+ editableField: {
115
+ border: '1px solid transparent',
116
+ borderRadius: '4px',
117
+ transition: 'border-color 0.2s, background-color 0.2s',
118
+ },
119
+ editableFieldHover: {
120
+ borderColor: '#007bff',
121
+ backgroundColor: 'rgba(0, 123, 255, 0.05)',
122
+ },
123
+ };
124
+ // ============================================
125
+ // Default Content
126
+ // ============================================
127
+ function createDefaultOgilvyContent() {
128
+ return {
129
+ image: {
130
+ src: '',
131
+ altText: '',
132
+ },
133
+ legend: '',
134
+ legendAsterisk: false,
135
+ title: 'Titre de la section',
136
+ subtitle: 'Sous-titre descriptif',
137
+ bodyText: '',
138
+ columns: 2,
139
+ dropCap: { ...page_1.DEFAULT_DROP_CAP },
140
+ footnote: '',
141
+ };
142
+ }
143
+ function EditableText({ value, onChange, isEditing, placeholder = 'Cliquez pour éditer...', style = {}, inputStyle = {}, multiline = false, as: Component = 'p', }) {
144
+ const [isHovered, setIsHovered] = (0, react_1.useState)(false);
145
+ if (!isEditing) {
146
+ return (0, jsx_runtime_1.jsx)(Component, { style: style, children: value || placeholder });
147
+ }
148
+ const combinedStyle = {
149
+ ...style,
150
+ ...inputStyle,
151
+ ...(isHovered ? styles.editableFieldHover : {}),
152
+ };
153
+ if (multiline) {
154
+ return ((0, jsx_runtime_1.jsx)("textarea", { value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, style: {
155
+ ...combinedStyle,
156
+ resize: 'none',
157
+ minHeight: '100px',
158
+ }, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false) }));
159
+ }
160
+ return ((0, jsx_runtime_1.jsx)("input", { type: "text", value: value, onChange: (e) => onChange(e.target.value), placeholder: placeholder, style: combinedStyle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false) }));
161
+ }
162
+ function ImagePicker({ image, onChange, isEditing }) {
163
+ const [showDialog, setShowDialog] = (0, react_1.useState)(false);
164
+ const [tempUrl, setTempUrl] = (0, react_1.useState)(image.src);
165
+ const handleClick = () => {
166
+ if (isEditing) {
167
+ setTempUrl(image.src);
168
+ setShowDialog(true);
169
+ }
170
+ };
171
+ const handleSave = () => {
172
+ onChange({ ...image, src: tempUrl });
173
+ setShowDialog(false);
174
+ };
175
+ if (!image.src) {
176
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: styles.imagePlaceholder, onClick: handleClick, children: isEditing ? 'Cliquez pour ajouter une image' : 'Aucune image' }), showDialog && ((0, jsx_runtime_1.jsx)(ImageDialog, { url: tempUrl, onUrlChange: setTempUrl, onSave: handleSave, onCancel: () => setShowDialog(false) }))] }));
177
+ }
178
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: styles.imageContainer, children: (0, jsx_runtime_1.jsx)("img", { src: image.src, alt: image.altText || '', style: {
179
+ ...styles.image,
180
+ cursor: isEditing ? 'pointer' : 'default',
181
+ }, onClick: handleClick }) }), showDialog && ((0, jsx_runtime_1.jsx)(ImageDialog, { url: tempUrl, onUrlChange: setTempUrl, onSave: handleSave, onCancel: () => setShowDialog(false) }))] }));
182
+ }
183
+ function ImageDialog({ url, onUrlChange, onSave, onCancel }) {
184
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
185
+ position: 'fixed',
186
+ top: 0,
187
+ left: 0,
188
+ right: 0,
189
+ bottom: 0,
190
+ backgroundColor: 'rgba(0,0,0,0.5)',
191
+ display: 'flex',
192
+ alignItems: 'center',
193
+ justifyContent: 'center',
194
+ zIndex: 1000,
195
+ }, onClick: onCancel, children: (0, jsx_runtime_1.jsxs)("div", { style: {
196
+ backgroundColor: 'white',
197
+ padding: '1.5rem',
198
+ borderRadius: '8px',
199
+ minWidth: '400px',
200
+ }, onClick: (e) => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { style: { margin: '0 0 1rem 0' }, children: "URL de l'image" }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: url, onChange: (e) => onUrlChange(e.target.value), placeholder: "https://...", style: {
201
+ width: '100%',
202
+ padding: '0.5rem',
203
+ marginBottom: '1rem',
204
+ border: '1px solid #ccc',
205
+ borderRadius: '4px',
206
+ } }), url && ((0, jsx_runtime_1.jsx)("img", { src: url, alt: "Preview", style: {
207
+ maxWidth: '100%',
208
+ maxHeight: '200px',
209
+ marginBottom: '1rem',
210
+ display: 'block',
211
+ } })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '0.5rem', justifyContent: 'flex-end' }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: onCancel, style: {
212
+ padding: '0.5rem 1rem',
213
+ border: '1px solid #ccc',
214
+ borderRadius: '4px',
215
+ backgroundColor: 'white',
216
+ cursor: 'pointer',
217
+ }, children: "Annuler" }), (0, jsx_runtime_1.jsx)("button", { onClick: onSave, style: {
218
+ padding: '0.5rem 1rem',
219
+ border: 'none',
220
+ borderRadius: '4px',
221
+ backgroundColor: '#007bff',
222
+ color: 'white',
223
+ cursor: 'pointer',
224
+ }, children: "Enregistrer" })] })] }) }));
225
+ }
226
+ function DropCapText({ text, dropCap }) {
227
+ if (!text || !dropCap.enabled) {
228
+ return (0, jsx_runtime_1.jsx)("div", { style: styles.column, children: text });
229
+ }
230
+ const firstChar = text.charAt(0);
231
+ const restOfText = text.slice(1);
232
+ const dropCapStyle = {
233
+ ...styles.dropCap,
234
+ fontSize: `${dropCap.fontSize || 3}em`,
235
+ fontFamily: dropCap.fontFamily || 'inherit',
236
+ color: dropCap.color || 'inherit',
237
+ };
238
+ if (dropCap.type === 'icon' && dropCap.iconUrl) {
239
+ return ((0, jsx_runtime_1.jsxs)("div", { style: styles.column, children: [(0, jsx_runtime_1.jsx)("img", { src: dropCap.iconUrl, alt: "", style: {
240
+ float: 'left',
241
+ width: `${dropCap.iconSize || 48}px`,
242
+ height: `${dropCap.iconSize || 48}px`,
243
+ marginRight: '0.5em',
244
+ marginTop: '0.1em',
245
+ } }), text] }));
246
+ }
247
+ return ((0, jsx_runtime_1.jsxs)("div", { style: styles.column, children: [(0, jsx_runtime_1.jsx)("span", { style: dropCapStyle, children: firstChar }), restOfText] }));
248
+ }
249
+ function Columns({ text, columns, dropCap }) {
250
+ // Pour l'instant, on divise simplement le texte en paragraphes
251
+ // TODO: Intégrer RichTextEditor pour l'édition du corps de texte
252
+ const paragraphs = text.split('\n\n').filter(Boolean);
253
+ // Distribuer les paragraphes dans les colonnes
254
+ const columnTexts = Array(columns).fill('');
255
+ paragraphs.forEach((para, idx) => {
256
+ columnTexts[idx % columns] += (columnTexts[idx % columns] ? '\n\n' : '') + para;
257
+ });
258
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
259
+ ...styles.columnsContainer,
260
+ gridTemplateColumns: `repeat(${columns}, 1fr)`,
261
+ }, children: columnTexts.map((colText, idx) => ((0, jsx_runtime_1.jsx)("div", { children: idx === 0 ? ((0, jsx_runtime_1.jsx)(DropCapText, { text: colText, dropCap: dropCap })) : ((0, jsx_runtime_1.jsx)("div", { style: styles.column, children: colText })) }, idx))) }));
262
+ }
263
+ // ============================================
264
+ // Main Layout Component
265
+ // ============================================
266
+ function OgilvyLayout({ section, isEditing, onContentChange, }) {
267
+ const content = section.content;
268
+ const updateField = (0, react_1.useCallback)((field, value) => {
269
+ onContentChange({
270
+ ...content,
271
+ [field]: value,
272
+ });
273
+ }, [content, onContentChange]);
274
+ return ((0, jsx_runtime_1.jsxs)("div", { style: styles.container, children: [(0, jsx_runtime_1.jsx)(ImagePicker, { image: content.image, onChange: (img) => updateField('image', img), isEditing: isEditing }), (content.legend || isEditing) && ((0, jsx_runtime_1.jsxs)("div", { style: styles.legend, children: [(0, jsx_runtime_1.jsx)(EditableText, { value: content.legend, onChange: (v) => updateField('legend', v), isEditing: isEditing, placeholder: "L\u00E9gende de l'image...", style: styles.legend }), content.legendAsterisk && '*'] })), (0, jsx_runtime_1.jsxs)("div", { style: styles.titleContainer, children: [(0, jsx_runtime_1.jsx)(EditableText, { value: content.title, onChange: (v) => updateField('title', v), isEditing: isEditing, placeholder: "Titre", style: styles.title, inputStyle: styles.titleInput, as: "h1" }), (0, jsx_runtime_1.jsx)(EditableText, { value: content.subtitle, onChange: (v) => updateField('subtitle', v), isEditing: isEditing, placeholder: "Sous-titre", style: styles.subtitle, inputStyle: styles.subtitleInput, as: "h2" })] }), (0, jsx_runtime_1.jsxs)("div", { className: content.dropCap.enabled ? 'ogilvy-drop-cap' : '', style: {
275
+ ['--drop-cap-size']: `${content.dropCap.fontSize || 3}em`,
276
+ ['--drop-cap-color']: content.dropCap.color || 'inherit',
277
+ ['--drop-cap-font']: content.dropCap.fontFamily || 'Georgia, serif',
278
+ }, children: [(0, jsx_runtime_1.jsx)("style", { children: `
279
+ .ogilvy-drop-cap .editor-paragraph:first-of-type::first-letter {
280
+ float: left;
281
+ font-size: var(--drop-cap-size, 3em);
282
+ font-family: var(--drop-cap-font, Georgia, serif);
283
+ color: var(--drop-cap-color, inherit);
284
+ line-height: 0.8;
285
+ margin-right: 0.1em;
286
+ margin-top: 0.1em;
287
+ }
288
+ ` }), isEditing ? ((0, jsx_runtime_1.jsx)(RichTextEditor_1.RichTextEditor, { initialContent: content.bodyText, onChange: (_html, json) => updateField('bodyText', json), placeholder: "Corps du texte...", columns: content.columns, minHeight: content.columnLines ? `calc(${content.columnLines * 1.7}em + 60px)` : "200px", autoGrow: !content.columnLines })) : ((0, jsx_runtime_1.jsx)(RichTextViewer_1.RichTextViewer, { content: content.bodyText, columns: content.columns }))] }), (content.footnote || (isEditing && content.legendAsterisk)) && ((0, jsx_runtime_1.jsx)("div", { style: styles.footnote, children: (0, jsx_runtime_1.jsx)(EditableText, { value: content.footnote || '', onChange: (v) => updateField('footnote', v), isEditing: isEditing, placeholder: "* Note explicative...", style: styles.footnote }) }))] }));
289
+ }
290
+ // ============================================
291
+ // Register Layout
292
+ // ============================================
293
+ (0, index_1.registerLayout)({
294
+ type: 'ogilvy',
295
+ name: 'Ogilvy',
296
+ description: 'Image hero + légende + titre + sous-titre + texte en colonnes avec lettrine',
297
+ icon: '📰',
298
+ component: OgilvyLayout,
299
+ defaultContent: createDefaultOgilvyContent,
300
+ category: 'editorial',
301
+ });
@@ -0,0 +1,7 @@
1
+ import { LayoutComponentProps } from './index';
2
+ export interface RichTextContent {
3
+ lexicalState: string;
4
+ }
5
+ export declare function createDefaultRichTextContent(): RichTextContent;
6
+ export declare function RichTextLayout({ section, isEditing, onContentChange, }: LayoutComponentProps<RichTextContent>): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=RichTextLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RichTextLayout.d.ts","sourceRoot":"","sources":["../../src/layouts/RichTextLayout.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAkB,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAQ9D,MAAM,WAAW,eAAe;IAE9B,YAAY,EAAE,MAAM,CAAA;CACrB;AAMD,wBAAgB,4BAA4B,IAAI,eAAe,CAI9D;AAMD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,SAAS,EACT,eAAe,GAChB,EAAE,oBAAoB,CAAC,eAAe,CAAC,2CA6BvC"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createDefaultRichTextContent = createDefaultRichTextContent;
5
+ exports.RichTextLayout = RichTextLayout;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const react_1 = require("react");
8
+ const index_1 = require("./index");
9
+ const RichTextEditor_1 = require("../components/RichTextEditor");
10
+ const RichTextViewer_1 = require("../components/RichTextViewer");
11
+ // ============================================
12
+ // Default Content
13
+ // ============================================
14
+ function createDefaultRichTextContent() {
15
+ return {
16
+ lexicalState: '',
17
+ };
18
+ }
19
+ // ============================================
20
+ // Layout Component
21
+ // ============================================
22
+ function RichTextLayout({ section, isEditing, onContentChange, }) {
23
+ const content = section.content;
24
+ const handleChange = (0, react_1.useCallback)((_html, json) => {
25
+ onContentChange({
26
+ lexicalState: json,
27
+ });
28
+ }, [onContentChange]);
29
+ if (!isEditing) {
30
+ // Mode lecture: utiliser RichTextViewer
31
+ return ((0, jsx_runtime_1.jsx)(RichTextViewer_1.RichTextViewer, { content: content.lexicalState }));
32
+ }
33
+ // Mode édition: utiliser RichTextEditor
34
+ return ((0, jsx_runtime_1.jsx)(RichTextEditor_1.RichTextEditor, { initialContent: content.lexicalState, onChange: handleChange, placeholder: "Commencez \u00E0 \u00E9crire..." }));
35
+ }
36
+ // ============================================
37
+ // Register Layout
38
+ // ============================================
39
+ (0, index_1.registerLayout)({
40
+ type: 'text-only', // On utilise 'text-only' qui est déjà dans les types
41
+ name: 'Texte riche',
42
+ description: 'Éditeur de texte riche simple (compatible avec l\'ancien format)',
43
+ icon: '📝',
44
+ component: RichTextLayout,
45
+ defaultContent: createDefaultRichTextContent,
46
+ category: 'editorial',
47
+ });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Layout Registry
3
+ * Centralise tous les layouts disponibles pour les sections
4
+ */
5
+ import React from 'react';
6
+ import { LayoutType, Section } from '../types/page';
7
+ export interface LayoutComponentProps<T = unknown> {
8
+ section: Section<T>;
9
+ isEditing: boolean;
10
+ onContentChange: (content: T) => void;
11
+ }
12
+ export interface LayoutRegistryEntry<T = unknown> {
13
+ type: LayoutType;
14
+ name: string;
15
+ description: string;
16
+ icon?: string;
17
+ component: React.ComponentType<LayoutComponentProps<T>>;
18
+ defaultContent: () => T;
19
+ category: 'editorial' | 'media' | 'grid' | 'special';
20
+ }
21
+ export declare function registerLayout<T>(entry: LayoutRegistryEntry<T>): void;
22
+ export declare function getLayout(type: LayoutType): LayoutRegistryEntry | undefined;
23
+ export declare function getAllLayouts(): LayoutRegistryEntry[];
24
+ export declare function getLayoutsByCategory(category: LayoutRegistryEntry['category']): LayoutRegistryEntry[];
25
+ export declare function getLayoutComponent(type: LayoutType): React.ComponentType<LayoutComponentProps> | null;
26
+ export declare function getLayoutDefaultContent<T>(type: LayoutType): T | null;
27
+ export * from './OgilvyLayout';
28
+ export * from './RichTextLayout';
29
+ export declare function initializeLayouts(): void;
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layouts/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAMnD,MAAM,WAAW,oBAAoB,CAAC,CAAC,GAAG,OAAO;IAC/C,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO;IAC9C,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAA;IACvD,cAAc,EAAE,MAAM,CAAC,CAAA;IAEvB,QAAQ,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;CACrD;AAQD,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAErE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,GAAG,SAAS,CAE3E;AAED,wBAAgB,aAAa,IAAI,mBAAmB,EAAE,CAErD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,mBAAmB,EAAE,CAErG;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAGrG;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,GAAG,IAAI,CAGrE;AASD,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAUhC,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Layout Registry
4
+ * Centralise tous les layouts disponibles pour les sections
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.registerLayout = registerLayout;
22
+ exports.getLayout = getLayout;
23
+ exports.getAllLayouts = getAllLayouts;
24
+ exports.getLayoutsByCategory = getLayoutsByCategory;
25
+ exports.getLayoutComponent = getLayoutComponent;
26
+ exports.getLayoutDefaultContent = getLayoutDefaultContent;
27
+ exports.initializeLayouts = initializeLayouts;
28
+ // ============================================
29
+ // Registry
30
+ // ============================================
31
+ const layoutRegistry = new Map();
32
+ function registerLayout(entry) {
33
+ layoutRegistry.set(entry.type, entry);
34
+ }
35
+ function getLayout(type) {
36
+ return layoutRegistry.get(type);
37
+ }
38
+ function getAllLayouts() {
39
+ return Array.from(layoutRegistry.values());
40
+ }
41
+ function getLayoutsByCategory(category) {
42
+ return getAllLayouts().filter((layout) => layout.category === category);
43
+ }
44
+ function getLayoutComponent(type) {
45
+ const entry = layoutRegistry.get(type);
46
+ return entry?.component ?? null;
47
+ }
48
+ function getLayoutDefaultContent(type) {
49
+ const entry = layoutRegistry.get(type);
50
+ return entry ? entry.defaultContent() : null;
51
+ }
52
+ // ============================================
53
+ // Re-export des layouts individuels
54
+ // ============================================
55
+ // Les layouts seront importés et enregistrés automatiquement
56
+ // quand on les importe depuis ce fichier
57
+ __exportStar(require("./OgilvyLayout"), exports);
58
+ __exportStar(require("./RichTextLayout"), exports);
59
+ // export * from './HeroLayout' // À créer plus tard
60
+ // export * from './TwoColumnsLayout' // À créer plus tard
61
+ // etc.
62
+ // ============================================
63
+ // Initialisation des layouts par défaut
64
+ // ============================================
65
+ // Cette fonction sera appelée pour s'assurer que tous les layouts sont enregistrés
66
+ function initializeLayouts() {
67
+ // Import dynamique pour éviter les problèmes de circular dependencies
68
+ // Les layouts s'enregistrent eux-mêmes lors de l'import
69
+ require('./OgilvyLayout');
70
+ require('./RichTextLayout');
71
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Re-export all types
3
+ */
4
+ export * from './page';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,QAAQ,CAAA"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * Re-export all types
19
+ */
20
+ __exportStar(require("./page"), exports);
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Types pour le système de Pages et Sections
3
+ * Extension de qwanyx-ai-editor
4
+ */
5
+ export type PageFormat = 'web' | 'print' | 'video';
6
+ export interface PrintSize {
7
+ width: number;
8
+ height: number;
9
+ unit: 'mm' | 'in';
10
+ name?: string;
11
+ }
12
+ export interface VideoSize {
13
+ width: number;
14
+ height: number;
15
+ name: string;
16
+ }
17
+ export declare const PRINT_PRESETS: Record<string, PrintSize>;
18
+ export declare const VIDEO_PRESETS: Record<string, VideoSize>;
19
+ export type AnimationType = 'none' | 'fade' | 'slide-left' | 'slide-right' | 'slide-up' | 'slide-down' | 'zoom-in' | 'zoom-out';
20
+ export interface SectionAnimation {
21
+ entrance: AnimationType;
22
+ exit?: AnimationType;
23
+ duration: number;
24
+ delay?: number;
25
+ }
26
+ export interface DropCapConfig {
27
+ enabled: boolean;
28
+ type: 'letter' | 'icon';
29
+ fontSize?: number;
30
+ fontFamily?: string;
31
+ color?: string;
32
+ lineHeight?: number;
33
+ iconUrl?: string;
34
+ iconSize?: number;
35
+ }
36
+ export declare const DEFAULT_DROP_CAP: DropCapConfig;
37
+ export interface ImageData {
38
+ src: string;
39
+ altText?: string;
40
+ title?: string;
41
+ photographer?: string;
42
+ copyright?: string;
43
+ comment?: string;
44
+ }
45
+ export type LayoutType = 'ogilvy' | 'hero' | 'two-columns' | 'three-columns' | 'text-only' | 'image-only' | 'gallery' | 'quote' | 'custom';
46
+ export interface Section<T = unknown> {
47
+ id: string;
48
+ layoutType: LayoutType;
49
+ content: T;
50
+ animation?: SectionAnimation;
51
+ className?: string;
52
+ backgroundColor?: string;
53
+ padding?: string;
54
+ }
55
+ export interface OgilvyContent {
56
+ image: ImageData;
57
+ legend: string;
58
+ legendAsterisk: boolean;
59
+ title: string;
60
+ subtitle: string;
61
+ bodyText: string;
62
+ columns: 2 | 3;
63
+ columnLines?: number;
64
+ dropCap: DropCapConfig;
65
+ footnote?: string;
66
+ }
67
+ export interface HeroContent {
68
+ image: ImageData;
69
+ title: string;
70
+ subtitle?: string;
71
+ ctaText?: string;
72
+ ctaUrl?: string;
73
+ overlayColor?: string;
74
+ overlayOpacity?: number;
75
+ textPosition: 'center' | 'left' | 'right' | 'bottom-left' | 'bottom-right';
76
+ }
77
+ export interface TwoColumnsContent {
78
+ leftContent: string;
79
+ rightContent: string;
80
+ leftWidth: number;
81
+ gap?: number;
82
+ }
83
+ export interface ThreeColumnsContent {
84
+ columns: [string, string, string];
85
+ gap?: number;
86
+ }
87
+ export interface TextOnlyContent {
88
+ text: string;
89
+ maxWidth?: string;
90
+ alignment?: 'left' | 'center' | 'right';
91
+ }
92
+ export interface ImageOnlyContent {
93
+ image: ImageData;
94
+ caption?: string;
95
+ maxWidth?: string;
96
+ alignment?: 'left' | 'center' | 'right';
97
+ }
98
+ export interface QuoteContent {
99
+ quote: string;
100
+ author?: string;
101
+ source?: string;
102
+ style: 'simple' | 'large' | 'with-image';
103
+ authorImage?: ImageData;
104
+ }
105
+ export interface GalleryContent {
106
+ images: ImageData[];
107
+ columns: 2 | 3 | 4;
108
+ gap?: number;
109
+ style: 'grid' | 'masonry';
110
+ }
111
+ export interface PageDocument {
112
+ id: string;
113
+ title?: string;
114
+ format: PageFormat;
115
+ printSize?: PrintSize;
116
+ videoSize?: VideoSize;
117
+ sections: Section[];
118
+ createdAt?: string;
119
+ updatedAt?: string;
120
+ defaultFontFamily?: string;
121
+ defaultFontSize?: number;
122
+ backgroundColor?: string;
123
+ }
124
+ export interface LayoutDefinition<T = unknown> {
125
+ type: LayoutType;
126
+ name: string;
127
+ description: string;
128
+ icon?: string;
129
+ defaultContent: T;
130
+ }
131
+ export interface PageEditorProps {
132
+ initialDocument?: PageDocument;
133
+ onChange?: (document: PageDocument) => void;
134
+ className?: string;
135
+ }
136
+ export interface PageViewerProps {
137
+ document: PageDocument;
138
+ className?: string;
139
+ }
140
+ export interface SectionProps<T = unknown> {
141
+ section: Section<T>;
142
+ isEditing: boolean;
143
+ onUpdate: (content: T) => void;
144
+ onDelete?: () => void;
145
+ onMoveUp?: () => void;
146
+ onMoveDown?: () => void;
147
+ }
148
+ export declare function generateId(): string;
149
+ export declare function createSection<T>(layoutType: LayoutType, content: T, animation?: SectionAnimation): Section<T>;
150
+ export declare function createEmptyPage(format?: PageFormat): PageDocument;
151
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/types/page.ts"],"names":[],"mappings":"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"}