@pixerate/editor-react 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +6 -1
  2. package/dist/canvas/index.cjs +352 -118
  3. package/dist/canvas/index.cjs.map +1 -1
  4. package/dist/canvas/index.d.cts +112 -8
  5. package/dist/canvas/index.d.ts +112 -8
  6. package/dist/canvas/index.js +258 -19
  7. package/dist/canvas/index.js.map +1 -1
  8. package/dist/chunk-4ZC2WCUO.js +196 -0
  9. package/dist/chunk-4ZC2WCUO.js.map +1 -0
  10. package/dist/chunk-7SPRQZ6H.js +216 -0
  11. package/dist/chunk-7SPRQZ6H.js.map +1 -0
  12. package/dist/{chunk-25S5EHH4.js → chunk-FYIPXHAE.js} +22 -13
  13. package/dist/chunk-FYIPXHAE.js.map +1 -0
  14. package/dist/{chunk-TL27COKM.js → chunk-XTFR3IMK.js} +683 -286
  15. package/dist/chunk-XTFR3IMK.js.map +1 -0
  16. package/dist/chunk-XWFU2CSG.js +167 -0
  17. package/dist/chunk-XWFU2CSG.js.map +1 -0
  18. package/dist/commands/index.cjs +232 -0
  19. package/dist/commands/index.cjs.map +1 -0
  20. package/dist/commands/index.d.cts +69 -0
  21. package/dist/commands/index.d.ts +69 -0
  22. package/dist/commands/index.js +13 -0
  23. package/dist/commands/index.js.map +1 -0
  24. package/dist/generation/index.cjs +235 -0
  25. package/dist/generation/index.cjs.map +1 -0
  26. package/dist/generation/index.d.cts +60 -0
  27. package/dist/generation/index.d.ts +60 -0
  28. package/dist/generation/index.js +13 -0
  29. package/dist/generation/index.js.map +1 -0
  30. package/dist/image-editor/index.cjs +688 -299
  31. package/dist/image-editor/index.cjs.map +1 -1
  32. package/dist/image-editor/index.d.cts +65 -5
  33. package/dist/image-editor/index.d.ts +65 -5
  34. package/dist/image-editor/index.js +13 -3
  35. package/dist/index.cjs +2200 -683
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +201 -23
  38. package/dist/index.d.ts +201 -23
  39. package/dist/index.js +743 -129
  40. package/dist/index.js.map +1 -1
  41. package/dist/persistence/index.cjs +191 -0
  42. package/dist/persistence/index.cjs.map +1 -0
  43. package/dist/persistence/index.d.cts +77 -0
  44. package/dist/persistence/index.d.ts +77 -0
  45. package/dist/persistence/index.js +9 -0
  46. package/dist/persistence/index.js.map +1 -0
  47. package/dist/spreadsheet/index.cjs +17 -10
  48. package/dist/spreadsheet/index.cjs.map +1 -1
  49. package/dist/spreadsheet/index.d.cts +9 -7
  50. package/dist/spreadsheet/index.d.ts +9 -7
  51. package/dist/spreadsheet/index.js +1 -1
  52. package/package.json +26 -2
  53. package/dist/chunk-25S5EHH4.js.map +0 -1
  54. package/dist/chunk-TL27COKM.js.map +0 -1
