@deckedout/visual-editor 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,31 @@
8
8
 
9
9
  A flexible, drag-and-drop visual editor built with React and Konva for creating interactive canvases with customizable elements.
10
10
 
11
+ ## 🚀 Try It Online
12
+
13
+ The app example is published at: [https://deckedout.fr/dev/visual-editor/playground/](https://deckedout.fr/dev/visual-editor/playground/)
14
+
15
+ You can check app example codebase: [https://github.com/EIP-DeckedOut-Orga/eip-visual-editor-example-vite/](https://github.com/EIP-DeckedOut-Orga/eip-visual-editor-example-vite/)
16
+
17
+ > 💡 **Tip**: Fork the demo and start customizing immediately!
18
+
19
+ ## Preview
20
+
21
+ **Basic Editor Interface:**
22
+
23
+ ![Basic Editor](./src/doc-assets/examples-preview/basic_editor_preview.png)
24
+ *Full editor with toolbar, canvas, inspector, and layers panel*
25
+
26
+ **Custom Mode - Card Designer:**
27
+
28
+ ![Custom Mode](./src/doc-assets/examples-preview/custom_mode_preview.png)
29
+ *Custom canvas size (750×1050) with custom toolbar and topbar*
30
+
31
+ **Asset Picker with Background Selector:**
32
+
33
+ ![Asset Picker](./src/doc-assets/examples-preview/with_background_assets_preview.png)
34
+ *Asset management with background color*
35
+
11
36
  ## Features
12
37
 
13
38
  - 🎨 **Visual Canvas Editor**: Drag, resize, and rotate elements on a canvas
@@ -62,25 +87,24 @@ import '@deckedout/visual-editor/styles';
62
87
 
63
88
  ```tsx
64
89
  import { VisualEditorWorkspace } from '@deckedout/visual-editor';
65
- import { useState } from 'react';
66
90
 
67
91
  function App() {
68
- const [mode, setMode] = useState('edit');
69
-
70
92
  return (
71
93
  <div style={{ width: '100vw', height: '100vh' }}>
72
94
  <VisualEditorWorkspace
73
- canvasWidth={800}
74
- canvasHeight={600}
75
- mode={mode}
95
+ showToolbar={true}
96
+ showTopbar={true}
76
97
  showInspector={true}
77
98
  showLayers={true}
99
+ enableSnapGuides={true}
78
100
  />
79
101
  </div>
80
102
  );
81
103
  }
82
104
  ```
83
105
 
106
+ **Want to see it in action?** Check out the [live Vite example](#-live-examples) with three interactive demos!
107
+
84
108
  ## Core Components
85
109
 
86
110
  ### VisualEditorWorkspace
@@ -186,7 +210,59 @@ globalElementRegistry.register(customElementRenderer);
186
210
  - `globalElementRegistry`: Global registry for element types
187
211
  - Built-in elements: `textElementRenderer`, `imageElementRenderer`
188
212
 
189
- ## Examples
213
+ ## 🎯 Live Examples
214
+
215
+ A complete **Vite + React example project** with three interactive demos:
216
+
217
+ ### [📁 example-vite/](./example-vite) - Full Application
218
+
219
+ **[Try in StackBlitz →](https://stackblitz.com/github/EIP-DeckedOut-Orga/eip-visual-editor-package/tree/main/example-vite?file=src/App.tsx)**
220
+
221
+ **Or run locally:**
222
+
223
+ ```bash
224
+ cd example-vite
225
+ npm install
226
+ npm run dev
227
+ ```
228
+
229
+ **Included Demos:**
230
+
231
+ 1. **[Basic Editor](./example-vite/src/pages/BasicEditor.tsx)** (`/`)
232
+
233
+ - Simple integration with all default features
234
+ - All panels enabled (toolbar, topbar, inspector, layers)
235
+ - Snap guides and alignment helpers
236
+ - Perfect starting point for new projects
237
+ 2. **[Custom Mode](./example-vite/src/pages/CustomMode.tsx)** (`/custom-mode`)
238
+
239
+ - Card designer with 750×1050 custom canvas
240
+ - Custom toolbar with "Load Template" action
241
+ - Custom topbar with "Export PNG" button
242
+ - Auto-save functionality with visual indicator
243
+ - Background color and grid configuration
244
+ - Shows advanced editor customization
245
+ 3. **[Asset Picker](./example-vite/src/pages/WithAssets.tsx)** (`/with-assets`)
246
+
247
+ - Asset management integration
248
+ - Mock game assets (sprites, backgrounds, items)
249
+ - **Background upload** - Upload custom images via file picker
250
+ - Dynamic background selector - Uploaded images added to dropdown
251
+ - 1200×800 canvas with dark theme
252
+ - Grid overlay for precise positioning
253
+
254
+ **Features demonstrated:**
255
+
256
+ - 🎨 Custom canvas sizes and layouts
257
+ - 🔧 Toolbar and topbar customization
258
+ - 📦 Asset picker integration
259
+ - 💾 State persistence and auto-save
260
+ - 🎭 Different editor modes
261
+ - 🌙 Dark mode theming
262
+
263
+ See the [example-vite/README.md](./example-vite/README.md) for full setup instructions and customization guide.
264
+
265
+ ## 📘 Code Examples
190
266
 
191
267
  ### Basic Editor
192
268
 
@@ -197,8 +273,11 @@ function BasicEditor() {
197
273
  return (
198
274
  <div style={{ width: '100%', height: '600px' }}>
199
275
  <VisualEditorWorkspace
200
- canvasWidth={800}
201
- canvasHeight={600}
276
+ showToolbar={true}
277
+ showTopbar={true}
278
+ showInspector={true}
279
+ showLayers={true}
280
+ enableSnapGuides={true}
202
281
  />
203
282
  </div>
204
283
  );
@@ -222,10 +301,76 @@ globalElementRegistry.register(imageElementRenderer);
222
301
  globalElementRegistry.register(myCustomElement);
223
302
 
224
303
  function EditorWithCustomElements() {
225
- return <VisualEditorWorkspace canvasWidth={800} canvasHeight={600} />;
304
+ return <VisualEditorWorkspace />;
305
+ }
306
+ ```
307
+
308
+ ### With Asset Picker
309
+
310
+ ```tsx
311
+ import { VisualEditorWorkspace } from '@deckedout/visual-editor';
312
+
313
+ const assets = [
314
+ { name: 'Character', path: '/assets/character.png', type: 'sprite' },
315
+ { name: 'Background', path: '/assets/bg.png', type: 'background' }
316
+ ];
317
+
318
+ function EditorWithAssets() {
319
+ return (
320
+ <VisualEditorWorkspace
321
+ showAssetPicker={true}
322
+ mode={{
323
+ name: 'Asset Editor',
324
+ assetPickerProps: { assets }
325
+ }}
326
+ />
327
+ );
226
328
  }
227
329
  ```
228
330
 
331
+ ## 📚 Documentation
332
+
333
+ ### Full API Documentation
334
+
335
+ Available at: [https://deckedout.fr/dev/docs/editor/](https://deckedout.fr/dev/docs/editor/)
336
+
337
+ ### TypeScript Examples (`/examples`)
338
+
339
+ Comprehensive standalone examples showing specific features:
340
+
341
+ - **[01-basic-usage.tsx](./examples/01-basic-usage.tsx)** - Quickstart with minimal configuration
342
+ - **[02-controlled-mode.tsx](./examples/02-controlled-mode.tsx)** - External state management and persistence
343
+ - **[03-custom-elements.tsx](./examples/03-custom-elements.tsx)** - Creating custom element types
344
+ - **[04-programmatic-api.tsx](./examples/04-programmatic-api.tsx)** - Using the editor API programmatically
345
+ - **[05-editor-modes.tsx](./examples/05-editor-modes.tsx)** - Configuring different editor modes
346
+ - **[06-asset-picker.tsx](./examples/06-asset-picker.tsx)** - Integrating asset management
347
+
348
+ See the [examples README](./examples/README.md) for detailed documentation and usage patterns.
349
+
350
+ ### Runnable Vite Example (`/example-vite`)
351
+
352
+ Complete working application with React Router and three interactive demos:
353
+
354
+ - **[BasicEditor.tsx](./example-vite/src/pages/BasicEditor.tsx)** - Simple integration
355
+ - **[CustomMode.tsx](./example-vite/src/pages/CustomMode.tsx)** - Card designer with custom toolbar/topbar
356
+ - **[WithAssets.tsx](./example-vite/src/pages/WithAssets.tsx)** - Asset picker and background selector
357
+
358
+ Run it locally: `cd example-vite && npm install && npm run dev`
359
+
360
+ Full guide: [example-vite/README.md](./example-vite/README.md)
361
+
362
+ ### Generating Documentation Locally
363
+
364
+ ```bash
365
+ # Generate documentation
366
+ npm run docs
367
+
368
+ # Watch mode (regenerates on file changes)
369
+ npm run docs:watch
370
+ ```
371
+
372
+ Documentation is automatically generated and deployed to the server on every push to the main branch.
373
+
229
374
  ## Development
230
375
 
231
376
  ### Running Tests
@@ -257,16 +402,26 @@ npm run lint
257
402
  ### Testing Coverage
258
403
 
259
404
  This package maintains high test coverage:
405
+
260
406
  - **95.26%** statements
261
- - **94.2%** branches
407
+ - **94.2%** branches
262
408
  - **93.05%** functions
263
409
  - **95.77%** lines
264
410
 
265
411
  See [TESTING.md](./TESTING.md) for detailed testing documentation.
266
412
 
413
+ ## Documentation
414
+
415
+ - **[API Reference](./API_REFERENCE.md)** - Complete API documentation
416
+ - **[Quick Reference](./QUICK_REFERENCE.md)** - Quick start guide
417
+ - **[Testing Guide](./TESTING.md)** - Testing documentation and coverage
418
+ - **[Changelog](./CHANGELOG.md)** - Version history and changes
419
+ - **[Architecture Decision Records](./adr/)** - Design decisions and rationale
420
+
267
421
  ## Contributing
268
422
 
269
423
  Contributions are welcome! Please ensure:
424
+
270
425
  1. All tests pass (`npm test`)
271
426
  2. Code coverage remains above 90%
272
427
  3. Code is properly linted (`npm run lint`)
@@ -275,7 +430,3 @@ Contributions are welcome! Please ensure:
275
430
  ## License
276
431
 
277
432
  MIT
278
-
279
- ## Contributing
280
-
281
- Contributions are welcome! Please feel free to submit a Pull Request.
package/dist/index.d.mts CHANGED
@@ -317,6 +317,7 @@ interface CustomEditorSeparator {
317
317
  type CustomEditorAction = CustomEditorButtonAction | CustomEditorDropdownAction | CustomEditorInputAction | CustomEditorColorAction | CustomEditorToggleAction | CustomEditorSeparator;
318
318
  /**
319
319
  * Configuration for topbar controls visibility
320
+ * @public
320
321
  */
321
322
  interface TopbarConfig {
322
323
  /** Show undo button */
@@ -352,6 +353,7 @@ interface TopbarConfig {
352
353
  }
353
354
  /**
354
355
  * Configuration for toolbar controls visibility
356
+ * @public
355
357
  */
356
358
  interface ToolbarConfig {
357
359
  /** Show element creation tools */
@@ -546,6 +548,10 @@ declare const VisualEditor: React$1.FC<VisualEditorProps>;
546
548
  * Dynamically renders fields based on the element's inspectorSchema.
547
549
  */
548
550
 
551
+ /**
552
+ * Props for the Inspector component
553
+ * @public
554
+ */
549
555
  interface InspectorProps {
550
556
  /** Currently selected element */
551
557
  selectedElement: EditorElement | null;
@@ -583,6 +589,10 @@ declare function renderField(field: InspectorFieldSchema, props: any, editingVal
583
589
  * reorder, and delete elements.
584
590
  */
585
591
 
592
+ /**
593
+ * Props for the LayersPanel component
594
+ * @public
595
+ */
586
596
  interface LayersPanelProps {
587
597
  /** All elements in the canvas */
588
598
  elements: EditorElement[];
@@ -609,6 +619,10 @@ declare const LayersPanel: React$1.FC<LayersPanelProps>;
609
619
  * This component creates a complete editor experience by coordinating all three parts.
610
620
  */
611
621
 
622
+ /**
623
+ * Props for the VisualEditorWorkspace component
624
+ * @public
625
+ */
612
626
  interface VisualEditorWorkspaceProps {
613
627
  /** Editor mode configuration */
614
628
  mode?: EditorMode;
@@ -694,7 +708,37 @@ declare const AssetPicker: React$1.FC<AssetPickerProps>;
694
708
  */
695
709
 
696
710
  /**
697
- * Custom hook for managing editor state
711
+ * Custom hook for managing visual editor state.
712
+ *
713
+ * Provides a complete state management solution for the visual editor, including:
714
+ * - Element CRUD operations
715
+ * - Selection management
716
+ * - Undo/redo functionality
717
+ * - Canvas operations (zoom, pan)
718
+ * - History tracking
719
+ * - Import/export capabilities
720
+ *
721
+ * @param initialMode - Optional initial editor mode configuration
722
+ * @returns Object containing editor state, API methods, and utility functions
723
+ *
724
+ * @example
725
+ * ```tsx
726
+ * function MyEditor() {
727
+ * const { state, api, undo, redo, canUndo, canRedo } = useEditorState();
728
+ *
729
+ * const handleAddText = () => {
730
+ * api.addElement(createElement('text', { content: 'Hello' }));
731
+ * };
732
+ *
733
+ * return (
734
+ * <div>
735
+ * <button onClick={handleAddText}>Add Text</button>
736
+ * <button onClick={undo} disabled={!canUndo}>Undo</button>
737
+ * <button onClick={redo} disabled={!canRedo}>Redo</button>
738
+ * </div>
739
+ * );
740
+ * }
741
+ * ```
698
742
  */
699
743
  declare const useEditorState: (initialMode?: EditorMode | null) => {
700
744
  state: EditorState;
@@ -765,6 +809,30 @@ declare class ElementRegistry {
765
809
  * Create a global singleton registry (can be used across the app)
766
810
  */
767
811
  declare const globalElementRegistry: ElementRegistry;
812
+ /**
813
+ * React hook for creating and managing an element registry instance.
814
+ *
815
+ * The registry is memoized and will only re-initialize if initialRenderers changes.
816
+ * This ensures stable registry instances across re-renders.
817
+ *
818
+ * @param initialRenderers - Optional array of element renderers to register on initialization
819
+ * @returns ElementRegistry instance with registered renderers
820
+ *
821
+ * @example
822
+ * ```tsx
823
+ * import { useElementRegistry } from '@/core/ElementRegistry';
824
+ * import { TextElement, ImageElement } from '@/elements';
825
+ *
826
+ * function MyEditor() {
827
+ * const registry = useElementRegistry([TextElement, ImageElement]);
828
+ *
829
+ * // Use registry to look up renderers
830
+ * const renderer = registry.get('text');
831
+ *
832
+ * return <Canvas registry={registry} />;
833
+ * }
834
+ * ```
835
+ */
768
836
  declare const useElementRegistry: (initialRenderers?: ElementRenderer[]) => ElementRegistry;
769
837
 
770
838
  /**
package/dist/index.d.ts CHANGED
@@ -317,6 +317,7 @@ interface CustomEditorSeparator {
317
317
  type CustomEditorAction = CustomEditorButtonAction | CustomEditorDropdownAction | CustomEditorInputAction | CustomEditorColorAction | CustomEditorToggleAction | CustomEditorSeparator;
318
318
  /**
319
319
  * Configuration for topbar controls visibility
320
+ * @public
320
321
  */
321
322
  interface TopbarConfig {
322
323
  /** Show undo button */
@@ -352,6 +353,7 @@ interface TopbarConfig {
352
353
  }
353
354
  /**
354
355
  * Configuration for toolbar controls visibility
356
+ * @public
355
357
  */
356
358
  interface ToolbarConfig {
357
359
  /** Show element creation tools */
@@ -546,6 +548,10 @@ declare const VisualEditor: React$1.FC<VisualEditorProps>;
546
548
  * Dynamically renders fields based on the element's inspectorSchema.
547
549
  */
548
550
 
551
+ /**
552
+ * Props for the Inspector component
553
+ * @public
554
+ */
549
555
  interface InspectorProps {
550
556
  /** Currently selected element */
551
557
  selectedElement: EditorElement | null;
@@ -583,6 +589,10 @@ declare function renderField(field: InspectorFieldSchema, props: any, editingVal
583
589
  * reorder, and delete elements.
584
590
  */
585
591
 
592
+ /**
593
+ * Props for the LayersPanel component
594
+ * @public
595
+ */
586
596
  interface LayersPanelProps {
587
597
  /** All elements in the canvas */
588
598
  elements: EditorElement[];
@@ -609,6 +619,10 @@ declare const LayersPanel: React$1.FC<LayersPanelProps>;
609
619
  * This component creates a complete editor experience by coordinating all three parts.
610
620
  */
611
621
 
622
+ /**
623
+ * Props for the VisualEditorWorkspace component
624
+ * @public
625
+ */
612
626
  interface VisualEditorWorkspaceProps {
613
627
  /** Editor mode configuration */
614
628
  mode?: EditorMode;
@@ -694,7 +708,37 @@ declare const AssetPicker: React$1.FC<AssetPickerProps>;
694
708
  */
695
709
 
696
710
  /**
697
- * Custom hook for managing editor state
711
+ * Custom hook for managing visual editor state.
712
+ *
713
+ * Provides a complete state management solution for the visual editor, including:
714
+ * - Element CRUD operations
715
+ * - Selection management
716
+ * - Undo/redo functionality
717
+ * - Canvas operations (zoom, pan)
718
+ * - History tracking
719
+ * - Import/export capabilities
720
+ *
721
+ * @param initialMode - Optional initial editor mode configuration
722
+ * @returns Object containing editor state, API methods, and utility functions
723
+ *
724
+ * @example
725
+ * ```tsx
726
+ * function MyEditor() {
727
+ * const { state, api, undo, redo, canUndo, canRedo } = useEditorState();
728
+ *
729
+ * const handleAddText = () => {
730
+ * api.addElement(createElement('text', { content: 'Hello' }));
731
+ * };
732
+ *
733
+ * return (
734
+ * <div>
735
+ * <button onClick={handleAddText}>Add Text</button>
736
+ * <button onClick={undo} disabled={!canUndo}>Undo</button>
737
+ * <button onClick={redo} disabled={!canRedo}>Redo</button>
738
+ * </div>
739
+ * );
740
+ * }
741
+ * ```
698
742
  */
699
743
  declare const useEditorState: (initialMode?: EditorMode | null) => {
700
744
  state: EditorState;
@@ -765,6 +809,30 @@ declare class ElementRegistry {
765
809
  * Create a global singleton registry (can be used across the app)
766
810
  */
767
811
  declare const globalElementRegistry: ElementRegistry;
812
+ /**
813
+ * React hook for creating and managing an element registry instance.
814
+ *
815
+ * The registry is memoized and will only re-initialize if initialRenderers changes.
816
+ * This ensures stable registry instances across re-renders.
817
+ *
818
+ * @param initialRenderers - Optional array of element renderers to register on initialization
819
+ * @returns ElementRegistry instance with registered renderers
820
+ *
821
+ * @example
822
+ * ```tsx
823
+ * import { useElementRegistry } from '@/core/ElementRegistry';
824
+ * import { TextElement, ImageElement } from '@/elements';
825
+ *
826
+ * function MyEditor() {
827
+ * const registry = useElementRegistry([TextElement, ImageElement]);
828
+ *
829
+ * // Use registry to look up renderers
830
+ * const renderer = registry.get('text');
831
+ *
832
+ * return <Canvas registry={registry} />;
833
+ * }
834
+ * ```
835
+ */
768
836
  declare const useElementRegistry: (initialRenderers?: ElementRenderer[]) => ElementRegistry;
769
837
 
770
838
  /**