@pixerate/editor-react 0.19.1 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,300 +20,307 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/canvas/index.ts
21
21
  var canvas_exports = {};
22
22
  __export(canvas_exports, {
23
- ANIMATABLE_PROPERTIES: () => import_canvas24.ANIMATABLE_PROPERTIES,
24
- ANIMATION_DATA_KEY: () => import_canvas24.ANIMATION_DATA_KEY,
25
- ANIMATION_EASING_LABELS: () => import_canvas24.ANIMATION_EASING_LABELS,
26
- ANIMATION_EASING_PRESETS: () => import_canvas24.ANIMATION_EASING_PRESETS,
27
- ANIMATION_TIME_EPSILON: () => import_canvas24.ANIMATION_TIME_EPSILON,
28
- AUTO_LAYOUT_DATA_KEY: () => import_canvas22.AUTO_LAYOUT_DATA_KEY,
23
+ ANIMATABLE_PROPERTIES: () => import_canvas26.ANIMATABLE_PROPERTIES,
24
+ ANIMATION_DATA_KEY: () => import_canvas26.ANIMATION_DATA_KEY,
25
+ ANIMATION_EASING_LABELS: () => import_canvas26.ANIMATION_EASING_LABELS,
26
+ ANIMATION_EASING_PRESETS: () => import_canvas26.ANIMATION_EASING_PRESETS,
27
+ ANIMATION_TIME_EPSILON: () => import_canvas26.ANIMATION_TIME_EPSILON,
28
+ AUTO_LAYOUT_DATA_KEY: () => import_canvas24.AUTO_LAYOUT_DATA_KEY,
29
29
  AgentPresenceLayer: () => AgentPresenceLayer,
30
- AnimationEditError: () => import_canvas24.AnimationEditError,
31
- AnimationPlayer: () => import_canvas24.AnimationPlayer,
30
+ AnimationEditError: () => import_canvas26.AnimationEditError,
31
+ AnimationPlayer: () => import_canvas26.AnimationPlayer,
32
32
  AnimationTimeline: () => AnimationTimeline,
33
- CANVAS_COMPONENT_DRAG_TYPE: () => import_canvas25.CANVAS_COMPONENT_DRAG_TYPE,
34
- CANVAS_TOKEN_PROPERTIES: () => import_canvas23.CANVAS_TOKEN_PROPERTIES,
35
- CHILD_LAYOUT_DATA_KEY: () => import_canvas22.CHILD_LAYOUT_DATA_KEY,
36
- CONNECTION_LINE_TYPES: () => import_canvas18.CONNECTION_LINE_TYPES,
37
- CSS_ANIMATION_PROPERTIES: () => import_canvas24.CSS_ANIMATION_PROPERTIES,
38
- CUBIC_BEZIER_PRESETS: () => import_canvas24.CUBIC_BEZIER_PRESETS,
33
+ CANVAS_COMPONENT_DRAG_TYPE: () => import_canvas27.CANVAS_COMPONENT_DRAG_TYPE,
34
+ CANVAS_TOKEN_PROPERTIES: () => import_canvas25.CANVAS_TOKEN_PROPERTIES,
35
+ CHILD_LAYOUT_DATA_KEY: () => import_canvas24.CHILD_LAYOUT_DATA_KEY,
36
+ CONNECTION_LINE_TYPES: () => import_canvas20.CONNECTION_LINE_TYPES,
37
+ CSS_ANIMATION_PROPERTIES: () => import_canvas26.CSS_ANIMATION_PROPERTIES,
38
+ CUBIC_BEZIER_PRESETS: () => import_canvas26.CUBIC_BEZIER_PRESETS,
39
39
  CanvasComponentsPanel: () => CanvasComponentsPanel,
40
+ CanvasDrawLayer: () => CanvasDrawLayer,
40
41
  CanvasGuidesLayer: () => CanvasGuidesLayer,
41
42
  CanvasInstanceInspector: () => CanvasInstanceInspector,
42
- CanvasScenesStore: () => import_canvas18.CanvasScenesStore,
43
- DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas18.DEFAULT_ARRANGE_SHORTCUTS,
44
- MAX_KEYFRAME_REFS: () => import_canvas24.MAX_KEYFRAME_REFS,
45
- ManualClock: () => import_canvas21.ManualClock,
46
- RESIZE_HANDLES: () => import_canvas17.RESIZE_HANDLES,
47
- SHAPE_DATA_KEY: () => import_canvas19.SHAPE_DATA_KEY,
48
- SHAPE_KINDS: () => import_canvas19.SHAPE_KINDS,
49
- SHAPE_NODE_TYPE: () => import_canvas19.SHAPE_NODE_TYPE,
50
- SHAPE_OPERATIONS: () => import_canvas19.SHAPE_OPERATIONS,
43
+ CanvasScenesStore: () => import_canvas20.CanvasScenesStore,
44
+ DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas20.DEFAULT_ARRANGE_SHORTCUTS,
45
+ MAX_KEYFRAME_REFS: () => import_canvas26.MAX_KEYFRAME_REFS,
46
+ ManualClock: () => import_canvas23.ManualClock,
47
+ RESIZE_HANDLES: () => import_canvas19.RESIZE_HANDLES,
48
+ SHAPE_DATA_KEY: () => import_canvas21.SHAPE_DATA_KEY,
49
+ SHAPE_KINDS: () => import_canvas21.SHAPE_KINDS,
50
+ SHAPE_NODE_TYPE: () => import_canvas21.SHAPE_NODE_TYPE,
51
+ SHAPE_OPERATIONS: () => import_canvas21.SHAPE_OPERATIONS,
51
52
  ShapeNode: () => ShapeNode,
52
- TOKEN_BINDINGS_DATA_KEY: () => import_canvas23.TOKEN_BINDINGS_DATA_KEY,
53
- TOKEN_MODES_DATA_KEY: () => import_canvas23.TOKEN_MODES_DATA_KEY,
53
+ TOKEN_BINDINGS_DATA_KEY: () => import_canvas25.TOKEN_BINDINGS_DATA_KEY,
54
+ TOKEN_MODES_DATA_KEY: () => import_canvas25.TOKEN_MODES_DATA_KEY,
54
55
  TokenBindingPicker: () => TokenBindingPicker,
55
56
  TokenModeSwitcher: () => TokenModeSwitcher,
56
- addCanvasVariant: () => import_canvas25.addCanvasVariant,
57
- addKeyframesAtTime: () => import_canvas24.addKeyframesAtTime,
58
- alignNodes: () => import_canvas18.alignNodes,
59
- animateNode: () => import_canvas24.animateNode,
60
- applyAnimation: () => import_canvas24.applyAnimation,
61
- applyAnimationOverrides: () => import_canvas24.applyAnimationOverrides,
62
- applyConstraints: () => import_canvas22.applyConstraints,
63
- applyNodeUpdates: () => import_canvas18.applyNodeUpdates,
64
- applyShapeCombination: () => import_canvas19.applyShapeCombination,
65
- applyShapeReplacement: () => import_canvas20.applyShapeReplacement,
66
- bezierPathArea: () => import_canvas20.bezierPathArea,
67
- bezierPathBounds: () => import_canvas20.bezierPathBounds,
68
- bezierPathLength: () => import_canvas20.bezierPathLength,
69
- bezierPathPointAtLength: () => import_canvas20.bezierPathPointAtLength,
70
- bezierPathSignedArea: () => import_canvas20.bezierPathSignedArea,
71
- bezierPathToSvg: () => import_canvas20.bezierPathToSvg,
72
- bindCanvasComponentProperty: () => import_canvas25.bindCanvasComponentProperty,
73
- bindCanvasToken: () => import_canvas23.bindCanvasToken,
74
- blendLayout: () => import_canvas21.blendLayout,
75
- boundsOf: () => import_canvas21.boundsOf,
76
- calculateDagreReflowDisplacement: () => import_canvas21.calculateDagreReflowDisplacement,
77
- calculateDirectionalDisplacement: () => import_canvas21.calculateDirectionalDisplacement,
78
- canCombineShapeNodes: () => import_canvas19.canCombineShapeNodes,
79
- canOffsetShapeNodes: () => import_canvas20.canOffsetShapeNodes,
80
- canOutlineShapeNodeStrokes: () => import_canvas20.canOutlineShapeNodeStrokes,
81
- canvasHeight: () => import_canvas21.canvasHeight,
82
- centerNodes: () => import_canvas21.centerNodes,
83
- centre: () => import_canvas21.centre,
84
- clampAnimationValue: () => import_canvas24.clampAnimationValue,
85
- clampLayoutSize: () => import_canvas22.clampLayoutSize,
86
- combineCanvasComponentsAsVariants: () => import_canvas25.combineCanvasComponentsAsVariants,
87
- combineShapeNodes: () => import_canvas19.combineShapeNodes,
88
- computeNodesBoundingBox: () => import_canvas21.computeNodesBoundingBox,
89
- computeSnapGuides: () => import_canvas18.computeSnapGuides,
90
- connectedOnly: () => import_canvas21.connectedOnly,
91
- copyKeyframes: () => import_canvas24.copyKeyframes,
92
- countPathSegments: () => import_canvas20.countPathSegments,
93
- createAnimationPlayer: () => import_canvas24.createAnimationPlayer,
94
- createBezierTrajectory: () => import_canvas21.createBezierTrajectory,
95
- createCanvasAnimationController: () => import_canvas24.createCanvasAnimationController,
96
- createCanvasAutoLayoutController: () => import_canvas22.createCanvasAutoLayoutController,
97
- createCanvasComponent: () => import_canvas25.createCanvasComponent,
98
- createCanvasComponentsController: () => import_canvas25.createCanvasComponentsController,
99
- createCanvasInstance: () => import_canvas25.createCanvasInstance,
100
- createCanvasScenesStore: () => import_canvas18.createCanvasScenesStore,
101
- createFanOutTrajectory: () => import_canvas21.createFanOutTrajectory,
102
- createGuideIndex: () => import_canvas18.createGuideIndex,
103
- createNodeGuideIndex: () => import_canvas18.createNodeGuideIndex,
104
- cubicBezierAt: () => import_canvas24.cubicBezierAt,
105
- cubicPointAt: () => import_canvas17.cubicPointAt,
106
- cubicsToPathData: () => import_canvas17.cubicsToPathData,
107
- dashContours: () => import_canvas20.dashContours,
108
- defaultEasing: () => import_canvas21.defaultEasing,
109
- deleteKeyframes: () => import_canvas24.deleteKeyframes,
110
- detachCanvasInstance: () => import_canvas25.detachCanvasInstance,
111
- detachTokenBindings: () => import_canvas23.detachTokenBindings,
112
- distanceToBezierPath: () => import_canvas20.distanceToBezierPath,
113
- distributeNodes: () => import_canvas18.distributeNodes,
114
- dividePaths: () => import_canvas20.dividePaths,
115
- dividePolygons: () => import_canvas19.dividePolygons,
116
- easingFromInfluence: () => import_canvas24.easingFromInfluence,
117
- easingLabel: () => import_canvas24.easingLabel,
118
- easingToCss: () => import_canvas24.easingToCss,
119
- ensureLayout: () => import_canvas21.ensureLayout,
120
- estimateCanvasHeight: () => import_canvas21.estimateCanvasHeight,
121
- estimateNodeSize: () => import_canvas21.estimateNodeSize,
122
- evaluateAnimation: () => import_canvas24.evaluateAnimation,
123
- evaluateEasing: () => import_canvas24.evaluateEasing,
124
- evaluateTrack: () => import_canvas24.evaluateTrack,
125
- excludePaths: () => import_canvas20.excludePaths,
126
- exportCssAnimation: () => import_canvas24.exportCssAnimation,
127
- findConnectorSnap: () => import_canvas18.findConnectorSnap,
128
- fitCubicRun: () => import_canvas17.fitCubicRun,
129
- fitCubics: () => import_canvas17.fitCubics,
130
- fitFreehandPath: () => import_canvas17.fitFreehandPath,
131
- fitPathData: () => import_canvas17.fitPathData,
132
- fitViewportToNodes: () => import_canvas18.fitViewportToNodes,
133
- fitViewportToRect: () => import_canvas18.fitViewportToRect,
134
- flattenSvgPath: () => import_canvas19.flattenSvgPath,
135
- flowSide: () => import_canvas21.flowSide,
136
- formatAnimationTime: () => import_canvas24.formatAnimationTime,
137
- formatOklab: () => import_canvas24.formatOklab,
138
- getAbsolutePosition: () => import_canvas18.getAbsolutePosition,
139
- getAnimatableProperty: () => import_canvas24.getAnimatableProperty,
140
- getAnimatedProperties: () => import_canvas24.getAnimatedProperties,
141
- getAnimatedValue: () => import_canvas24.getAnimatedValue,
142
- getAnimationDuration: () => import_canvas24.getAnimationDuration,
143
- getAnimationTrack: () => import_canvas24.getAnimationTrack,
144
- getAutoLayout: () => import_canvas22.getAutoLayout,
145
- getAutoLayoutGrid: () => import_canvas22.getAutoLayoutGrid,
146
- getAutoLayoutInsertTarget: () => import_canvas22.getAutoLayoutInsertTarget,
147
- getBindableTokenProperties: () => import_canvas23.getBindableTokenProperties,
148
- getCanvasComponentDragId: () => import_canvas25.getCanvasComponentDragId,
149
- getCanvasTokenProperty: () => import_canvas23.getCanvasTokenProperty,
150
- getCenteredNodePosition: () => import_canvas21.getCenteredNodePosition,
151
- getChildLayout: () => import_canvas22.getChildLayout,
152
- getComponentSourceId: () => import_canvas25.getComponentSourceId,
153
- getCssPropertyAnimations: () => import_canvas24.getCssPropertyAnimations,
154
- getEffectiveTokenModes: () => import_canvas23.getEffectiveTokenModes,
155
- getFlowChildren: () => import_canvas22.getFlowChildren,
156
- getInstanceData: () => import_canvas25.getInstanceData,
157
- getInstanceStatus: () => import_canvas25.getInstanceStatus,
158
- getKeyframeTimes: () => import_canvas24.getKeyframeTimes,
159
- getLayoutParent: () => import_canvas22.getLayoutParent,
160
- getLayoutSizing: () => import_canvas22.getLayoutSizing,
161
- getLayoutedNodes: () => import_canvas21.getLayoutedNodes,
162
- getNextVariantValues: () => import_canvas25.getNextVariantValues,
163
- getNodeAnimation: () => import_canvas24.getNodeAnimation,
164
- getNodeOverrides: () => import_canvas25.getNodeOverrides,
165
- getNodeRect: () => import_canvas18.getNodeRect,
166
- getNodeShape: () => import_canvas19.getNodeShape,
167
- getNodeSize: () => import_canvas18.getNodeSize,
168
- getNodeTokenBindings: () => import_canvas23.getNodeTokenBindings,
169
- getNodeTokenModes: () => import_canvas23.getNodeTokenModes,
170
- getResizingNodeRect: () => import_canvas17.getResizingNodeRect,
171
- getShapeRenderData: () => import_canvas19.getShapeRenderData,
172
- getShapeSvg: () => import_canvas19.getShapeSvg,
173
- getTimelineRows: () => import_canvas24.getTimelineRows,
174
- getTimelineTicks: () => import_canvas24.getTimelineTicks,
175
- getTokenPropertyScope: () => import_canvas23.getTokenPropertyScope,
176
- getTokensForProperty: () => import_canvas23.getTokensForProperty,
177
- handlePoint: () => import_canvas18.handlePoint,
178
- hasVisibleStroke: () => import_canvas20.hasVisibleStroke,
179
- inferResizeHandle: () => import_canvas17.inferResizeHandle,
180
- inspectCanvasInstance: () => import_canvas25.inspectCanvasInstance,
181
- inspectNodeTokens: () => import_canvas23.inspectNodeTokens,
182
- interpolateAnimationValue: () => import_canvas24.interpolateAnimationValue,
183
- intersectPaths: () => import_canvas20.intersectPaths,
184
- intersectPolygons: () => import_canvas19.intersectPolygons,
185
- invertNodeUpdates: () => import_canvas18.invertNodeUpdates,
186
- isAnimationEasing: () => import_canvas24.isAnimationEasing,
187
- isAnimationKeyframe: () => import_canvas24.isAnimationKeyframe,
188
- isAutoLayoutFrame: () => import_canvas22.isAutoLayoutFrame,
189
- isCanvasComponent: () => import_canvas25.isCanvasComponent,
190
- isCanvasComponentSet: () => import_canvas25.isCanvasComponentSet,
191
- isCanvasInstance: () => import_canvas25.isCanvasInstance,
192
- isCssExportExact: () => import_canvas24.isCssExportExact,
193
- isEventFromTextInput: () => import_canvas21.isEventFromTextInput,
194
- isKeyframeSelected: () => import_canvas24.isKeyframeSelected,
195
- isLocked: () => import_canvas18.isLocked,
196
- isMeasureModifierHeld: () => import_canvas17.isMeasureModifierHeld,
197
- isNodeAnimated: () => import_canvas24.isNodeAnimated,
198
- isShapeDescription: () => import_canvas19.isShapeDescription,
199
- isShapeNode: () => import_canvas19.isShapeNode,
200
- isStraightCubic: () => import_canvas17.isStraightCubic,
201
- isValidCanvasNode: () => import_canvas21.isValidCanvasNode,
202
- isValidUrl: () => import_canvas21.isValidUrl,
203
- layoutAll: () => import_canvas22.layoutAll,
204
- layoutBounds: () => import_canvas21.layoutBounds,
205
- layoutFrame: () => import_canvas22.layoutFrame,
206
- layoutUp: () => import_canvas22.layoutUp,
207
- layoutUpMany: () => import_canvas22.layoutUpMany,
208
- linearPositionTrajectory: () => import_canvas21.linearPositionTrajectory,
209
- linearTrajectory: () => import_canvas21.linearTrajectory,
210
- listCanvasComponents: () => import_canvas25.listCanvasComponents,
211
- lockNodes: () => import_canvas18.lockNodes,
212
- makeSizingCoherent: () => import_canvas22.makeSizingCoherent,
213
- matchArrangeShortcut: () => import_canvas18.matchArrangeShortcut,
214
- matchSize: () => import_canvas18.matchSize,
215
- measureBetween: () => import_canvas17.measureBetween,
216
- measureLabel: () => import_canvas17.measureLabel,
217
- measureSelection: () => import_canvas17.measureSelection,
218
- measureToLine: () => import_canvas17.measureToLine,
219
- mergeNodeUpdates: () => import_canvas22.mergeNodeUpdates,
220
- mixColorsOklab: () => import_canvas24.mixColorsOklab,
221
- moveKeyframes: () => import_canvas24.moveKeyframes,
222
- moveLayoutChild: () => import_canvas22.moveLayoutChild,
223
- multiPolygonArea: () => import_canvas19.multiPolygonArea,
224
- multiPolygonBounds: () => import_canvas19.multiPolygonBounds,
225
- nearestHandlePositions: () => import_canvas18.nearestHandlePositions,
226
- normalizeBezierPath: () => import_canvas20.normalizeBezierPath,
227
- normalizeKeyframes: () => import_canvas24.normalizeKeyframes,
228
- offsetPath: () => import_canvas20.offsetPath,
229
- offsetShapeNodes: () => import_canvas20.offsetShapeNodes,
230
- oklabToRgb: () => import_canvas24.oklabToRgb,
231
- oppositePosition: () => import_canvas18.oppositePosition,
232
- outlineShapeNodeStrokes: () => import_canvas20.outlineShapeNodeStrokes,
233
- outlineStroke: () => import_canvas20.outlineStroke,
234
- overlaps: () => import_canvas21.overlaps,
235
- parseCanvasClipboardData: () => import_canvas21.parseCanvasClipboardData,
236
- parseCanvasScenes: () => import_canvas18.parseCanvasScenes,
237
- parseCssEasing: () => import_canvas24.parseCssEasing,
238
- parseKeyframeClipboard: () => import_canvas24.parseKeyframeClipboard,
239
- parseOklab: () => import_canvas24.parseOklab,
240
- parseSvgPath: () => import_canvas19.parseSvgPath,
241
- pasteKeyframes: () => import_canvas24.pasteKeyframes,
242
- pathBoolean: () => import_canvas20.pathBoolean,
243
- placeBeside: () => import_canvas21.placeBeside,
244
- playWebAnimations: () => import_canvas24.playWebAnimations,
245
- pointInBezierPath: () => import_canvas20.pointInBezierPath,
246
- pointInMultiPolygon: () => import_canvas19.pointInMultiPolygon,
247
- pointInRings: () => import_canvas19.pointInRings,
248
- polygonArea: () => import_canvas19.polygonArea,
249
- polygonBoolean: () => import_canvas19.polygonBoolean,
250
- polygonToSvgPath: () => import_canvas19.polygonToSvgPath,
251
- positionToSide: () => import_canvas18.positionToSide,
252
- pruneCanvasTokenModes: () => import_canvas23.pruneCanvasTokenModes,
253
- pushCanvasInstanceOverrides: () => import_canvas25.pushCanvasInstanceOverrides,
254
- readAnimatableValue: () => import_canvas24.readAnimatableValue,
255
- readNodeStyleProperty: () => import_canvas23.readNodeStyleProperty,
256
- readStyleSize: () => import_canvas18.readStyleSize,
257
- realClock: () => import_canvas21.realClock,
258
- recordAnimationChanges: () => import_canvas24.recordAnimationChanges,
259
- relayoutUpdates: () => import_canvas22.relayoutUpdates,
260
- remapPastedNodes: () => import_canvas21.remapPastedNodes,
261
- removeCanvasVariant: () => import_canvas25.removeCanvasVariant,
262
- removeTrack: () => import_canvas24.removeTrack,
263
- renameCanvasVariantProperty: () => import_canvas25.renameCanvasVariantProperty,
264
- renameCanvasVariantValue: () => import_canvas25.renameCanvasVariantValue,
265
- reorderNodes: () => import_canvas18.reorderNodes,
266
- repositionNodesTo: () => import_canvas21.repositionNodesTo,
267
- resetCanvasInstanceOverrides: () => import_canvas25.resetCanvasInstanceOverrides,
268
- resizeHandleAxes: () => import_canvas17.resizeHandleAxes,
269
- resolveCanvasTokens: () => import_canvas23.resolveCanvasTokens,
270
- resolveEasing: () => import_canvas24.resolveEasing,
271
- resolvePadding: () => import_canvas22.resolvePadding,
272
- restoreCanvasMainComponent: () => import_canvas25.restoreCanvasMainComponent,
273
- revertShapeCombination: () => import_canvas19.revertShapeCombination,
274
- rgbToOklab: () => import_canvas24.rgbToOklab,
275
- ringSignedArea: () => import_canvas19.ringSignedArea,
276
- runMultiNodeTransition: () => import_canvas21.runMultiNodeTransition,
277
- sampleAnimationFrames: () => import_canvas24.sampleAnimationFrames,
278
- scaleKeyframes: () => import_canvas24.scaleKeyframes,
279
- serializeCanvasNodes: () => import_canvas21.serializeCanvasNodes,
280
- setCanvasComponentProperty: () => import_canvas25.setCanvasComponentProperty,
281
- setCanvasInstanceProperties: () => import_canvas25.setCanvasInstanceProperties,
282
- setCanvasTokenMode: () => import_canvas23.setCanvasTokenMode,
283
- setCanvasVariantProperties: () => import_canvas25.setCanvasVariantProperties,
284
- setKeyframe: () => import_canvas24.setKeyframe,
285
- setKeyframeEasing: () => import_canvas24.setKeyframeEasing,
286
- setMotionPath: () => import_canvas24.setMotionPath,
287
- setTrackEnabled: () => import_canvas24.setTrackEnabled,
288
- shapeNodeToBezierPath: () => import_canvas20.shapeNodeToBezierPath,
289
- shapeNodeToPolygon: () => import_canvas19.shapeNodeToPolygon,
290
- shapeToBezierPath: () => import_canvas20.shapeToBezierPath,
291
- shapeToPolygon: () => import_canvas19.shapeToPolygon,
292
- sideToPosition: () => import_canvas18.sideToPosition,
293
- simplifyRing: () => import_canvas19.simplifyRing,
294
- snapKeyframeDelta: () => import_canvas24.snapKeyframeDelta,
295
- snapNodeDrag: () => import_canvas18.snapNodeDrag,
296
- snapNodeResize: () => import_canvas17.snapNodeResize,
297
- snapResize: () => import_canvas17.snapResize,
298
- snapTimeToFrame: () => import_canvas24.snapTimeToFrame,
299
- snapToGrid: () => import_canvas17.snapToGrid,
300
- springAt: () => import_canvas24.springAt,
301
- strokeOutlineRings: () => import_canvas20.strokeOutlineRings,
302
- subtractPaths: () => import_canvas20.subtractPaths,
303
- subtractPolygons: () => import_canvas19.subtractPolygons,
304
- swapCanvasInstance: () => import_canvas25.swapCanvasInstance,
305
- syncAllCanvasInstances: () => import_canvas25.syncAllCanvasInstances,
306
- syncCanvasComponents: () => import_canvas25.syncCanvasComponents,
307
- syncCanvasInstance: () => import_canvas25.syncCanvasInstance,
308
- timeToX: () => import_canvas24.timeToX,
309
- toBezierPath: () => import_canvas20.toBezierPath,
310
- toWebAnimations: () => import_canvas24.toWebAnimations,
311
- toggleLockNodes: () => import_canvas18.toggleLockNodes,
312
- transformBezierPath: () => import_canvas20.transformBezierPath,
313
- unionPolygons: () => import_canvas19.unionPolygons,
314
- unitePaths: () => import_canvas20.unitePaths,
315
- unlockNodes: () => import_canvas18.unlockNodes,
316
- updateKeyframe: () => import_canvas24.updateKeyframe,
57
+ addCanvasVariant: () => import_canvas27.addCanvasVariant,
58
+ addKeyframesAtTime: () => import_canvas26.addKeyframesAtTime,
59
+ alignNodes: () => import_canvas20.alignNodes,
60
+ animateNode: () => import_canvas26.animateNode,
61
+ applyAnimation: () => import_canvas26.applyAnimation,
62
+ applyAnimationOverrides: () => import_canvas26.applyAnimationOverrides,
63
+ applyConstraints: () => import_canvas24.applyConstraints,
64
+ applyNodeUpdates: () => import_canvas20.applyNodeUpdates,
65
+ applyShapeCombination: () => import_canvas21.applyShapeCombination,
66
+ applyShapeReplacement: () => import_canvas22.applyShapeReplacement,
67
+ bezierPathArea: () => import_canvas22.bezierPathArea,
68
+ bezierPathBounds: () => import_canvas22.bezierPathBounds,
69
+ bezierPathLength: () => import_canvas22.bezierPathLength,
70
+ bezierPathPointAtLength: () => import_canvas22.bezierPathPointAtLength,
71
+ bezierPathSignedArea: () => import_canvas22.bezierPathSignedArea,
72
+ bezierPathToSvg: () => import_canvas22.bezierPathToSvg,
73
+ bindCanvasComponentProperty: () => import_canvas27.bindCanvasComponentProperty,
74
+ bindCanvasToken: () => import_canvas25.bindCanvasToken,
75
+ blendLayout: () => import_canvas23.blendLayout,
76
+ boundsOf: () => import_canvas23.boundsOf,
77
+ calculateDagreReflowDisplacement: () => import_canvas23.calculateDagreReflowDisplacement,
78
+ calculateDirectionalDisplacement: () => import_canvas23.calculateDirectionalDisplacement,
79
+ canCombineShapeNodes: () => import_canvas21.canCombineShapeNodes,
80
+ canOffsetShapeNodes: () => import_canvas22.canOffsetShapeNodes,
81
+ canOutlineShapeNodeStrokes: () => import_canvas22.canOutlineShapeNodeStrokes,
82
+ canvasHeight: () => import_canvas23.canvasHeight,
83
+ centerNodes: () => import_canvas23.centerNodes,
84
+ centre: () => import_canvas23.centre,
85
+ clampAnimationValue: () => import_canvas26.clampAnimationValue,
86
+ clampLayoutSize: () => import_canvas24.clampLayoutSize,
87
+ combineCanvasComponentsAsVariants: () => import_canvas27.combineCanvasComponentsAsVariants,
88
+ combineShapeNodes: () => import_canvas21.combineShapeNodes,
89
+ computeNodesBoundingBox: () => import_canvas23.computeNodesBoundingBox,
90
+ computeSnapGuides: () => import_canvas20.computeSnapGuides,
91
+ connectedOnly: () => import_canvas23.connectedOnly,
92
+ copyKeyframes: () => import_canvas26.copyKeyframes,
93
+ countPathSegments: () => import_canvas22.countPathSegments,
94
+ createAnimationPlayer: () => import_canvas26.createAnimationPlayer,
95
+ createBezierTrajectory: () => import_canvas23.createBezierTrajectory,
96
+ createCanvasAnimationController: () => import_canvas26.createCanvasAnimationController,
97
+ createCanvasAutoLayoutController: () => import_canvas24.createCanvasAutoLayoutController,
98
+ createCanvasComponent: () => import_canvas27.createCanvasComponent,
99
+ createCanvasComponentsController: () => import_canvas27.createCanvasComponentsController,
100
+ createCanvasDrawController: () => import_canvas27.createCanvasDrawController,
101
+ createCanvasInstance: () => import_canvas27.createCanvasInstance,
102
+ createCanvasScenesStore: () => import_canvas20.createCanvasScenesStore,
103
+ createDefaultStrokeStyle: () => import_canvas27.createDefaultStrokeStyle,
104
+ createFanOutTrajectory: () => import_canvas23.createFanOutTrajectory,
105
+ createGuideIndex: () => import_canvas20.createGuideIndex,
106
+ createNodeGuideIndex: () => import_canvas20.createNodeGuideIndex,
107
+ cubicBezierAt: () => import_canvas26.cubicBezierAt,
108
+ cubicPointAt: () => import_canvas19.cubicPointAt,
109
+ cubicsToPathData: () => import_canvas19.cubicsToPathData,
110
+ dashContours: () => import_canvas22.dashContours,
111
+ defaultEasing: () => import_canvas23.defaultEasing,
112
+ deleteKeyframes: () => import_canvas26.deleteKeyframes,
113
+ detachCanvasInstance: () => import_canvas27.detachCanvasInstance,
114
+ detachTokenBindings: () => import_canvas25.detachTokenBindings,
115
+ distanceToBezierPath: () => import_canvas22.distanceToBezierPath,
116
+ distributeNodes: () => import_canvas20.distributeNodes,
117
+ dividePaths: () => import_canvas22.dividePaths,
118
+ dividePolygons: () => import_canvas21.dividePolygons,
119
+ easingFromInfluence: () => import_canvas26.easingFromInfluence,
120
+ easingLabel: () => import_canvas26.easingLabel,
121
+ easingToCss: () => import_canvas26.easingToCss,
122
+ ensureLayout: () => import_canvas23.ensureLayout,
123
+ estimateCanvasHeight: () => import_canvas23.estimateCanvasHeight,
124
+ estimateNodeSize: () => import_canvas23.estimateNodeSize,
125
+ evaluateAnimation: () => import_canvas26.evaluateAnimation,
126
+ evaluateEasing: () => import_canvas26.evaluateEasing,
127
+ evaluateTrack: () => import_canvas26.evaluateTrack,
128
+ excludePaths: () => import_canvas22.excludePaths,
129
+ exportCssAnimation: () => import_canvas26.exportCssAnimation,
130
+ findConnectorSnap: () => import_canvas20.findConnectorSnap,
131
+ findStrokesAtPoint: () => import_canvas27.findStrokesAtPoint,
132
+ fitCubicRun: () => import_canvas19.fitCubicRun,
133
+ fitCubics: () => import_canvas19.fitCubics,
134
+ fitFreehandPath: () => import_canvas19.fitFreehandPath,
135
+ fitPathData: () => import_canvas19.fitPathData,
136
+ fitViewportToNodes: () => import_canvas20.fitViewportToNodes,
137
+ fitViewportToRect: () => import_canvas20.fitViewportToRect,
138
+ flattenSvgPath: () => import_canvas21.flattenSvgPath,
139
+ flowSide: () => import_canvas23.flowSide,
140
+ formatAnimationTime: () => import_canvas26.formatAnimationTime,
141
+ formatOklab: () => import_canvas26.formatOklab,
142
+ getAbsolutePosition: () => import_canvas20.getAbsolutePosition,
143
+ getAnimatableProperty: () => import_canvas26.getAnimatableProperty,
144
+ getAnimatedProperties: () => import_canvas26.getAnimatedProperties,
145
+ getAnimatedValue: () => import_canvas26.getAnimatedValue,
146
+ getAnimationDuration: () => import_canvas26.getAnimationDuration,
147
+ getAnimationTrack: () => import_canvas26.getAnimationTrack,
148
+ getAutoLayout: () => import_canvas24.getAutoLayout,
149
+ getAutoLayoutGrid: () => import_canvas24.getAutoLayoutGrid,
150
+ getAutoLayoutInsertTarget: () => import_canvas24.getAutoLayoutInsertTarget,
151
+ getBindableTokenProperties: () => import_canvas25.getBindableTokenProperties,
152
+ getCanvasComponentDragId: () => import_canvas27.getCanvasComponentDragId,
153
+ getCanvasTokenProperty: () => import_canvas25.getCanvasTokenProperty,
154
+ getCenteredNodePosition: () => import_canvas23.getCenteredNodePosition,
155
+ getChildLayout: () => import_canvas24.getChildLayout,
156
+ getComponentSourceId: () => import_canvas27.getComponentSourceId,
157
+ getCssPropertyAnimations: () => import_canvas26.getCssPropertyAnimations,
158
+ getEffectiveTokenModes: () => import_canvas25.getEffectiveTokenModes,
159
+ getFlowChildren: () => import_canvas24.getFlowChildren,
160
+ getInstanceData: () => import_canvas27.getInstanceData,
161
+ getInstanceStatus: () => import_canvas27.getInstanceStatus,
162
+ getKeyframeTimes: () => import_canvas26.getKeyframeTimes,
163
+ getLayoutParent: () => import_canvas24.getLayoutParent,
164
+ getLayoutSizing: () => import_canvas24.getLayoutSizing,
165
+ getLayoutedNodes: () => import_canvas23.getLayoutedNodes,
166
+ getNextVariantValues: () => import_canvas27.getNextVariantValues,
167
+ getNodeAnimation: () => import_canvas26.getNodeAnimation,
168
+ getNodeOverrides: () => import_canvas27.getNodeOverrides,
169
+ getNodeRect: () => import_canvas20.getNodeRect,
170
+ getNodeShape: () => import_canvas21.getNodeShape,
171
+ getNodeSize: () => import_canvas20.getNodeSize,
172
+ getNodeTokenBindings: () => import_canvas25.getNodeTokenBindings,
173
+ getNodeTokenModes: () => import_canvas25.getNodeTokenModes,
174
+ getResizingNodeRect: () => import_canvas19.getResizingNodeRect,
175
+ getShapeRenderData: () => import_canvas21.getShapeRenderData,
176
+ getShapeSvg: () => import_canvas21.getShapeSvg,
177
+ getTimelineRows: () => import_canvas26.getTimelineRows,
178
+ getTimelineTicks: () => import_canvas26.getTimelineTicks,
179
+ getTokenPropertyScope: () => import_canvas25.getTokenPropertyScope,
180
+ getTokensForProperty: () => import_canvas25.getTokensForProperty,
181
+ handlePoint: () => import_canvas20.handlePoint,
182
+ hasVisibleStroke: () => import_canvas22.hasVisibleStroke,
183
+ inferResizeHandle: () => import_canvas19.inferResizeHandle,
184
+ inspectCanvasInstance: () => import_canvas27.inspectCanvasInstance,
185
+ inspectNodeTokens: () => import_canvas25.inspectNodeTokens,
186
+ interpolateAnimationValue: () => import_canvas26.interpolateAnimationValue,
187
+ intersectPaths: () => import_canvas22.intersectPaths,
188
+ intersectPolygons: () => import_canvas21.intersectPolygons,
189
+ invertNodeUpdates: () => import_canvas20.invertNodeUpdates,
190
+ isAnimationEasing: () => import_canvas26.isAnimationEasing,
191
+ isAnimationKeyframe: () => import_canvas26.isAnimationKeyframe,
192
+ isAutoLayoutFrame: () => import_canvas24.isAutoLayoutFrame,
193
+ isCanvasComponent: () => import_canvas27.isCanvasComponent,
194
+ isCanvasComponentSet: () => import_canvas27.isCanvasComponentSet,
195
+ isCanvasInstance: () => import_canvas27.isCanvasInstance,
196
+ isCssExportExact: () => import_canvas26.isCssExportExact,
197
+ isEventFromTextInput: () => import_canvas23.isEventFromTextInput,
198
+ isKeyframeSelected: () => import_canvas26.isKeyframeSelected,
199
+ isLocked: () => import_canvas20.isLocked,
200
+ isMeasureModifierHeld: () => import_canvas19.isMeasureModifierHeld,
201
+ isNodeAnimated: () => import_canvas26.isNodeAnimated,
202
+ isShapeDescription: () => import_canvas21.isShapeDescription,
203
+ isShapeNode: () => import_canvas21.isShapeNode,
204
+ isStraightCubic: () => import_canvas19.isStraightCubic,
205
+ isValidCanvasNode: () => import_canvas23.isValidCanvasNode,
206
+ isValidUrl: () => import_canvas23.isValidUrl,
207
+ layoutAll: () => import_canvas24.layoutAll,
208
+ layoutBounds: () => import_canvas23.layoutBounds,
209
+ layoutFrame: () => import_canvas24.layoutFrame,
210
+ layoutUp: () => import_canvas24.layoutUp,
211
+ layoutUpMany: () => import_canvas24.layoutUpMany,
212
+ linearPositionTrajectory: () => import_canvas23.linearPositionTrajectory,
213
+ linearTrajectory: () => import_canvas23.linearTrajectory,
214
+ listCanvasComponents: () => import_canvas27.listCanvasComponents,
215
+ lockNodes: () => import_canvas20.lockNodes,
216
+ makeSizingCoherent: () => import_canvas24.makeSizingCoherent,
217
+ matchArrangeShortcut: () => import_canvas20.matchArrangeShortcut,
218
+ matchSize: () => import_canvas20.matchSize,
219
+ measureBetween: () => import_canvas19.measureBetween,
220
+ measureLabel: () => import_canvas19.measureLabel,
221
+ measureSelection: () => import_canvas19.measureSelection,
222
+ measureToLine: () => import_canvas19.measureToLine,
223
+ mergeNodeUpdates: () => import_canvas24.mergeNodeUpdates,
224
+ mixColorsOklab: () => import_canvas26.mixColorsOklab,
225
+ moveKeyframes: () => import_canvas26.moveKeyframes,
226
+ moveLayoutChild: () => import_canvas24.moveLayoutChild,
227
+ multiPolygonArea: () => import_canvas21.multiPolygonArea,
228
+ multiPolygonBounds: () => import_canvas21.multiPolygonBounds,
229
+ nearestHandlePositions: () => import_canvas20.nearestHandlePositions,
230
+ normalizeBezierPath: () => import_canvas22.normalizeBezierPath,
231
+ normalizeKeyframes: () => import_canvas26.normalizeKeyframes,
232
+ offsetPath: () => import_canvas22.offsetPath,
233
+ offsetShapeNodes: () => import_canvas22.offsetShapeNodes,
234
+ oklabToRgb: () => import_canvas26.oklabToRgb,
235
+ oppositePosition: () => import_canvas20.oppositePosition,
236
+ outlineShapeNodeStrokes: () => import_canvas22.outlineShapeNodeStrokes,
237
+ outlineStroke: () => import_canvas22.outlineStroke,
238
+ overlaps: () => import_canvas23.overlaps,
239
+ parseCanvasClipboardData: () => import_canvas23.parseCanvasClipboardData,
240
+ parseCanvasScenes: () => import_canvas20.parseCanvasScenes,
241
+ parseCssEasing: () => import_canvas26.parseCssEasing,
242
+ parseKeyframeClipboard: () => import_canvas26.parseKeyframeClipboard,
243
+ parseOklab: () => import_canvas26.parseOklab,
244
+ parseSvgPath: () => import_canvas21.parseSvgPath,
245
+ pasteKeyframes: () => import_canvas26.pasteKeyframes,
246
+ pathBoolean: () => import_canvas22.pathBoolean,
247
+ placeBeside: () => import_canvas23.placeBeside,
248
+ playWebAnimations: () => import_canvas26.playWebAnimations,
249
+ pointInBezierPath: () => import_canvas22.pointInBezierPath,
250
+ pointInMultiPolygon: () => import_canvas21.pointInMultiPolygon,
251
+ pointInRings: () => import_canvas21.pointInRings,
252
+ polygonArea: () => import_canvas21.polygonArea,
253
+ polygonBoolean: () => import_canvas21.polygonBoolean,
254
+ polygonToSvgPath: () => import_canvas21.polygonToSvgPath,
255
+ positionToSide: () => import_canvas20.positionToSide,
256
+ pruneCanvasTokenModes: () => import_canvas25.pruneCanvasTokenModes,
257
+ pushCanvasInstanceOverrides: () => import_canvas27.pushCanvasInstanceOverrides,
258
+ readAnimatableValue: () => import_canvas26.readAnimatableValue,
259
+ readNodeStyleProperty: () => import_canvas25.readNodeStyleProperty,
260
+ readStyleSize: () => import_canvas20.readStyleSize,
261
+ realClock: () => import_canvas23.realClock,
262
+ recordAnimationChanges: () => import_canvas26.recordAnimationChanges,
263
+ relayoutUpdates: () => import_canvas24.relayoutUpdates,
264
+ remapPastedNodes: () => import_canvas23.remapPastedNodes,
265
+ removeCanvasVariant: () => import_canvas27.removeCanvasVariant,
266
+ removeTrack: () => import_canvas26.removeTrack,
267
+ renameCanvasVariantProperty: () => import_canvas27.renameCanvasVariantProperty,
268
+ renameCanvasVariantValue: () => import_canvas27.renameCanvasVariantValue,
269
+ reorderNodes: () => import_canvas20.reorderNodes,
270
+ repositionNodesTo: () => import_canvas23.repositionNodesTo,
271
+ resetCanvasInstanceOverrides: () => import_canvas27.resetCanvasInstanceOverrides,
272
+ resizeHandleAxes: () => import_canvas19.resizeHandleAxes,
273
+ resolveCanvasTokens: () => import_canvas25.resolveCanvasTokens,
274
+ resolveEasing: () => import_canvas26.resolveEasing,
275
+ resolvePadding: () => import_canvas24.resolvePadding,
276
+ restoreCanvasMainComponent: () => import_canvas27.restoreCanvasMainComponent,
277
+ revertShapeCombination: () => import_canvas21.revertShapeCombination,
278
+ rgbToOklab: () => import_canvas26.rgbToOklab,
279
+ ringSignedArea: () => import_canvas21.ringSignedArea,
280
+ runMultiNodeTransition: () => import_canvas23.runMultiNodeTransition,
281
+ sampleAnimationFrames: () => import_canvas26.sampleAnimationFrames,
282
+ scaleKeyframes: () => import_canvas26.scaleKeyframes,
283
+ serializeCanvasNodes: () => import_canvas23.serializeCanvasNodes,
284
+ setCanvasComponentProperty: () => import_canvas27.setCanvasComponentProperty,
285
+ setCanvasInstanceProperties: () => import_canvas27.setCanvasInstanceProperties,
286
+ setCanvasTokenMode: () => import_canvas25.setCanvasTokenMode,
287
+ setCanvasVariantProperties: () => import_canvas27.setCanvasVariantProperties,
288
+ setKeyframe: () => import_canvas26.setKeyframe,
289
+ setKeyframeEasing: () => import_canvas26.setKeyframeEasing,
290
+ setMotionPath: () => import_canvas26.setMotionPath,
291
+ setTrackEnabled: () => import_canvas26.setTrackEnabled,
292
+ shapeNodeToBezierPath: () => import_canvas22.shapeNodeToBezierPath,
293
+ shapeNodeToPolygon: () => import_canvas21.shapeNodeToPolygon,
294
+ shapeToBezierPath: () => import_canvas22.shapeToBezierPath,
295
+ shapeToPolygon: () => import_canvas21.shapeToPolygon,
296
+ sideToPosition: () => import_canvas20.sideToPosition,
297
+ simplifyRing: () => import_canvas21.simplifyRing,
298
+ snapKeyframeDelta: () => import_canvas26.snapKeyframeDelta,
299
+ snapNodeDrag: () => import_canvas20.snapNodeDrag,
300
+ snapNodeResize: () => import_canvas19.snapNodeResize,
301
+ snapResize: () => import_canvas19.snapResize,
302
+ snapTimeToFrame: () => import_canvas26.snapTimeToFrame,
303
+ snapToGrid: () => import_canvas19.snapToGrid,
304
+ springAt: () => import_canvas26.springAt,
305
+ streamlinePoints: () => import_canvas27.streamlinePoints,
306
+ strokeOutlineRings: () => import_canvas22.strokeOutlineRings,
307
+ strokePointsToPathData: () => import_canvas27.strokePointsToPathData,
308
+ strokeToShapeNode: () => import_canvas27.strokeToShapeNode,
309
+ subtractPaths: () => import_canvas22.subtractPaths,
310
+ subtractPolygons: () => import_canvas21.subtractPolygons,
311
+ swapCanvasInstance: () => import_canvas27.swapCanvasInstance,
312
+ syncAllCanvasInstances: () => import_canvas27.syncAllCanvasInstances,
313
+ syncCanvasComponents: () => import_canvas27.syncCanvasComponents,
314
+ syncCanvasInstance: () => import_canvas27.syncCanvasInstance,
315
+ timeToX: () => import_canvas26.timeToX,
316
+ toBezierPath: () => import_canvas22.toBezierPath,
317
+ toWebAnimations: () => import_canvas26.toWebAnimations,
318
+ toggleLockNodes: () => import_canvas20.toggleLockNodes,
319
+ transformBezierPath: () => import_canvas22.transformBezierPath,
320
+ unionPolygons: () => import_canvas21.unionPolygons,
321
+ unitePaths: () => import_canvas22.unitePaths,
322
+ unlockNodes: () => import_canvas20.unlockNodes,
323
+ updateKeyframe: () => import_canvas26.updateKeyframe,
317
324
  useCanvasAnimation: () => useCanvasAnimation,
318
325
  useCanvasArrange: () => useCanvasArrange,
319
326
  useCanvasArrangeShortcuts: () => useCanvasArrangeShortcuts,
@@ -321,6 +328,7 @@ __export(canvas_exports, {
321
328
  useCanvasClipboard: () => useCanvasClipboard,
322
329
  useCanvasComponents: () => useCanvasComponents,
323
330
  useCanvasDocking: () => useCanvasDocking,
331
+ useCanvasDraw: () => useCanvasDraw,
324
332
  useCanvasExplosion: () => useCanvasExplosion,
325
333
  useCanvasGraph: () => useCanvasGraph,
326
334
  useCanvasLayout: () => useCanvasLayout,
@@ -329,13 +337,13 @@ __export(canvas_exports, {
329
337
  useCanvasShortcuts: () => useCanvasShortcuts,
330
338
  useCanvasTokens: () => useCanvasTokens,
331
339
  useStreamingCanvas: () => useStreamingCanvas,
332
- withNodeAnimation: () => import_canvas24.withNodeAnimation,
333
- withStyleSize: () => import_canvas18.withStyleSize,
334
- wouldCreateComponentCycle: () => import_canvas25.wouldCreateComponentCycle,
335
- wrapAnimationTime: () => import_canvas24.wrapAnimationTime,
336
- writeNodeStyleProperty: () => import_canvas23.writeNodeStyleProperty,
337
- xToTime: () => import_canvas24.xToTime,
338
- xorPolygons: () => import_canvas19.xorPolygons
340
+ withNodeAnimation: () => import_canvas26.withNodeAnimation,
341
+ withStyleSize: () => import_canvas20.withStyleSize,
342
+ wouldCreateComponentCycle: () => import_canvas27.wouldCreateComponentCycle,
343
+ wrapAnimationTime: () => import_canvas26.wrapAnimationTime,
344
+ writeNodeStyleProperty: () => import_canvas25.writeNodeStyleProperty,
345
+ xToTime: () => import_canvas26.xToTime,
346
+ xorPolygons: () => import_canvas21.xorPolygons
339
347
  });
340
348
  module.exports = __toCommonJS(canvas_exports);
341
349
 
@@ -1292,21 +1300,219 @@ function CanvasGuidesLayer({
1292
1300
  );
1293
1301
  }
1294
1302
 
1295
- // src/canvas/useCanvasMeasure.ts
1303
+ // src/canvas/useCanvasDraw.ts
1296
1304
  var import_react10 = require("react");
1297
1305
  var import_canvas8 = require("@pixerate/editor/canvas");
1306
+ function useCanvasDraw(options) {
1307
+ const nodesRef = (0, import_react10.useRef)(options.nodes);
1308
+ nodesRef.current = options.nodes;
1309
+ const optionsRef = (0, import_react10.useRef)(options);
1310
+ optionsRef.current = options;
1311
+ const [tool, setToolState] = (0, import_react10.useState)(options.initialTool ?? "select");
1312
+ const [activeStroke, setActiveStroke] = (0, import_react10.useState)(null);
1313
+ const controller = (0, import_react10.useMemo)(
1314
+ () => (0, import_canvas8.createCanvasDrawController)({
1315
+ getNodes: () => nodesRef.current,
1316
+ setNodes: (next) => {
1317
+ nodesRef.current = next;
1318
+ optionsRef.current.setNodes(next);
1319
+ },
1320
+ get history() {
1321
+ return optionsRef.current.history;
1322
+ },
1323
+ tool: options.initialTool ?? "select",
1324
+ style: options.initialStyle,
1325
+ drawOptions: options.drawOptions,
1326
+ generateNodeId: options.generateNodeId,
1327
+ onToolChange: setToolState,
1328
+ onStyleChange: (s) => setStyleState(s),
1329
+ onActiveStrokeChange: setActiveStroke,
1330
+ onStrokeComplete: (n) => optionsRef.current.onStrokeComplete?.(n),
1331
+ onNodesErase: (erased) => optionsRef.current.onNodesErase?.(erased)
1332
+ }),
1333
+ []
1334
+ );
1335
+ const [style, setStyleState] = (0, import_react10.useState)(controller.style);
1336
+ (0, import_react10.useEffect)(() => {
1337
+ if (options.initialTool && options.initialTool !== controller.tool) {
1338
+ controller.setTool(options.initialTool);
1339
+ }
1340
+ }, [options.initialTool, controller]);
1341
+ return (0, import_react10.useMemo)(
1342
+ () => ({
1343
+ tool,
1344
+ style,
1345
+ activeStroke,
1346
+ isDrawing: activeStroke !== null,
1347
+ setTool: controller.setTool,
1348
+ setStyle: controller.setStyle,
1349
+ startStroke: controller.startStroke,
1350
+ continueStroke: controller.continueStroke,
1351
+ endStroke: controller.endStroke,
1352
+ cancelStroke: controller.cancelStroke,
1353
+ eraseAt: controller.eraseAt
1354
+ }),
1355
+ [tool, style, activeStroke, controller]
1356
+ );
1357
+ }
1358
+
1359
+ // src/canvas/CanvasDrawLayer.tsx
1360
+ var import_react11 = require("react");
1361
+ var import_canvas9 = require("@pixerate/editor/canvas");
1362
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1363
+ var DEFAULT_VIEWPORT2 = { x: 0, y: 0, zoom: 1 };
1364
+ function CanvasDrawLayer({
1365
+ draw,
1366
+ viewport = DEFAULT_VIEWPORT2,
1367
+ className = "",
1368
+ style,
1369
+ cursor,
1370
+ eraserRadius = 12
1371
+ }) {
1372
+ const svgRef = (0, import_react11.useRef)(null);
1373
+ const [spaceHeld, setSpaceHeld] = (0, import_react11.useState)(false);
1374
+ const [eraserPos, setEraserPos] = (0, import_react11.useState)(null);
1375
+ (0, import_react11.useEffect)(() => {
1376
+ function onKeyDown(e) {
1377
+ if (e.code === "Space" && !e.repeat) {
1378
+ const tag = e.target?.tagName;
1379
+ if (tag === "INPUT" || tag === "TEXTAREA" || e.target?.isContentEditable) {
1380
+ return;
1381
+ }
1382
+ setSpaceHeld(true);
1383
+ }
1384
+ }
1385
+ function onKeyUp(e) {
1386
+ if (e.code === "Space") {
1387
+ setSpaceHeld(false);
1388
+ }
1389
+ }
1390
+ window.addEventListener("keydown", onKeyDown);
1391
+ window.addEventListener("keyup", onKeyUp);
1392
+ return () => {
1393
+ window.removeEventListener("keydown", onKeyDown);
1394
+ window.removeEventListener("keyup", onKeyUp);
1395
+ };
1396
+ }, []);
1397
+ const clientToFlow = (0, import_react11.useCallback)(
1398
+ (clientX, clientY) => {
1399
+ if (!svgRef.current) return [0, 0];
1400
+ const rect = svgRef.current.getBoundingClientRect();
1401
+ const screenX = clientX - rect.left;
1402
+ const screenY = clientY - rect.top;
1403
+ const flowX = (screenX - viewport.x) / viewport.zoom;
1404
+ const flowY = (screenY - viewport.y) / viewport.zoom;
1405
+ return [flowX, flowY];
1406
+ },
1407
+ [viewport.x, viewport.y, viewport.zoom]
1408
+ );
1409
+ const isDrawingMode = draw.tool !== "select";
1410
+ const interactive = isDrawingMode && !spaceHeld;
1411
+ const handlePointerDown = (e) => {
1412
+ if (!interactive || e.button !== 0) return;
1413
+ e.preventDefault();
1414
+ e.stopPropagation();
1415
+ e.target.setPointerCapture?.(e.pointerId);
1416
+ const flowPt = clientToFlow(e.clientX, e.clientY);
1417
+ draw.startStroke(flowPt);
1418
+ if (draw.tool === "eraser") {
1419
+ setEraserPos([e.clientX, e.clientY]);
1420
+ }
1421
+ };
1422
+ const handlePointerMove = (e) => {
1423
+ if (draw.tool === "eraser" && !spaceHeld) {
1424
+ setEraserPos([e.clientX, e.clientY]);
1425
+ }
1426
+ if (!interactive) return;
1427
+ if (e.buttons === 1) {
1428
+ e.preventDefault();
1429
+ e.stopPropagation();
1430
+ const flowPt = clientToFlow(e.clientX, e.clientY);
1431
+ draw.continueStroke(flowPt);
1432
+ }
1433
+ };
1434
+ const handlePointerUp = (e) => {
1435
+ if (!interactive || e.button !== 0) return;
1436
+ e.preventDefault();
1437
+ e.stopPropagation();
1438
+ try {
1439
+ e.target.releasePointerCapture?.(e.pointerId);
1440
+ } catch {
1441
+ }
1442
+ draw.endStroke();
1443
+ };
1444
+ const handlePointerLeave = () => {
1445
+ setEraserPos(null);
1446
+ };
1447
+ const resolvedCursor = cursor ? cursor : spaceHeld ? "grab" : draw.tool === "eraser" ? "crosshair" : draw.tool === "pen" || draw.tool === "highlighter" ? "crosshair" : "default";
1448
+ const strokePath = draw.activeStroke ? (0, import_canvas9.strokePointsToPathData)(draw.activeStroke.points) : null;
1449
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1450
+ "svg",
1451
+ {
1452
+ ref: svgRef,
1453
+ className: `pixerate-canvas-draw-layer ${className}`,
1454
+ style: {
1455
+ position: "absolute",
1456
+ inset: 0,
1457
+ width: "100%",
1458
+ height: "100%",
1459
+ pointerEvents: interactive ? "all" : "none",
1460
+ cursor: interactive ? resolvedCursor : void 0,
1461
+ overflow: "visible",
1462
+ zIndex: 20,
1463
+ touchAction: "none",
1464
+ ...style
1465
+ },
1466
+ onPointerDown: handlePointerDown,
1467
+ onPointerMove: handlePointerMove,
1468
+ onPointerUp: handlePointerUp,
1469
+ onPointerLeave: handlePointerLeave,
1470
+ children: [
1471
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("g", { transform: `translate(${viewport.x}, ${viewport.y}) scale(${viewport.zoom})`, children: draw.activeStroke && strokePath && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1472
+ "path",
1473
+ {
1474
+ d: strokePath,
1475
+ fill: "none",
1476
+ stroke: draw.activeStroke.style.color,
1477
+ strokeWidth: draw.activeStroke.style.width,
1478
+ opacity: draw.activeStroke.style.opacity,
1479
+ strokeLinecap: draw.activeStroke.style.cap ?? "round",
1480
+ strokeLinejoin: draw.activeStroke.style.join ?? "round"
1481
+ }
1482
+ ) }),
1483
+ draw.tool === "eraser" && eraserPos && svgRef.current && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1484
+ "circle",
1485
+ {
1486
+ cx: eraserPos[0] - svgRef.current.getBoundingClientRect().left,
1487
+ cy: eraserPos[1] - svgRef.current.getBoundingClientRect().top,
1488
+ r: eraserRadius,
1489
+ fill: "rgba(239, 68, 68, 0.15)",
1490
+ stroke: "rgba(239, 68, 68, 0.8)",
1491
+ strokeWidth: 1.5,
1492
+ strokeDasharray: "3 3",
1493
+ pointerEvents: "none"
1494
+ }
1495
+ )
1496
+ ]
1497
+ }
1498
+ );
1499
+ }
1500
+
1501
+ // src/canvas/useCanvasMeasure.ts
1502
+ var import_react12 = require("react");
1503
+ var import_canvas10 = require("@pixerate/editor/canvas");
1298
1504
  var EMPTY = { guides: [], target: null, selection: null };
1299
1505
  function useCanvasMeasure(options) {
1300
1506
  const { nodes, enabled = true, requireModifier = true, targetElement, rectOptions } = options;
1301
- const [hoveredId, setHoveredId] = (0, import_react10.useState)(null);
1302
- const [modifier, setModifier] = (0, import_react10.useState)(false);
1303
- const optionsRef = (0, import_react10.useRef)(options);
1507
+ const [hoveredId, setHoveredId] = (0, import_react12.useState)(null);
1508
+ const [modifier, setModifier] = (0, import_react12.useState)(false);
1509
+ const optionsRef = (0, import_react12.useRef)(options);
1304
1510
  optionsRef.current = options;
1305
- (0, import_react10.useEffect)(() => {
1511
+ (0, import_react12.useEffect)(() => {
1306
1512
  if (!enabled) return;
1307
1513
  const target = targetElement ?? (typeof window !== "undefined" ? window : null);
1308
1514
  if (!target) return;
1309
- const onKey = (event) => setModifier((0, import_canvas8.isMeasureModifierHeld)(event));
1515
+ const onKey = (event) => setModifier((0, import_canvas10.isMeasureModifierHeld)(event));
1310
1516
  const onBlur = () => setModifier(false);
1311
1517
  target.addEventListener("keydown", onKey);
1312
1518
  target.addEventListener("keyup", onKey);
@@ -1319,16 +1525,16 @@ function useCanvasMeasure(options) {
1319
1525
  };
1320
1526
  }, [enabled, targetElement]);
1321
1527
  const active = enabled && (!requireModifier || modifier);
1322
- const result = (0, import_react10.useMemo)(() => {
1528
+ const result = (0, import_react12.useMemo)(() => {
1323
1529
  if (!active) return EMPTY;
1324
1530
  const ids = optionsRef.current.getSelectedIds?.() ?? nodes.filter((n) => n.selected).map((n) => n.id);
1325
- return (0, import_canvas8.measureSelection)(nodes, ids, hoveredId, rectOptions);
1531
+ return (0, import_canvas10.measureSelection)(nodes, ids, hoveredId, rectOptions);
1326
1532
  }, [active, nodes, hoveredId, rectOptions]);
1327
- const onNodeMouseEnter = (0, import_react10.useCallback)((event, node) => {
1533
+ const onNodeMouseEnter = (0, import_react12.useCallback)((event, node) => {
1328
1534
  setHoveredId(node.id);
1329
1535
  if (event && typeof event.altKey === "boolean") setModifier(event.altKey);
1330
1536
  }, []);
1331
- const onNodeMouseLeave = (0, import_react10.useCallback)((_event, node) => {
1537
+ const onNodeMouseLeave = (0, import_react12.useCallback)((_event, node) => {
1332
1538
  setHoveredId((current) => current === node.id ? null : current);
1333
1539
  }, []);
1334
1540
  return {
@@ -1348,17 +1554,17 @@ function useCanvasMeasure(options) {
1348
1554
  }
1349
1555
 
1350
1556
  // src/canvas/index.ts
1351
- var import_canvas17 = require("@pixerate/editor/canvas");
1352
- var import_canvas18 = require("@pixerate/editor/canvas");
1557
+ var import_canvas19 = require("@pixerate/editor/canvas");
1558
+ var import_canvas20 = require("@pixerate/editor/canvas");
1353
1559
 
1354
1560
  // src/canvas/ShapeNode.tsx
1355
- var import_canvas9 = require("@pixerate/editor/canvas");
1356
- var import_jsx_runtime3 = require("react/jsx-runtime");
1561
+ var import_canvas11 = require("@pixerate/editor/canvas");
1562
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1357
1563
  function ShapeNode({ data, width, height, selected, className = "", children }) {
1358
1564
  const shape = data?.shape;
1359
- if (!(0, import_canvas9.isShapeDescription)(shape)) return null;
1360
- const render = (0, import_canvas9.getShapeRenderData)(shape, { width, height });
1361
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1565
+ if (!(0, import_canvas11.isShapeDescription)(shape)) return null;
1566
+ const render = (0, import_canvas11.getShapeRenderData)(shape, { width, height });
1567
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1362
1568
  "div",
1363
1569
  {
1364
1570
  className: `pixerate-shape-node ${className}`.trim(),
@@ -1366,7 +1572,7 @@ function ShapeNode({ data, width, height, selected, className = "", children })
1366
1572
  "data-selected": selected ? "true" : void 0,
1367
1573
  style: { position: "relative", width: "100%", height: "100%" },
1368
1574
  children: [
1369
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1575
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1370
1576
  "svg",
1371
1577
  {
1372
1578
  viewBox: render.viewBox,
@@ -1375,7 +1581,7 @@ function ShapeNode({ data, width, height, selected, className = "", children })
1375
1581
  height: "100%",
1376
1582
  style: { display: "block", overflow: "visible" },
1377
1583
  "aria-hidden": "true",
1378
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1584
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1379
1585
  "path",
1380
1586
  {
1381
1587
  d: render.d,
@@ -1397,22 +1603,22 @@ function ShapeNode({ data, width, height, selected, className = "", children })
1397
1603
  }
1398
1604
 
1399
1605
  // src/canvas/index.ts
1400
- var import_canvas19 = require("@pixerate/editor/canvas");
1401
- var import_canvas20 = require("@pixerate/editor/canvas");
1402
1606
  var import_canvas21 = require("@pixerate/editor/canvas");
1403
1607
  var import_canvas22 = require("@pixerate/editor/canvas");
1608
+ var import_canvas23 = require("@pixerate/editor/canvas");
1609
+ var import_canvas24 = require("@pixerate/editor/canvas");
1404
1610
 
1405
1611
  // src/canvas/useCanvasAutoLayout.ts
1406
- var import_react11 = require("react");
1407
- var import_canvas10 = require("@pixerate/editor/canvas");
1612
+ var import_react13 = require("react");
1613
+ var import_canvas12 = require("@pixerate/editor/canvas");
1408
1614
  function useCanvasAutoLayout(options) {
1409
- const [guides, setGuides] = (0, import_react11.useState)([]);
1410
- const nodesRef = (0, import_react11.useRef)(options.nodes);
1615
+ const [guides, setGuides] = (0, import_react13.useState)([]);
1616
+ const nodesRef = (0, import_react13.useRef)(options.nodes);
1411
1617
  nodesRef.current = options.nodes;
1412
- const optionsRef = (0, import_react11.useRef)(options);
1618
+ const optionsRef = (0, import_react13.useRef)(options);
1413
1619
  optionsRef.current = options;
1414
- const controller = (0, import_react11.useMemo)(
1415
- () => (0, import_canvas10.createCanvasAutoLayoutController)({
1620
+ const controller = (0, import_react13.useMemo)(
1621
+ () => (0, import_canvas12.createCanvasAutoLayoutController)({
1416
1622
  getNodes: () => nodesRef.current,
1417
1623
  setNodes: (next) => {
1418
1624
  nodesRef.current = next;
@@ -1437,10 +1643,10 @@ function useCanvasAutoLayout(options) {
1437
1643
  }),
1438
1644
  []
1439
1645
  );
1440
- (0, import_react11.useLayoutEffect)(() => {
1646
+ (0, import_react13.useLayoutEffect)(() => {
1441
1647
  if (controller.hasPending) controller.flush();
1442
1648
  }, [options.nodes, controller]);
1443
- return (0, import_react11.useMemo)(
1649
+ return (0, import_react13.useMemo)(
1444
1650
  () => ({
1445
1651
  ...controller,
1446
1652
  /** Drop marker of the active reorder drag (flow coordinates). */
@@ -1454,47 +1660,47 @@ function useCanvasAutoLayout(options) {
1454
1660
  }
1455
1661
 
1456
1662
  // src/canvas/useCanvasTokens.ts
1457
- var import_react12 = require("react");
1458
- var import_canvas11 = require("@pixerate/editor/canvas");
1663
+ var import_react14 = require("react");
1664
+ var import_canvas13 = require("@pixerate/editor/canvas");
1459
1665
  function useCanvasTokens(options) {
1460
1666
  const { store, nodes, setNodes, modes, properties } = options;
1461
- const state = (0, import_react12.useSyncExternalStore)(store.subscribe, store.getState, store.getState);
1462
- const latest = (0, import_react12.useRef)({ nodes, setNodes, modes, properties });
1667
+ const state = (0, import_react14.useSyncExternalStore)(store.subscribe, store.getState, store.getState);
1668
+ const latest = (0, import_react14.useRef)({ nodes, setNodes, modes, properties });
1463
1669
  latest.current = { nodes, setNodes, modes, properties };
1464
1670
  const opts = () => ({ modes: latest.current.modes, properties: latest.current.properties });
1465
- (0, import_react12.useEffect)(
1671
+ (0, import_react14.useEffect)(
1466
1672
  () => store.subscribe((event) => {
1467
1673
  if (event.deletedVariableIds.length === 0) return;
1468
- latest.current.setNodes((prev) => (0, import_canvas11.detachTokenBindings)(prev, event.previous, event.deletedVariableIds, opts()));
1674
+ latest.current.setNodes((prev) => (0, import_canvas13.detachTokenBindings)(prev, event.previous, event.deletedVariableIds, opts()));
1469
1675
  }),
1470
1676
  // eslint-disable-next-line react-hooks/exhaustive-deps
1471
1677
  [store]
1472
1678
  );
1473
1679
  const modesKey = JSON.stringify(modes ?? {});
1474
- (0, import_react12.useEffect)(() => {
1475
- const next = (0, import_canvas11.resolveCanvasTokens)(nodes, state, opts());
1680
+ (0, import_react14.useEffect)(() => {
1681
+ const next = (0, import_canvas13.resolveCanvasTokens)(nodes, state, opts());
1476
1682
  if (next !== nodes) setNodes(next);
1477
1683
  }, [nodes, state, modesKey, properties]);
1478
- const bind = (0, import_react12.useCallback)(
1684
+ const bind = (0, import_react14.useCallback)(
1479
1685
  (ids, propertyKey, variableId) => {
1480
- const next = (0, import_canvas11.bindCanvasToken)(latest.current.nodes, ids, propertyKey, variableId, store.getState(), opts());
1686
+ const next = (0, import_canvas13.bindCanvasToken)(latest.current.nodes, ids, propertyKey, variableId, store.getState(), opts());
1481
1687
  if (next !== latest.current.nodes) latest.current.setNodes(next);
1482
1688
  },
1483
1689
  // eslint-disable-next-line react-hooks/exhaustive-deps
1484
1690
  [store]
1485
1691
  );
1486
- const setMode = (0, import_react12.useCallback)(
1692
+ const setMode = (0, import_react14.useCallback)(
1487
1693
  (ids, collectionId, modeId) => {
1488
- const next = (0, import_canvas11.setCanvasTokenMode)(latest.current.nodes, ids, collectionId, modeId, store.getState(), opts());
1694
+ const next = (0, import_canvas13.setCanvasTokenMode)(latest.current.nodes, ids, collectionId, modeId, store.getState(), opts());
1489
1695
  if (next !== latest.current.nodes) latest.current.setNodes(next);
1490
1696
  },
1491
1697
  // eslint-disable-next-line react-hooks/exhaustive-deps
1492
1698
  [store]
1493
1699
  );
1494
- const modesOf = (0, import_react12.useCallback)(
1700
+ const modesOf = (0, import_react14.useCallback)(
1495
1701
  (nodeId) => {
1496
1702
  const node = latest.current.nodes.find((n) => n.id === nodeId);
1497
- return node ? (0, import_canvas11.getEffectiveTokenModes)(node, latest.current.nodes, store.getState(), opts()) : {};
1703
+ return node ? (0, import_canvas13.getEffectiveTokenModes)(node, latest.current.nodes, store.getState(), opts()) : {};
1498
1704
  },
1499
1705
  // eslint-disable-next-line react-hooks/exhaustive-deps
1500
1706
  [store]
@@ -1503,9 +1709,9 @@ function useCanvasTokens(options) {
1503
1709
  }
1504
1710
 
1505
1711
  // src/canvas/TokenBindingPicker.tsx
1506
- var import_canvas12 = require("@pixerate/editor/canvas");
1712
+ var import_canvas14 = require("@pixerate/editor/canvas");
1507
1713
  var import_tokens = require("@pixerate/editor/tokens");
1508
- var import_jsx_runtime4 = require("react/jsx-runtime");
1714
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1509
1715
  function TokenBindingPicker({
1510
1716
  state,
1511
1717
  nodes,
@@ -1519,18 +1725,18 @@ function TokenBindingPicker({
1519
1725
  const selected = nodes.filter((n) => selectedIds.includes(n.id));
1520
1726
  const first = selected[0];
1521
1727
  if (!first) return null;
1522
- let rows = (0, import_canvas12.getBindableTokenProperties)(first, options);
1728
+ let rows = (0, import_canvas14.getBindableTokenProperties)(first, options);
1523
1729
  if (properties) rows = properties.map((key) => rows.find((p) => p.key === key)).filter((p) => !!p);
1524
- const modes = (0, import_canvas12.getEffectiveTokenModes)(first, nodes, state, options);
1525
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { "data-token-binding-picker": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
1730
+ const modes = (0, import_canvas14.getEffectiveTokenModes)(first, nodes, state, options);
1731
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { "data-token-binding-picker": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
1526
1732
  rows.map((property) => {
1527
- const ids = new Set(selected.map((n) => (0, import_canvas12.getNodeTokenBindings)(n)[property.key] ?? ""));
1733
+ const ids = new Set(selected.map((n) => (0, import_canvas14.getNodeTokenBindings)(n)[property.key] ?? ""));
1528
1734
  const value = ids.size === 1 ? [...ids][0] : "__mixed";
1529
- const candidates = (0, import_canvas12.getTokensForProperty)(state, property, first);
1735
+ const candidates = (0, import_canvas14.getTokensForProperty)(state, property, first);
1530
1736
  const resolved = value && value !== "__mixed" ? (0, import_tokens.resolveToken)(state, value, modes) : null;
1531
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-2", "data-token-property": property.key, children: [
1532
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-28 shrink-0 text-muted-foreground", children: property.label }),
1533
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1737
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex items-center gap-2", "data-token-property": property.key, children: [
1738
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-28 shrink-0 text-muted-foreground", children: property.label }),
1739
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1534
1740
  "select",
1535
1741
  {
1536
1742
  "aria-label": `${property.label} variable`,
@@ -1539,17 +1745,17 @@ function TokenBindingPicker({
1539
1745
  onChange: (e) => {
1540
1746
  const id = e.currentTarget.value || null;
1541
1747
  try {
1542
- onChange((0, import_canvas12.bindCanvasToken)(nodes, selectedIds, property.key, id, state, options));
1748
+ onChange((0, import_canvas14.bindCanvasToken)(nodes, selectedIds, property.key, id, state, options));
1543
1749
  } catch (error) {
1544
1750
  onError?.(error);
1545
1751
  }
1546
1752
  },
1547
1753
  children: [
1548
- value === "__mixed" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "__mixed", children: "Mixed" }) : null,
1549
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "None" }),
1754
+ value === "__mixed" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "__mixed", children: "Mixed" }) : null,
1755
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "", children: "None" }),
1550
1756
  candidates.map((v) => {
1551
1757
  const collection = state.collections.find((c) => c.id === v.collectionId);
1552
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("option", { value: v.id, children: [
1758
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: v.id, children: [
1553
1759
  v.name,
1554
1760
  collection && state.collections.length > 1 ? ` (${collection.name})` : ""
1555
1761
  ] }, v.id);
@@ -1557,17 +1763,17 @@ function TokenBindingPicker({
1557
1763
  ]
1558
1764
  }
1559
1765
  ),
1560
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-16 shrink-0 truncate text-right text-muted-foreground", "data-token-resolved": "", children: resolved?.ok ? property.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1766
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-16 shrink-0 truncate text-right text-muted-foreground", "data-token-resolved": "", children: resolved?.ok ? property.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1561
1767
  "span",
1562
1768
  {
1563
1769
  className: "inline-block h-3 w-3 rounded border border-border align-middle",
1564
1770
  style: { background: String(resolved.value) },
1565
1771
  title: String(resolved.value)
1566
1772
  }
1567
- ) : String(resolved.value) : resolved ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { title: resolved.message, children: "\u26A0" }) : null })
1773
+ ) : String(resolved.value) : resolved ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { title: resolved.message, children: "\u26A0" }) : null })
1568
1774
  ] }, property.key);
1569
1775
  }),
1570
- state.collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-muted-foreground", children: "No variables yet." }) : null
1776
+ state.collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-muted-foreground", children: "No variables yet." }) : null
1571
1777
  ] });
1572
1778
  }
1573
1779
  function TokenModeSwitcher({
@@ -1581,29 +1787,29 @@ function TokenModeSwitcher({
1581
1787
  }) {
1582
1788
  const first = nodes.find((n) => nodeIds.includes(n.id));
1583
1789
  if (!first) return null;
1584
- const own = (0, import_canvas12.getNodeTokenModes)(first);
1790
+ const own = (0, import_canvas14.getNodeTokenModes)(first);
1585
1791
  const parent = first.parentId ? nodes.find((n) => n.id === first.parentId) : void 0;
1586
- const inherited = parent ? (0, import_canvas12.getEffectiveTokenModes)(parent, nodes, state, options) : { ...options.modes };
1792
+ const inherited = parent ? (0, import_canvas14.getEffectiveTokenModes)(parent, nodes, state, options) : { ...options.modes };
1587
1793
  const collections = state.collections.filter((c) => showSingleMode || c.modes.length > 1);
1588
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { "data-token-mode-switcher": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: collections.map((collection) => {
1794
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { "data-token-mode-switcher": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: collections.map((collection) => {
1589
1795
  const auto = (0, import_tokens.getCurrentMode)(collection, inherited);
1590
1796
  const explicit = collection.modes.some((m) => m.id === own[collection.id]) ? own[collection.id] : "";
1591
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "flex items-center gap-2", "data-token-collection": collection.id, children: [
1592
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-28 shrink-0 truncate text-muted-foreground", children: collection.name }),
1593
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1797
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex items-center gap-2", "data-token-collection": collection.id, children: [
1798
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-28 shrink-0 truncate text-muted-foreground", children: collection.name }),
1799
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1594
1800
  "select",
1595
1801
  {
1596
1802
  "aria-label": `${collection.name} mode`,
1597
1803
  className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
1598
1804
  value: explicit,
1599
- onChange: (e) => onChange((0, import_canvas12.setCanvasTokenMode)(nodes, nodeIds, collection.id, e.currentTarget.value || null, state, options)),
1805
+ onChange: (e) => onChange((0, import_canvas14.setCanvasTokenMode)(nodes, nodeIds, collection.id, e.currentTarget.value || null, state, options)),
1600
1806
  children: [
1601
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("option", { value: "", children: [
1807
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: "", children: [
1602
1808
  "Auto (",
1603
1809
  auto.name,
1604
1810
  ")"
1605
1811
  ] }),
1606
- collection.modes.map((m) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: m.id, children: m.name }, m.id))
1812
+ collection.modes.map((m) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: m.id, children: m.name }, m.id))
1607
1813
  ]
1608
1814
  }
1609
1815
  )
@@ -1612,18 +1818,18 @@ function TokenModeSwitcher({
1612
1818
  }
1613
1819
 
1614
1820
  // src/canvas/index.ts
1615
- var import_canvas23 = require("@pixerate/editor/canvas");
1821
+ var import_canvas25 = require("@pixerate/editor/canvas");
1616
1822
 
1617
1823
  // src/canvas/useCanvasAnimation.ts
1618
- var import_react13 = require("react");
1619
- var import_canvas13 = require("@pixerate/editor/canvas");
1824
+ var import_react15 = require("react");
1825
+ var import_canvas15 = require("@pixerate/editor/canvas");
1620
1826
  function useCanvasAnimation(options) {
1621
- const nodesRef = (0, import_react13.useRef)(options.nodes);
1827
+ const nodesRef = (0, import_react15.useRef)(options.nodes);
1622
1828
  nodesRef.current = options.nodes;
1623
- const optionsRef = (0, import_react13.useRef)(options);
1829
+ const optionsRef = (0, import_react15.useRef)(options);
1624
1830
  optionsRef.current = options;
1625
- const controller = (0, import_react13.useMemo)(
1626
- () => (0, import_canvas13.createCanvasAnimationController)({
1831
+ const controller = (0, import_react15.useMemo)(
1832
+ () => (0, import_canvas15.createCanvasAnimationController)({
1627
1833
  getNodes: () => nodesRef.current,
1628
1834
  setNodes: (next) => {
1629
1835
  nodesRef.current = next;
@@ -1649,26 +1855,26 @@ function useCanvasAnimation(options) {
1649
1855
  }),
1650
1856
  []
1651
1857
  );
1652
- (0, import_react13.useEffect)(() => () => controller.destroy(), [controller]);
1653
- (0, import_react13.useEffect)(() => {
1858
+ (0, import_react15.useEffect)(() => () => controller.destroy(), [controller]);
1859
+ (0, import_react15.useEffect)(() => {
1654
1860
  if (options.loop !== void 0) controller.setLoop(options.loop);
1655
1861
  }, [controller, options.loop]);
1656
- (0, import_react13.useEffect)(() => {
1862
+ (0, import_react15.useEffect)(() => {
1657
1863
  if (options.playbackRate !== void 0) controller.setPlaybackRate(options.playbackRate);
1658
1864
  }, [controller, options.playbackRate]);
1659
- (0, import_react13.useEffect)(() => {
1865
+ (0, import_react15.useEffect)(() => {
1660
1866
  if (options.recording !== void 0) controller.setRecording(options.recording);
1661
1867
  }, [controller, options.recording]);
1662
- const state = (0, import_react13.useSyncExternalStore)(
1868
+ const state = (0, import_react15.useSyncExternalStore)(
1663
1869
  (listener) => controller.subscribe(listener),
1664
1870
  () => controller.getState(),
1665
1871
  () => controller.getState()
1666
1872
  );
1667
- (0, import_react13.useEffect)(() => {
1873
+ (0, import_react15.useEffect)(() => {
1668
1874
  controller.refresh();
1669
1875
  }, [controller, options.nodes]);
1670
- const displayNodes = (0, import_react13.useMemo)(() => controller.display(options.nodes), [controller, options.nodes, state.time]);
1671
- return (0, import_react13.useMemo)(
1876
+ const displayNodes = (0, import_react15.useMemo)(() => controller.display(options.nodes), [controller, options.nodes, state.time]);
1877
+ return (0, import_react15.useMemo)(
1672
1878
  () => ({
1673
1879
  ...controller,
1674
1880
  state,
@@ -1689,24 +1895,24 @@ function useCanvasAnimation(options) {
1689
1895
  }
1690
1896
 
1691
1897
  // src/canvas/AnimationTimeline.tsx
1692
- var import_react14 = require("react");
1693
- var import_canvas14 = require("@pixerate/editor/canvas");
1694
- var import_jsx_runtime5 = require("react/jsx-runtime");
1898
+ var import_react16 = require("react");
1899
+ var import_canvas16 = require("@pixerate/editor/canvas");
1900
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1695
1901
  var LOOP_LABELS = { none: "Once", loop: "Loop", "ping-pong": "Ping-pong" };
1696
1902
  var easingValue = (easing) => typeof easing === "string" ? easing : easing ? "custom" : "linear";
1697
1903
  function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8, labelOf, className = "" }) {
1698
1904
  const { state } = animation;
1699
1905
  const duration = state.duration;
1700
1906
  const rows = animation.timelineRows(nodeIds ?? void 0, labelOf ? { labelOf } : {});
1701
- const ticks = (0, import_canvas14.getTimelineTicks)(duration, width);
1907
+ const ticks = (0, import_canvas16.getTimelineTicks)(duration, width);
1702
1908
  const selectedEasing = (() => {
1703
1909
  const first = state.selection[0];
1704
1910
  if (!first) return "";
1705
1911
  for (const row of rows) for (const k of row.keyframes) if (k.selected && k.ref.property === first.property && k.ref.nodeId === first.nodeId) return easingValue(k.easing);
1706
1912
  return "";
1707
1913
  })();
1708
- const dragRef = (0, import_react14.useRef)(null);
1709
- (0, import_react14.useEffect)(() => {
1914
+ const dragRef = (0, import_react16.useRef)(null);
1915
+ (0, import_react16.useEffect)(() => {
1710
1916
  const onKey = (event) => {
1711
1917
  if (event.key === "Escape" && dragRef.current) {
1712
1918
  dragRef.current = null;
@@ -1719,8 +1925,8 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1719
1925
  const onRulerDown = (event) => {
1720
1926
  const lane = event.currentTarget;
1721
1927
  const left = lane.getBoundingClientRect().left;
1722
- animation.scrub((0, import_canvas14.xToTime)(event.clientX - left, duration, width));
1723
- const move = (e) => animation.scrub((0, import_canvas14.xToTime)(e.clientX - left, duration, width));
1928
+ animation.scrub((0, import_canvas16.xToTime)(event.clientX - left, duration, width));
1929
+ const move = (e) => animation.scrub((0, import_canvas16.xToTime)(e.clientX - left, duration, width));
1724
1930
  const up = () => {
1725
1931
  window.removeEventListener("pointermove", move);
1726
1932
  window.removeEventListener("pointerup", up);
@@ -1760,12 +1966,12 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1760
1966
  }
1761
1967
  };
1762
1968
  const btn = "rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-50";
1763
- const playheadX = (0, import_canvas14.timeToX)(state.time, duration, width);
1969
+ const playheadX = (0, import_canvas16.timeToX)(state.time, duration, width);
1764
1970
  const labelWidth = 120;
1765
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { "data-animation-timeline": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, tabIndex: 0, onKeyDown: onTimelineKey, children: [
1766
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "toolbar", "aria-label": "Animation", children: [
1767
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: btn, "data-action": "toggle-play", "aria-label": state.playing ? "Pause" : "Play", onClick: () => animation.toggle(), children: state.playing ? "\u275A\u275A" : "\u25B6" }),
1768
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1971
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-animation-timeline": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, tabIndex: 0, onKeyDown: onTimelineKey, children: [
1972
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "toolbar", "aria-label": "Animation", children: [
1973
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "toggle-play", "aria-label": state.playing ? "Pause" : "Play", onClick: () => animation.toggle(), children: state.playing ? "\u275A\u275A" : "\u25B6" }),
1974
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1769
1975
  "button",
1770
1976
  {
1771
1977
  type: "button",
@@ -1777,13 +1983,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1777
1983
  children: "\u25CF Rec"
1778
1984
  }
1779
1985
  ),
1780
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: btn, "data-action": "add-keyframe", onClick: () => animation.addKeyframe(), children: "\u25C6 Key" }),
1781
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-time": "", className: "tabular-nums text-muted-foreground", children: [
1782
- (0, import_canvas14.formatAnimationTime)(state.time),
1986
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "add-keyframe", onClick: () => animation.addKeyframe(), children: "\u25C6 Key" }),
1987
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { "data-time": "", className: "tabular-nums text-muted-foreground", children: [
1988
+ (0, import_canvas16.formatAnimationTime)(state.time),
1783
1989
  " / ",
1784
- (0, import_canvas14.formatAnimationTime)(duration)
1990
+ (0, import_canvas16.formatAnimationTime)(duration)
1785
1991
  ] }),
1786
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1992
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1787
1993
  "select",
1788
1994
  {
1789
1995
  "aria-label": "Easing",
@@ -1793,13 +1999,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1793
1999
  disabled: state.selection.length === 0,
1794
2000
  onChange: (e) => e.target.value && e.target.value !== "custom" && animation.setEasing(e.target.value),
1795
2001
  children: [
1796
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "", children: "Easing\u2026" }),
1797
- import_canvas14.ANIMATION_EASING_PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: preset, children: import_canvas14.ANIMATION_EASING_LABELS[preset] }, preset)),
1798
- selectedEasing === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "custom", children: "Custom" }) : null
2002
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: "Easing\u2026" }),
2003
+ import_canvas16.ANIMATION_EASING_PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: preset, children: import_canvas16.ANIMATION_EASING_LABELS[preset] }, preset)),
2004
+ selectedEasing === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "custom", children: "Custom" }) : null
1799
2005
  ]
1800
2006
  }
1801
2007
  ),
1802
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2008
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1803
2009
  "select",
1804
2010
  {
1805
2011
  "aria-label": "Loop",
@@ -1807,13 +2013,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1807
2013
  className: "rounded border border-border bg-background px-1 py-0.5",
1808
2014
  value: state.loop,
1809
2015
  onChange: (e) => animation.setLoop(e.target.value),
1810
- children: Object.keys(LOOP_LABELS).map((mode) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: mode, children: LOOP_LABELS[mode] }, mode))
2016
+ children: Object.keys(LOOP_LABELS).map((mode) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: mode, children: LOOP_LABELS[mode] }, mode))
1811
2017
  }
1812
2018
  )
1813
2019
  ] }),
1814
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex", children: [
1815
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { width: labelWidth }, className: "shrink-0" }),
1816
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2020
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex", children: [
2021
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { width: labelWidth }, className: "shrink-0" }),
2022
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1817
2023
  "div",
1818
2024
  {
1819
2025
  "data-timeline-ruler": "",
@@ -1821,15 +2027,15 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1821
2027
  style: { width },
1822
2028
  onPointerDown: onRulerDown,
1823
2029
  children: [
1824
- ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "absolute top-0 -translate-x-1/2 text-[10px] text-muted-foreground", style: { left: tick.x }, children: tick.label }, tick.time)),
1825
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { "data-playhead": "", className: "absolute top-0 h-5 w-px bg-red-500", style: { left: playheadX } })
2030
+ ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "absolute top-0 -translate-x-1/2 text-[10px] text-muted-foreground", style: { left: tick.x }, children: tick.label }, tick.time)),
2031
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-playhead": "", className: "absolute top-0 h-5 w-px bg-red-500", style: { left: playheadX } })
1826
2032
  ]
1827
2033
  }
1828
2034
  )
1829
2035
  ] }),
1830
- rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-muted-foreground", "data-timeline-empty": "", children: "Select an animated node, or press \u25C6 Key to add a keyframe." }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center", "data-track": row.id, children: [
1831
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex shrink-0 items-center gap-1 truncate pr-2", style: { width: labelWidth }, title: `${row.nodeLabel} \xB7 ${row.label}`, children: [
1832
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2036
+ rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-muted-foreground", "data-timeline-empty": "", children: "Select an animated node, or press \u25C6 Key to add a keyframe." }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center", "data-track": row.id, children: [
2037
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex shrink-0 items-center gap-1 truncate pr-2", style: { width: labelWidth }, title: `${row.nodeLabel} \xB7 ${row.label}`, children: [
2038
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1833
2039
  "input",
1834
2040
  {
1835
2041
  type: "checkbox",
@@ -1838,24 +2044,24 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1838
2044
  onChange: (e) => animation.setTrackEnabled(row.nodeId, row.property, e.target.checked)
1839
2045
  }
1840
2046
  ),
1841
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "truncate", children: [
2047
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "truncate", children: [
1842
2048
  rows.filter((r) => r.nodeId === row.nodeId).length < rows.length ? `${row.nodeLabel} \xB7 ` : "",
1843
2049
  row.label
1844
2050
  ] })
1845
2051
  ] }),
1846
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { "data-lane": "", className: `relative h-5 rounded bg-muted/40 ${row.enabled ? "" : "opacity-50"}`, style: { width }, children: [
1847
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pointer-events-none absolute top-0 h-5 w-px bg-red-500/60", style: { left: playheadX } }),
1848
- state.drag?.target != null ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { "data-snap-target": "", className: "pointer-events-none absolute top-0 h-5 w-px bg-sky-400", style: { left: (0, import_canvas14.timeToX)(state.drag.target, duration, width) } }) : null,
1849
- row.keyframes.map((k) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2052
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-lane": "", className: `relative h-5 rounded bg-muted/40 ${row.enabled ? "" : "opacity-50"}`, style: { width }, children: [
2053
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pointer-events-none absolute top-0 h-5 w-px bg-red-500/60", style: { left: playheadX } }),
2054
+ state.drag?.target != null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-snap-target": "", className: "pointer-events-none absolute top-0 h-5 w-px bg-sky-400", style: { left: (0, import_canvas16.timeToX)(state.drag.target, duration, width) } }) : null,
2055
+ row.keyframes.map((k) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1850
2056
  "button",
1851
2057
  {
1852
2058
  type: "button",
1853
2059
  "data-keyframe": k.ref.time,
1854
2060
  "aria-pressed": k.selected,
1855
- "aria-label": `${row.label} keyframe at ${(0, import_canvas14.formatAnimationTime)(k.ref.time)}`,
1856
- title: `${(0, import_canvas14.formatAnimationTime)(k.time)} \xB7 ${String(k.value)}`,
2061
+ "aria-label": `${row.label} keyframe at ${(0, import_canvas16.formatAnimationTime)(k.ref.time)}`,
2062
+ title: `${(0, import_canvas16.formatAnimationTime)(k.time)} \xB7 ${String(k.value)}`,
1857
2063
  className: `absolute top-1/2 h-2.5 w-2.5 -translate-x-1/2 -translate-y-1/2 rotate-45 border ${k.selected ? "border-sky-300 bg-sky-500" : "border-foreground/60 bg-background"} ${k.easing === "hold" ? "rounded-none" : "rounded-[1px]"}`,
1858
- style: { left: (0, import_canvas14.timeToX)(k.time, duration, width) },
2064
+ style: { left: (0, import_canvas16.timeToX)(k.time, duration, width) },
1859
2065
  onPointerDown: onKeyDown(k.ref)
1860
2066
  },
1861
2067
  k.ref.time
@@ -1866,18 +2072,18 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1866
2072
  }
1867
2073
 
1868
2074
  // src/canvas/index.ts
1869
- var import_canvas24 = require("@pixerate/editor/canvas");
2075
+ var import_canvas26 = require("@pixerate/editor/canvas");
1870
2076
 
1871
2077
  // src/canvas/useCanvasComponents.ts
1872
- var import_react15 = require("react");
1873
- var import_canvas15 = require("@pixerate/editor/canvas");
2078
+ var import_react17 = require("react");
2079
+ var import_canvas17 = require("@pixerate/editor/canvas");
1874
2080
  function useCanvasComponents(options) {
1875
- const nodesRef = (0, import_react15.useRef)(options.nodes);
2081
+ const nodesRef = (0, import_react17.useRef)(options.nodes);
1876
2082
  nodesRef.current = options.nodes;
1877
- const optionsRef = (0, import_react15.useRef)(options);
2083
+ const optionsRef = (0, import_react17.useRef)(options);
1878
2084
  optionsRef.current = options;
1879
- const controller = (0, import_react15.useMemo)(
1880
- () => (0, import_canvas15.createCanvasComponentsController)({
2085
+ const controller = (0, import_react17.useMemo)(
2086
+ () => (0, import_canvas17.createCanvasComponentsController)({
1881
2087
  getNodes: () => nodesRef.current,
1882
2088
  setNodes: (next) => {
1883
2089
  nodesRef.current = next;
@@ -1905,18 +2111,18 @@ function useCanvasComponents(options) {
1905
2111
  }),
1906
2112
  []
1907
2113
  );
1908
- (0, import_react15.useLayoutEffect)(() => {
2114
+ (0, import_react17.useLayoutEffect)(() => {
1909
2115
  if (optionsRef.current.autoSync !== false) controller.sync();
1910
2116
  }, [options.nodes, controller]);
1911
2117
  return controller;
1912
2118
  }
1913
2119
 
1914
2120
  // src/canvas/CanvasComponentsPanel.tsx
1915
- var import_react16 = require("react");
1916
- var import_canvas16 = require("@pixerate/editor/canvas");
1917
- var import_jsx_runtime6 = require("react/jsx-runtime");
2121
+ var import_react18 = require("react");
2122
+ var import_canvas18 = require("@pixerate/editor/canvas");
2123
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1918
2124
  function InlineField({ value, label, onCommit }) {
1919
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2125
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1920
2126
  "input",
1921
2127
  {
1922
2128
  type: "text",
@@ -1947,11 +2153,11 @@ function CanvasComponentsPanel({
1947
2153
  search = true,
1948
2154
  className = ""
1949
2155
  }) {
1950
- const [query, setQuery] = (0, import_react16.useState)("");
1951
- const [propsOpen, setPropsOpen] = (0, import_react16.useState)(null);
1952
- const [menuFor, setMenuFor] = (0, import_react16.useState)(null);
1953
- const [editing, setEditing] = (0, import_react16.useState)(null);
1954
- const { components: all, sets } = (0, import_canvas16.listCanvasComponents)(nodes);
2156
+ const [query, setQuery] = (0, import_react18.useState)("");
2157
+ const [propsOpen, setPropsOpen] = (0, import_react18.useState)(null);
2158
+ const [menuFor, setMenuFor] = (0, import_react18.useState)(null);
2159
+ const [editing, setEditing] = (0, import_react18.useState)(null);
2160
+ const { components: all, sets } = (0, import_canvas18.listCanvasComponents)(nodes);
1955
2161
  const q = query.trim().toLowerCase();
1956
2162
  const match = (name) => !q || name.toLowerCase().includes(q);
1957
2163
  const lone = all.filter((c) => !c.setId && match(c.name));
@@ -1962,7 +2168,7 @@ function CanvasComponentsPanel({
1962
2168
  };
1963
2169
  const small = "shrink-0 rounded px-1 text-[10px] text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-40";
1964
2170
  const menuItem = "rounded px-2 py-0.5 text-left hover:bg-muted disabled:opacity-40";
1965
- const item = (id, name, count, extra = {}, onContextMenu) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2171
+ const item = (id, name, count, extra = {}, onContextMenu) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1966
2172
  "button",
1967
2173
  {
1968
2174
  type: "button",
@@ -1974,22 +2180,22 @@ function CanvasComponentsPanel({
1974
2180
  onClick: () => onInsert(id),
1975
2181
  onContextMenu,
1976
2182
  onDragStart: (e) => {
1977
- e.dataTransfer.setData(import_canvas16.CANVAS_COMPONENT_DRAG_TYPE, id);
2183
+ e.dataTransfer.setData(import_canvas18.CANVAS_COMPONENT_DRAG_TYPE, id);
1978
2184
  e.dataTransfer.setData("text/plain", name);
1979
2185
  e.dataTransfer.effectAllowed = "copy";
1980
2186
  },
1981
2187
  children: [
1982
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "truncate", children: [
1983
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": true, className: "mr-1 text-muted-foreground", children: "\u25C7" }),
2188
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "truncate", children: [
2189
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": true, className: "mr-1 text-muted-foreground", children: "\u25C7" }),
1984
2190
  name
1985
2191
  ] }),
1986
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[10px] text-muted-foreground", "data-instance-count": "", children: count })
2192
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-[10px] text-muted-foreground", "data-instance-count": "", children: count })
1987
2193
  ]
1988
2194
  },
1989
2195
  id
1990
2196
  );
1991
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-components-panel": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
1992
- search ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2197
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-components-panel": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
2198
+ search ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1993
2199
  "input",
1994
2200
  {
1995
2201
  type: "search",
@@ -1999,11 +2205,11 @@ function CanvasComponentsPanel({
1999
2205
  onInput: (e) => setQuery(e.target.value)
2000
2206
  }
2001
2207
  ) : null,
2002
- shownSets.map((set) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-component-set": set.id, className: "flex flex-col", children: [
2003
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-1", children: [
2208
+ shownSets.map((set) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-component-set": set.id, className: "flex flex-col", children: [
2209
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1", children: [
2004
2210
  item(set.id, set.name, set.variants.reduce((sum, v) => sum + v.instanceCount, 0), { "data-kind": "set" }),
2005
- components ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2006
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2211
+ components ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2212
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2007
2213
  "button",
2008
2214
  {
2009
2215
  type: "button",
@@ -2015,7 +2221,7 @@ function CanvasComponentsPanel({
2015
2221
  children: "+\xA0Variant"
2016
2222
  }
2017
2223
  ),
2018
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2224
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2019
2225
  "button",
2020
2226
  {
2021
2227
  type: "button",
@@ -2030,8 +2236,8 @@ function CanvasComponentsPanel({
2030
2236
  )
2031
2237
  ] }) : null
2032
2238
  ] }),
2033
- components && propsOpen === set.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-variant-properties": set.id, className: "ml-3 flex flex-col gap-1 border-l border-border py-1 pl-2", children: set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-variant-option": option.name, className: "flex flex-col gap-0.5", children: [
2034
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2239
+ components && propsOpen === set.id ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-variant-properties": set.id, className: "ml-3 flex flex-col gap-1 border-l border-border py-1 pl-2", children: set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-variant-option": option.name, className: "flex flex-col gap-0.5", children: [
2240
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2035
2241
  InlineField,
2036
2242
  {
2037
2243
  value: option.name,
@@ -2039,7 +2245,7 @@ function CanvasComponentsPanel({
2039
2245
  onCommit: (next) => report(components.renameVariantProperty(option.name, next, set.id))
2040
2246
  }
2041
2247
  ),
2042
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ml-2 flex flex-wrap gap-1", children: option.values.map((value) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2248
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ml-2 flex flex-wrap gap-1", children: option.values.map((value) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2043
2249
  InlineField,
2044
2250
  {
2045
2251
  value,
@@ -2049,8 +2255,8 @@ function CanvasComponentsPanel({
2049
2255
  value
2050
2256
  )) })
2051
2257
  ] }, option.name)) }) : null,
2052
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ml-3 flex flex-col border-l border-border pl-1", children: set.variants.map((v) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-variant-row": v.id, className: "flex flex-col", children: [
2053
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-1", children: [
2258
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ml-3 flex flex-col border-l border-border pl-1", children: set.variants.map((v) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-variant-row": v.id, className: "flex flex-col", children: [
2259
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1", children: [
2054
2260
  item(
2055
2261
  v.id,
2056
2262
  v.name,
@@ -2061,7 +2267,7 @@ function CanvasComponentsPanel({
2061
2267
  setMenuFor(v.id);
2062
2268
  } : void 0
2063
2269
  ),
2064
- components ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2270
+ components ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2065
2271
  "button",
2066
2272
  {
2067
2273
  type: "button",
@@ -2075,8 +2281,8 @@ function CanvasComponentsPanel({
2075
2281
  }
2076
2282
  ) : null
2077
2283
  ] }),
2078
- components && menuFor === v.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "menu", "data-variant-menu": v.id, className: "ml-2 flex flex-col rounded border border-border bg-background p-1 shadow", children: [
2079
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2284
+ components && menuFor === v.id ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { role: "menu", "data-variant-menu": v.id, className: "ml-2 flex flex-col rounded border border-border bg-background p-1 shadow", children: [
2285
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2080
2286
  "button",
2081
2287
  {
2082
2288
  type: "button",
@@ -2090,7 +2296,7 @@ function CanvasComponentsPanel({
2090
2296
  children: "Edit values\u2026"
2091
2297
  }
2092
2298
  ),
2093
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2299
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2094
2300
  "button",
2095
2301
  {
2096
2302
  type: "button",
@@ -2104,7 +2310,7 @@ function CanvasComponentsPanel({
2104
2310
  children: "Duplicate"
2105
2311
  }
2106
2312
  ),
2107
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2313
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2108
2314
  "button",
2109
2315
  {
2110
2316
  type: "button",
@@ -2121,7 +2327,7 @@ function CanvasComponentsPanel({
2121
2327
  }
2122
2328
  )
2123
2329
  ] }) : null,
2124
- components && editing === v.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2330
+ components && editing === v.id ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2125
2331
  "form",
2126
2332
  {
2127
2333
  "data-variant-editor": v.id,
@@ -2135,9 +2341,9 @@ function CanvasComponentsPanel({
2135
2341
  if (report(components.setVariantProperties(values, v.id))) setEditing(null);
2136
2342
  },
2137
2343
  children: [
2138
- set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex items-center gap-2", children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-16 shrink-0 truncate text-muted-foreground", children: option.name }),
2140
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2344
+ set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-2", children: [
2345
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-16 shrink-0 truncate text-muted-foreground", children: option.name }),
2346
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2141
2347
  "input",
2142
2348
  {
2143
2349
  type: "text",
@@ -2148,9 +2354,9 @@ function CanvasComponentsPanel({
2148
2354
  }
2149
2355
  )
2150
2356
  ] }, option.name)),
2151
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex gap-1", children: [
2152
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "submit", className: "rounded border border-border px-2 py-0.5 hover:bg-muted", "data-action": "save-variant", children: "Save" }),
2153
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "rounded px-2 py-0.5 hover:bg-muted", "data-action": "cancel-variant", onClick: () => setEditing(null), children: "Cancel" })
2357
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex gap-1", children: [
2358
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", className: "rounded border border-border px-2 py-0.5 hover:bg-muted", "data-action": "save-variant", children: "Save" }),
2359
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rounded px-2 py-0.5 hover:bg-muted", "data-action": "cancel-variant", onClick: () => setEditing(null), children: "Cancel" })
2154
2360
  ] })
2155
2361
  ]
2156
2362
  }
@@ -2158,7 +2364,7 @@ function CanvasComponentsPanel({
2158
2364
  ] }, v.id)) })
2159
2365
  ] }, set.id)),
2160
2366
  lone.map((c) => item(c.id, c.name, c.instanceCount, { "data-kind": "component" })),
2161
- all.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-muted-foreground", children: "No components yet. Select a frame and choose Create Component." }) : null
2367
+ all.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-muted-foreground", children: "No components yet. Select a frame and choose Create Component." }) : null
2162
2368
  ] });