package/README.md CHANGED
@@ -75,6 +75,8 @@ const editor = useEditor({ extensions: [Comments.configure({ author: me }), Trac
75
75
 
76
76
  `ReviewToolbar` steps through insertions, deletions, formatting and block changes and shows the current one's author and description (e.g. "Ada: Changed Paragraph to Heading 2"); hide it with `showDescription={false}` or restyle it with `descriptionClassName`. `useComments(editorOrStore)` and `useTrackChanges(editor)` expose the same state for custom UIs (each change has `type` and `description`).
77
77
 
78
+ `FindReplaceBar` is a Word-style find bar for editors with the `FindReplace` extension (`useEditor({ richTextOptions: { findReplace: true } })`): it appears on Mod+F / Mod+H (or `editor.commands.openFindReplace()`), with find and replace fields, option toggles (match case, whole words, wildcards, regex, plus prefix/suffix/ignore punctuation/white space under "More options"), a "3 of 12" counter, previous/next, Replace and Replace all. Enter / Shift+Enter step, Enter in the replace field replaces, Mod+Enter replaces all, Escape closes. Pass `alwaysOpen` to keep it visible. `useFindReplace(editor)` exposes the state and commands for custom UIs.
79
+
78
80
  `useEditor({ fileImport: true, richClipboard: true })` imports dropped/pasted `.md`, `.html`, `.txt`, `.rtf` and `.docx` files (plus any adapter you register, e.g. PDF or zipped exports) at the drop position and copies lossless slices between editors. `useFileImport(editor)` returns `{ openFilePicker, importFiles, accept, isImporting, error }` for an import button. `usePromptEditor({ fileImport: true })` imports dropped files as plain text.
79
81
 
80
82
  `useAgentToolProvider(registry, provider)` registers an agent tool provider (see `ToolRegistry` in `@pixerate/editor/agent`) while the component is mounted. Memoize the provider:
@@ -88,9 +90,12 @@ useAgentToolProvider(registry, provider);
88
90
 
89
91
  | Import | Exports |
90
92
  | :--- | :--- |
91
- | `@pixerate/editor-react` | `usePromptEditor`, `useEditor`, `EditorContent`, `BubbleMenu`, `TemplateRenderer`, `useHistory`, `useHistoryShortcuts`, `useNavigationGuard`, `useDismissGuard`, `EditorSlotsProvider` / `useEditorSlots`, `SpreadsheetEditor` / `useSpreadsheetEditor`, `FormulaHints`, `DirtyTracker` |
93
+ | `@pixerate/editor-react` | `usePromptEditor`, `useEditor`, `EditorContent`, `BubbleMenu`, `TemplateRenderer`, `useHistory`, `useHistoryDirty`, `useHistoryShortcuts`, `useNavigationGuard`, `useDismissGuard`, `EditorSlotsProvider` / `useEditorSlots`, `SpreadsheetEditor` / `useSpreadsheetEditor`, `FormulaHints`, `DirtyTracker` |
92
94
  | `@pixerate/editor-react/spreadsheet` | `SpreadsheetEditor`, `useSpreadsheetEditor`, `useSpreadsheetTableInteractions`, `FormulaHints`, `SpreadsheetContextMenu`, `SpreadsheetGroupRow` (also re-exported from the root entry) |
93
95
  | `@pixerate/editor-react/image-editor` | `ImageEditor`, `useImageEditor`: crop, rotate/flip, adjustments, annotations, depth masks, and `onInpaint` / `onRemoveBackground` AI hooks |
96
+ | `@pixerate/editor-react/commands` | `CommandPalette`, `useCommandPalette` (`hotkey: "Mod+K"`), `useCommandShortcuts`, `useRegisterCommands` over a `CommandRegistry` from `@pixerate/editor/commands` (also re-exported from the root entry) |
97
+ | `@pixerate/editor-react/persistence` | `useAutosave` (crash-recovery snapshots bound to a history / dirty flag, flushed on `pagehide`, with a recovery check on mount) and `<RecoveryPrompt>` (also re-exported from the root entry) |
98
+ | `@pixerate/editor-react/generation` | `GenerationSettings` (controls generated from a model's capabilities, reference slots by role, plan adjustments), `useGenerationPlan`, `JobProgress`, `useJobProgress` over `@pixerate/editor/generation` (also re-exported from the root entry) |
94
99
  | `@pixerate/editor-react/canvas` | `useCanvasGraph`, `useCanvasLayout`, `useCanvasClipboard`, `useCanvasDocking`, `useCanvasShortcuts`, `useCanvasExplosion`, `useStreamingCanvas`, `AgentPresenceLayer`, plus the pure layout helpers from `@pixerate/editor/canvas` |
95
100
 
96
101
  ## Styling (Tailwind CSS required)
@@ -20,116 +20,159 @@ 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
+ AUTO_LAYOUT_DATA_KEY: () => import_canvas15.AUTO_LAYOUT_DATA_KEY,
23
24
  AgentPresenceLayer: () => AgentPresenceLayer,
24
- CONNECTION_LINE_TYPES: () => import_canvas9.CONNECTION_LINE_TYPES,
25
+ CHILD_LAYOUT_DATA_KEY: () => import_canvas15.CHILD_LAYOUT_DATA_KEY,
26
+ CONNECTION_LINE_TYPES: () => import_canvas12.CONNECTION_LINE_TYPES,
25
27
  CanvasGuidesLayer: () => CanvasGuidesLayer,
26
- CanvasScenesStore: () => import_canvas9.CanvasScenesStore,
27
- DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas9.DEFAULT_ARRANGE_SHORTCUTS,
28
- ManualClock: () => import_canvas11.ManualClock,
29
- SHAPE_DATA_KEY: () => import_canvas10.SHAPE_DATA_KEY,
30
- SHAPE_KINDS: () => import_canvas10.SHAPE_KINDS,
31
- SHAPE_NODE_TYPE: () => import_canvas10.SHAPE_NODE_TYPE,
32
- SHAPE_OPERATIONS: () => import_canvas10.SHAPE_OPERATIONS,
28
+ CanvasScenesStore: () => import_canvas12.CanvasScenesStore,
29
+ DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas12.DEFAULT_ARRANGE_SHORTCUTS,
30
+ ManualClock: () => import_canvas14.ManualClock,
31
+ RESIZE_HANDLES: () => import_canvas11.RESIZE_HANDLES,
32
+ SHAPE_DATA_KEY: () => import_canvas13.SHAPE_DATA_KEY,
33
+ SHAPE_KINDS: () => import_canvas13.SHAPE_KINDS,
34
+ SHAPE_NODE_TYPE: () => import_canvas13.SHAPE_NODE_TYPE,
35
+ SHAPE_OPERATIONS: () => import_canvas13.SHAPE_OPERATIONS,
33
36
  ShapeNode: () => ShapeNode,
34
- alignNodes: () => import_canvas9.alignNodes,
35
- applyNodeUpdates: () => import_canvas9.applyNodeUpdates,
36
- applyShapeCombination: () => import_canvas10.applyShapeCombination,
37
- blendLayout: () => import_canvas11.blendLayout,
38
- boundsOf: () => import_canvas11.boundsOf,
39
- calculateDagreReflowDisplacement: () => import_canvas11.calculateDagreReflowDisplacement,
40
- calculateDirectionalDisplacement: () => import_canvas11.calculateDirectionalDisplacement,
41
- canCombineShapeNodes: () => import_canvas10.canCombineShapeNodes,
42
- canvasHeight: () => import_canvas11.canvasHeight,
43
- centerNodes: () => import_canvas11.centerNodes,
44
- centre: () => import_canvas11.centre,
45
- combineShapeNodes: () => import_canvas10.combineShapeNodes,
46
- computeNodesBoundingBox: () => import_canvas11.computeNodesBoundingBox,
47
- computeSnapGuides: () => import_canvas9.computeSnapGuides,
48
- connectedOnly: () => import_canvas11.connectedOnly,
49
- createBezierTrajectory: () => import_canvas11.createBezierTrajectory,
50
- createCanvasScenesStore: () => import_canvas9.createCanvasScenesStore,
51
- createFanOutTrajectory: () => import_canvas11.createFanOutTrajectory,
52
- createGuideIndex: () => import_canvas9.createGuideIndex,
53
- createNodeGuideIndex: () => import_canvas9.createNodeGuideIndex,
54
- defaultEasing: () => import_canvas11.defaultEasing,
55
- distributeNodes: () => import_canvas9.distributeNodes,
56
- dividePolygons: () => import_canvas10.dividePolygons,
57
- ensureLayout: () => import_canvas11.ensureLayout,
58
- estimateCanvasHeight: () => import_canvas11.estimateCanvasHeight,
59
- estimateNodeSize: () => import_canvas11.estimateNodeSize,
60
- findConnectorSnap: () => import_canvas9.findConnectorSnap,
61
- fitViewportToNodes: () => import_canvas9.fitViewportToNodes,
62
- fitViewportToRect: () => import_canvas9.fitViewportToRect,
63
- flattenSvgPath: () => import_canvas10.flattenSvgPath,
64
- flowSide: () => import_canvas11.flowSide,
65
- getAbsolutePosition: () => import_canvas9.getAbsolutePosition,
66
- getCenteredNodePosition: () => import_canvas11.getCenteredNodePosition,
67
- getLayoutedNodes: () => import_canvas11.getLayoutedNodes,
68
- getNodeRect: () => import_canvas9.getNodeRect,
69
- getNodeShape: () => import_canvas10.getNodeShape,
70
- getNodeSize: () => import_canvas9.getNodeSize,
71
- getShapeRenderData: () => import_canvas10.getShapeRenderData,
72
- getShapeSvg: () => import_canvas10.getShapeSvg,
73
- handlePoint: () => import_canvas9.handlePoint,
74
- intersectPolygons: () => import_canvas10.intersectPolygons,
75
- invertNodeUpdates: () => import_canvas9.invertNodeUpdates,
76
- isEventFromTextInput: () => import_canvas11.isEventFromTextInput,
77
- isLocked: () => import_canvas9.isLocked,
78
- isShapeDescription: () => import_canvas10.isShapeDescription,
79
- isShapeNode: () => import_canvas10.isShapeNode,
80
- isValidCanvasNode: () => import_canvas11.isValidCanvasNode,
81
- isValidUrl: () => import_canvas11.isValidUrl,
82
- layoutBounds: () => import_canvas11.layoutBounds,
83
- linearPositionTrajectory: () => import_canvas11.linearPositionTrajectory,
84
- linearTrajectory: () => import_canvas11.linearTrajectory,
85
- lockNodes: () => import_canvas9.lockNodes,
86
- matchArrangeShortcut: () => import_canvas9.matchArrangeShortcut,
87
- matchSize: () => import_canvas9.matchSize,
88
- multiPolygonArea: () => import_canvas10.multiPolygonArea,
89
- multiPolygonBounds: () => import_canvas10.multiPolygonBounds,
90
- nearestHandlePositions: () => import_canvas9.nearestHandlePositions,
91
- oppositePosition: () => import_canvas9.oppositePosition,
92
- overlaps: () => import_canvas11.overlaps,
93
- parseCanvasClipboardData: () => import_canvas11.parseCanvasClipboardData,
94
- parseCanvasScenes: () => import_canvas9.parseCanvasScenes,
95
- parseSvgPath: () => import_canvas10.parseSvgPath,
96
- placeBeside: () => import_canvas11.placeBeside,
97
- pointInMultiPolygon: () => import_canvas10.pointInMultiPolygon,
98
- pointInRings: () => import_canvas10.pointInRings,
99
- polygonArea: () => import_canvas10.polygonArea,
100
- polygonBoolean: () => import_canvas10.polygonBoolean,
101
- polygonToSvgPath: () => import_canvas10.polygonToSvgPath,
102
- positionToSide: () => import_canvas9.positionToSide,
103
- readStyleSize: () => import_canvas9.readStyleSize,
104
- realClock: () => import_canvas11.realClock,
105
- remapPastedNodes: () => import_canvas11.remapPastedNodes,
106
- reorderNodes: () => import_canvas9.reorderNodes,
107
- repositionNodesTo: () => import_canvas11.repositionNodesTo,
108
- revertShapeCombination: () => import_canvas10.revertShapeCombination,
109
- ringSignedArea: () => import_canvas10.ringSignedArea,
110
- runMultiNodeTransition: () => import_canvas11.runMultiNodeTransition,
111
- serializeCanvasNodes: () => import_canvas11.serializeCanvasNodes,
112
- shapeNodeToPolygon: () => import_canvas10.shapeNodeToPolygon,
113
- shapeToPolygon: () => import_canvas10.shapeToPolygon,
114
- sideToPosition: () => import_canvas9.sideToPosition,
115
- simplifyRing: () => import_canvas10.simplifyRing,
116
- snapNodeDrag: () => import_canvas9.snapNodeDrag,
117
- subtractPolygons: () => import_canvas10.subtractPolygons,
118
- toggleLockNodes: () => import_canvas9.toggleLockNodes,
119
- unionPolygons: () => import_canvas10.unionPolygons,
120
- unlockNodes: () => import_canvas9.unlockNodes,
37
+ alignNodes: () => import_canvas12.alignNodes,
38
+ applyConstraints: () => import_canvas15.applyConstraints,
39
+ applyNodeUpdates: () => import_canvas12.applyNodeUpdates,
40
+ applyShapeCombination: () => import_canvas13.applyShapeCombination,
41
+ blendLayout: () => import_canvas14.blendLayout,
42
+ boundsOf: () => import_canvas14.boundsOf,
43
+ calculateDagreReflowDisplacement: () => import_canvas14.calculateDagreReflowDisplacement,
44
+ calculateDirectionalDisplacement: () => import_canvas14.calculateDirectionalDisplacement,
45
+ canCombineShapeNodes: () => import_canvas13.canCombineShapeNodes,
46
+ canvasHeight: () => import_canvas14.canvasHeight,
47
+ centerNodes: () => import_canvas14.centerNodes,
48
+ centre: () => import_canvas14.centre,
49
+ clampLayoutSize: () => import_canvas15.clampLayoutSize,
50
+ combineShapeNodes: () => import_canvas13.combineShapeNodes,
51
+ computeNodesBoundingBox: () => import_canvas14.computeNodesBoundingBox,
52
+ computeSnapGuides: () => import_canvas12.computeSnapGuides,
53
+ connectedOnly: () => import_canvas14.connectedOnly,
54
+ createBezierTrajectory: () => import_canvas14.createBezierTrajectory,
55
+ createCanvasAutoLayoutController: () => import_canvas15.createCanvasAutoLayoutController,
56
+ createCanvasScenesStore: () => import_canvas12.createCanvasScenesStore,
57
+ createFanOutTrajectory: () => import_canvas14.createFanOutTrajectory,
58
+ createGuideIndex: () => import_canvas12.createGuideIndex,
59
+ createNodeGuideIndex: () => import_canvas12.createNodeGuideIndex,
60
+ cubicPointAt: () => import_canvas11.cubicPointAt,
61
+ cubicsToPathData: () => import_canvas11.cubicsToPathData,
62
+ defaultEasing: () => import_canvas14.defaultEasing,
63
+ distributeNodes: () => import_canvas12.distributeNodes,
64
+ dividePolygons: () => import_canvas13.dividePolygons,
65
+ ensureLayout: () => import_canvas14.ensureLayout,
66
+ estimateCanvasHeight: () => import_canvas14.estimateCanvasHeight,
67
+ estimateNodeSize: () => import_canvas14.estimateNodeSize,
68
+ findConnectorSnap: () => import_canvas12.findConnectorSnap,
69
+ fitCubicRun: () => import_canvas11.fitCubicRun,
70
+ fitCubics: () => import_canvas11.fitCubics,
71
+ fitFreehandPath: () => import_canvas11.fitFreehandPath,
72
+ fitPathData: () => import_canvas11.fitPathData,
73
+ fitViewportToNodes: () => import_canvas12.fitViewportToNodes,
74
+ fitViewportToRect: () => import_canvas12.fitViewportToRect,
75
+ flattenSvgPath: () => import_canvas13.flattenSvgPath,
76
+ flowSide: () => import_canvas14.flowSide,
77
+ getAbsolutePosition: () => import_canvas12.getAbsolutePosition,
78
+ getAutoLayout: () => import_canvas15.getAutoLayout,
79
+ getAutoLayoutGrid: () => import_canvas15.getAutoLayoutGrid,
80
+ getAutoLayoutInsertTarget: () => import_canvas15.getAutoLayoutInsertTarget,
81
+ getCenteredNodePosition: () => import_canvas14.getCenteredNodePosition,
82
+ getChildLayout: () => import_canvas15.getChildLayout,
83
+ getFlowChildren: () => import_canvas15.getFlowChildren,
84
+ getLayoutParent: () => import_canvas15.getLayoutParent,
85
+ getLayoutSizing: () => import_canvas15.getLayoutSizing,
86
+ getLayoutedNodes: () => import_canvas14.getLayoutedNodes,
87
+ getNodeRect: () => import_canvas12.getNodeRect,
88
+ getNodeShape: () => import_canvas13.getNodeShape,
89
+ getNodeSize: () => import_canvas12.getNodeSize,
90
+ getResizingNodeRect: () => import_canvas11.getResizingNodeRect,
91
+ getShapeRenderData: () => import_canvas13.getShapeRenderData,
92
+ getShapeSvg: () => import_canvas13.getShapeSvg,
93
+ handlePoint: () => import_canvas12.handlePoint,
94
+ inferResizeHandle: () => import_canvas11.inferResizeHandle,
95
+ intersectPolygons: () => import_canvas13.intersectPolygons,
96
+ invertNodeUpdates: () => import_canvas12.invertNodeUpdates,
97
+ isAutoLayoutFrame: () => import_canvas15.isAutoLayoutFrame,
98
+ isEventFromTextInput: () => import_canvas14.isEventFromTextInput,
99
+ isLocked: () => import_canvas12.isLocked,
100
+ isMeasureModifierHeld: () => import_canvas11.isMeasureModifierHeld,
101
+ isShapeDescription: () => import_canvas13.isShapeDescription,
102
+ isShapeNode: () => import_canvas13.isShapeNode,
103
+ isStraightCubic: () => import_canvas11.isStraightCubic,
104
+ isValidCanvasNode: () => import_canvas14.isValidCanvasNode,
105
+ isValidUrl: () => import_canvas14.isValidUrl,
106
+ layoutAll: () => import_canvas15.layoutAll,
107
+ layoutBounds: () => import_canvas14.layoutBounds,
108
+ layoutFrame: () => import_canvas15.layoutFrame,
109
+ layoutUp: () => import_canvas15.layoutUp,
110
+ layoutUpMany: () => import_canvas15.layoutUpMany,
111
+ linearPositionTrajectory: () => import_canvas14.linearPositionTrajectory,
112
+ linearTrajectory: () => import_canvas14.linearTrajectory,
113
+ lockNodes: () => import_canvas12.lockNodes,
114
+ makeSizingCoherent: () => import_canvas15.makeSizingCoherent,
115
+ matchArrangeShortcut: () => import_canvas12.matchArrangeShortcut,
116
+ matchSize: () => import_canvas12.matchSize,
117
+ measureBetween: () => import_canvas11.measureBetween,
118
+ measureLabel: () => import_canvas11.measureLabel,
119
+ measureSelection: () => import_canvas11.measureSelection,
120
+ measureToLine: () => import_canvas11.measureToLine,
121
+ mergeNodeUpdates: () => import_canvas15.mergeNodeUpdates,
122
+ moveLayoutChild: () => import_canvas15.moveLayoutChild,
123
+ multiPolygonArea: () => import_canvas13.multiPolygonArea,
124
+ multiPolygonBounds: () => import_canvas13.multiPolygonBounds,
125
+ nearestHandlePositions: () => import_canvas12.nearestHandlePositions,
126
+ oppositePosition: () => import_canvas12.oppositePosition,
127
+ overlaps: () => import_canvas14.overlaps,
128
+ parseCanvasClipboardData: () => import_canvas14.parseCanvasClipboardData,
129
+ parseCanvasScenes: () => import_canvas12.parseCanvasScenes,
130
+ parseSvgPath: () => import_canvas13.parseSvgPath,
131
+ placeBeside: () => import_canvas14.placeBeside,
132
+ pointInMultiPolygon: () => import_canvas13.pointInMultiPolygon,
133
+ pointInRings: () => import_canvas13.pointInRings,
134
+ polygonArea: () => import_canvas13.polygonArea,
135
+ polygonBoolean: () => import_canvas13.polygonBoolean,
136
+ polygonToSvgPath: () => import_canvas13.polygonToSvgPath,
137
+ positionToSide: () => import_canvas12.positionToSide,
138
+ readStyleSize: () => import_canvas12.readStyleSize,
139
+ realClock: () => import_canvas14.realClock,
140
+ relayoutUpdates: () => import_canvas15.relayoutUpdates,
141
+ remapPastedNodes: () => import_canvas14.remapPastedNodes,
142
+ reorderNodes: () => import_canvas12.reorderNodes,
143
+ repositionNodesTo: () => import_canvas14.repositionNodesTo,
144
+ resizeHandleAxes: () => import_canvas11.resizeHandleAxes,
145
+ resolvePadding: () => import_canvas15.resolvePadding,
146
+ revertShapeCombination: () => import_canvas13.revertShapeCombination,
147
+ ringSignedArea: () => import_canvas13.ringSignedArea,
148
+ runMultiNodeTransition: () => import_canvas14.runMultiNodeTransition,
149
+ serializeCanvasNodes: () => import_canvas14.serializeCanvasNodes,
150
+ shapeNodeToPolygon: () => import_canvas13.shapeNodeToPolygon,
151
+ shapeToPolygon: () => import_canvas13.shapeToPolygon,
152
+ sideToPosition: () => import_canvas12.sideToPosition,
153
+ simplifyRing: () => import_canvas13.simplifyRing,
154
+ snapNodeDrag: () => import_canvas12.snapNodeDrag,
155
+ snapNodeResize: () => import_canvas11.snapNodeResize,
156
+ snapResize: () => import_canvas11.snapResize,
157
+ snapToGrid: () => import_canvas11.snapToGrid,
158
+ subtractPolygons: () => import_canvas13.subtractPolygons,
159
+ toggleLockNodes: () => import_canvas12.toggleLockNodes,
160
+ unionPolygons: () => import_canvas13.unionPolygons,
161
+ unlockNodes: () => import_canvas12.unlockNodes,
121
162
  useCanvasArrange: () => useCanvasArrange,
122
163
  useCanvasArrangeShortcuts: () => useCanvasArrangeShortcuts,
164
+ useCanvasAutoLayout: () => useCanvasAutoLayout,
123
165
  useCanvasClipboard: () => useCanvasClipboard,
124
166
  useCanvasDocking: () => useCanvasDocking,
125
167
  useCanvasExplosion: () => useCanvasExplosion,
126
168
  useCanvasGraph: () => useCanvasGraph,
127
169
  useCanvasLayout: () => useCanvasLayout,
170
+ useCanvasMeasure: () => useCanvasMeasure,
128
171
  useCanvasScenes: () => useCanvasScenes,
129
172
  useCanvasShortcuts: () => useCanvasShortcuts,
130
173
  useStreamingCanvas: () => useStreamingCanvas,
131
- withStyleSize: () => import_canvas9.withStyleSize,
132
- xorPolygons: () => import_canvas10.xorPolygons
174
+ withStyleSize: () => import_canvas12.withStyleSize,
175
+ xorPolygons: () => import_canvas13.xorPolygons
133
176
  });
134
177
  module.exports = __toCommonJS(canvas_exports);
135
178
 
@@ -904,6 +947,9 @@ function useCanvasArrange(options) {
904
947
  get rectOptions() {
905
948
  return optionsRef.current.rectOptions;
906
949
  },
950
+ get autoLayout() {
951
+ return optionsRef.current.autoLayout;
952
+ },
907
953
  onGuidesChange: setGuides
908
954
  }),
909
955
  []
@@ -1008,12 +1054,13 @@ function CanvasGuidesLayer({
1008
1054
  viewport = DEFAULT_VIEWPORT,
1009
1055
  color = "#f59e0b",
1010
1056
  spacingColor = "#ec4899",
1057
+ measureColor = "#ef4444",
1011
1058
  className = ""
1012
1059
  }) {
1013
1060
  if (!guides || guides.length === 0) return null;
1014
1061
  const sx = (x) => x * viewport.zoom + viewport.x;
1015
1062
  const sy = (y) => y * viewport.zoom + viewport.y;
1016
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1063
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1017
1064
  "svg",
1018
1065
  {
1019
1066
  className: `pixerate-canvas-guides ${className}`,
@@ -1027,35 +1074,127 @@ function CanvasGuidesLayer({
1027
1074
  zIndex: 10
1028
1075
  },
1029
1076
  "aria-hidden": "true",
1030
- children: guides.map((guide, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1031
- "line",
1032
- {
1033
- "data-kind": guide.kind,
1034
- x1: sx(guide.x1),
1035
- y1: sy(guide.y1),
1036
- x2: sx(guide.x2),
1037
- y2: sy(guide.y2),
1038
- stroke: guide.kind === "spacing" ? spacingColor : color,
1039
- strokeWidth: 1,
1040
- strokeDasharray: guide.kind === "centre" ? "4 3" : void 0,
1041
- shapeRendering: "crispEdges"
1042
- },
1043
- i
1044
- ))
1077
+ children: [
1078
+ guides.map((guide, i) => {
1079
+ const measuring = guide.kind === "measure" || guide.kind === "extension";
1080
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1081
+ "line",
1082
+ {
1083
+ "data-kind": guide.kind,
1084
+ x1: sx(guide.x1),
1085
+ y1: sy(guide.y1),
1086
+ x2: sx(guide.x2),
1087
+ y2: sy(guide.y2),
1088
+ stroke: measuring ? measureColor : guide.kind === "spacing" ? spacingColor : color,
1089
+ strokeWidth: 1,
1090
+ strokeDasharray: guide.kind === "centre" ? "4 3" : guide.kind === "extension" ? "3 3" : void 0,
1091
+ shapeRendering: "crispEdges"
1092
+ },
1093
+ i
1094
+ );
1095
+ }),
1096
+ guides.map((guide, i) => {
1097
+ if (!guide.label) return null;
1098
+ const x = sx((guide.x1 + guide.x2) / 2);
1099
+ const y = sy((guide.y1 + guide.y2) / 2);
1100
+ const vertical = guide.orientation === "vertical";
1101
+ const width = guide.label.length * 6.5 + 8;
1102
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1103
+ "g",
1104
+ {
1105
+ className: "pixerate-canvas-guides__label",
1106
+ "data-label": guide.label,
1107
+ transform: `translate(${vertical ? x + 4 : x - width / 2} ${vertical ? y - 8 : y + 4})`,
1108
+ children: [
1109
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width, height: 16, rx: 3, fill: measureColor }),
1110
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1111
+ "text",
1112
+ {
1113
+ x: width / 2,
1114
+ y: 11.5,
1115
+ textAnchor: "middle",
1116
+ fontSize: 11,
1117
+ fontFamily: "system-ui, sans-serif",
1118
+ fill: "#fff",
1119
+ children: guide.label
1120
+ }
1121
+ )
1122
+ ]
1123
+ },
1124
+ `label-${i}`
1125
+ );
1126
+ })
1127
+ ]
1045
1128
  }
