@pixerate/editor-react 0.13.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 +5 -4
  2. package/dist/canvas/index.cjs +329 -84
  3. package/dist/canvas/index.cjs.map +1 -1
  4. package/dist/canvas/index.d.cts +82 -4
  5. package/dist/canvas/index.d.ts +82 -4
  6. package/dist/canvas/index.js +266 -18
  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-MHTAR3RS.js → chunk-QVQYYHJ5.js} +87 -29
  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 +2 -0
  23. package/dist/image-editor/index.d.ts +2 -0
  24. package/dist/image-editor/index.js +1 -1
  25. package/dist/index.cjs +624 -268
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +57 -9
  28. package/dist/index.d.ts +57 -9
  29. package/dist/index.js +147 -71
  30. package/dist/index.js.map +1 -1
  31. package/dist/spreadsheet/index.cjs +79 -22
  32. package/dist/spreadsheet/index.cjs.map +1 -1
  33. package/dist/spreadsheet/index.d.cts +2 -3
  34. package/dist/spreadsheet/index.d.ts +2 -3
  35. package/dist/spreadsheet/index.js +1 -1
  36. package/package.json +10 -2
  37. package/dist/chunk-MHTAR3RS.js.map +0 -1
  38. package/dist/chunk-TL27COKM.js.map +0 -1
package/README.md CHANGED
@@ -68,14 +68,14 @@ import { CommentsPanel, ReviewToolbar, CommentButton, BubbleMenu } from "@pixera
68
68
 
69
69
  const editor = useEditor({ extensions: [Comments.configure({ author: me }), TrackChanges.configure({ author: me })] });
70
70
 
71
- <ReviewToolbar editor={editor} /> {/* toggle tracking, prev/next, accept/reject (all) */}
71
+ <ReviewToolbar editor={editor} /> {/* toggle tracking, prev/next, accept/reject (all), current change description */}
72
72
  <BubbleMenu editor={editor}><CommentButton editor={editor} /></BubbleMenu>
73
73
  <CommentsPanel editor={editor} /> {/* threads: reply, resolve, delete, click to select */}
74
74
  ```
75
75
 
76
- `useComments(editorOrStore)` and `useTrackChanges(editor)` expose the same state for custom UIs.
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
- `useEditor({ fileImport: true, richClipboard: true })` imports dropped/pasted `.md`, `.html`, `.txt` and `.rtf` files 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.
78
+ `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
79
 
80
80
  `useAgentToolProvider(registry, provider)` registers an agent tool provider (see `ToolRegistry` in `@pixerate/editor/agent`) while the component is mounted. Memoize the provider:
81
81
 
@@ -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,72 +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_canvas8.CONNECTION_LINE_TYPES,
24
+ CONNECTION_LINE_TYPES: () => import_canvas11.CONNECTION_LINE_TYPES,
25
25
  CanvasGuidesLayer: () => CanvasGuidesLayer,