2163
2369
  }
2164
2370
  function CanvasInstanceInspector({
@@ -2168,36 +2374,36 @@ function CanvasInstanceInspector({
2168
2374
  onError,
2169
2375
  className = ""
2170
2376
  }) {
2171
- const info = nodeId ? (0, import_canvas16.inspectCanvasInstance)(nodes, nodeId) : void 0;
2377
+ const info = nodeId ? (0, import_canvas18.inspectCanvasInstance)(nodes, nodeId) : void 0;
2172
2378
  if (!info) return null;
2173
2379
  const report = (result) => {
2174
2380
  if (result && !result.ok && result.reason) onError?.(result.reason);
2175
2381
  };
2176
2382
  const setProp = (name, value) => report(components.setInstanceProperties({ [name]: value }, [info.id]));
2177
- const allComponents = (0, import_canvas16.listCanvasComponents)(nodes).components;
2383
+ const allComponents = (0, import_canvas18.listCanvasComponents)(nodes).components;
2178
2384
  const linked = info.status === "linked";
2179
2385
  const btn = "rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-40";
2180
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-instance-inspector": "", "data-instance-id": info.id, className: `flex flex-col gap-2 text-xs text-foreground ${className}`, children: [
2181
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
2182
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate font-medium", "data-instance-main": "", children: linked ? info.componentName : "Main component missing" }),
2183
- info.nested ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground", children: "Nested" }) : null
2386
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-instance-inspector": "", "data-instance-id": info.id, className: `flex flex-col gap-2 text-xs text-foreground ${className}`, children: [
2387
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
2388
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate font-medium", "data-instance-main": "", children: linked ? info.componentName : "Main component missing" }),
2389
+ info.nested ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground", children: "Nested" }) : null
2184
2390
  ] }),