1046
1129
  );
1047
1130
  }
1048
1131
 
1132
+ // src/canvas/useCanvasMeasure.ts
1133
+ var import_react10 = require("react");
1134
+ var import_canvas8 = require("@pixerate/editor/canvas");
1135
+ var EMPTY = { guides: [], target: null, selection: null };
1136
+ function useCanvasMeasure(options) {
1137
+ const { nodes, enabled = true, requireModifier = true, targetElement, rectOptions } = options;
1138
+ const [hoveredId, setHoveredId] = (0, import_react10.useState)(null);
1139
+ const [modifier, setModifier] = (0, import_react10.useState)(false);
1140
+ const optionsRef = (0, import_react10.useRef)(options);
1141
+ optionsRef.current = options;
1142
+ (0, import_react10.useEffect)(() => {
1143
+ if (!enabled) return;
1144
+ const target = targetElement ?? (typeof window !== "undefined" ? window : null);
1145
+ if (!target) return;
1146
+ const onKey = (event) => setModifier((0, import_canvas8.isMeasureModifierHeld)(event));
1147
+ const onBlur = () => setModifier(false);
1148
+ target.addEventListener("keydown", onKey);
1149
+ target.addEventListener("keyup", onKey);
1150
+ const win = typeof window !== "undefined" ? window : null;
1151
+ win?.addEventListener("blur", onBlur);
1152
+ return () => {
1153
+ target.removeEventListener("keydown", onKey);
1154
+ target.removeEventListener("keyup", onKey);
1155
+ win?.removeEventListener("blur", onBlur);
1156
+ };
1157
+ }, [enabled, targetElement]);
1158
+ const active = enabled && (!requireModifier || modifier);
1159
+ const result = (0, import_react10.useMemo)(() => {
1160
+ if (!active) return EMPTY;
1161
+ const ids = optionsRef.current.getSelectedIds?.() ?? nodes.filter((n) => n.selected).map((n) => n.id);
1162
+ return (0, import_canvas8.measureSelection)(nodes, ids, hoveredId, rectOptions);
1163
+ }, [active, nodes, hoveredId, rectOptions]);
1164
+ const onNodeMouseEnter = (0, import_react10.useCallback)((event, node) => {
1165
+ setHoveredId(node.id);
1166
+ if (event && typeof event.altKey === "boolean") setModifier(event.altKey);
1167
+ }, []);
1168
+ const onNodeMouseLeave = (0, import_react10.useCallback)((_event, node) => {
1169
+ setHoveredId((current) => current === node.id ? null : current);
1170
+ }, []);
1171
+ return {
1172
+ /** Measuring lines (flow coordinates) to pass to `<CanvasGuidesLayer>`. */
1173
+ guides: result.guides,
1174
+ /** The box measured to (outline it), or `null`. */
1175
+ target: result.target,
1176
+ /** Whether measuring is showing (enabled and Alt held, unless `requireModifier: false`). */
1177
+ active,
1178
+ hoveredId,
1179
+ setHoveredId,
1180
+ /** Sets the modifier state by hand (e.g. from a toolbar toggle). */
1181
+ setModifier,
1182
+ onNodeMouseEnter,
1183
+ onNodeMouseLeave
1184
+ };
1185
+ }
1186
+
1049
1187
  // src/canvas/index.ts