26
- CanvasScenesStore: () => import_canvas8.CanvasScenesStore,
27
- DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas8.DEFAULT_ARRANGE_SHORTCUTS,
28
- ManualClock: () => import_canvas9.ManualClock,
29
- alignNodes: () => import_canvas8.alignNodes,
30
- applyNodeUpdates: () => import_canvas8.applyNodeUpdates,
31
- blendLayout: () => import_canvas9.blendLayout,
32
- boundsOf: () => import_canvas9.boundsOf,
33
- calculateDagreReflowDisplacement: () => import_canvas9.calculateDagreReflowDisplacement,
34
- calculateDirectionalDisplacement: () => import_canvas9.calculateDirectionalDisplacement,
35
- canvasHeight: () => import_canvas9.canvasHeight,
36
- centerNodes: () => import_canvas9.centerNodes,
37
- centre: () => import_canvas9.centre,
38
- computeNodesBoundingBox: () => import_canvas9.computeNodesBoundingBox,
39
- computeSnapGuides: () => import_canvas8.computeSnapGuides,
40
- connectedOnly: () => import_canvas9.connectedOnly,
41
- createBezierTrajectory: () => import_canvas9.createBezierTrajectory,
42
- createCanvasScenesStore: () => import_canvas8.createCanvasScenesStore,
43
- createFanOutTrajectory: () => import_canvas9.createFanOutTrajectory,
44
- createGuideIndex: () => import_canvas8.createGuideIndex,
45
- createNodeGuideIndex: () => import_canvas8.createNodeGuideIndex,
46
- defaultEasing: () => import_canvas9.defaultEasing,
47
- distributeNodes: () => import_canvas8.distributeNodes,
48
- ensureLayout: () => import_canvas9.ensureLayout,
49
- estimateCanvasHeight: () => import_canvas9.estimateCanvasHeight,
50
- estimateNodeSize: () => import_canvas9.estimateNodeSize,
51
- findConnectorSnap: () => import_canvas8.findConnectorSnap,
52
- fitViewportToNodes: () => import_canvas8.fitViewportToNodes,
53
- fitViewportToRect: () => import_canvas8.fitViewportToRect,
54
- flowSide: () => import_canvas9.flowSide,
55
- getAbsolutePosition: () => import_canvas8.getAbsolutePosition,
56
- getCenteredNodePosition: () => import_canvas9.getCenteredNodePosition,
57
- getLayoutedNodes: () => import_canvas9.getLayoutedNodes,
58
- getNodeRect: () => import_canvas8.getNodeRect,
59
- getNodeSize: () => import_canvas8.getNodeSize,
60
- handlePoint: () => import_canvas8.handlePoint,
61
- invertNodeUpdates: () => import_canvas8.invertNodeUpdates,
62
- isEventFromTextInput: () => import_canvas9.isEventFromTextInput,
63
- isLocked: () => import_canvas8.isLocked,
64
- isValidCanvasNode: () => import_canvas9.isValidCanvasNode,
65
- isValidUrl: () => import_canvas9.isValidUrl,
66
- layoutBounds: () => import_canvas9.layoutBounds,
67
- linearPositionTrajectory: () => import_canvas9.linearPositionTrajectory,
68
- linearTrajectory: () => import_canvas9.linearTrajectory,
69
- lockNodes: () => import_canvas8.lockNodes,
70
- matchArrangeShortcut: () => import_canvas8.matchArrangeShortcut,
71
- matchSize: () => import_canvas8.matchSize,
72
- nearestHandlePositions: () => import_canvas8.nearestHandlePositions,
73
- oppositePosition: () => import_canvas8.oppositePosition,
74
- overlaps: () => import_canvas9.overlaps,
75
- parseCanvasClipboardData: () => import_canvas9.parseCanvasClipboardData,
76
- parseCanvasScenes: () => import_canvas8.parseCanvasScenes,
77
- placeBeside: () => import_canvas9.placeBeside,
78
- positionToSide: () => import_canvas8.positionToSide,
79
- readStyleSize: () => import_canvas8.readStyleSize,
80
- realClock: () => import_canvas9.realClock,
81
- remapPastedNodes: () => import_canvas9.remapPastedNodes,
82
- reorderNodes: () => import_canvas8.reorderNodes,
83
- repositionNodesTo: () => import_canvas9.repositionNodesTo,
84
- runMultiNodeTransition: () => import_canvas9.runMultiNodeTransition,
85
- serializeCanvasNodes: () => import_canvas9.serializeCanvasNodes,
86
- sideToPosition: () => import_canvas8.sideToPosition,
87
- snapNodeDrag: () => import_canvas8.snapNodeDrag,
88
- toggleLockNodes: () => import_canvas8.toggleLockNodes,
89
- unlockNodes: () => import_canvas8.unlockNodes,
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,
34
+ ShapeNode: () => ShapeNode,
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,
90
140
  useCanvasArrange: () => useCanvasArrange,
91
141
  useCanvasArrangeShortcuts: () => useCanvasArrangeShortcuts,
92
142
  useCanvasClipboard: () => useCanvasClipboard,
@@ -94,10 +144,12 @@ __export(canvas_exports, {
94
144
  useCanvasExplosion: () => useCanvasExplosion,
95
145
  useCanvasGraph: () => useCanvasGraph,
96
146
  useCanvasLayout: () => useCanvasLayout,
147
+ useCanvasMeasure: () => useCanvasMeasure,
97
148
  useCanvasScenes: () => useCanvasScenes,
98
149
  useCanvasShortcuts: () => useCanvasShortcuts,
99
150
  useStreamingCanvas: () => useStreamingCanvas,
100
- withStyleSize: () => import_canvas8.withStyleSize
151
+ withStyleSize: () => import_canvas11.withStyleSize,
152
+ xorPolygons: () => import_canvas12.xorPolygons
101
153
  });
102
154
  module.exports = __toCommonJS(canvas_exports);
103
155
 