2185
- info.variantOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex items-center gap-2", "data-variant-property": option.name, children: [
2186
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: option.name }),
2187
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2391
+ info.variantOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-2", "data-variant-property": option.name, children: [
2392
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: option.name }),
2393
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2188
2394
  "select",
2189
2395
  {
2190
2396
  "aria-label": `${option.name} variant`,
2191
2397
  className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
2192
2398
  value: info.variant[option.name] ?? "",
2193
2399
  onChange: (e) => setProp(option.name, e.currentTarget.value),
2194
- children: option.values.map((v) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: v, children: v }, v))
2400
+ children: option.values.map((v) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: v, children: v }, v))
2195
2401
  }
2196
2402
  )
2197
2403
  ] }, option.name)),
2198
- info.properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex items-center gap-2", "data-component-property": p.name, children: [
2199
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: p.name }),
2200
- p.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", "aria-label": p.name, checked: p.value === true, onChange: (e) => setProp(p.name, e.currentTarget.checked) }) : p.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2404
+ info.properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-2", "data-component-property": p.name, children: [
2405
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: p.name }),
2406
+ p.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "checkbox", "aria-label": p.name, checked: p.value === true, onChange: (e) => setProp(p.name, e.currentTarget.checked) }) : p.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2201
2407
  "input",