1050
- var import_canvas9 = require("@pixerate/editor/canvas");
1188
+ var import_canvas11 = require("@pixerate/editor/canvas");
1189
+ var import_canvas12 = require("@pixerate/editor/canvas");
1051
1190
 
1052
1191
  // src/canvas/ShapeNode.tsx
1053
- var import_canvas8 = require("@pixerate/editor/canvas");
1192
+ var import_canvas9 = require("@pixerate/editor/canvas");
1054
1193
  var import_jsx_runtime3 = require("react/jsx-runtime");
1055
1194
  function ShapeNode({ data, width, height, selected, className = "", children }) {
1056
1195
  const shape = data?.shape;
1057
- if (!(0, import_canvas8.isShapeDescription)(shape)) return null;
1058
- const render = (0, import_canvas8.getShapeRenderData)(shape, { width, height });
1196
+ if (!(0, import_canvas9.isShapeDescription)(shape)) return null;
1197
+ const render = (0, import_canvas9.getShapeRenderData)(shape, { width, height });
1059
1198
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1060
1199
  "div",
1061
1200
  {
@@ -1095,22 +1234,78 @@ function ShapeNode({ data, width, height, selected, className = "", children })
1095
1234
  }
1096
1235
 
1097
1236
  // src/canvas/index.ts
1237
+ var import_canvas13 = require("@pixerate/editor/canvas");
1238
+ var import_canvas14 = require("@pixerate/editor/canvas");
1239
+ var import_canvas15 = require("@pixerate/editor/canvas");
1240
+
1241
+ // src/canvas/useCanvasAutoLayout.ts
1242
+ var import_react11 = require("react");
1098
1243
  var import_canvas10 = require("@pixerate/editor/canvas");
1099
- var import_canvas11 = require("@pixerate/editor/canvas");
1244
+ function useCanvasAutoLayout(options) {
1245
+ const [guides, setGuides] = (0, import_react11.useState)([]);
1246
+ const nodesRef = (0, import_react11.useRef)(options.nodes);
1247
+ nodesRef.current = options.nodes;
1248
+ const optionsRef = (0, import_react11.useRef)(options);
1249
+ optionsRef.current = options;
1250
+ const controller = (0, import_react11.useMemo)(
1251
+ () => (0, import_canvas10.createCanvasAutoLayoutController)({
1252
+ getNodes: () => nodesRef.current,
1253
+ setNodes: (next) => {
1254
+ nodesRef.current = next;
1255
+ optionsRef.current.setNodes(next);
1256
+ },
1257
+ get history() {
1258
+ return optionsRef.current.history;
1259
+ },
1260
+ get enabled() {
1261
+ return optionsRef.current.enabled;
1262
+ },
1263
+ get dragReorder() {
1264
+ return optionsRef.current.dragReorder;
1265
+ },
1266
+ get measure() {
1267
+ return optionsRef.current.measure;
1268
+ },
1269
+ get rectOptions() {
1270
+ return optionsRef.current.rectOptions;
1271
+ },
1272
+ onGuidesChange: setGuides
1273
+ }),
1274
+ []
1275
+ );
1276
+ (0, import_react11.useLayoutEffect)(() => {
1277
+ if (controller.hasPending) controller.flush();
1278
+ }, [options.nodes, controller]);
1279
+ return (0, import_react11.useMemo)(
1280
+ () => ({
1281
+ ...controller,
1282
+ /** Drop marker of the active reorder drag (flow coordinates). */
1283
+ guides,
1284
+ get hasPending() {
1285
+ return controller.hasPending;
1286
+ }
1287
+ }),
1288
+ [controller, guides]
1289
+ );
1290
+ }
1100
1291
  // Annotate the CommonJS export names for ESM import in node:
1101
1292
  0 && (module.exports = {
1293
+ AUTO_LAYOUT_DATA_KEY,
1102
1294
  AgentPresenceLayer,
1295
+ CHILD_LAYOUT_DATA_KEY,
1103
1296
  CONNECTION_LINE_TYPES,
1104
1297
  CanvasGuidesLayer,
1105
1298
  CanvasScenesStore,
1106
1299
  DEFAULT_ARRANGE_SHORTCUTS,
1107
1300
  ManualClock,
1301
+ RESIZE_HANDLES,
1108
1302
  SHAPE_DATA_KEY,
1109
1303
  SHAPE_KINDS,
1110
1304
  SHAPE_NODE_TYPE,
1111
1305
  SHAPE_OPERATIONS,
1112
1306
  ShapeNode,
1113
1307
  alignNodes,
1308
+ applyConstraints,
1114
1309
  applyNodeUpdates,
1115
1310
  applyShapeCombination,
1116
1311
  blendLayout,
@@ -1121,15 +1316,19 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1121
1316
  canvasHeight,
1122
1317
  centerNodes,
1123
1318
  centre,
1319
+ clampLayoutSize,
1124
1320
  combineShapeNodes,
1125
1321
  computeNodesBoundingBox,
1126
1322
  computeSnapGuides,
1127
1323
  connectedOnly,
1128
1324
  createBezierTrajectory,
1325
+ createCanvasAutoLayoutController,
1129
1326
  createCanvasScenesStore,
1130
1327
  createFanOutTrajectory,
1131
1328
  createGuideIndex,
1132
1329
  createNodeGuideIndex,
1330
+ cubicPointAt,
1331
+ cubicsToPathData,
1133
1332
  defaultEasing,
1134
1333
  distributeNodes,
1135
1334
  dividePolygons,
@@ -1137,33 +1336,60 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1137
1336
  estimateCanvasHeight,
1138
1337
  estimateNodeSize,
1139
1338
  findConnectorSnap,
1339
+ fitCubicRun,
1340
+ fitCubics,
1341
+ fitFreehandPath,
1342
+ fitPathData,
1140
1343
  fitViewportToNodes,
1141
1344
  fitViewportToRect,
1142
1345
  flattenSvgPath,
1143
1346
  flowSide,
1144
1347
  getAbsolutePosition,
1348
+ getAutoLayout,
1349
+ getAutoLayoutGrid,
1350
+ getAutoLayoutInsertTarget,
1145
1351
  getCenteredNodePosition,
1352
+ getChildLayout,
1353
+ getFlowChildren,
1354
+ getLayoutParent,
1355
+ getLayoutSizing,
1146
1356
  getLayoutedNodes,
1147
1357
  getNodeRect,
1148
1358
  getNodeShape,
1149
1359
  getNodeSize,
1360
+ getResizingNodeRect,
1150
1361
  getShapeRenderData,
1151
1362
  getShapeSvg,
1152
1363
  handlePoint,
1364
+ inferResizeHandle,
1153
1365
  intersectPolygons,
1154
1366
  invertNodeUpdates,
1367
+ isAutoLayoutFrame,
1155
1368
  isEventFromTextInput,
1156
1369
  isLocked,
1370
+ isMeasureModifierHeld,
1157
1371
  isShapeDescription,
1158
1372
  isShapeNode,
1373
+ isStraightCubic,
1159
1374
  isValidCanvasNode,
1160
1375
  isValidUrl,
1376
+ layoutAll,
1161
1377
  layoutBounds,
1378
+ layoutFrame,
1379
+ layoutUp,
1380
+ layoutUpMany,
1162
1381
  linearPositionTrajectory,
1163
1382
  linearTrajectory,
1164
1383
  lockNodes,
1384
+ makeSizingCoherent,
1165
1385
  matchArrangeShortcut,
1166
1386
  matchSize,
1387
+ measureBetween,
1388
+ measureLabel,
1389
+ measureSelection,
1390
+ measureToLine,
1391
+ mergeNodeUpdates,
1392
+ moveLayoutChild,
1167
1393
  multiPolygonArea,
1168
1394
  multiPolygonBounds,
1169
1395
  nearestHandlePositions,
@@ -1181,9 +1407,12 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1181
1407
  positionToSide,
1182
1408
  readStyleSize,
1183
1409
  realClock,
1410
+ relayoutUpdates,
1184
1411
  remapPastedNodes,
1185
1412
  reorderNodes,
1186
1413
  repositionNodesTo,
1414
+ resizeHandleAxes,
1415
+ resolvePadding,
1187
1416
  revertShapeCombination,
1188
1417
  ringSignedArea,
1189
1418
  runMultiNodeTransition,
@@ -1193,17 +1422,22 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1193
1422
  sideToPosition,
1194
1423
  simplifyRing,
1195
1424
  snapNodeDrag,
1425
+ snapNodeResize,
1426
+ snapResize,
1427
+ snapToGrid,
1196
1428
  subtractPolygons,
1197
1429
  toggleLockNodes,
1198
1430
  unionPolygons,
1199
1431
  unlockNodes,
1200
1432
  useCanvasArrange,
1201
1433
  useCanvasArrangeShortcuts,
1434
+ useCanvasAutoLayout,
1202
1435
  useCanvasClipboard,
1203
1436
  useCanvasDocking,
1204
1437
  useCanvasExplosion,
1205
1438
  useCanvasGraph,
1206
1439
  useCanvasLayout,
1440
+ useCanvasMeasure,
1207
1441
  useCanvasScenes,
1208
1442
  useCanvasShortcuts,
1209
1443
  useStreamingCanvas,