@@ -976,12 +1028,13 @@ function CanvasGuidesLayer({
976
1028
  viewport = DEFAULT_VIEWPORT,
977
1029
  color = "#f59e0b",
978
1030
  spacingColor = "#ec4899",
1031
+ measureColor = "#ef4444",
979
1032
  className = ""
980
1033
  }) {
981
1034
  if (!guides || guides.length === 0) return null;
982
1035
  const sx = (x) => x * viewport.zoom + viewport.x;
983
1036
  const sy = (y) => y * viewport.zoom + viewport.y;
984
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1037
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
985
1038
  "svg",
986
1039
  {
987
1040
  className: `pixerate-canvas-guides ${className}`,
@@ -995,28 +1048,168 @@ function CanvasGuidesLayer({
995
1048
  zIndex: 10
996
1049
  },
997
1050
  "aria-hidden": "true",
998
- children: guides.map((guide, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
999
- "line",
1000
- {
1001
- "data-kind": guide.kind,
1002
- x1: sx(guide.x1),
1003
- y1: sy(guide.y1),
1004
- x2: sx(guide.x2),
1005
- y2: sy(guide.y2),
1006
- stroke: guide.kind === "spacing" ? spacingColor : color,
1007
- strokeWidth: 1,
1008
- strokeDasharray: guide.kind === "centre" ? "4 3" : void 0,
1009
- shapeRendering: "crispEdges"
1010
- },
1011
- i
1012
- ))
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
+ ]
1013
1102
  }
1014
1103
  );
1015
1104
  }
1016
1105
 
1017
- // src/canvas/index.ts
1106
+ // src/canvas/useCanvasMeasure.ts
1107
+ var import_react10 = require("react");
1018
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
+
1161
+ // src/canvas/index.ts
1162
+ var import_canvas10 = require("@pixerate/editor/canvas");
1163
+ var import_canvas11 = require("@pixerate/editor/canvas");
1164
+
1165
+ // src/canvas/ShapeNode.tsx
1019
1166
  var import_canvas9 = require("@pixerate/editor/canvas");
1167
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1168
+ function ShapeNode({ data, width, height, selected, className = "", children }) {
1169
+ const shape = data?.shape;
1170
+ if (!(0, import_canvas9.isShapeDescription)(shape)) return null;
1171
+ const render = (0, import_canvas9.getShapeRenderData)(shape, { width, height });
1172
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1173
+ "div",
1174
+ {
1175
+ className: `pixerate-shape-node ${className}`.trim(),
1176
+ "data-shape-kind": shape.kind,
1177
+ "data-selected": selected ? "true" : void 0,
1178
+ style: { position: "relative", width: "100%", height: "100%" },
1179
+ children: [
1180
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1181
+ "svg",
1182
+ {
1183
+ viewBox: render.viewBox,
1184
+ preserveAspectRatio: "none",
1185
+ width: "100%",
1186
+ height: "100%",
1187
+ style: { display: "block", overflow: "visible" },
1188
+ "aria-hidden": "true",
1189
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1190
+ "path",
1191
+ {
1192
+ d: render.d,
1193
+ transform: render.transform,
1194
+ fill: render.fill,
1195
+ fillRule: render.fillRule,
1196
+ stroke: render.stroke,
1197
+ strokeWidth: render.strokeWidth,
1198
+ opacity: render.opacity,
1199
+ vectorEffect: "non-scaling-stroke"
1200
+ }
1201
+ )
1202
+ }
1203
+ ),
1204
+ children
1205
+ ]
1206
+ }
1207
+ );
1208
+ }
1209
+
1210
+ // src/canvas/index.ts
1211
+ var import_canvas12 = require("@pixerate/editor/canvas");
1212
+ var import_canvas13 = require("@pixerate/editor/canvas");
1020
1213
  // Annotate the CommonJS export names for ESM import in node:
