@pixerate/editor-react 0.14.0 → 0.15.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 (38) hide show
  1. package/README.md +2 -1
  2. package/dist/canvas/index.cjs +252 -119
  3. package/dist/canvas/index.cjs.map +1 -1
  4. package/dist/canvas/index.d.cts +55 -7
  5. package/dist/canvas/index.d.ts +55 -7
  6. package/dist/canvas/index.js +155 -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-TL27COKM.js → chunk-LPFZMZ3L.js} +45 -2
  11. package/dist/chunk-LPFZMZ3L.js.map +1 -0
  12. package/dist/{chunk-25S5EHH4.js → chunk-QVQYYHJ5.js} +4 -3
  13. package/dist/chunk-QVQYYHJ5.js.map +1 -0
  14. package/dist/commands/index.cjs +232 -0
  15. package/dist/commands/index.cjs.map +1 -0
  16. package/dist/commands/index.d.cts +69 -0
  17. package/dist/commands/index.d.ts +69 -0
  18. package/dist/commands/index.js +13 -0
  19. package/dist/commands/index.js.map +1 -0
  20. package/dist/image-editor/index.cjs +41 -0
  21. package/dist/image-editor/index.cjs.map +1 -1
  22. package/dist/image-editor/index.d.cts +5 -3
  23. package/dist/image-editor/index.d.ts +5 -3
  24. package/dist/image-editor/index.js +1 -1
  25. package/dist/index.cjs +535 -251
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +61 -22
  28. package/dist/index.d.ts +61 -22
  29. package/dist/index.js +131 -70
  30. package/dist/index.js.map +1 -1
  31. package/dist/spreadsheet/index.cjs +1 -1
  32. package/dist/spreadsheet/index.cjs.map +1 -1
  33. package/dist/spreadsheet/index.d.cts +7 -7
  34. package/dist/spreadsheet/index.d.ts +7 -7
  35. package/dist/spreadsheet/index.js +1 -1
  36. package/package.json +10 -2
  37. package/dist/chunk-25S5EHH4.js.map +0 -1
  38. package/dist/chunk-TL27COKM.js.map +0 -1
package/README.md CHANGED
@@ -88,9 +88,10 @@ useAgentToolProvider(registry, provider);
88
88
 
89
89
  | Import | Exports |
90
90
  | :--- | :--- |
91
- | `@pixerate/editor-react` | `usePromptEditor`, `useEditor`, `EditorContent`, `BubbleMenu`, `TemplateRenderer`, `useHistory`, `useHistoryShortcuts`, `useNavigationGuard`, `useDismissGuard`, `EditorSlotsProvider` / `useEditorSlots`, `SpreadsheetEditor` / `useSpreadsheetEditor`, `FormulaHints`, `DirtyTracker` |
91
+ | `@pixerate/editor-react` | `usePromptEditor`, `useEditor`, `EditorContent`, `BubbleMenu`, `TemplateRenderer`, `useHistory`, `useHistoryDirty`, `useHistoryShortcuts`, `useNavigationGuard`, `useDismissGuard`, `EditorSlotsProvider` / `useEditorSlots`, `SpreadsheetEditor` / `useSpreadsheetEditor`, `FormulaHints`, `DirtyTracker` |
92
92
  | `@pixerate/editor-react/spreadsheet` | `SpreadsheetEditor`, `useSpreadsheetEditor`, `useSpreadsheetTableInteractions`, `FormulaHints`, `SpreadsheetContextMenu`, `SpreadsheetGroupRow` (also re-exported from the root entry) |
93
93
  | `@pixerate/editor-react/image-editor` | `ImageEditor`, `useImageEditor`: crop, rotate/flip, adjustments, annotations, depth masks, and `onInpaint` / `onRemoveBackground` AI hooks |