2202
2408
  {
2203
2409
  type: "text",
@@ -2212,22 +2418,22 @@ function CanvasInstanceInspector({
2212
2418
  }
2213
2419
  },
2214
2420
  String(p.value)
2215
- ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2421
+ ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2216
2422
  "select",
2217
2423
  {
2218
2424
  "aria-label": p.name,
2219
2425
  className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
2220
2426
  value: String(p.value),
2221
2427
  onChange: (e) => setProp(p.name, e.currentTarget.value),
2222
- children: allComponents.filter((c) => !p.preferred?.length || p.preferred.includes(c.id) || c.id === p.value).map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: c.id, children: c.name }, c.id))
2428
+ children: allComponents.filter((c) => !p.preferred?.length || p.preferred.includes(c.id) || c.id === p.value).map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: c.id, children: c.name }, c.id))
2223
2429
  }
2224
2430
  )
2225
2431
  ] }, p.name)),
2226
- info.overrides.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col gap-1", "data-instance-overrides": "", children: [
2227
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground", children: "Overrides" }),
2228
- info.overrides.map((o) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-override-layer": o.id, children: [
2229
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mr-1 truncate", children: o.name }),
2230
- o.groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2432
+ info.overrides.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-1", "data-instance-overrides": "", children: [
2433
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground", children: "Overrides" }),
2434
+ info.overrides.map((o) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-override-layer": o.id, children: [
2435
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mr-1 truncate", children: o.name }),
2436
+ o.groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2231
2437
  "button",
2232
2438
  {
2233
2439
  type: "button",
@@ -2244,11 +2450,11 @@ function CanvasInstanceInspector({
2244
2450
  ))
2245
2451
  ] }, o.id))