1021
1214
  0 && (module.exports = {
1022
1215
  AgentPresenceLayer,
@@ -1025,15 +1218,24 @@ var import_canvas9 = require("@pixerate/editor/canvas");
1025
1218
  CanvasScenesStore,
1026
1219
  DEFAULT_ARRANGE_SHORTCUTS,
1027
1220
  ManualClock,
1221
+ RESIZE_HANDLES,
1222
+ SHAPE_DATA_KEY,
1223
+ SHAPE_KINDS,
1224
+ SHAPE_NODE_TYPE,
1225
+ SHAPE_OPERATIONS,
1226
+ ShapeNode,
1028
1227
  alignNodes,
1029
1228
  applyNodeUpdates,
1229
+ applyShapeCombination,
1030
1230
  blendLayout,
1031
1231
  boundsOf,
1032
1232
  calculateDagreReflowDisplacement,
1033
1233
  calculateDirectionalDisplacement,
1234
+ canCombineShapeNodes,
1034
1235
  canvasHeight,
1035
1236
  centerNodes,
1036
1237
  centre,
1238
+ combineShapeNodes,
1037
1239
  computeNodesBoundingBox,
1038
1240
  computeSnapGuides,
1039
1241
  connectedOnly,
@@ -1042,24 +1244,42 @@ var import_canvas9 = require("@pixerate/editor/canvas");
1042
1244
  createFanOutTrajectory,
1043
1245
  createGuideIndex,
1044
1246
  createNodeGuideIndex,
1247
+ cubicPointAt,
1248
+ cubicsToPathData,
1045
1249
  defaultEasing,
1046
1250
  distributeNodes,
1251
+ dividePolygons,
1047
1252
  ensureLayout,
1048
1253
  estimateCanvasHeight,
1049
1254
  estimateNodeSize,
1050
1255
  findConnectorSnap,
1256
+ fitCubicRun,
1257
+ fitCubics,
1258
+ fitFreehandPath,
1259
+ fitPathData,
1051
1260
  fitViewportToNodes,
1052
1261
  fitViewportToRect,
1262
+ flattenSvgPath,
1053
1263
  flowSide,
1054
1264
  getAbsolutePosition,
1055
1265
  getCenteredNodePosition,
1056
1266
  getLayoutedNodes,
1057
1267
  getNodeRect,
1268
+ getNodeShape,
1058
1269
  getNodeSize,
1270
+ getResizingNodeRect,
1271
+ getShapeRenderData,
1272
+ getShapeSvg,
1059
1273
  handlePoint,
1274
+ inferResizeHandle,
1275
+ intersectPolygons,
1060
1276
  invertNodeUpdates,
1061
1277
  isEventFromTextInput,
1062
1278
  isLocked,
1279
+ isMeasureModifierHeld,
1280
+ isShapeDescription,
1281
+ isShapeNode,
1282
+ isStraightCubic,
1063
1283
  isValidCanvasNode,
1064
1284
  isValidUrl,
1065
1285
  layoutBounds,
@@ -1068,23 +1288,46 @@ var import_canvas9 = require("@pixerate/editor/canvas");
1068
1288
  lockNodes,
1069
1289
  matchArrangeShortcut,
1070
1290
  matchSize,
1291
+ measureBetween,
1292
+ measureLabel,
1293
+ measureSelection,
1294
+ measureToLine,
1295
+ multiPolygonArea,
1296
+ multiPolygonBounds,
1071
1297
  nearestHandlePositions,
1072
1298
  oppositePosition,
1073
1299
  overlaps,
1074
1300
  parseCanvasClipboardData,
1075
1301
  parseCanvasScenes,
1302
+ parseSvgPath,
1076
1303
  placeBeside,
1304
+ pointInMultiPolygon,
1305
+ pointInRings,
1306
+ polygonArea,
1307
+ polygonBoolean,
1308
+ polygonToSvgPath,
1077
1309
  positionToSide,
1078
1310
  readStyleSize,
1079
1311
  realClock,
1080
1312
  remapPastedNodes,
1081
1313
  reorderNodes,
1082
1314
  repositionNodesTo,
1315
+ resizeHandleAxes,
1316
+ revertShapeCombination,
1317
+ ringSignedArea,
1083
1318
  runMultiNodeTransition,
1084
1319
  serializeCanvasNodes,
1320
+ shapeNodeToPolygon,
1321
+ shapeToPolygon,
1085
1322
  sideToPosition,
1323
+ simplifyRing,
1086
1324
  snapNodeDrag,
1325
+ snapNodeResize,
1326
+ snapResize,
1327
+ snapToGrid,
1328
+ subtractPolygons,
1087
1329
  toggleLockNodes,
1330
+ unionPolygons,
1088
1331
  unlockNodes,
1089
1332
  useCanvasArrange,
1090
1333
  useCanvasArrangeShortcuts,
@@ -1093,9 +1336,11 @@ var import_canvas9 = require("@pixerate/editor/canvas");
1093
1336
  useCanvasExplosion,
1094
1337
  useCanvasGraph,
1095
1338
  useCanvasLayout,
1339
+ useCanvasMeasure,
1096
1340
  useCanvasScenes,
1097
1341
  useCanvasShortcuts,
1098
1342
  useStreamingCanvas,
1099
- withStyleSize
1343
+ withStyleSize,
1344
+ xorPolygons
1100
1345
  });
1101
1346
  //# sourceMappingURL=index.cjs.map