94
+ | `@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) |
94
95
  | `@pixerate/editor-react/canvas` | `useCanvasGraph`, `useCanvasLayout`, `useCanvasClipboard`, `useCanvasDocking`, `useCanvasShortcuts`, `useCanvasExplosion`, `useStreamingCanvas`, `AgentPresenceLayer`, plus the pure layout helpers from `@pixerate/editor/canvas` |
95
96
 
96
97
  ## Styling (Tailwind CSS required)
@@ -21,103 +21,122 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var canvas_exports = {};
22
22
  __export(canvas_exports, {
23
23
  AgentPresenceLayer: () => AgentPresenceLayer,
24
- CONNECTION_LINE_TYPES: () => import_canvas9.CONNECTION_LINE_TYPES,
24
+ CONNECTION_LINE_TYPES: () => import_canvas11.CONNECTION_LINE_TYPES,
25
25
  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,
26
+ CanvasScenesStore: () => import_canvas11.CanvasScenesStore,
27
+ DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas11.DEFAULT_ARRANGE_SHORTCUTS,
28
+ ManualClock: () => import_canvas13.ManualClock,
29
+ RESIZE_HANDLES: () => import_canvas10.RESIZE_HANDLES,
30
+ SHAPE_DATA_KEY: () => import_canvas12.SHAPE_DATA_KEY,
31
+ SHAPE_KINDS: () => import_canvas12.SHAPE_KINDS,
32
+ SHAPE_NODE_TYPE: () => import_canvas12.SHAPE_NODE_TYPE,
33
+ SHAPE_OPERATIONS: () => import_canvas12.SHAPE_OPERATIONS,
33
34
  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,
35
+ alignNodes: () => import_canvas11.alignNodes,
36
+ applyNodeUpdates: () => import_canvas11.applyNodeUpdates,
37
+ applyShapeCombination: () => import_canvas12.applyShapeCombination,
38
+ blendLayout: () => import_canvas13.blendLayout,
39
+ boundsOf: () => import_canvas13.boundsOf,
40
+ calculateDagreReflowDisplacement: () => import_canvas13.calculateDagreReflowDisplacement,
41
+ calculateDirectionalDisplacement: () => import_canvas13.calculateDirectionalDisplacement,
42
+ canCombineShapeNodes: () => import_canvas12.canCombineShapeNodes,
43
+ canvasHeight: () => import_canvas13.canvasHeight,
44
+ centerNodes: () => import_canvas13.centerNodes,
45
+ centre: () => import_canvas13.centre,
46
+ combineShapeNodes: () => import_canvas12.combineShapeNodes,
47
+ computeNodesBoundingBox: () => import_canvas13.computeNodesBoundingBox,
48
+ computeSnapGuides: () => import_canvas11.computeSnapGuides,
49
+ connectedOnly: () => import_canvas13.connectedOnly,
50
+ createBezierTrajectory: () => import_canvas13.createBezierTrajectory,
51
+ createCanvasScenesStore: () => import_canvas11.createCanvasScenesStore,
52
+ createFanOutTrajectory: () => import_canvas13.createFanOutTrajectory,
53
+ createGuideIndex: () => import_canvas11.createGuideIndex,
54
+ createNodeGuideIndex: () => import_canvas11.createNodeGuideIndex,
55
+ cubicPointAt: () => import_canvas10.cubicPointAt,
56
+ cubicsToPathData: () => import_canvas10.cubicsToPathData,
57
+ defaultEasing: () => import_canvas13.defaultEasing,
58
+ distributeNodes: () => import_canvas11.distributeNodes,
59
+ dividePolygons: () => import_canvas12.dividePolygons,
60
+ ensureLayout: () => import_canvas13.ensureLayout,
61
+ estimateCanvasHeight: () => import_canvas13.estimateCanvasHeight,
62
+ estimateNodeSize: () => import_canvas13.estimateNodeSize,
63
+ findConnectorSnap: () => import_canvas11.findConnectorSnap,
64
+ fitCubicRun: () => import_canvas10.fitCubicRun,
65
+ fitCubics: () => import_canvas10.fitCubics,
66
+ fitFreehandPath: () => import_canvas10.fitFreehandPath,
67
+ fitPathData: () => import_canvas10.fitPathData,
68
+ fitViewportToNodes: () => import_canvas11.fitViewportToNodes,
69
+ fitViewportToRect: () => import_canvas11.fitViewportToRect,
70
+ flattenSvgPath: () => import_canvas12.flattenSvgPath,
71
+ flowSide: () => import_canvas13.flowSide,
72
+ getAbsolutePosition: () => import_canvas11.getAbsolutePosition,
73
+ getCenteredNodePosition: () => import_canvas13.getCenteredNodePosition,
74
+ getLayoutedNodes: () => import_canvas13.getLayoutedNodes,
75
+ getNodeRect: () => import_canvas11.getNodeRect,
76
+ getNodeShape: () => import_canvas12.getNodeShape,
77
+ getNodeSize: () => import_canvas11.getNodeSize,
78
+ getResizingNodeRect: () => import_canvas10.getResizingNodeRect,
79
+ getShapeRenderData: () => import_canvas12.getShapeRenderData,
80
+ getShapeSvg: () => import_canvas12.getShapeSvg,
81
+ handlePoint: () => import_canvas11.handlePoint,
82
+ inferResizeHandle: () => import_canvas10.inferResizeHandle,
83
+ intersectPolygons: () => import_canvas12.intersectPolygons,
84
+ invertNodeUpdates: () => import_canvas11.invertNodeUpdates,
85
+ isEventFromTextInput: () => import_canvas13.isEventFromTextInput,
86
+ isLocked: () => import_canvas11.isLocked,
87
+ isMeasureModifierHeld: () => import_canvas10.isMeasureModifierHeld,
88
+ isShapeDescription: () => import_canvas12.isShapeDescription,
89
+ isShapeNode: () => import_canvas12.isShapeNode,
90
+ isStraightCubic: () => import_canvas10.isStraightCubic,
91
+ isValidCanvasNode: () => import_canvas13.isValidCanvasNode,
92
+ isValidUrl: () => import_canvas13.isValidUrl,
93
+ layoutBounds: () => import_canvas13.layoutBounds,
94
+ linearPositionTrajectory: () => import_canvas13.linearPositionTrajectory,
95
+ linearTrajectory: () => import_canvas13.linearTrajectory,
96
+ lockNodes: () => import_canvas11.lockNodes,
97
+ matchArrangeShortcut: () => import_canvas11.matchArrangeShortcut,
98
+ matchSize: () => import_canvas11.matchSize,
99
+ measureBetween: () => import_canvas10.measureBetween,
100
+ measureLabel: () => import_canvas10.measureLabel,
101
+ measureSelection: () => import_canvas10.measureSelection,
102
+ measureToLine: () => import_canvas10.measureToLine,
103
+ multiPolygonArea: () => import_canvas12.multiPolygonArea,
104
+ multiPolygonBounds: () => import_canvas12.multiPolygonBounds,
105
+ nearestHandlePositions: () => import_canvas11.nearestHandlePositions,
106
+ oppositePosition: () => import_canvas11.oppositePosition,
107
+ overlaps: () => import_canvas13.overlaps,
108
+ parseCanvasClipboardData: () => import_canvas13.parseCanvasClipboardData,
109
+ parseCanvasScenes: () => import_canvas11.parseCanvasScenes,
110
+ parseSvgPath: () => import_canvas12.parseSvgPath,
111
+ placeBeside: () => import_canvas13.placeBeside,
112
+ pointInMultiPolygon: () => import_canvas12.pointInMultiPolygon,
113
+ pointInRings: () => import_canvas12.pointInRings,
114
+ polygonArea: () => import_canvas12.polygonArea,
115
+ polygonBoolean: () => import_canvas12.polygonBoolean,
116
+ polygonToSvgPath: () => import_canvas12.polygonToSvgPath,
117
+ positionToSide: () => import_canvas11.positionToSide,
118
+ readStyleSize: () => import_canvas11.readStyleSize,
119
+ realClock: () => import_canvas13.realClock,
120
+ remapPastedNodes: () => import_canvas13.remapPastedNodes,
121
+ reorderNodes: () => import_canvas11.reorderNodes,
122
+ repositionNodesTo: () => import_canvas13.repositionNodesTo,
123
+ resizeHandleAxes: () => import_canvas10.resizeHandleAxes,
124
+ revertShapeCombination: () => import_canvas12.revertShapeCombination,
125
+ ringSignedArea: () => import_canvas12.ringSignedArea,
126
+ runMultiNodeTransition: () => import_canvas13.runMultiNodeTransition,
127
+ serializeCanvasNodes: () => import_canvas13.serializeCanvasNodes,
128
+ shapeNodeToPolygon: () => import_canvas12.shapeNodeToPolygon,
129
+ shapeToPolygon: () => import_canvas12.shapeToPolygon,
130
+ sideToPosition: () => import_canvas11.sideToPosition,
131
+ simplifyRing: () => import_canvas12.simplifyRing,
132
+ snapNodeDrag: () => import_canvas11.snapNodeDrag,
133
+ snapNodeResize: () => import_canvas10.snapNodeResize,
134
+ snapResize: () => import_canvas10.snapResize,
135
+ snapToGrid: () => import_canvas10.snapToGrid,
136
+ subtractPolygons: () => import_canvas12.subtractPolygons,
137
+ toggleLockNodes: () => import_canvas11.toggleLockNodes,
138
+ unionPolygons: () => import_canvas12.unionPolygons,
139
+ unlockNodes: () => import_canvas11.unlockNodes,
121
140
  useCanvasArrange: () => useCanvasArrange,
122
141
  useCanvasArrangeShortcuts: () => useCanvasArrangeShortcuts,
123
142
  useCanvasClipboard: () => useCanvasClipboard,
@@ -125,11 +144,12 @@ __export(canvas_exports, {
125
144
  useCanvasExplosion: () => useCanvasExplosion,
126
145
  useCanvasGraph: () => useCanvasGraph,
127
146
  useCanvasLayout: () => useCanvasLayout,
147
+ useCanvasMeasure: () => useCanvasMeasure,
128
148
  useCanvasScenes: () => useCanvasScenes,
129
149
  useCanvasShortcuts: () => useCanvasShortcuts,
130
150
  useStreamingCanvas: () => useStreamingCanvas,
131
- withStyleSize: () => import_canvas9.withStyleSize,
132
- xorPolygons: () => import_canvas10.xorPolygons
151
+ withStyleSize: () => import_canvas11.withStyleSize,
152
+ xorPolygons: () => import_canvas12.xorPolygons
133
153
  });
134
154
  module.exports = __toCommonJS(canvas_exports);
135
155
 
@@ -1008,12 +1028,13 @@ function CanvasGuidesLayer({
1008
1028
  viewport = DEFAULT_VIEWPORT,
1009
1029
  color = "#f59e0b",
1010
1030
  spacingColor = "#ec4899",
1031
+ measureColor = "#ef4444",
1011
1032
  className = ""
1012
1033
  }) {
1013
1034
  if (!guides || guides.length === 0) return null;
1014
1035
  const sx = (x) => x * viewport.zoom + viewport.x;
1015
1036
  const sy = (y) => y * viewport.zoom + viewport.y;
1016
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1037
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1017
1038
  "svg",
1018
1039
  {
1019
1040
  className: `pixerate-canvas-guides ${className}`,
@@ -1027,35 +1048,127 @@ function CanvasGuidesLayer({
1027
1048
  zIndex: 10
1028
1049
  },
1029
1050
  "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
- ))
1051
+ children: [
1052
+ guides.map((guide, i) => {
1053
+ const measuring = guide.kind === "measure" || guide.kind === "extension";
1054
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1055
+ "line",
1056
+ {
1057
+ "data-kind": guide.kind,
1058
+ x1: sx(guide.x1),
1059
+ y1: sy(guide.y1),
1060
+ x2: sx(guide.x2),
1061
+ y2: sy(guide.y2),
1062
+ stroke: measuring ? measureColor : guide.kind === "spacing" ? spacingColor : color,
1063
+ strokeWidth: 1,
1064
+ strokeDasharray: guide.kind === "centre" ? "4 3" : guide.kind === "extension" ? "3 3" : void 0,
1065
+ shapeRendering: "crispEdges"
1066
+ },
1067
+ i
1068
+ );
1069
+ }),
1070
+ guides.map((guide, i) => {
1071
+ if (!guide.label) return null;
1072
+ const x = sx((guide.x1 + guide.x2) / 2);
1073
+ const y = sy((guide.y1 + guide.y2) / 2);
1074
+ const vertical = guide.orientation === "vertical";
1075
+ const width = guide.label.length * 6.5 + 8;
1076
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1077
+ "g",
1078
+ {
1079
+ className: "pixerate-canvas-guides__label",
1080
+ "data-label": guide.label,
1081
+ transform: `translate(${vertical ? x + 4 : x - width / 2} ${vertical ? y - 8 : y + 4})`,
1082
+ children: [
1083
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width, height: 16, rx: 3, fill: measureColor }),
1084
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1085
+ "text",
1086
+ {
1087
+ x: width / 2,
1088
+ y: 11.5,
1089
+ textAnchor: "middle",
1090
+ fontSize: 11,
1091
+ fontFamily: "system-ui, sans-serif",
1092
+ fill: "#fff",
1093
+ children: guide.label
1094
+ }
1095
+ )
1096
+ ]
1097
+ },
1098
+ `label-${i}`
1099
+ );
1100
+ })
1101
+ ]
1045
1102
  }
1046
1103
  );
1047
1104
  }
1048
1105
 
1106
+ // src/canvas/useCanvasMeasure.ts
1107
+ var import_react10 = require("react");
1108
+ var import_canvas8 = require("@pixerate/editor/canvas");
1109
+ var EMPTY = { guides: [], target: null, selection: null };
1110
+ function useCanvasMeasure(options) {
1111
+ const { nodes, enabled = true, requireModifier = true, targetElement, rectOptions } = options;
1112
+ const [hoveredId, setHoveredId] = (0, import_react10.useState)(null);
1113
+ const [modifier, setModifier] = (0, import_react10.useState)(false);
1114
+ const optionsRef = (0, import_react10.useRef)(options);
1115
+ optionsRef.current = options;
1116
+ (0, import_react10.useEffect)(() => {
1117
+ if (!enabled) return;
1118
+ const target = targetElement ?? (typeof window !== "undefined" ? window : null);
1119
+ if (!target) return;
1120
+ const onKey = (event) => setModifier((0, import_canvas8.isMeasureModifierHeld)(event));
1121
+ const onBlur = () => setModifier(false);
1122
+ target.addEventListener("keydown", onKey);
1123
+ target.addEventListener("keyup", onKey);
1124
+ const win = typeof window !== "undefined" ? window : null;
1125
+ win?.addEventListener("blur", onBlur);
1126
+ return () => {
1127
+ target.removeEventListener("keydown", onKey);
1128
+ target.removeEventListener("keyup", onKey);
1129
+ win?.removeEventListener("blur", onBlur);
1130
+ };
1131
+ }, [enabled, targetElement]);
1132
+ const active = enabled && (!requireModifier || modifier);
1133
+ const result = (0, import_react10.useMemo)(() => {
1134
+ if (!active) return EMPTY;
1135
+ const ids = optionsRef.current.getSelectedIds?.() ?? nodes.filter((n) => n.selected).map((n) => n.id);
1136
+ return (0, import_canvas8.measureSelection)(nodes, ids, hoveredId, rectOptions);
1137
+ }, [active, nodes, hoveredId, rectOptions]);
1138
+ const onNodeMouseEnter = (0, import_react10.useCallback)((event, node) => {
1139
+ setHoveredId(node.id);
1140
+ if (event && typeof event.altKey === "boolean") setModifier(event.altKey);
1141
+ }, []);
1142
+ const onNodeMouseLeave = (0, import_react10.useCallback)((_event, node) => {
1143
+ setHoveredId((current) => current === node.id ? null : current);
1144
+ }, []);
1145
+ return {
1146
+ /** Measuring lines (flow coordinates) to pass to `<CanvasGuidesLayer>`. */
1147
+ guides: result.guides,
1148
+ /** The box measured to (outline it), or `null`. */
1149
+ target: result.target,
1150
+ /** Whether measuring is showing (enabled and Alt held, unless `requireModifier: false`). */
1151
+ active,
1152
+ hoveredId,
1153
+ setHoveredId,
1154
+ /** Sets the modifier state by hand (e.g. from a toolbar toggle). */
1155
+ setModifier,
1156
+ onNodeMouseEnter,
1157
+ onNodeMouseLeave
1158
+ };
1159
+ }
1160
+
1049
1161
  // src/canvas/index.ts
1050
- var import_canvas9 = require("@pixerate/editor/canvas");
1162
+ var import_canvas10 = require("@pixerate/editor/canvas");
1163
+ var import_canvas11 = require("@pixerate/editor/canvas");
1051
1164
 
1052
1165
  // src/canvas/ShapeNode.tsx
1053
- var import_canvas8 = require("@pixerate/editor/canvas");
1166
+ var import_canvas9 = require("@pixerate/editor/canvas");
1054
1167
  var import_jsx_runtime3 = require("react/jsx-runtime");
1055
1168
  function ShapeNode({ data, width, height, selected, className = "", children }) {
1056
1169
  const shape = data?.shape;
1057
- if (!(0, import_canvas8.isShapeDescription)(shape)) return null;
1058
- const render = (0, import_canvas8.getShapeRenderData)(shape, { width, height });
1170
+ if (!(0, import_canvas9.isShapeDescription)(shape)) return null;
1171
+ const render = (0, import_canvas9.getShapeRenderData)(shape, { width, height });
1059
1172
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1060
1173
  "div",
1061
1174
  {
@@ -1095,8 +1208,8 @@ function ShapeNode({ data, width, height, selected, className = "", children })
1095
1208
  }
1096
1209
 
1097
1210
  // src/canvas/index.ts
1098
- var import_canvas10 = require("@pixerate/editor/canvas");
1099
- var import_canvas11 = require("@pixerate/editor/canvas");
1211
+ var import_canvas12 = require("@pixerate/editor/canvas");
1212
+ var import_canvas13 = require("@pixerate/editor/canvas");
1100
1213
  // Annotate the CommonJS export names for ESM import in node:
1101
1214
  0 && (module.exports = {
1102
1215
  AgentPresenceLayer,
@@ -1105,6 +1218,7 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1105
1218
  CanvasScenesStore,
1106
1219
  DEFAULT_ARRANGE_SHORTCUTS,
1107
1220
  ManualClock,
1221
+ RESIZE_HANDLES,
1108
1222
  SHAPE_DATA_KEY,
1109
1223
  SHAPE_KINDS,
1110
1224
  SHAPE_NODE_TYPE,
@@ -1130,6 +1244,8 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1130
1244
  createFanOutTrajectory,
1131
1245
  createGuideIndex,
1132
1246
  createNodeGuideIndex,
1247
+ cubicPointAt,
1248
+ cubicsToPathData,
1133
1249
  defaultEasing,
1134
1250
  distributeNodes,
1135
1251
  dividePolygons,
@@ -1137,6 +1253,10 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1137
1253
  estimateCanvasHeight,
1138
1254
  estimateNodeSize,
1139
1255
  findConnectorSnap,
1256
+ fitCubicRun,
1257
+ fitCubics,
1258
+ fitFreehandPath,
1259
+ fitPathData,
1140
1260
  fitViewportToNodes,
1141
1261
  fitViewportToRect,
1142
1262
  flattenSvgPath,
@@ -1147,15 +1267,19 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1147
1267
  getNodeRect,
1148
1268
  getNodeShape,
1149
1269
  getNodeSize,
1270
+ getResizingNodeRect,
1150
1271
  getShapeRenderData,
1151
1272
  getShapeSvg,
1152
1273
  handlePoint,
1274
+ inferResizeHandle,
1153
1275
  intersectPolygons,
1154
1276
  invertNodeUpdates,
1155
1277
  isEventFromTextInput,
1156
1278
  isLocked,
1279
+ isMeasureModifierHeld,
1157
1280
  isShapeDescription,
1158
1281
  isShapeNode,
1282
+ isStraightCubic,
1159
1283
  isValidCanvasNode,
1160
1284
  isValidUrl,
1161
1285
  layoutBounds,
@@ -1164,6 +1288,10 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1164
1288
  lockNodes,
1165
1289
  matchArrangeShortcut,
1166
1290
  matchSize,
1291
+ measureBetween,
1292
+ measureLabel,
1293
+ measureSelection,
1294
+ measureToLine,
1167
1295
  multiPolygonArea,
1168
1296
  multiPolygonBounds,
1169
1297
  nearestHandlePositions,
@@ -1184,6 +1312,7 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1184
1312
  remapPastedNodes,
1185
1313
  reorderNodes,
1186
1314
  repositionNodesTo,
1315
+ resizeHandleAxes,
1187
1316
  revertShapeCombination,
1188
1317
  ringSignedArea,
1189
1318
  runMultiNodeTransition,
@@ -1193,6 +1322,9 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1193
1322
  sideToPosition,
1194
1323
  simplifyRing,
1195
1324
  snapNodeDrag,
1325
+ snapNodeResize,
1326
+ snapResize,
1327
+ snapToGrid,
1196
1328
  subtractPolygons,
1197
1329
  toggleLockNodes,
1198
1330
  unionPolygons,
@@ -1204,6 +1336,7 @@ var import_canvas11 = require("@pixerate/editor/canvas");
1204
1336
  useCanvasExplosion,
1205
1337
  useCanvasGraph,
1206
1338
  useCanvasLayout,
1339
+ useCanvasMeasure,
1207
1340
  useCanvasScenes,
1208
1341
  useCanvasShortcuts,
1209
1342
  useStreamingCanvas,