@snowcone-app/canvas 0.1.9 → 0.1.12
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/{CanvasStateV1-D5GzvmnY.cjs → CanvasStateV1-C4hC1MCe.cjs} +5 -5
- package/dist/{CanvasStateV1-D5GzvmnY.cjs.map → CanvasStateV1-C4hC1MCe.cjs.map} +1 -1
- package/dist/{CanvasStateV1-ejb4d_LM.js → CanvasStateV1-CJU_xYW5.js} +3 -3
- package/dist/{CanvasStateV1-ejb4d_LM.js.map → CanvasStateV1-CJU_xYW5.js.map} +1 -1
- package/dist/{HybridHistoryManager-BV6XV0nD.js → HybridHistoryManager-jBBnVim8.js} +54 -54
- package/dist/{HybridHistoryManager-BV6XV0nD.js.map → HybridHistoryManager-jBBnVim8.js.map} +1 -1
- package/dist/{ElementFactory-uJTXU-nP.js → ImportManager-Oqu2yB54.js} +916 -697
- package/dist/ImportManager-Oqu2yB54.js.map +1 -0
- package/dist/{ElementFactory-B7UOaJSD.cjs → ImportManager-W1eWhfyM.cjs} +5 -5
- package/dist/ImportManager-W1eWhfyM.cjs.map +1 -0
- package/dist/ThemeContext-BMNQKl1c.cjs +2 -0
- package/dist/{ThemeContext-4mJ_y0Me.cjs.map → ThemeContext-BMNQKl1c.cjs.map} +1 -1
- package/dist/ThemeContext-wj-wSO7J.js +1158 -0
- package/dist/{ThemeContext-H0Z-MqqR.js.map → ThemeContext-wj-wSO7J.js.map} +1 -1
- package/dist/advanced.js +5 -32
- package/dist/advanced.js.map +1 -1
- package/dist/advanced.mjs +593 -15081
- package/dist/advanced.mjs.map +1 -1
- package/dist/components/embed/KitLayout.d.ts +22 -0
- package/dist/components/embed/UndoRedoControls.d.ts +3 -0
- package/dist/compose-Dqh2f8tS.js +22222 -0
- package/dist/compose-Dqh2f8tS.js.map +1 -0
- package/dist/compose-HDJp4Z_d.cjs +60 -0
- package/dist/compose-HDJp4Z_d.cjs.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +589 -508
- package/dist/index.mjs.map +1 -1
- package/dist/internals.js +1 -1
- package/dist/internals.js.map +1 -1
- package/dist/internals.mjs +101 -102
- package/dist/internals.mjs.map +1 -1
- package/dist/style.css.d.ts +4 -0
- package/dist/testing.js +1 -1
- package/dist/testing.mjs +11 -11
- package/package.json +9 -5
- package/dist/ElementFactory-B7UOaJSD.cjs.map +0 -1
- package/dist/ElementFactory-uJTXU-nP.js.map +0 -1
- package/dist/ImportManager-BYwuK6n4.cjs +0 -2
- package/dist/ImportManager-BYwuK6n4.cjs.map +0 -1
- package/dist/ImportManager-CxiaRg1N.js +0 -222
- package/dist/ImportManager-CxiaRg1N.js.map +0 -1
- package/dist/ThemeContext-4mJ_y0Me.cjs +0 -2
- package/dist/ThemeContext-H0Z-MqqR.js +0 -1077
- package/dist/components/stories/utils/MockEditorProvider.d.ts +0 -32
- package/dist/components/stories/utils/QACanvasCard.d.ts +0 -41
- package/dist/components/stories/utils/VisualQACard.d.ts +0 -24
- package/dist/components/stories/utils/element-factories.d.ts +0 -188
- package/dist/components/stories/utils/spec-to-elements.d.ts +0 -74
- package/dist/components/stories/utils/themeDecorator.d.ts +0 -45
- package/dist/components/stories/utils/unified-test-cases.d.ts +0 -27
- package/dist/compose-Bo108juW.cjs +0 -33
- package/dist/compose-Bo108juW.cjs.map +0 -1
- package/dist/compose-DQ1FZS3O.js +0 -7690
- package/dist/compose-DQ1FZS3O.js.map +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const h=require("./ElementFactory-B7UOaJSD.cjs"),d=require("./HybridHistoryManager-BXD93pp8.cjs"),u=d.createLogger("ImportManager"),m=class m{static async importFromJSON(t){try{const r=await this.readFileAsText(t),a=JSON.parse(r);if(this.validateDocument(a),!this.SUPPORTED_VERSIONS.includes(a.metadata.version))throw new Error(`Unsupported version: ${a.metadata.version}. Supported versions: ${this.SUPPORTED_VERSIONS.join(", ")}`);if(a.metadata.version==="1.0.0")return this.migrateV1Document(a);const s=[],n=[];return a.artboards.forEach(e=>{const o=d.ArtboardElement.fromJSON({id:e.id,name:e.name,x:e.x,y:e.y,width:e.width,height:e.height,backgroundColor:e.backgroundColor,elementIds:e.elements.map(c=>c.id||"")}),i=e.elements.map(c=>{try{return h.ElementFactory.createFromJSON(c)}catch(g){return u.error("Failed to create element:",c,g),null}}).filter(c=>c!==null);s.push(o),n.push(...i)}),await this.preloadAllImages(n),{success:!0,artboards:s,elements:n,activeArtboardId:a.activeArtboardId}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Unknown error"}}}static async migrateV1Document(t){var r,a,s;try{const n=t.elements||[],e=new d.ArtboardElement({id:"artboard-migrated",name:"Artboard 1",x:0,y:0,width:((r=t.canvas)==null?void 0:r.width)||1920,height:((a=t.canvas)==null?void 0:a.height)||1080,backgroundColor:((s=t.canvas)==null?void 0:s.backgroundColor)||"#ffffff"}),o=n.map(i=>{try{return h.ElementFactory.createFromJSON(i)}catch(c){return u.error("Failed to create element:",i,c),null}}).filter(i=>i!==null);return o.forEach(i=>{e.addElementId(i.id)}),await this.preloadAllImages(o),{success:!0,artboards:[e],elements:o,activeArtboardId:e.id}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Migration failed"}}}static async importImage(t){try{if(!t.type.startsWith("image/"))throw new Error("File is not an image");const r=10*1024*1024;if(t.size>r)throw new Error("Image file is too large (max 10MB)");const a=await this.readFileAsDataURL(t),{width:s,height:n}=await this.getImageDimensions(a);return{success:!0,dataUrl:a,filename:t.name,width:s,height:n}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Unknown error"}}}static validateDocument(t){if(!t||typeof t!="object")throw new Error("Invalid document");const r=t;if(!r.metadata)throw new Error("Missing metadata");if(!r.metadata.version)throw new Error("Missing version in metadata");if(!r.artboards&&!r.elements)throw new Error("Missing artboards or elements array");if(r.artboards&&!Array.isArray(r.artboards))throw new Error("Invalid artboards array")}static readFileAsText(t){return new Promise((r,a)=>{const s=new FileReader;s.onload=n=>{var e;return r((e=n.target)==null?void 0:e.result)},s.onerror=()=>a(new Error("Failed to read file")),s.readAsText(t)})}static readFileAsDataURL(t){return new Promise((r,a)=>{const s=new FileReader;s.onload=n=>{var e;return r((e=n.target)==null?void 0:e.result)},s.onerror=()=>a(new Error("Failed to read file")),s.readAsDataURL(t)})}static getImageDimensions(t){return new Promise((r,a)=>{const s=new Image;s.onload=()=>{r({width:s.width,height:s.height})},s.onerror=()=>a(new Error("Failed to load image")),s.src=t})}static validateImportedData(t,r){const a=[],s=new Set;t.forEach(e=>{s.has(e.id)&&a.push(`Duplicate artboard ID: ${e.id}`),s.add(e.id)});const n=new Set;return r.forEach(e=>{n.has(e.id)&&a.push(`Duplicate element ID: ${e.id}`),n.add(e.id)}),t.forEach(e=>{e.getElementIds().forEach(o=>{n.has(o)||a.push(`Artboard "${e.name}" references missing element: ${o}`)})}),{valid:a.length===0,errors:a}}static getImportSummary(t,r){const a=this.validateImportedData(t,r);return{artboardCount:t.length,elementCount:r.length,artboardNames:t.map(s=>s.name),warnings:a.errors}}static async preloadAllImages(t){const r=[],a=n=>{n.transformType==="image"?r.push(n):n.transformType==="group"&&"children"in n&&n.children.forEach(e=>a(e))};t.forEach(a);const s=r.map(n=>new Promise(e=>{if(n.imageLoaded)e();else if(n.imageElement){const o=n.imageElement,i=()=>{o.removeEventListener("load",i),o.removeEventListener("error",c),e()},c=()=>{o.removeEventListener("load",i),o.removeEventListener("error",c),e()};o.addEventListener("load",i),o.addEventListener("error",c)}else e()}));await Promise.all(s)}};m.SUPPORTED_VERSIONS=["1.0.0","2.0.0"];let l=m;exports.ImportManager=l;
|
|
2
|
-
//# sourceMappingURL=ImportManager-BYwuK6n4.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ImportManager-BYwuK6n4.cjs","sources":["../src/utils/ImportManager.ts"],"sourcesContent":["/**\n * ImportManager - Handles importing workspace from JSON and images\n */\n\nimport { ElementFactory } from '../core/ElementFactory.js';\nimport { ArtboardElement } from '../core/ArtboardElement.js';\nimport type { CanvasDocument } from './ExportManager.js';\nimport type { TextElement } from '../core/TextElement.js';\nimport type { ImageElement } from '../core/ImageElement.js';\nimport type { GroupElement } from '../core/GroupElement.js';\nimport { createLogger } from './logger.js';\n\nconst logger = createLogger('ImportManager');\n\n/** V1 document format (pre-artboard) */\ninterface V1CanvasDocument {\n metadata: { version: string };\n canvas?: { width?: number; height?: number; backgroundColor?: string };\n elements?: Record<string, unknown>[];\n}\n\nexport interface ImportResult {\n success: boolean;\n artboards?: ArtboardElement[];\n elements?: (TextElement | ImageElement | GroupElement)[];\n activeArtboardId?: string | null;\n error?: string;\n}\n\nexport interface ImageImportResult {\n success: boolean;\n dataUrl?: string;\n filename?: string;\n width?: number;\n height?: number;\n error?: string;\n}\n\nexport class ImportManager {\n private static readonly SUPPORTED_VERSIONS = ['1.0.0', '2.0.0'];\n\n /**\n * Import workspace from JSON file\n */\n static async importFromJSON(file: File): Promise<ImportResult> {\n try {\n // Read file as text\n const text = await this.readFileAsText(file);\n\n // Parse JSON\n const document: CanvasDocument = JSON.parse(text);\n\n // Validate structure\n this.validateDocument(document);\n\n // Check version compatibility\n if (!this.SUPPORTED_VERSIONS.includes(document.metadata.version)) {\n throw new Error(\n `Unsupported version: ${document.metadata.version}. ` +\n `Supported versions: ${this.SUPPORTED_VERSIONS.join(', ')}`\n );\n }\n\n // Handle version 1.0.0 (no artboards) - migrate to artboards\n if (document.metadata.version === '1.0.0') {\n return this.migrateV1Document(document as unknown as V1CanvasDocument);\n }\n\n // Deserialize artboards and elements\n const artboards: ArtboardElement[] = [];\n const allElements: (TextElement | ImageElement | GroupElement)[] = [];\n\n document.artboards.forEach((artboardData) => {\n // Create artboard\n const artboard = ArtboardElement.fromJSON({\n id: artboardData.id,\n name: artboardData.name,\n x: artboardData.x,\n y: artboardData.y,\n width: artboardData.width,\n height: artboardData.height,\n backgroundColor: artboardData.backgroundColor,\n elementIds: artboardData.elements.map((e) => e.id || ''),\n });\n\n // Deserialize elements for this artboard\n const elements = artboardData.elements\n .map((elementConfig) => {\n try {\n return ElementFactory.createFromJSON(elementConfig);\n } catch (error) {\n logger.error('Failed to create element:', elementConfig, error);\n return null;\n }\n })\n .filter((element) => element !== null) as (TextElement | ImageElement | GroupElement)[];\n\n artboards.push(artboard);\n allElements.push(...elements);\n });\n\n // PERFORMANCE: Wait for all images to load in parallel before returning\n await this.preloadAllImages(allElements);\n\n return {\n success: true,\n artboards,\n elements: allElements,\n activeArtboardId: document.activeArtboardId,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Migrate v1 document (no artboards) to v2 (with artboards)\n */\n private static async migrateV1Document(document: V1CanvasDocument): Promise<ImportResult> {\n try {\n // V1 format: { metadata, canvas, elements }\n const elements = document.elements || [];\n\n // Create a default artboard containing all elements\n const artboard = new ArtboardElement({\n id: 'artboard-migrated',\n name: 'Artboard 1',\n x: 0,\n y: 0,\n width: document.canvas?.width || 1920,\n height: document.canvas?.height || 1080,\n backgroundColor: document.canvas?.backgroundColor || '#ffffff',\n });\n\n // Deserialize elements\n const deserializedElements = elements\n .map((elementConfig: Record<string, unknown>) => {\n try {\n return ElementFactory.createFromJSON(elementConfig as unknown as import('../types/index.js').AnyElementConfig);\n } catch (error) {\n logger.error('Failed to create element:', elementConfig, error);\n return null;\n }\n })\n .filter((element): element is TextElement | ImageElement | GroupElement => element !== null);\n\n // Add all element IDs to artboard\n deserializedElements.forEach((element) => {\n artboard.addElementId(element.id);\n });\n\n // PERFORMANCE: Wait for all images to load in parallel before returning\n await this.preloadAllImages(deserializedElements);\n\n return {\n success: true,\n artboards: [artboard],\n elements: deserializedElements,\n activeArtboardId: artboard.id,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Migration failed',\n };\n }\n }\n\n /**\n * Import image file\n */\n static async importImage(file: File): Promise<ImageImportResult> {\n try {\n // Validate file type\n if (!file.type.startsWith('image/')) {\n throw new Error('File is not an image');\n }\n\n // Check file size (max 10MB)\n const maxSize = 10 * 1024 * 1024; // 10MB\n if (file.size > maxSize) {\n throw new Error('Image file is too large (max 10MB)');\n }\n\n // Read as data URL\n const dataUrl = await this.readFileAsDataURL(file);\n\n // Get image dimensions\n const { width, height } = await this.getImageDimensions(dataUrl);\n\n return {\n success: true,\n dataUrl,\n filename: file.name,\n width,\n height,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Validate document structure\n */\n private static validateDocument(document: unknown): asserts document is CanvasDocument {\n if (!document || typeof document !== 'object') {\n throw new Error('Invalid document');\n }\n const doc = document as Record<string, unknown>;\n if (!doc.metadata) {\n throw new Error('Missing metadata');\n }\n if (!(doc.metadata as Record<string, unknown>).version) {\n throw new Error('Missing version in metadata');\n }\n if (!doc.artboards && !doc.elements) {\n throw new Error('Missing artboards or elements array');\n }\n if (doc.artboards && !Array.isArray(doc.artboards)) {\n throw new Error('Invalid artboards array');\n }\n }\n\n /**\n * Read file as text\n */\n private static readFileAsText(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n }\n\n /**\n * Read file as data URL\n */\n private static readFileAsDataURL(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n });\n }\n\n /**\n * Get image dimensions from data URL\n */\n private static getImageDimensions(dataUrl: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n resolve({ width: img.width, height: img.height });\n };\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = dataUrl;\n });\n }\n\n /**\n * Validate imported data before applying to state\n */\n static validateImportedData(\n artboards: ArtboardElement[],\n elements: (TextElement | ImageElement | GroupElement)[]\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check for duplicate artboard IDs\n const artboardIds = new Set();\n artboards.forEach((artboard) => {\n if (artboardIds.has(artboard.id)) {\n errors.push(`Duplicate artboard ID: ${artboard.id}`);\n }\n artboardIds.add(artboard.id);\n });\n\n // Check for duplicate element IDs\n const elementIds = new Set();\n elements.forEach((element) => {\n if (elementIds.has(element.id)) {\n errors.push(`Duplicate element ID: ${element.id}`);\n }\n elementIds.add(element.id);\n });\n\n // Validate element-to-artboard references\n artboards.forEach((artboard) => {\n artboard.getElementIds().forEach((elementId: string) => {\n if (!elementIds.has(elementId)) {\n errors.push(`Artboard \"${artboard.name}\" references missing element: ${elementId}`);\n }\n });\n });\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get import summary (for UI display before confirming)\n */\n static getImportSummary(\n artboards: ArtboardElement[],\n elements: (TextElement | ImageElement | GroupElement)[]\n ): {\n artboardCount: number;\n elementCount: number;\n artboardNames: string[];\n warnings: string[];\n } {\n const validation = this.validateImportedData(artboards, elements);\n\n return {\n artboardCount: artboards.length,\n elementCount: elements.length,\n artboardNames: artboards.map((a) => a.name),\n warnings: validation.errors,\n };\n }\n\n /**\n * Preload all images in parallel for fast artboard switching\n * Recursively finds all ImageElements (including those in groups)\n */\n private static async preloadAllImages(elements: (TextElement | ImageElement | GroupElement)[]): Promise<void> {\n const imageElements: ImageElement[] = [];\n\n // Recursively find all image elements\n const findImages = (el: TextElement | ImageElement | GroupElement) => {\n if (el.transformType === 'image') {\n imageElements.push(el as ImageElement);\n } else if (el.transformType === 'group' && 'children' in el) {\n (el as GroupElement).children.forEach((child) => findImages(child as TextElement | ImageElement | GroupElement));\n }\n };\n\n elements.forEach(findImages);\n\n // Wait for all images to load in parallel\n const loadPromises = imageElements.map((img: ImageElement) => {\n return new Promise<void>((resolve) => {\n if (img.imageLoaded) {\n resolve();\n } else if (img.imageElement) {\n // Image is currently loading\n const imgEl = img.imageElement;\n const onLoad = () => {\n imgEl.removeEventListener('load', onLoad);\n imgEl.removeEventListener('error', onError);\n resolve();\n };\n const onError = () => {\n imgEl.removeEventListener('load', onLoad);\n imgEl.removeEventListener('error', onError);\n resolve(); // Resolve even on error to not block other images\n };\n imgEl.addEventListener('load', onLoad);\n imgEl.addEventListener('error', onError);\n } else {\n resolve();\n }\n });\n });\n\n await Promise.all(loadPromises);\n }\n}\n\nexport default ImportManager;\n"],"names":["logger","createLogger","_ImportManager","file","text","document","artboards","allElements","artboardData","artboard","ArtboardElement","e","elements","elementConfig","ElementFactory","error","element","_a","_b","_c","deserializedElements","maxSize","dataUrl","width","height","doc","resolve","reject","reader","img","errors","artboardIds","elementIds","elementId","validation","a","imageElements","findImages","el","child","loadPromises","imgEl","onLoad","onError","ImportManager"],"mappings":"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"}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { E as m } from "./ElementFactory-uJTXU-nP.js";
|
|
2
|
-
import { c as f, i as l } from "./HybridHistoryManager-BV6XV0nD.js";
|
|
3
|
-
const h = f("ImportManager"), c = class c {
|
|
4
|
-
/**
|
|
5
|
-
* Import workspace from JSON file
|
|
6
|
-
*/
|
|
7
|
-
static async importFromJSON(t) {
|
|
8
|
-
try {
|
|
9
|
-
const r = await this.readFileAsText(t), a = JSON.parse(r);
|
|
10
|
-
if (this.validateDocument(a), !this.SUPPORTED_VERSIONS.includes(a.metadata.version))
|
|
11
|
-
throw new Error(
|
|
12
|
-
`Unsupported version: ${a.metadata.version}. Supported versions: ${this.SUPPORTED_VERSIONS.join(", ")}`
|
|
13
|
-
);
|
|
14
|
-
if (a.metadata.version === "1.0.0")
|
|
15
|
-
return this.migrateV1Document(a);
|
|
16
|
-
const s = [], o = [];
|
|
17
|
-
return a.artboards.forEach((e) => {
|
|
18
|
-
const n = l.fromJSON({
|
|
19
|
-
id: e.id,
|
|
20
|
-
name: e.name,
|
|
21
|
-
x: e.x,
|
|
22
|
-
y: e.y,
|
|
23
|
-
width: e.width,
|
|
24
|
-
height: e.height,
|
|
25
|
-
backgroundColor: e.backgroundColor,
|
|
26
|
-
elementIds: e.elements.map((d) => d.id || "")
|
|
27
|
-
}), i = e.elements.map((d) => {
|
|
28
|
-
try {
|
|
29
|
-
return m.createFromJSON(d);
|
|
30
|
-
} catch (u) {
|
|
31
|
-
return h.error("Failed to create element:", d, u), null;
|
|
32
|
-
}
|
|
33
|
-
}).filter((d) => d !== null);
|
|
34
|
-
s.push(n), o.push(...i);
|
|
35
|
-
}), await this.preloadAllImages(o), {
|
|
36
|
-
success: !0,
|
|
37
|
-
artboards: s,
|
|
38
|
-
elements: o,
|
|
39
|
-
activeArtboardId: a.activeArtboardId
|
|
40
|
-
};
|
|
41
|
-
} catch (r) {
|
|
42
|
-
return {
|
|
43
|
-
success: !1,
|
|
44
|
-
error: r instanceof Error ? r.message : "Unknown error"
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Migrate v1 document (no artboards) to v2 (with artboards)
|
|
50
|
-
*/
|
|
51
|
-
static async migrateV1Document(t) {
|
|
52
|
-
var r, a, s;
|
|
53
|
-
try {
|
|
54
|
-
const o = t.elements || [], e = new l({
|
|
55
|
-
id: "artboard-migrated",
|
|
56
|
-
name: "Artboard 1",
|
|
57
|
-
x: 0,
|
|
58
|
-
y: 0,
|
|
59
|
-
width: ((r = t.canvas) == null ? void 0 : r.width) || 1920,
|
|
60
|
-
height: ((a = t.canvas) == null ? void 0 : a.height) || 1080,
|
|
61
|
-
backgroundColor: ((s = t.canvas) == null ? void 0 : s.backgroundColor) || "#ffffff"
|
|
62
|
-
}), n = o.map((i) => {
|
|
63
|
-
try {
|
|
64
|
-
return m.createFromJSON(i);
|
|
65
|
-
} catch (d) {
|
|
66
|
-
return h.error("Failed to create element:", i, d), null;
|
|
67
|
-
}
|
|
68
|
-
}).filter((i) => i !== null);
|
|
69
|
-
return n.forEach((i) => {
|
|
70
|
-
e.addElementId(i.id);
|
|
71
|
-
}), await this.preloadAllImages(n), {
|
|
72
|
-
success: !0,
|
|
73
|
-
artboards: [e],
|
|
74
|
-
elements: n,
|
|
75
|
-
activeArtboardId: e.id
|
|
76
|
-
};
|
|
77
|
-
} catch (o) {
|
|
78
|
-
return {
|
|
79
|
-
success: !1,
|
|
80
|
-
error: o instanceof Error ? o.message : "Migration failed"
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Import image file
|
|
86
|
-
*/
|
|
87
|
-
static async importImage(t) {
|
|
88
|
-
try {
|
|
89
|
-
if (!t.type.startsWith("image/"))
|
|
90
|
-
throw new Error("File is not an image");
|
|
91
|
-
const r = 10 * 1024 * 1024;
|
|
92
|
-
if (t.size > r)
|
|
93
|
-
throw new Error("Image file is too large (max 10MB)");
|
|
94
|
-
const a = await this.readFileAsDataURL(t), { width: s, height: o } = await this.getImageDimensions(a);
|
|
95
|
-
return {
|
|
96
|
-
success: !0,
|
|
97
|
-
dataUrl: a,
|
|
98
|
-
filename: t.name,
|
|
99
|
-
width: s,
|
|
100
|
-
height: o
|
|
101
|
-
};
|
|
102
|
-
} catch (r) {
|
|
103
|
-
return {
|
|
104
|
-
success: !1,
|
|
105
|
-
error: r instanceof Error ? r.message : "Unknown error"
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Validate document structure
|
|
111
|
-
*/
|
|
112
|
-
static validateDocument(t) {
|
|
113
|
-
if (!t || typeof t != "object")
|
|
114
|
-
throw new Error("Invalid document");
|
|
115
|
-
const r = t;
|
|
116
|
-
if (!r.metadata)
|
|
117
|
-
throw new Error("Missing metadata");
|
|
118
|
-
if (!r.metadata.version)
|
|
119
|
-
throw new Error("Missing version in metadata");
|
|
120
|
-
if (!r.artboards && !r.elements)
|
|
121
|
-
throw new Error("Missing artboards or elements array");
|
|
122
|
-
if (r.artboards && !Array.isArray(r.artboards))
|
|
123
|
-
throw new Error("Invalid artboards array");
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Read file as text
|
|
127
|
-
*/
|
|
128
|
-
static readFileAsText(t) {
|
|
129
|
-
return new Promise((r, a) => {
|
|
130
|
-
const s = new FileReader();
|
|
131
|
-
s.onload = (o) => {
|
|
132
|
-
var e;
|
|
133
|
-
return r((e = o.target) == null ? void 0 : e.result);
|
|
134
|
-
}, s.onerror = () => a(new Error("Failed to read file")), s.readAsText(t);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Read file as data URL
|
|
139
|
-
*/
|
|
140
|
-
static readFileAsDataURL(t) {
|
|
141
|
-
return new Promise((r, a) => {
|
|
142
|
-
const s = new FileReader();
|
|
143
|
-
s.onload = (o) => {
|
|
144
|
-
var e;
|
|
145
|
-
return r((e = o.target) == null ? void 0 : e.result);
|
|
146
|
-
}, s.onerror = () => a(new Error("Failed to read file")), s.readAsDataURL(t);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Get image dimensions from data URL
|
|
151
|
-
*/
|
|
152
|
-
static getImageDimensions(t) {
|
|
153
|
-
return new Promise((r, a) => {
|
|
154
|
-
const s = new Image();
|
|
155
|
-
s.onload = () => {
|
|
156
|
-
r({ width: s.width, height: s.height });
|
|
157
|
-
}, s.onerror = () => a(new Error("Failed to load image")), s.src = t;
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Validate imported data before applying to state
|
|
162
|
-
*/
|
|
163
|
-
static validateImportedData(t, r) {
|
|
164
|
-
const a = [], s = /* @__PURE__ */ new Set();
|
|
165
|
-
t.forEach((e) => {
|
|
166
|
-
s.has(e.id) && a.push(`Duplicate artboard ID: ${e.id}`), s.add(e.id);
|
|
167
|
-
});
|
|
168
|
-
const o = /* @__PURE__ */ new Set();
|
|
169
|
-
return r.forEach((e) => {
|
|
170
|
-
o.has(e.id) && a.push(`Duplicate element ID: ${e.id}`), o.add(e.id);
|
|
171
|
-
}), t.forEach((e) => {
|
|
172
|
-
e.getElementIds().forEach((n) => {
|
|
173
|
-
o.has(n) || a.push(`Artboard "${e.name}" references missing element: ${n}`);
|
|
174
|
-
});
|
|
175
|
-
}), {
|
|
176
|
-
valid: a.length === 0,
|
|
177
|
-
errors: a
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Get import summary (for UI display before confirming)
|
|
182
|
-
*/
|
|
183
|
-
static getImportSummary(t, r) {
|
|
184
|
-
const a = this.validateImportedData(t, r);
|
|
185
|
-
return {
|
|
186
|
-
artboardCount: t.length,
|
|
187
|
-
elementCount: r.length,
|
|
188
|
-
artboardNames: t.map((s) => s.name),
|
|
189
|
-
warnings: a.errors
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Preload all images in parallel for fast artboard switching
|
|
194
|
-
* Recursively finds all ImageElements (including those in groups)
|
|
195
|
-
*/
|
|
196
|
-
static async preloadAllImages(t) {
|
|
197
|
-
const r = [], a = (o) => {
|
|
198
|
-
o.transformType === "image" ? r.push(o) : o.transformType === "group" && "children" in o && o.children.forEach((e) => a(e));
|
|
199
|
-
};
|
|
200
|
-
t.forEach(a);
|
|
201
|
-
const s = r.map((o) => new Promise((e) => {
|
|
202
|
-
if (o.imageLoaded)
|
|
203
|
-
e();
|
|
204
|
-
else if (o.imageElement) {
|
|
205
|
-
const n = o.imageElement, i = () => {
|
|
206
|
-
n.removeEventListener("load", i), n.removeEventListener("error", d), e();
|
|
207
|
-
}, d = () => {
|
|
208
|
-
n.removeEventListener("load", i), n.removeEventListener("error", d), e();
|
|
209
|
-
};
|
|
210
|
-
n.addEventListener("load", i), n.addEventListener("error", d);
|
|
211
|
-
} else
|
|
212
|
-
e();
|
|
213
|
-
}));
|
|
214
|
-
await Promise.all(s);
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
c.SUPPORTED_VERSIONS = ["1.0.0", "2.0.0"];
|
|
218
|
-
let g = c;
|
|
219
|
-
export {
|
|
220
|
-
g as I
|
|
221
|
-
};
|
|
222
|
-
//# sourceMappingURL=ImportManager-CxiaRg1N.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ImportManager-CxiaRg1N.js","sources":["../src/utils/ImportManager.ts"],"sourcesContent":["/**\n * ImportManager - Handles importing workspace from JSON and images\n */\n\nimport { ElementFactory } from '../core/ElementFactory.js';\nimport { ArtboardElement } from '../core/ArtboardElement.js';\nimport type { CanvasDocument } from './ExportManager.js';\nimport type { TextElement } from '../core/TextElement.js';\nimport type { ImageElement } from '../core/ImageElement.js';\nimport type { GroupElement } from '../core/GroupElement.js';\nimport { createLogger } from './logger.js';\n\nconst logger = createLogger('ImportManager');\n\n/** V1 document format (pre-artboard) */\ninterface V1CanvasDocument {\n metadata: { version: string };\n canvas?: { width?: number; height?: number; backgroundColor?: string };\n elements?: Record<string, unknown>[];\n}\n\nexport interface ImportResult {\n success: boolean;\n artboards?: ArtboardElement[];\n elements?: (TextElement | ImageElement | GroupElement)[];\n activeArtboardId?: string | null;\n error?: string;\n}\n\nexport interface ImageImportResult {\n success: boolean;\n dataUrl?: string;\n filename?: string;\n width?: number;\n height?: number;\n error?: string;\n}\n\nexport class ImportManager {\n private static readonly SUPPORTED_VERSIONS = ['1.0.0', '2.0.0'];\n\n /**\n * Import workspace from JSON file\n */\n static async importFromJSON(file: File): Promise<ImportResult> {\n try {\n // Read file as text\n const text = await this.readFileAsText(file);\n\n // Parse JSON\n const document: CanvasDocument = JSON.parse(text);\n\n // Validate structure\n this.validateDocument(document);\n\n // Check version compatibility\n if (!this.SUPPORTED_VERSIONS.includes(document.metadata.version)) {\n throw new Error(\n `Unsupported version: ${document.metadata.version}. ` +\n `Supported versions: ${this.SUPPORTED_VERSIONS.join(', ')}`\n );\n }\n\n // Handle version 1.0.0 (no artboards) - migrate to artboards\n if (document.metadata.version === '1.0.0') {\n return this.migrateV1Document(document as unknown as V1CanvasDocument);\n }\n\n // Deserialize artboards and elements\n const artboards: ArtboardElement[] = [];\n const allElements: (TextElement | ImageElement | GroupElement)[] = [];\n\n document.artboards.forEach((artboardData) => {\n // Create artboard\n const artboard = ArtboardElement.fromJSON({\n id: artboardData.id,\n name: artboardData.name,\n x: artboardData.x,\n y: artboardData.y,\n width: artboardData.width,\n height: artboardData.height,\n backgroundColor: artboardData.backgroundColor,\n elementIds: artboardData.elements.map((e) => e.id || ''),\n });\n\n // Deserialize elements for this artboard\n const elements = artboardData.elements\n .map((elementConfig) => {\n try {\n return ElementFactory.createFromJSON(elementConfig);\n } catch (error) {\n logger.error('Failed to create element:', elementConfig, error);\n return null;\n }\n })\n .filter((element) => element !== null) as (TextElement | ImageElement | GroupElement)[];\n\n artboards.push(artboard);\n allElements.push(...elements);\n });\n\n // PERFORMANCE: Wait for all images to load in parallel before returning\n await this.preloadAllImages(allElements);\n\n return {\n success: true,\n artboards,\n elements: allElements,\n activeArtboardId: document.activeArtboardId,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Migrate v1 document (no artboards) to v2 (with artboards)\n */\n private static async migrateV1Document(document: V1CanvasDocument): Promise<ImportResult> {\n try {\n // V1 format: { metadata, canvas, elements }\n const elements = document.elements || [];\n\n // Create a default artboard containing all elements\n const artboard = new ArtboardElement({\n id: 'artboard-migrated',\n name: 'Artboard 1',\n x: 0,\n y: 0,\n width: document.canvas?.width || 1920,\n height: document.canvas?.height || 1080,\n backgroundColor: document.canvas?.backgroundColor || '#ffffff',\n });\n\n // Deserialize elements\n const deserializedElements = elements\n .map((elementConfig: Record<string, unknown>) => {\n try {\n return ElementFactory.createFromJSON(elementConfig as unknown as import('../types/index.js').AnyElementConfig);\n } catch (error) {\n logger.error('Failed to create element:', elementConfig, error);\n return null;\n }\n })\n .filter((element): element is TextElement | ImageElement | GroupElement => element !== null);\n\n // Add all element IDs to artboard\n deserializedElements.forEach((element) => {\n artboard.addElementId(element.id);\n });\n\n // PERFORMANCE: Wait for all images to load in parallel before returning\n await this.preloadAllImages(deserializedElements);\n\n return {\n success: true,\n artboards: [artboard],\n elements: deserializedElements,\n activeArtboardId: artboard.id,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Migration failed',\n };\n }\n }\n\n /**\n * Import image file\n */\n static async importImage(file: File): Promise<ImageImportResult> {\n try {\n // Validate file type\n if (!file.type.startsWith('image/')) {\n throw new Error('File is not an image');\n }\n\n // Check file size (max 10MB)\n const maxSize = 10 * 1024 * 1024; // 10MB\n if (file.size > maxSize) {\n throw new Error('Image file is too large (max 10MB)');\n }\n\n // Read as data URL\n const dataUrl = await this.readFileAsDataURL(file);\n\n // Get image dimensions\n const { width, height } = await this.getImageDimensions(dataUrl);\n\n return {\n success: true,\n dataUrl,\n filename: file.name,\n width,\n height,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Validate document structure\n */\n private static validateDocument(document: unknown): asserts document is CanvasDocument {\n if (!document || typeof document !== 'object') {\n throw new Error('Invalid document');\n }\n const doc = document as Record<string, unknown>;\n if (!doc.metadata) {\n throw new Error('Missing metadata');\n }\n if (!(doc.metadata as Record<string, unknown>).version) {\n throw new Error('Missing version in metadata');\n }\n if (!doc.artboards && !doc.elements) {\n throw new Error('Missing artboards or elements array');\n }\n if (doc.artboards && !Array.isArray(doc.artboards)) {\n throw new Error('Invalid artboards array');\n }\n }\n\n /**\n * Read file as text\n */\n private static readFileAsText(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n }\n\n /**\n * Read file as data URL\n */\n private static readFileAsDataURL(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => resolve(e.target?.result as string);\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n });\n }\n\n /**\n * Get image dimensions from data URL\n */\n private static getImageDimensions(dataUrl: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n resolve({ width: img.width, height: img.height });\n };\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = dataUrl;\n });\n }\n\n /**\n * Validate imported data before applying to state\n */\n static validateImportedData(\n artboards: ArtboardElement[],\n elements: (TextElement | ImageElement | GroupElement)[]\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check for duplicate artboard IDs\n const artboardIds = new Set();\n artboards.forEach((artboard) => {\n if (artboardIds.has(artboard.id)) {\n errors.push(`Duplicate artboard ID: ${artboard.id}`);\n }\n artboardIds.add(artboard.id);\n });\n\n // Check for duplicate element IDs\n const elementIds = new Set();\n elements.forEach((element) => {\n if (elementIds.has(element.id)) {\n errors.push(`Duplicate element ID: ${element.id}`);\n }\n elementIds.add(element.id);\n });\n\n // Validate element-to-artboard references\n artboards.forEach((artboard) => {\n artboard.getElementIds().forEach((elementId: string) => {\n if (!elementIds.has(elementId)) {\n errors.push(`Artboard \"${artboard.name}\" references missing element: ${elementId}`);\n }\n });\n });\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get import summary (for UI display before confirming)\n */\n static getImportSummary(\n artboards: ArtboardElement[],\n elements: (TextElement | ImageElement | GroupElement)[]\n ): {\n artboardCount: number;\n elementCount: number;\n artboardNames: string[];\n warnings: string[];\n } {\n const validation = this.validateImportedData(artboards, elements);\n\n return {\n artboardCount: artboards.length,\n elementCount: elements.length,\n artboardNames: artboards.map((a) => a.name),\n warnings: validation.errors,\n };\n }\n\n /**\n * Preload all images in parallel for fast artboard switching\n * Recursively finds all ImageElements (including those in groups)\n */\n private static async preloadAllImages(elements: (TextElement | ImageElement | GroupElement)[]): Promise<void> {\n const imageElements: ImageElement[] = [];\n\n // Recursively find all image elements\n const findImages = (el: TextElement | ImageElement | GroupElement) => {\n if (el.transformType === 'image') {\n imageElements.push(el as ImageElement);\n } else if (el.transformType === 'group' && 'children' in el) {\n (el as GroupElement).children.forEach((child) => findImages(child as TextElement | ImageElement | GroupElement));\n }\n };\n\n elements.forEach(findImages);\n\n // Wait for all images to load in parallel\n const loadPromises = imageElements.map((img: ImageElement) => {\n return new Promise<void>((resolve) => {\n if (img.imageLoaded) {\n resolve();\n } else if (img.imageElement) {\n // Image is currently loading\n const imgEl = img.imageElement;\n const onLoad = () => {\n imgEl.removeEventListener('load', onLoad);\n imgEl.removeEventListener('error', onError);\n resolve();\n };\n const onError = () => {\n imgEl.removeEventListener('load', onLoad);\n imgEl.removeEventListener('error', onError);\n resolve(); // Resolve even on error to not block other images\n };\n imgEl.addEventListener('load', onLoad);\n imgEl.addEventListener('error', onError);\n } else {\n resolve();\n }\n });\n });\n\n await Promise.all(loadPromises);\n }\n}\n\nexport default ImportManager;\n"],"names":["logger","createLogger","_ImportManager","file","text","document","artboards","allElements","artboardData","artboard","ArtboardElement","e","elements","elementConfig","ElementFactory","error","element","_a","_b","_c","deserializedElements","maxSize","dataUrl","width","height","doc","resolve","reject","reader","img","errors","artboardIds","elementIds","elementId","validation","a","imageElements","findImages","el","child","loadPromises","imgEl","onLoad","onError","ImportManager"],"mappings":";;AAYA,MAAMA,IAASC,EAAa,eAAe,GA0B9BC,IAAN,MAAMA,EAAc;AAAA;AAAA;AAAA;AAAA,EAMzB,aAAa,eAAeC,GAAmC;AAC7D,QAAI;AAEF,YAAMC,IAAO,MAAM,KAAK,eAAeD,CAAI,GAGrCE,IAA2B,KAAK,MAAMD,CAAI;AAMhD,UAHA,KAAK,iBAAiBC,CAAQ,GAG1B,CAAC,KAAK,mBAAmB,SAASA,EAAS,SAAS,OAAO;AAC7D,cAAM,IAAI;AAAA,UACR,wBAAwBA,EAAS,SAAS,OAAO,yBACxB,KAAK,mBAAmB,KAAK,IAAI,CAAC;AAAA,QAAA;AAK/D,UAAIA,EAAS,SAAS,YAAY;AAChC,eAAO,KAAK,kBAAkBA,CAAuC;AAIvE,YAAMC,IAA+B,CAAA,GAC/BC,IAA6D,CAAA;AAEnE,aAAAF,EAAS,UAAU,QAAQ,CAACG,MAAiB;AAE3C,cAAMC,IAAWC,EAAgB,SAAS;AAAA,UACxC,IAAIF,EAAa;AAAA,UACjB,MAAMA,EAAa;AAAA,UACnB,GAAGA,EAAa;AAAA,UAChB,GAAGA,EAAa;AAAA,UAChB,OAAOA,EAAa;AAAA,UACpB,QAAQA,EAAa;AAAA,UACrB,iBAAiBA,EAAa;AAAA,UAC9B,YAAYA,EAAa,SAAS,IAAI,CAACG,MAAMA,EAAE,MAAM,EAAE;AAAA,QAAA,CACxD,GAGKC,IAAWJ,EAAa,SAC3B,IAAI,CAACK,MAAkB;AACtB,cAAI;AACF,mBAAOC,EAAe,eAAeD,CAAa;AAAA,UACpD,SAASE,GAAO;AACd,mBAAAf,EAAO,MAAM,6BAA6Ba,GAAeE,CAAK,GACvD;AAAA,UACT;AAAA,QACF,CAAC,EACA,OAAO,CAACC,MAAYA,MAAY,IAAI;AAEvC,QAAAV,EAAU,KAAKG,CAAQ,GACvBF,EAAY,KAAK,GAAGK,CAAQ;AAAA,MAC9B,CAAC,GAGD,MAAM,KAAK,iBAAiBL,CAAW,GAEhC;AAAA,QACL,SAAS;AAAA,QACT,WAAAD;AAAA,QACA,UAAUC;AAAA,QACV,kBAAkBF,EAAS;AAAA,MAAA;AAAA,IAE/B,SAASU,GAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAOA,aAAiB,QAAQA,EAAM,UAAU;AAAA,MAAA;AAAA,IAEpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,kBAAkBV,GAAmD;;AACxF,QAAI;AAEF,YAAMO,IAAWP,EAAS,YAAY,CAAA,GAGhCI,IAAW,IAAIC,EAAgB;AAAA,QACnC,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,GAAG;AAAA,QACH,GAAG;AAAA,QACH,SAAOO,IAAAZ,EAAS,WAAT,gBAAAY,EAAiB,UAAS;AAAA,QACjC,UAAQC,IAAAb,EAAS,WAAT,gBAAAa,EAAiB,WAAU;AAAA,QACnC,mBAAiBC,IAAAd,EAAS,WAAT,gBAAAc,EAAiB,oBAAmB;AAAA,MAAA,CACtD,GAGKC,IAAuBR,EAC1B,IAAI,CAACC,MAA2C;AAC/C,YAAI;AACF,iBAAOC,EAAe,eAAeD,CAAwE;AAAA,QAC/G,SAASE,GAAO;AACd,iBAAAf,EAAO,MAAM,6BAA6Ba,GAAeE,CAAK,GACvD;AAAA,QACT;AAAA,MACF,CAAC,EACA,OAAO,CAACC,MAAkEA,MAAY,IAAI;AAG7F,aAAAI,EAAqB,QAAQ,CAACJ,MAAY;AACxC,QAAAP,EAAS,aAAaO,EAAQ,EAAE;AAAA,MAClC,CAAC,GAGD,MAAM,KAAK,iBAAiBI,CAAoB,GAEzC;AAAA,QACL,SAAS;AAAA,QACT,WAAW,CAACX,CAAQ;AAAA,QACpB,UAAUW;AAAA,QACV,kBAAkBX,EAAS;AAAA,MAAA;AAAA,IAE/B,SAASM,GAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAOA,aAAiB,QAAQA,EAAM,UAAU;AAAA,MAAA;AAAA,IAEpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,YAAYZ,GAAwC;AAC/D,QAAI;AAEF,UAAI,CAACA,EAAK,KAAK,WAAW,QAAQ;AAChC,cAAM,IAAI,MAAM,sBAAsB;AAIxC,YAAMkB,IAAU,KAAK,OAAO;AAC5B,UAAIlB,EAAK,OAAOkB;AACd,cAAM,IAAI,MAAM,oCAAoC;AAItD,YAAMC,IAAU,MAAM,KAAK,kBAAkBnB,CAAI,GAG3C,EAAE,OAAAoB,GAAO,QAAAC,EAAA,IAAW,MAAM,KAAK,mBAAmBF,CAAO;AAE/D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAAA;AAAA,QACA,UAAUnB,EAAK;AAAA,QACf,OAAAoB;AAAA,QACA,QAAAC;AAAA,MAAA;AAAA,IAEJ,SAAST,GAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAOA,aAAiB,QAAQA,EAAM,UAAU;AAAA,MAAA;AAAA,IAEpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,iBAAiBV,GAAuD;AACrF,QAAI,CAACA,KAAY,OAAOA,KAAa;AACnC,YAAM,IAAI,MAAM,kBAAkB;AAEpC,UAAMoB,IAAMpB;AACZ,QAAI,CAACoB,EAAI;AACP,YAAM,IAAI,MAAM,kBAAkB;AAEpC,QAAI,CAAEA,EAAI,SAAqC;AAC7C,YAAM,IAAI,MAAM,6BAA6B;AAE/C,QAAI,CAACA,EAAI,aAAa,CAACA,EAAI;AACzB,YAAM,IAAI,MAAM,qCAAqC;AAEvD,QAAIA,EAAI,aAAa,CAAC,MAAM,QAAQA,EAAI,SAAS;AAC/C,YAAM,IAAI,MAAM,yBAAyB;AAAA,EAE7C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,eAAetB,GAA6B;AACzD,WAAO,IAAI,QAAQ,CAACuB,GAASC,MAAW;AACtC,YAAMC,IAAS,IAAI,WAAA;AACnB,MAAAA,EAAO,SAAS,CAACjB,MAAA;;AAAM,eAAAe,GAAQT,IAAAN,EAAE,WAAF,gBAAAM,EAAU,MAAgB;AAAA,SACzDW,EAAO,UAAU,MAAMD,EAAO,IAAI,MAAM,qBAAqB,CAAC,GAC9DC,EAAO,WAAWzB,CAAI;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,kBAAkBA,GAA6B;AAC5D,WAAO,IAAI,QAAQ,CAACuB,GAASC,MAAW;AACtC,YAAMC,IAAS,IAAI,WAAA;AACnB,MAAAA,EAAO,SAAS,CAACjB,MAAA;;AAAM,eAAAe,GAAQT,IAAAN,EAAE,WAAF,gBAAAM,EAAU,MAAgB;AAAA,SACzDW,EAAO,UAAU,MAAMD,EAAO,IAAI,MAAM,qBAAqB,CAAC,GAC9DC,EAAO,cAAczB,CAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,mBAAmBmB,GAA6D;AAC7F,WAAO,IAAI,QAAQ,CAACI,GAASC,MAAW;AACtC,YAAME,IAAM,IAAI,MAAA;AAChB,MAAAA,EAAI,SAAS,MAAM;AACjB,QAAAH,EAAQ,EAAE,OAAOG,EAAI,OAAO,QAAQA,EAAI,QAAQ;AAAA,MAClD,GACAA,EAAI,UAAU,MAAMF,EAAO,IAAI,MAAM,sBAAsB,CAAC,GAC5DE,EAAI,MAAMP;AAAA,IACZ,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,qBACLhB,GACAM,GACsC;AACtC,UAAMkB,IAAmB,CAAA,GAGnBC,wBAAkB,IAAA;AACxB,IAAAzB,EAAU,QAAQ,CAACG,MAAa;AAC9B,MAAIsB,EAAY,IAAItB,EAAS,EAAE,KAC7BqB,EAAO,KAAK,0BAA0BrB,EAAS,EAAE,EAAE,GAErDsB,EAAY,IAAItB,EAAS,EAAE;AAAA,IAC7B,CAAC;AAGD,UAAMuB,wBAAiB,IAAA;AACvB,WAAApB,EAAS,QAAQ,CAACI,MAAY;AAC5B,MAAIgB,EAAW,IAAIhB,EAAQ,EAAE,KAC3Bc,EAAO,KAAK,yBAAyBd,EAAQ,EAAE,EAAE,GAEnDgB,EAAW,IAAIhB,EAAQ,EAAE;AAAA,IAC3B,CAAC,GAGDV,EAAU,QAAQ,CAACG,MAAa;AAC9B,MAAAA,EAAS,cAAA,EAAgB,QAAQ,CAACwB,MAAsB;AACtD,QAAKD,EAAW,IAAIC,CAAS,KAC3BH,EAAO,KAAK,aAAarB,EAAS,IAAI,iCAAiCwB,CAAS,EAAE;AAAA,MAEtF,CAAC;AAAA,IACH,CAAC,GAEM;AAAA,MACL,OAAOH,EAAO,WAAW;AAAA,MACzB,QAAAA;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,iBACLxB,GACAM,GAMA;AACA,UAAMsB,IAAa,KAAK,qBAAqB5B,GAAWM,CAAQ;AAEhE,WAAO;AAAA,MACL,eAAeN,EAAU;AAAA,MACzB,cAAcM,EAAS;AAAA,MACvB,eAAeN,EAAU,IAAI,CAAC6B,MAAMA,EAAE,IAAI;AAAA,MAC1C,UAAUD,EAAW;AAAA,IAAA;AAAA,EAEzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAqB,iBAAiBtB,GAAwE;AAC5G,UAAMwB,IAAgC,CAAA,GAGhCC,IAAa,CAACC,MAAkD;AACpE,MAAIA,EAAG,kBAAkB,UACvBF,EAAc,KAAKE,CAAkB,IAC5BA,EAAG,kBAAkB,WAAW,cAAcA,KACtDA,EAAoB,SAAS,QAAQ,CAACC,MAAUF,EAAWE,CAAkD,CAAC;AAAA,IAEnH;AAEA,IAAA3B,EAAS,QAAQyB,CAAU;AAG3B,UAAMG,IAAeJ,EAAc,IAAI,CAACP,MAC/B,IAAI,QAAc,CAACH,MAAY;AACpC,UAAIG,EAAI;AACN,QAAAH,EAAA;AAAA,eACSG,EAAI,cAAc;AAE3B,cAAMY,IAAQZ,EAAI,cACZa,IAAS,MAAM;AACnB,UAAAD,EAAM,oBAAoB,QAAQC,CAAM,GACxCD,EAAM,oBAAoB,SAASE,CAAO,GAC1CjB,EAAA;AAAA,QACF,GACMiB,IAAU,MAAM;AACpB,UAAAF,EAAM,oBAAoB,QAAQC,CAAM,GACxCD,EAAM,oBAAoB,SAASE,CAAO,GAC1CjB,EAAA;AAAA,QACF;AACA,QAAAe,EAAM,iBAAiB,QAAQC,CAAM,GACrCD,EAAM,iBAAiB,SAASE,CAAO;AAAA,MACzC;AACE,QAAAjB,EAAA;AAAA,IAEJ,CAAC,CACF;AAED,UAAM,QAAQ,IAAIc,CAAY;AAAA,EAChC;AACF;AAnVEtC,EAAwB,qBAAqB,CAAC,SAAS,OAAO;AADzD,IAAM0C,IAAN1C;"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const V=require("react/jsx-runtime"),t=require("react"),b=require("./HybridHistoryManager-BXD93pp8.cjs"),ne=b.createLogger("useCommandHistory");function We(o,e,r,c){const i=t.useRef(new b.HybridHistoryManager(r)),[n,d]=t.useState({canUndo:!1,canRedo:!1,canUndoActiveArtboard:!1,canRedoActiveArtboard:!1}),s=t.useCallback(()=>{const a=i.current,f=r.getActiveArtboardId();d({canUndo:a.canUndo(),canRedo:a.canRedo(),canUndoActiveArtboard:f?a.canUndoArtboard(f):!1,canRedoActiveArtboard:f?a.canRedoArtboard(f):!1})},[r]),v=t.useCallback((a,f)=>{const F=new b.UpdateElementCommand(f.id,a||null,f,k=>{e(W=>W.map(z=>z.id===k.id?k:z))}),w=r.getArtboardIdForElement(f.id);if(w)i.current.executeOnArtboard(w,F);else{const k=r.getActiveArtboardId();k&&i.current.executeOnArtboard(k,F)}s()},[e,r,s]),P=t.useCallback((a,f,F,w)=>{const k=f||r.getActiveArtboardId();if(!k){ne.warn("No active artboard to add element to");return}const W=new b.AddElementCommand(a,z=>{const L=z;e(U=>{if(w){const D=U.findIndex(g=>g.id===w);if(D!==-1){const g=[...U];return g.splice(D,0,L),g}}if(F){const D=U.findIndex(g=>g.id===F);if(D!==-1){const g=[...U];return g.splice(D+1,0,L),g}for(let g=0;g<U.length;g++){const Z=U[g];if(Z instanceof b.GroupElement&&Z.children){const M=Z.children.findIndex($=>$.id===F);if(M!==-1){const $=Z.clone();$.children.splice(M+1,0,L);const G=[...U];return G[g]=$,G}}}}return[...U,L]}),r.addElementToArtboard(z.id,k)},z=>{e(L=>L.filter(U=>U.id!==z)),r.removeElementFromArtboard(z)});i.current.executeOnArtboard(k,W),s()},[e,r,s]),O=t.useCallback(a=>{const f=r.getArtboardIdForElement(a.id);if(!f){ne.warn("Element not found in any artboard");return}const F=new b.RemoveElementCommand(a,w=>{e(k=>[...k,w]),r.addElementToArtboard(w.id,f)},w=>{e(k=>k.filter(W=>W.id!==w)),r.removeElementFromArtboard(w)});i.current.executeOnArtboard(f,F),s()},[e,r,s]),x=t.useCallback(a=>{const f=new b.CreateArtboardCommand(a,r);i.current.executeGlobal(f),s(),c==null||c()},[r,s,c]),h=t.useCallback(a=>{const f=new b.DeleteArtboardCommand(a,r);i.current.executeGlobal(f),s(),c==null||c()},[r,s,c]),y=t.useCallback((a,f,F)=>{const w=new b.UpdateArtboardCommand(a,f,F,r);i.current.executeGlobal(w),s(),c==null||c()},[r,s,c]),S=t.useCallback(a=>{if(a.length===0)return;const f=r.getActiveArtboardId();if(!f){ne.warn("No active artboard for batch execution");return}const F=a.map(w=>new class extends Object{execute(){w.execute()}undo(){w.undo()}});i.current.executeBatchOnArtboard(f,F),s()},[r,s]),u=t.useCallback(()=>{i.current.undo()&&(s(),c==null||c())},[s,c]),m=t.useCallback(()=>{i.current.redo()&&(s(),c==null||c())},[s,c]),R=t.useCallback(()=>{const a=r.getActiveArtboardId();a&&i.current.undoArtboard(a)&&(s(),c==null||c())},[r,s,c]),A=t.useCallback(()=>{const a=r.getActiveArtboardId();a&&i.current.redoArtboard(a)&&(s(),c==null||c())},[r,s,c]),E=t.useCallback(()=>{i.current.clear(),s()},[s]),B=t.useCallback(a=>{i.current.clearArtboardHistory(a),s()},[s]),H=t.useRef(null);t.useEffect(()=>{const a=r.getActiveArtboardId();a!==H.current&&(H.current=a,s())});const j=t.useCallback((a,f,F)=>{const w=o.map(z=>z.id),k=r.getArtboardIdForElement(a);if(!k){ne.warn("Element not found in any artboard");return}const W=new b.ReorderElementCommand(a,f,F,w,z=>{e(L=>{const U=new Map(L.map(D=>[D.id,D]));return z.map(D=>U.get(D)).filter(Boolean)})});i.current.executeOnArtboard(k,W),s()},[o,e,r,s]);return{executeElementUpdate:v,executeAddElement:P,executeRemoveElement:O,executeReorderElement:j,executeCommandBatch:S,executeCreateArtboard:x,executeDeleteArtboard:h,executeUpdateArtboard:y,undo:u,redo:m,undoActiveArtboard:R,redoActiveArtboard:A,clearHistory:E,clearArtboardHistory:B,canUndo:n.canUndo,canRedo:n.canRedo,canUndoActiveArtboard:n.canUndoActiveArtboard,canRedoActiveArtboard:n.canRedoActiveArtboard,historyManager:i.current}}function q(o){return o&&"fontSize"in o&&"color"in o&&"fontFamily"in o}function _e(o,e){const[r,c]=t.useState(32),[i,n]=t.useState("#333333"),[d,s]=t.useState("Arial"),[v,P]=t.useState("center");t.useEffect(()=>{if(o&&q(o)){const u=o.transformType==="circle"&&"getEffectiveFontSize"in o?Math.round(o.getEffectiveFontSize()):Math.round(o.fontSize),m=o.color,R=o.fontFamily,A=o.textAlign;c(E=>E!==u?u:E),n(E=>E!==m?m:E),s(E=>E!==R?R:E),P(E=>E!==A?A:E)}},[o]);const O=t.useCallback(u=>{if(!o||!q(o))return;const m=Math.max(b.MIN_FONT_SIZE,Math.min(b.MAX_FONT_SIZE,r+u));c(m);const R=o.clone();R.transformType==="circle"&&"setEffectiveFontSize"in R?R.setEffectiveFontSize(m):R.setFontSize(m),e(R)},[o,r,e]),x=t.useCallback(u=>{if(!o||!q(o))return;c(u);const m=o.clone();m.transformType==="circle"&&"setEffectiveFontSize"in m?m.setEffectiveFontSize(u):m.setFontSize(u),e(m)},[o,e]),h=t.useCallback(u=>{if(!o||!q(o))return;n(u);const m=o.clone();if(m.color=u,m.richText)for(const R of m.richText.spans)R.style.color=void 0;e(m)},[o,e]),y=t.useCallback(u=>{if(!o||!q(o))return;const m=o.fontFamily;m!==u&&b.FontAnalyzer.clearCache(m),s(u);const R=o.clone();R.fontFamily=u,e(R)},[o,e]),S=t.useCallback(u=>{if(!o||!q(o))return;P(u);const m=o.clone();m.textAlign=u,e(m)},[o,e]);return{fontSize:r,fontColor:i,fontFamily:d,textAlign:v,setFontSize:c,setFontColor:n,setFontFamily:s,setTextAlign:P,updateFontSize:O,setFontSizeValue:x,updateFontColor:h,updateFontFamily:y,updateTextAlign:S}}const de="data-preserve-selection";function Te(o){if(!(o instanceof Element))return!1;let e=o;const r=[];for(;e;){const c=e.id?`#${e.id}`:"",i=e.className?`.${String(e.className).split(" ").slice(0,2).join(".")}`:"";if(r.push(`${e.tagName.toLowerCase()}${c}${i}`),e.hasAttribute(de))return!0;const n=e.getAttribute("role");if(n==="dialog"||n==="alertdialog"||n==="menu"||n==="listbox")return!0;const d=e.getAttribute("data-slot");if(d&&(d.includes("popover")||d.includes("dialog"))||e.hasAttribute("data-radix-popper-content-wrapper"))return!0;e=e.parentElement}return!1}const Be={[de]:""},ke=t.createContext(null),Ze=.1,$e=4,we=.25,Ge=({children:o,artboardManager:e,canvasRef:r,viewPadding:c=.9})=>{const[i,n]=t.useState(1),[d,s]=t.useState({x:0,y:0}),[v,P]=t.useState(!1),[O,x]=t.useState(1),h=t.useCallback(()=>{x(1),s({x:0,y:0})},[]),y=t.useCallback(()=>{n(A=>Math.min(A+we,$e))},[]),S=t.useCallback(()=>{n(A=>Math.max(A-we,Ze))},[]),u=t.useCallback(()=>{const A=e.getActiveArtboard();if(!A||!r.current)return;let E=r.current.parentElement,B=0,H=0;for(;E&&(B=E.clientWidth,H=E.clientHeight,!(B>0&&H>0));)E=E.parentElement;if(!B||!H)return;const j=Math.min(B*c/A.width,H*c/A.height,1);n(j),s({x:0,y:0})},[e,r,c]),m=t.useCallback(()=>{n(1),s({x:0,y:0})},[]),R=t.useMemo(()=>({zoom:i,panOffset:d,isPanning:v,zoomIn:y,zoomOut:S,zoomToFit:u,resetView:m,setZoom:n,setPanOffset:s,setIsPanning:P,userZoom:O,setUserZoom:x,resetUserView:h}),[i,d,v,y,S,u,m,O,h]);return V.jsx(ke.Provider,{value:R,children:o})};function Ie(){const o=t.useContext(ke);if(!o)throw new Error("useViewportContext must be used within a ViewportProvider (or EditorProvider)");return o}const Re=t.createContext(null),Me=({children:o})=>{const[e,r]=t.useState(null),[c,i]=t.useState([]),[n,d]=t.useState(null),[s,v]=t.useState(null),[P,O]=t.useState(!1),x=t.useCallback(S=>{r(S)},[]),h=t.useCallback(S=>{d(S)},[]),y=t.useMemo(()=>({selectedId:e,multiSelection:c,activeChildElement:n,hoveredElementId:s,hideHandles:P,setSelectedId:r,setMultiSelection:i,setHoveredElementId:v,setHideHandles:O,handleSelectionChange:x,handleActiveChildChange:h}),[e,c,n,s,P,x,h]);return V.jsx(Re.Provider,{value:y,children:o})};function ve(){const o=t.useContext(Re);if(!o)throw new Error("useSelectionContext must be used within a SelectionProvider (or EditorProvider)");return o}const Pe=t.createContext(null),Xe=({children:o,value:e})=>{const r=t.useMemo(()=>({undo:e.undo,redo:e.redo,canUndo:e.canUndo,canRedo:e.canRedo,undoActiveArtboard:e.undoActiveArtboard,redoActiveArtboard:e.redoActiveArtboard,canUndoActiveArtboard:e.canUndoActiveArtboard,canRedoActiveArtboard:e.canRedoActiveArtboard}),[e.undo,e.redo,e.canUndo,e.canRedo,e.undoActiveArtboard,e.redoActiveArtboard,e.canUndoActiveArtboard,e.canRedoActiveArtboard]);return V.jsx(Pe.Provider,{value:r,children:o})};function qe(){const o=t.useContext(Pe);if(!o)throw new Error("useHistoryContext must be used within a HistoryProvider (or EditorProvider)");return o}const ge=t.createContext(null),Je=({children:o})=>{const[e,r]=t.useState(null),[c,i]=t.useState(!1),[n,d]=t.useState(0),[s,v]=t.useState(!1),[P,O]=t.useState(!1),x=t.useMemo(()=>({expandedPanelType:e,setExpandedPanelType:r,isToolbarMenuOpen:c,setIsToolbarMenuOpen:i,textSelectionVersion:n,setTextSelectionVersion:d,isCanvasReady:s,setCanvasReady:v,isRotating:P,setIsRotating:O}),[e,c,n,s,P]);return V.jsx(ge.Provider,{value:x,children:o})};function Fe(){const o=t.useContext(ge);if(!o)throw new Error("useToolStateContext must be used within a ToolStateProvider (or EditorProvider)");return o}const ze=t.createContext(null),Ye=({children:o,value:e})=>{const r=t.useMemo(()=>({elements:e.elements,elementStore:e.elementStore,artboards:e.artboards,artboardManager:e.artboardManager,artboardVersion:e.artboardVersion,setElements:e.setElements,refreshArtboards:e.refreshArtboards,getElementById:e.getElementById,handleAddElement:e.handleAddElement,handleElementUpdate:e.handleElementUpdate,handleLoadWorkspace:e.handleLoadWorkspace,handleCopyElements:e.handleCopyElements,handlePasteElements:e.handlePasteElements,fontSize:e.fontSize,fontColor:e.fontColor,fontFamily:e.fontFamily,textAlign:e.textAlign,updateFontSize:e.updateFontSize,setFontSizeValue:e.setFontSizeValue,updateFontColor:e.updateFontColor,updateFontFamily:e.updateFontFamily,updateTextAlign:e.updateTextAlign,canvasRef:e.canvasRef,canvasEditorRef:e.canvasEditorRef}),[e.elements,e.elementStore,e.artboards,e.artboardManager,e.artboardVersion,e.setElements,e.refreshArtboards,e.getElementById,e.handleAddElement,e.handleElementUpdate,e.handleLoadWorkspace,e.handleCopyElements,e.handlePasteElements,e.fontSize,e.fontColor,e.fontFamily,e.textAlign,e.updateFontSize,e.setFontSizeValue,e.updateFontColor,e.updateFontFamily,e.updateTextAlign,e.canvasRef,e.canvasEditorRef]);return V.jsx(ze.Provider,{value:r,children:o})};function Qe(){const o=t.useContext(ze);if(!o)throw new Error("useElementsContext must be used within an ElementsProvider (or EditorProvider)");return o}const Ue=t.createContext(null),Ke=({children:o,value:e})=>{const r=t.useMemo(()=>({executeElementUpdate:e.executeElementUpdate,executeAddElement:e.executeAddElement,executeRemoveElement:e.executeRemoveElement,executeReorderElement:e.executeReorderElement,executeCreateArtboard:e.executeCreateArtboard,executeDeleteArtboard:e.executeDeleteArtboard,executeUpdateArtboard:e.executeUpdateArtboard,executeCommandBatch:e.executeCommandBatch,undo:e.undo,redo:e.redo,canUndo:e.canUndo,canRedo:e.canRedo,undoActiveArtboard:e.undoActiveArtboard,redoActiveArtboard:e.redoActiveArtboard,canUndoActiveArtboard:e.canUndoActiveArtboard,canRedoActiveArtboard:e.canRedoActiveArtboard,historyManager:e.historyManager}),[e.executeElementUpdate,e.executeAddElement,e.executeRemoveElement,e.executeReorderElement,e.executeCreateArtboard,e.executeDeleteArtboard,e.executeUpdateArtboard,e.executeCommandBatch,e.undo,e.redo,e.canUndo,e.canRedo,e.undoActiveArtboard,e.redoActiveArtboard,e.canUndoActiveArtboard,e.canRedoActiveArtboard,e.historyManager]);return V.jsx(Ue.Provider,{value:r,children:o})};function et(){const o=t.useContext(Ue);if(!o)throw new Error("useCommandContext must be used within a CommandProvider (or EditorProvider)");return o}const tt=b.createLogger("EditorContext"),Oe=t.createContext(null),ot=({children:o,artboardManager:e,canvasRef:r,canvasEditorRef:c})=>{const i=Ie(),n=ve(),d=Fe(),[s,v]=t.useState(()=>e.getAllArtboards()),[P,O]=t.useState(0),[x,h]=t.useState(()=>new b.ElementStore),y=t.useMemo(()=>x.toArray(),[x]),S=t.useCallback(l=>{h(p=>{const C=p.toArray(),T=typeof l=="function"?l(C):l;return T===C?p:b.ElementStore.fromArray(T)})},[]),u=t.useCallback(l=>x.get(l),[x]),[m,R]=t.useState([]),A=n.selectedId?x.get(n.selectedId):void 0,E=t.useCallback(()=>{v([...e.getAllArtboards()]),O(l=>l+1)},[e]),{historyManager:B,executeElementUpdate:H,executeAddElement:j,executeRemoveElement:a,executeReorderElement:f,executeCommandBatch:F,executeCreateArtboard:w,executeDeleteArtboard:k,executeUpdateArtboard:W,undo:z,redo:L,canUndo:U,canRedo:D,undoActiveArtboard:g,redoActiveArtboard:Z,canUndoActiveArtboard:M,canRedoActiveArtboard:$}=We(y,S,e,E),G=t.useCallback(l=>{const p=x.get(l.id);H(p,l)},[x,H]),He=t.useCallback(l=>{if(!A||!(A instanceof b.GroupElement))return;const p=A.clone(),C=p.children.findIndex(T=>T.id===l.id);C>=0&&(p.children[C]=l,G(p))},[A,G]),De=n.activeChildElement||A,Le=n.activeChildElement?He:G,{fontSize:ae,fontColor:le,fontFamily:ue,textAlign:me,updateFontSize:fe,setFontSizeValue:he,updateFontColor:Ae,updateFontFamily:xe,updateTextAlign:pe}=_e(De,Le),be=t.useCallback(async(l,p)=>{var Ce;const C=e.getActiveArtboardId();if(!C){alert("Please create or select an artboard first");return}const T=`element-${Date.now()}`,I=e.getActiveArtboard(),J=I?I.x+I.width/2:window.innerWidth/2,Y=I?I.y+I.height/2:window.innerHeight/2,N=((Ce=c.current)==null?void 0:Ce.getZoom())||i.zoom||1;if(l==="image"){const oe="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",X=new b.ImageElement({id:T,x:J,y:Y,imageUrl:oe,transformData:{type:"image",width:200/N,height:200/N,cropX:0,cropY:0,cropWidth:1,cropHeight:1,flipHorizontal:!1,flipVertical:!1,borderRadius:0}});j(X,C),n.setSelectedId(X.id);return}let Q;const _={text:"custom",circle:"circle",wave:"wave",arch:"arch",shape:"shape"}[l]||"custom",ee=b.getTransformById(_);if(!ee||!ee.Component)return;const te=e.getActiveArtboard(),Ne=te?Math.min(te.width,te.height)*.1:80,se=te?te.width*.5:300;if(l==="shape"){const oe=(p==null?void 0:p.shapeType)??"rectangle";let X=200/N,ie=200/N;oe==="ellipse"?(X=150/N,ie=250/N):oe==="line"&&(X=300/N,ie=8/N),Q=new b.ShapeElement({id:T,x:J,y:Y,transformData:{type:"shape",shapeType:oe,width:X,height:ie,fillColor:"#3b82f6",fillOpacity:1}})}else Q=new ee.Component({id:T,text:"New Text",x:J,y:Y,fontSize:Ne,fontFamily:"Poppins",color:"#000000",transformData:_==="arch"?{type:"arch",width:se,archHeight:b.ARCH_DEFAULTS.archHeight}:_==="wave"?{type:"wave",width:se,amplitude:b.WAVE_DEFAULTS.amplitude,frequency:b.WAVE_DEFAULTS.frequency}:_==="circle"?{type:"circle",radius:se/2}:void 0});e.addElementToArtboard(T,C),j(Q,C,n.selectedId||void 0),n.setSelectedId(T)},[e,j,n,i.zoom,c]),Se=t.useCallback(()=>{const l=[];if(n.multiSelection.length>0){const p=y.filter(C=>n.multiSelection.includes(C.id));l.push(...p)}else A&&l.push(A);if(l.length>0){const p=l.map(C=>C.clone());R(p)}},[A,n.multiSelection,y]),Ee=t.useCallback(()=>{if(m.length===0)return;const l=[],p=30,C=30;m.forEach(T=>{const I=x.get(T.id),J=I?I.x:T.x,Y=I?I.y:T.y,N=T.toJSON();delete N.id;const Q=T.constructor,K=new Q(N);K.x=J+p,K.y=Y+C;let _=null;if(I&&(_=e.getArtboardIdForElement(I.id)),_||(_=e.getActiveArtboardId()),!_){tt.warn("[handlePasteElements] No artboard found for pasting");return}const ee=I?I.id:void 0;j(K,_,ee),l.push(K.id)}),l.length===1?n.handleSelectionChange(l[0]):l.length>1&&n.setMultiSelection(l)},[m,x,e,j,n]),ce=t.useCallback(()=>{if(d.expandedPanelType==="crop"&&(A==null?void 0:A.transformType)==="image"){const l=A;if(l.isCropping){const p=l.clone();p.exitCropMode(),H(l,p)}}d.setExpandedPanelType(null)},[d.expandedPanelType,d.setExpandedPanelType,A,H]);t.useEffect(()=>{const l=p=>{const C=p.target;if(C.tagName==="CANVAS"||Te(C))return;const I=document.activeElement;if(I!=null&&I.hasAttribute("data-preserve-selection")){I.blur();return}if(d.expandedPanelType!==null){ce();return}n.setSelectedId(null),n.setMultiSelection([])};return document.addEventListener("pointerdown",l),()=>document.removeEventListener("pointerdown",l)},[d.expandedPanelType,ce,n]);const ye=t.useCallback((l,p,C)=>{e.clear(),l.forEach(T=>{e.createArtboard(T.toJSON())}),C&&e.setActiveArtboard(C),v([...e.getAllArtboards()]),O(T=>T+1),S(p),n.setSelectedId(null)},[e,n,S]),je={zoom:i.zoom,panOffset:i.panOffset,isPanning:i.isPanning,zoomIn:i.zoomIn,zoomOut:i.zoomOut,zoomToFit:i.zoomToFit,resetView:i.resetView,setZoom:i.setZoom,setPanOffset:i.setPanOffset,setIsPanning:i.setIsPanning,selectedId:n.selectedId,multiSelection:n.multiSelection,activeChildElement:n.activeChildElement,hoveredElementId:n.hoveredElementId,hideHandles:n.hideHandles,setSelectedId:n.setSelectedId,setMultiSelection:n.setMultiSelection,setHoveredElementId:n.setHoveredElementId,setHideHandles:n.setHideHandles,handleSelectionChange:n.handleSelectionChange,handleActiveChildChange:n.handleActiveChildChange,expandedPanelType:d.expandedPanelType,setExpandedPanelType:d.setExpandedPanelType,isToolbarMenuOpen:d.isToolbarMenuOpen,setIsToolbarMenuOpen:d.setIsToolbarMenuOpen,textSelectionVersion:d.textSelectionVersion,setTextSelectionVersion:d.setTextSelectionVersion,isCanvasReady:d.isCanvasReady,setCanvasReady:d.setCanvasReady,isRotating:d.isRotating,setIsRotating:d.setIsRotating,clearExpandedPanel:ce,artboardManager:e,artboards:s,elements:y,elementStore:x,getElementById:u,selectedElement:A,canvasRef:r,canvasEditorRef:c,setElements:S,artboardVersion:P,refreshArtboards:E,handleElementUpdate:G,handleAddElement:be,handleLoadWorkspace:ye,handleCopyElements:Se,handlePasteElements:Ee,historyManager:B,executeElementUpdate:H,executeAddElement:j,executeRemoveElement:a,executeReorderElement:f,executeCommandBatch:F,executeCreateArtboard:w,executeDeleteArtboard:k,executeUpdateArtboard:W,undo:z,redo:L,canUndo:U,canRedo:D,undoActiveArtboard:g,redoActiveArtboard:Z,canUndoActiveArtboard:M,canRedoActiveArtboard:$,fontSize:ae,fontColor:le,fontFamily:ue,textAlign:me,updateFontSize:fe,setFontSizeValue:he,updateFontColor:Ae,updateFontFamily:xe,updateTextAlign:pe};return V.jsx(Xe,{value:{undo:z,redo:L,canUndo:U,canRedo:D,undoActiveArtboard:g,redoActiveArtboard:Z,canUndoActiveArtboard:M,canRedoActiveArtboard:$},children:V.jsx(Ye,{value:{elements:y,elementStore:x,artboards:s,artboardManager:e,artboardVersion:P,setElements:S,refreshArtboards:E,getElementById:u,handleAddElement:be,handleElementUpdate:G,handleLoadWorkspace:ye,handleCopyElements:Se,handlePasteElements:Ee,fontSize:ae,fontColor:le,fontFamily:ue,textAlign:me,updateFontSize:fe,setFontSizeValue:he,updateFontColor:Ae,updateFontFamily:xe,updateTextAlign:pe,canvasRef:r,canvasEditorRef:c},children:V.jsx(Ke,{value:{executeElementUpdate:H,executeAddElement:j,executeRemoveElement:a,executeReorderElement:f,executeCommandBatch:F,executeCreateArtboard:w,executeDeleteArtboard:k,executeUpdateArtboard:W,undo:z,redo:L,canUndo:U,canRedo:D,undoActiveArtboard:g,redoActiveArtboard:Z,canUndoActiveArtboard:M,canRedoActiveArtboard:$,historyManager:B},children:V.jsx(Oe.Provider,{value:je,children:o})})})})},nt=({children:o,initialArtboardConfig:e={},viewPadding:r=.9})=>{const[c]=t.useState(()=>{const d=new b.ArtboardManager,s={name:e.name||"Artboard 1",x:e.x??0,y:e.y??0,width:e.width??1e3,height:e.height??1e3,backgroundColor:e.backgroundColor||b.DEFAULT_ARTBOARD_COLOR};return d.createArtboard(s),d}),i=t.useRef(null),n=t.useRef(null);return V.jsx(Ge,{artboardManager:c,canvasRef:i,viewPadding:r,children:V.jsx(Me,{children:V.jsx(Je,{children:V.jsx(ot,{artboardManager:c,canvasRef:i,canvasEditorRef:n,children:o})})})})},rt=()=>{const o=t.useContext(Oe);if(!o)throw new Error("useEditor must be used within EditorProvider");return o},Ve=t.createContext(void 0);function re(){if(typeof window>"u")return{theme:"light",resolvedTheme:"light",isDark:!1};const o=document.documentElement.classList.contains("dark"),e=document.documentElement.getAttribute("data-theme");let r=o?"dark":"light";e&&["light","dark","axis-light","axis-dark","ocean-light","ocean-dark","sunset-light","sunset-dark"].includes(e)&&(r=e);let c=o?"dark":"light";return r.startsWith("axis")?c="axis":r.startsWith("ocean")?c="ocean":r.startsWith("sunset")&&(c="sunset"),{theme:c,resolvedTheme:r,isDark:o}}const ct=({children:o,defaultTheme:e="light",passive:r=!1})=>{const c=()=>typeof window>"u"?e:r?re().theme:localStorage.getItem("snowcone-theme")||e,i=()=>typeof window>"u"?"light":r?re().resolvedTheme:"light",[n,d]=t.useState(c),[s,v]=t.useState(i);t.useEffect(()=>{if(!r||typeof window>"u")return;const{resolvedTheme:h,theme:y}=re();v(h),d(y);const S=new MutationObserver(()=>{const{resolvedTheme:u,theme:m}=re();v(u),d(m)});return S.observe(document.documentElement,{attributes:!0,attributeFilter:["class","data-theme"]}),()=>S.disconnect()},[r]),t.useEffect(()=>{if(r||typeof window>"u")return;const h=window.matchMedia("(prefers-color-scheme: dark)"),y=S=>{let u;if(n==="auto")u=S.matches?"dark":"light";else{if(n==="light"||n==="dark")return;u=S.matches?`${n}-dark`:`${n}-light`}v(u),document.documentElement.setAttribute("data-theme",u),u==="dark"||u.endsWith("-dark")?(document.documentElement.classList.add("dark"),document.body.classList.add("dark")):(document.documentElement.classList.remove("dark"),document.body.classList.remove("dark"))};return h.addEventListener("change",y),()=>h.removeEventListener("change",y)},[n,r]),t.useEffect(()=>{if(r||typeof window>"u")return;let h;const y=window.matchMedia("(prefers-color-scheme: dark)").matches;n==="auto"?h=y?"dark":"light":n==="light"||n==="dark"?h=n:h=y?`${n}-dark`:`${n}-light`,v(h),document.documentElement.setAttribute("data-theme",h),h==="dark"||h.endsWith("-dark")?(document.documentElement.classList.add("dark"),document.body.classList.add("dark")):(document.documentElement.classList.remove("dark"),document.body.classList.remove("dark")),localStorage.setItem("snowcone-theme",n)},[n,r]);const P=h=>{r||d(h)},O=s==="dark"||s.endsWith("-dark"),x={theme:n,resolvedTheme:s,setTheme:P,isDark:O};return V.jsx(Ve.Provider,{value:x,children:o})},st=()=>{const o=t.useContext(Ve);if(!o)throw new Error("useTheme must be used within ThemeProvider");return o};exports.EditorProvider=nt;exports.PRESERVE_SELECTION_ATTR=de;exports.ThemeProvider=ct;exports.preserveSelectionProps=Be;exports.shouldPreserveSelection=Te;exports.useCommandContext=et;exports.useEditor=rt;exports.useElementsContext=Qe;exports.useHistoryContext=qe;exports.useSelectionContext=ve;exports.useTheme=st;exports.useToolStateContext=Fe;exports.useViewportContext=Ie;
|
|
2
|
-
//# sourceMappingURL=ThemeContext-4mJ_y0Me.cjs.map
|