import type { ToolcraftControlLayoutGroupColumns, ToolcraftControlLayoutGroupLayout, ToolcraftSectionLayout, } from "../contracts/types"; import type { ToolcraftCollectionItemControlType } from "./collection-item-controls"; export type ToolcraftCanvasSize = { height: number; unit: "px"; width: number; }; export type ToolcraftAppIdentitySchema = { id: string; title: string; }; export type ResolvedToolcraftAppIdentity = Readonly<{ id: string; title: string; }>; export type ToolcraftCanvasSizeSource = "app" | "runtime-default"; export type ToolcraftCanvasSizingMode = | "editable-output" | "fixed-output" | "intrinsic-media"; export type ToolcraftCanvasSizingSchema = | { defaultMode?: "finite" | "infinite"; mode: "editable-output"; } | { defaultMode?: never; mode: Exclude; }; export type ToolcraftCanvasRenderScaleSchema = | boolean | { defaultValue?: never; enabled?: never; max?: never; min?: never; step?: number; }; export type ResolvedToolcraftCanvasRenderScaleSchema = { defaultValue: number; enabled: boolean; max: number; min: number; step: number; }; export type ToolcraftPngExportBackground = "include" | "transparent"; export type ToolcraftPngExportSchema = { background?: ToolcraftPngExportBackground; }; export type ToolcraftExportSchema = { png?: ToolcraftPngExportSchema; }; export type ResolvedToolcraftExportSchema = { png: Required; }; export type ToolcraftAssemblyComponentId = | "canvas" | "controlsPanel" | "layersPanel" | "timelinePanel" | "toolbar"; export type ToolcraftAssemblyCapability = | "canvas.draggable" | "canvas.editableSize" | "canvas.infinity" | "canvas.renderScale" | "canvas.upload" | "controls.defaults" | "controls.panel" | "history.undoRedo" | "layers.groups" | "layers.panel" | "layers.selection" | "layers.visibility" | "panels.doubleClickReset" | "panels.draggable" | "panels.snap" | "timeline.duration" | "timeline.keyframes" | "timeline.panel" | "timeline.playback" | "toolbar.history" | "toolbar.radar" | "toolbar.theme" | "toolbar.zoom"; export type ToolcraftAssemblyCommand = | "canvas.center" | "canvas.panBy" | "canvas.setOffset" | "canvas.setSize" | "canvas.setViewport" | "canvas.zoomIn" | "canvas.zoomOut" | "canvas.zoomReset" | "controls.apply" | "controls.reset" | "controls.resetTargets" | "controls.setValue" | "history.redo" | "history.undo" | "layers.add" | "layers.delete" | "layers.moveToGroup" | "layers.rename" | "layers.reorder" | "layers.select" | "layers.toggleCollapsed" | "layers.toggleVisibility" | "media.delete" | "media.import" | "media.importBatch" | "media.reorder" | "media.transform" | "panels.resetOffset" | "panels.setSectionCollapsed" | "panels.setHidden" | "panels.setOffset" | "panels.update" | "timeline.changeKeyframeEasing" | "timeline.deleteControlKeyframes" | "timeline.deleteKeyframe" | "timeline.moveKeyframe" | "timeline.selectKeyframe" | "timeline.setCurrentTime" | "timeline.setDuration" | "timeline.setExpanded" | "timeline.setPlaying" | "timeline.toggleControlKeyframes" | "timeline.toggleExpanded" | "timeline.toggleLoop" | "timeline.togglePlayback"; export type ToolcraftAssemblyPanelContract = { capabilities: readonly ToolcraftAssemblyCapability[]; commands: readonly ToolcraftAssemblyCommand[]; defaultPlacement: "bottom" | "left" | "right" | "top"; dragMode: "handle" | "panel"; enabled: boolean; requiredWrapper: "PanelHost"; snapEdges: readonly ("bottom" | "left" | "right" | "top")[]; visualComponent: string; }; export type ToolcraftAssemblyCanvasContract = { capabilities: readonly ToolcraftAssemblyCapability[]; commands: readonly ToolcraftAssemblyCommand[]; enabled: boolean; visualComponent: "CanvasShell"; }; export type ToolcraftAssemblyContract = { capabilities: readonly ToolcraftAssemblyCapability[]; commands: readonly ToolcraftAssemblyCommand[]; components: readonly ToolcraftAssemblyComponentId[]; surfaces: { canvas: ToolcraftAssemblyCanvasContract; panels: { controls?: ToolcraftAssemblyPanelContract; layers?: ToolcraftAssemblyPanelContract; timeline?: ToolcraftAssemblyPanelContract; toolbar: ToolcraftAssemblyPanelContract; }; }; }; export type ToolcraftCanvasSchema = { draggable?: boolean; enabled: boolean; renderScale?: ToolcraftCanvasRenderScaleSchema; size?: ToolcraftCanvasSize; sizing?: ToolcraftCanvasSizingSchema; upload?: boolean; }; export type ToolcraftToolbarSchema = { history?: boolean; radar?: boolean; theme?: boolean; zoom?: boolean; }; export type ToolcraftTimelineMode = "keyframes" | "playback"; export type ToolcraftTimelinePanelSchema = | boolean | { defaultDurationSeconds?: number; enabled?: boolean; mode?: ToolcraftTimelineMode; }; export type ResolvedToolcraftTimelinePanelSchema = { defaultDurationSeconds: number; enabled: boolean; mode: ToolcraftTimelineMode; }; export type ToolcraftPersistableStateSlice = | "canvas" | "layers" | "media" | "panels" | "timeline" | "values"; export type ToolcraftNoPersistenceSchema = { storage: "none"; }; export type ToolcraftLocalStoragePersistenceSchema = { additionalValueTargets?: readonly string[]; include: readonly ToolcraftPersistableStateSlice[]; key: `toolcraft:${string}:state:v${number}`; storage: "localStorage"; version: number; }; export type ResolvedToolcraftLocalStoragePersistenceSchema = Readonly<{ additionalValueTargets: readonly string[]; include: readonly ToolcraftPersistableStateSlice[]; key: `toolcraft:${string}:state:v${number}`; storage: "localStorage"; version: number; }>; export type ToolcraftPersistenceSchema = | ToolcraftNoPersistenceSchema | ToolcraftLocalStoragePersistenceSchema; export type ResolvedToolcraftPersistenceSchema = | { storage: "none" } | ResolvedToolcraftLocalStoragePersistenceSchema; export type ToolcraftSettingsTransferMode = boolean | "auto"; export type ToolcraftSettingsTransferObjectSchema = { additionalValueTargets?: readonly string[]; appId?: string; enabled?: ToolcraftSettingsTransferMode; fileName?: string; }; export type ToolcraftSettingsTransferSchema = | ToolcraftSettingsTransferMode | ToolcraftSettingsTransferObjectSchema; export type ResolvedToolcraftSettingsTransferSchema = { additionalValueTargets: readonly string[]; appId: string; enabled: boolean; fileName: string; mode: ToolcraftSettingsTransferMode; }; export type ToolcraftActionCommand = "controls.apply" | "controls.reset"; export type ToolcraftActionRole = | "copy-output" | "download-output" | "export-image" | "export-svg" | "export-video"; export type ToolcraftActionSchema = { command?: ToolcraftActionCommand; icon?: | "check" | "copy" | "download" | "download-simple" | "eraser" | "export" | "rotate-ccw" | "shuffle" | "upload-simple" | "wand-sparkles"; label?: string; role?: ToolcraftActionRole; value: string; variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary"; }; export type ToolcraftImagePickerItemSchema = { alt?: string; src: string; value: string; }; export type ToolcraftControlOrderRole = | "action" | "advanced" | "color" | "detail" | "input" | "mode" | "primary" | "spatial" | "strength"; export type ToolcraftControlPerformanceRole = | "responsiveness" | "workload"; export type ToolcraftCurveIntent = "color-channels" | "single-value-map"; export type ToolcraftSliderValueKind = "continuous" | "discrete"; export type ToolcraftTextValueKind = "multiline" | "single-line" | "structured"; export type ToolcraftModelFormat = | "fbx" | "glb" | "gltf" | "obj" | "ply" | "stl"; export type ToolcraftModelTopologyProfile = | "realtime-mesh" | "solid-mesh"; export type ToolcraftModelImportLimits = { maxArchiveCompressionRatio: number; maxArchiveEntries: number; maxArchiveEntryBytes: number; maxArchivePathLength: number; maxArchiveUncompressedBytes: number; maxBundleFiles: number; maxDecodedBytes: number; maxEstimatedWorkerBytes: number; maxNodes: number; maxPrimitives: number; maxSourceBytes: number; maxTextureBytes: number; maxTextureCount: number; maxTextureDimension: number; maxTexturePixels: number; maxTriangles: number; maxVertices: number; }; export type ToolcraftMediaAssetKind = "file" | "image"; export type ToolcraftFileDropAssetKind = ToolcraftMediaAssetKind | "model"; export type ToolcraftMediaPositionSchema = { x: number; y: number; }; export type ToolcraftMediaTransformSchema = { flipHorizontal?: boolean; flipVertical?: boolean; rotationDeg?: 0 | 90 | 180 | 270; }; export type ToolcraftDefaultImageOrFileAssetSchema = { assetKind?: ToolcraftMediaAssetKind; dataUrl: string; fileName: string; id?: string; layerId?: string; layerName?: string; mimeType?: string; position?: ToolcraftMediaPositionSchema; size?: ToolcraftCanvasSize; sourceTarget?: string; transform?: ToolcraftMediaTransformSchema; }; export type ToolcraftDefaultModelAssetSchema = { assetKind: "model"; fileName: string; id?: string; layerId?: string; layerName?: string; mimeType?: string; sourceFiles: readonly { dataUrl: string; mimeType?: string; path: string; }[]; sourceTarget?: string; }; export type ToolcraftDefaultMediaAssetSchema = | ToolcraftDefaultImageOrFileAssetSchema | ToolcraftDefaultModelAssetSchema; export type ToolcraftMediaSchema = { defaultAssets?: readonly ToolcraftDefaultMediaAssetSchema[]; }; export type ResolvedToolcraftMediaSchema = { defaultAssets: readonly ToolcraftDefaultMediaAssetSchema[]; }; export type ToolcraftControlPredicateSchema = Readonly<{ equals?: unknown; greaterThan?: number; greaterThanOrEqual?: number; lessThan?: number; lessThanOrEqual?: number; notOneOf?: readonly unknown[]; notEquals?: unknown; oneOf?: readonly unknown[]; target: string; }>; export type ToolcraftControlConditionSchema = ToolcraftControlPredicateSchema; export type ToolcraftControlApplicabilitySchema = | Readonly<{ mode: "always" }> | Readonly<{ all: readonly ToolcraftControlPredicateSchema[]; mode: "conditional"; }>; export type ToolcraftResolvedControlApplicabilitySchema = | Readonly<{ mode: "always"; origin: "explicit" | "implicit"; }> | Readonly<{ all: readonly ToolcraftControlPredicateSchema[]; mode: "conditional"; origin: "explicit" | "legacy"; }>; export type ToolcraftControlDisabledConditionSchema = ToolcraftControlConditionSchema; export type ToolcraftColorOpacityValueSchema = { hex: string; opacity?: number; }; export type ToolcraftCollectionItemControlSchema = { commitMode?: "content" | "setting"; coordinateMode?: ToolcraftVectorCoordinateMode; defaultValue?: unknown; description?: string; label?: boolean | string; markerCount?: number; max?: number; min?: number; options?: readonly { label: string; value: string }[]; performanceReason?: string; performanceRole?: ToolcraftControlPerformanceRole; sliderValueKind?: ToolcraftSliderValueKind; step?: number; type: ToolcraftCollectionItemControlType; unit?: string; variant?: string; xLabel?: string; yLabel?: string; }; export type ToolcraftCollectionItemControlsSchema = Readonly< Record >; export type ToolcraftFontPickerValueSchema = { color?: string; fontId: string; fontSize?: number; fontWeight?: string; letterSpacing?: "tight" | "tighter" | "normal" | "wide" | "wider" | "widest"; lineHeight?: "loose" | "none" | "normal" | "relaxed" | "snug" | "tight"; opacity?: number; textCase?: "capitalize" | "lowercase" | "original" | "titleCase" | "uppercase"; }; export type ToolcraftCurveInterpolation = "monotone" | "smooth"; export type ToolcraftVectorCoordinateMode = "cartesian" | "screen"; type ToolcraftControlSchemaFields = { accept?: string; actions?: readonly (ToolcraftActionSchema | string)[]; addLabel?: string; commitMode?: "content" | "setting"; coordinateMode?: ToolcraftVectorCoordinateMode; curveIntent?: ToolcraftCurveIntent; defaultValue?: unknown; description?: string; disabled?: boolean; disabledWhen?: ToolcraftControlDisabledConditionSchema; hardMaxItems?: number; interpolation?: ToolcraftCurveInterpolation; items?: readonly ToolcraftImagePickerItemSchema[]; itemControl?: ToolcraftCollectionItemControlSchema; itemControls?: ToolcraftCollectionItemControlsSchema; itemDefaultValue?: unknown; itemLabel?: string; keyframeable?: boolean; label?: boolean | string; markerCount?: number; max?: number; min?: number; minItems?: number; orderRole?: ToolcraftControlOrderRole; performanceReason?: string; performanceRole?: ToolcraftControlPerformanceRole; options?: readonly { label: string; value: string }[]; recommendedMaxItems?: number; removeLabel?: string; semanticGroup?: string; sliderValueKind?: ToolcraftSliderValueKind; step?: number; target: string; textValueKind?: ToolcraftTextValueKind; unit?: string; valueLabel?: string; variant?: string; xLabel?: string; yLabel?: string; }; export type ToolcraftControlSchemaBase = ToolcraftControlSchemaFields & { applicability?: ToolcraftControlApplicabilitySchema; /** @deprecated Product controls use conditional applicability. */ visibleWhen?: ToolcraftControlPredicateSchema; }; export type ToolcraftNonModelControlSchema = ToolcraftControlSchemaBase & { assetKind?: ToolcraftMediaAssetKind; modelFormats?: never; modelLimits?: never; multiple?: boolean; topologyProfile?: never; type: string; }; export type ToolcraftModelFileDropSchema = ToolcraftControlSchemaBase & { assetKind: "model"; modelFormats?: readonly ToolcraftModelFormat[]; modelLimits?: Partial; multiple?: false; topologyProfile?: ToolcraftModelTopologyProfile; type: "fileDrop"; }; export type ToolcraftControlSchema = | ToolcraftNonModelControlSchema | ToolcraftModelFileDropSchema; type ToolcraftResolvedControlApplicabilityFields = Readonly<{ applicability: ToolcraftResolvedControlApplicabilitySchema; }>; export type ResolvedToolcraftNonModelControlSchema = Omit< ToolcraftNonModelControlSchema, "applicability" | "visibleWhen" > & ToolcraftResolvedControlApplicabilityFields; export type ResolvedToolcraftModelFileDropSchema = Omit< ToolcraftModelFileDropSchema, | "applicability" | "modelFormats" | "modelLimits" | "multiple" | "topologyProfile" | "visibleWhen" > & ToolcraftResolvedControlApplicabilityFields & { modelFormats: readonly ToolcraftModelFormat[]; modelLimits: ToolcraftModelImportLimits; multiple: false; topologyProfile: ToolcraftModelTopologyProfile; }; export type ResolvedToolcraftControlSchema = | ResolvedToolcraftNonModelControlSchema | ResolvedToolcraftModelFileDropSchema; export type ToolcraftControlLayoutGroupSchema = { columns?: ToolcraftControlLayoutGroupColumns; controls: readonly string[]; layout: ToolcraftControlLayoutGroupLayout; }; export type ToolcraftControlSectionSchemaBase< TControl extends ToolcraftControlSchema, > = { actionGroup?: "primary" | "secondary"; controls: Record; layout?: ToolcraftSectionLayout; layoutGroups?: readonly ToolcraftControlLayoutGroupSchema[]; title?: string; visibleWhen?: ToolcraftControlConditionSchema; }; export type ToolcraftControlSectionSchema = ToolcraftControlSectionSchemaBase< ToolcraftControlSchema > & { /** Stable lowercase ASCII segments separated by `.`, `_`, or `-`; runtime/internal namespaces are reserved. */ id?: string; }; export type ToolcraftControlSectionSchemaFor< TControl extends ToolcraftControlSchema, > = ToolcraftControlSectionSchemaBase & { /** Stable lowercase ASCII segments separated by `.`, `_`, or `-`; runtime/internal namespaces are reserved. */ id?: string; }; export type ResolvedToolcraftControlSectionSchema = ToolcraftControlSectionSchemaBase & { id: string; }; export type ToolcraftControlsPanelSchemaFor< TControl extends ToolcraftControlSchema, > = { sections: readonly ToolcraftControlSectionSchemaFor[]; title: string; }; export type ToolcraftControlsPanelSchema = ToolcraftControlsPanelSchemaFor; export type ResolvedToolcraftControlsPanelSchema = { sections: readonly ResolvedToolcraftControlSectionSchema[]; title: string; }; export type ToolcraftPanelsSchema = { controls?: ToolcraftControlsPanelSchema; layers?: boolean; timeline?: ToolcraftTimelinePanelSchema; }; export type ResolvedToolcraftPanelsSchema = { controls?: ResolvedToolcraftControlsPanelSchema; layers?: boolean; timeline?: ResolvedToolcraftTimelinePanelSchema; }; export type ToolcraftAppSchema = { canvas: ToolcraftCanvasSchema; export?: ToolcraftExportSchema; identity?: ToolcraftAppIdentitySchema; media?: ToolcraftMediaSchema; panels: ToolcraftPanelsSchema; persistence?: ToolcraftPersistenceSchema; settingsTransfer?: ToolcraftSettingsTransferSchema; toolbar?: ToolcraftToolbarSchema; }; export type ResolvedToolcraftAppSchema = { assembly: ToolcraftAssemblyContract; canvas: Omit, "renderScale"> & { renderScale: ResolvedToolcraftCanvasRenderScaleSchema; size: ToolcraftCanvasSize; sizeSource: ToolcraftCanvasSizeSource; }; export: ResolvedToolcraftExportSchema; identity: ResolvedToolcraftAppIdentity; media: ResolvedToolcraftMediaSchema; panels: ResolvedToolcraftPanelsSchema; persistence: ResolvedToolcraftPersistenceSchema; settingsTransfer: ResolvedToolcraftSettingsTransferSchema; toolbar: Required; };