2246
2452
  ] }) : null,
2247
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
2248
- linked ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2249
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "reset", onClick: () => report(components.resetOverrides(info.id)), children: "Reset all" }),
2250
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "go-to-main", onClick: () => components.goToMainComponent(info.id), children: "Go to main" }),
2251
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2453
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
2454
+ linked ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2455
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "reset", onClick: () => report(components.resetOverrides(info.id)), children: "Reset all" }),
2456
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "go-to-main", onClick: () => components.goToMainComponent(info.id), children: "Go to main" }),
2457
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2252
2458
  "button",
2253
2459
  {
2254
2460
  type: "button",
@@ -2259,8 +2465,8 @@ function CanvasInstanceInspector({
2259
2465
  children: "Push changes"
2260
2466
  }
2261
2467
  )
2262
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "restore", onClick: () => report(components.restoreMainComponent(info.rootId)), children: "Restore main component" }),
2263
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2468
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "restore", onClick: () => report(components.restoreMainComponent(info.rootId)), children: "Restore main component" }),
2469
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2264
2470
  "button",
2265
2471
  {
2266
2472
  type: "button",
@@ -2277,7 +2483,7 @@ function CanvasInstanceInspector({
2277
2483
  }
2278
2484
 
2279
2485
  // src/canvas/index.ts
2280
- var import_canvas25 = require("@pixerate/editor/canvas");
2486
+ var import_canvas27 = require("@pixerate/editor/canvas");
2281
2487
  // Annotate the CommonJS export names for ESM import in node:
2282
2488
  0 && (module.exports = {
2283
2489
  ANIMATABLE_PROPERTIES,
@@ -2297,6 +2503,7 @@ var import_canvas25 = require("@pixerate/editor/canvas");
2297
2503
  CSS_ANIMATION_PROPERTIES,
2298
2504
  CUBIC_BEZIER_PRESETS,
2299
2505
  CanvasComponentsPanel,
2506
+ CanvasDrawLayer,
2300
2507
  CanvasGuidesLayer,
2301
2508
  CanvasInstanceInspector,
2302
2509
  CanvasScenesStore,
@@ -2356,8 +2563,10 @@ var import_canvas25 = require("@pixerate/editor/canvas");
2356
2563
  createCanvasAutoLayoutController,
2357
2564
  createCanvasComponent,
2358
2565
  createCanvasComponentsController,
2566
+ createCanvasDrawController,
2359
2567
  createCanvasInstance,
2360
2568
  createCanvasScenesStore,
2569
+ createDefaultStrokeStyle,
2361
2570
  createFanOutTrajectory,
2362
2571
  createGuideIndex,
2363
2572
  createNodeGuideIndex,
@@ -2385,6 +2594,7 @@ var import_canvas25 = require("@pixerate/editor/canvas");
2385
2594
  excludePaths,
2386
2595
  exportCssAnimation,
2387
2596
  findConnectorSnap,
2597
+ findStrokesAtPoint,
2388
2598
  fitCubicRun,
2389
2599
  fitCubics,
2390
2600
  fitFreehandPath,
@@ -2558,7 +2768,10 @@ var import_canvas25 = require("@pixerate/editor/canvas");
2558
2768
  snapTimeToFrame,
2559
2769
  snapToGrid,
2560
2770
  springAt,
2771
+ streamlinePoints,
2561
2772
  strokeOutlineRings,
2773
+ strokePointsToPathData,
2774
+ strokeToShapeNode,
2562
2775
  subtractPaths,
2563
2776
  subtractPolygons,
2564
2777
  swapCanvasInstance,
@@ -2581,6 +2794,7 @@ var import_canvas25 = require("@pixerate/editor/canvas");
2581
2794
  useCanvasClipboard,
2582
2795
  useCanvasComponents,
2583
2796
  useCanvasDocking,
2797
+ useCanvasDraw,
2584
2798
  useCanvasExplosion,
2585
2799
  useCanvasGraph,
2586
2800
  useCanvasLayout,