@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
@@ -1,8 +1,9 @@
1
- import React$1 from 'react';
1
+ import * as React$1 from 'react';
2
+ import React__default from 'react';
2
3
  import { AgentPresence } from '@pixerate/editor/agent';
3
4
  import * as _pixerate_editor_canvas from '@pixerate/editor/canvas';
4
- import { CanvasNode, CanvasEdge, IncrementalLayoutOptions, XYPosition, GraphDifferences, Rect, CanvasLayoutOptions, Side, PlaceBesideOptions, getCenteredNodePosition, CanvasDockingCallbacks, DockStrategy, ExplodeNodeOptions, CollapseNodeOptions, ExplosionSnapshot, ArrangeHistoryTarget, SnapGuidesOptions, NodeRectOptions, GuideLine, CanvasArrangeAction, ArrangeShortcutBinding, CanvasScenesOptions, CanvasViewport, CanvasScenesStore, CanvasScene, FitViewportOptions, ShapeDescription } from '@pixerate/editor/canvas';
5
- export { AlignEdge, ArrangeShortcutBinding, CONNECTION_LINE_TYPES, CanvasArrangeAction, CanvasClipboardPayload, CanvasConnectionLineType, CanvasDockingCallbacks, CanvasEdge, CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeUpdate, CanvasScene, CanvasScenesState, CanvasScenesStore, CanvasViewport, Clock, CollapseNodeOptions, CombineShapeNodesOptions, CombineShapeNodesRefusal, CombineShapeNodesResult, ConnectorSnap, ConnectorSnapTarget, DEFAULT_ARRANGE_SHORTCUTS, DirectionalDisplacementOptions, DisplacementDirection, DistributeAxis, DistributeMode, DockStrategy, EllipseShape, ExplodeNodeOptions, ExplosionSnapshot, FanOutTrajectoryOptions, FlattenOptions, GraphDifferences, GuideIndex, GuideLine, IncrementalLayoutOptions, ManualClock, MultiPolygon, NodeTransition, PathCommand, PathShape, PlaceBesideOptions, Point, PolygonBooleanOperation, PolygonBooleanOptions, PolygonFillRule, PolygonInput, PolygonOperand, PolygonPiece, PolygonRing, PolygonToPathOptions, PolygonWithHoles, Position, Rect, RectShape, ReflowDisplacementOptions, RegularPolygonShape, SHAPE_DATA_KEY, SHAPE_KINDS, SHAPE_NODE_TYPE, SHAPE_OPERATIONS, ShapeDescription, ShapeKind, ShapeNodePolygonOptions, ShapeOperation, ShapePaint, ShapeRenderData, ShapeSize, Side, SizeDimension, SnapGuidesOptions, SnapResult, StarShape, TrajectoryFunction, TrajectoryPoint, XYPosition, ZOrderOperation, alignNodes, applyNodeUpdates, applyShapeCombination, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canCombineShapeNodes, canvasHeight, centerNodes, centre, combineShapeNodes, computeNodesBoundingBox, computeSnapGuides, connectedOnly, createBezierTrajectory, createCanvasScenesStore, createFanOutTrajectory, createGuideIndex, createNodeGuideIndex, defaultEasing, distributeNodes, dividePolygons, ensureLayout, estimateCanvasHeight, estimateNodeSize, findConnectorSnap, fitViewportToNodes, fitViewportToRect, flattenSvgPath, flowSide, getAbsolutePosition, getCenteredNodePosition, getLayoutedNodes, getNodeRect, getNodeShape, getNodeSize, getShapeRenderData, getShapeSvg, handlePoint, intersectPolygons, invertNodeUpdates, isEventFromTextInput, isLocked, isShapeDescription, isShapeNode, isValidCanvasNode, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, lockNodes, matchArrangeShortcut, matchSize, multiPolygonArea, multiPolygonBounds, nearestHandlePositions, oppositePosition, overlaps, parseCanvasClipboardData, parseCanvasScenes, parseSvgPath, placeBeside, pointInMultiPolygon, pointInRings, polygonArea, polygonBoolean, polygonToSvgPath, positionToSide, readStyleSize, realClock, remapPastedNodes, reorderNodes, repositionNodesTo, revertShapeCombination, ringSignedArea, runMultiNodeTransition, serializeCanvasNodes, shapeNodeToPolygon, shapeToPolygon, sideToPosition, simplifyRing, snapNodeDrag, subtractPolygons, toggleLockNodes, unionPolygons, unlockNodes, withStyleSize, xorPolygons } from '@pixerate/editor/canvas';
5
+ import { CanvasNode, CanvasEdge, IncrementalLayoutOptions, XYPosition, GraphDifferences, Rect, CanvasLayoutOptions, Side, PlaceBesideOptions, getCenteredNodePosition, CanvasDockingCallbacks, DockStrategy, ExplodeNodeOptions, CollapseNodeOptions, ExplosionSnapshot, ArrangeHistoryTarget, SnapGuidesOptions, NodeRectOptions, AutoLayoutOptions, GuideLine, CanvasArrangeAction, ArrangeShortcutBinding, CanvasScenesOptions, CanvasViewport, CanvasScenesStore, CanvasScene, FitViewportOptions, ShapeDescription, AutoLayoutMeasure } from '@pixerate/editor/canvas';
6
+ export { AUTO_LAYOUT_DATA_KEY, AlignEdge, ArrangeShortcutBinding, AutoLayout, AutoLayoutAlignContent, AutoLayoutAlignCross, AutoLayoutAlignMain, AutoLayoutCellAlign, AutoLayoutChild, AutoLayoutConstraints, AutoLayoutGrid, AutoLayoutGridArea, AutoLayoutGridCell, AutoLayoutGridGeometry, AutoLayoutGridTrack, AutoLayoutHorizontalConstraint, AutoLayoutInsertTarget, AutoLayoutMeasure, AutoLayoutMode, AutoLayoutOptions, AutoLayoutPadding, AutoLayoutSize, AutoLayoutSizing, AutoLayoutSizingPair, AutoLayoutVerticalConstraint, CHILD_LAYOUT_DATA_KEY, CONNECTION_LINE_TYPES, CanvasArrangeAction, CanvasAutoLayoutController, CanvasAutoLayoutControllerOptions, CanvasClipboardPayload, CanvasConnectionLineType, CanvasDockingCallbacks, CanvasEdge, CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeUpdate, CanvasScene, CanvasScenesState, CanvasScenesStore, CanvasViewport, Clock, CollapseNodeOptions, CombineShapeNodesOptions, CombineShapeNodesRefusal, CombineShapeNodesResult, ConnectorSnap, ConnectorSnapTarget, CubicSegment, DEFAULT_ARRANGE_SHORTCUTS, DirectionalDisplacementOptions, DisplacementDirection, DistributeAxis, DistributeMode, DockStrategy, EllipseShape, ExplodeNodeOptions, ExplosionSnapshot, FanOutTrajectoryOptions, FitCubicsOptions, FitPathDataOptions, FlattenOptions, GraphDifferences, GuideIndex, GuideLine, IncrementalLayoutOptions, ManualClock, MeasureGuide, MeasureSelectionOptions, MeasureSelectionResult, MultiPolygon, NodeTransition, PathCommand, PathShape, PlaceBesideOptions, Point, PolygonBooleanOperation, PolygonBooleanOptions, PolygonFillRule, PolygonInput, PolygonOperand, PolygonPiece, PolygonRing, PolygonToPathOptions, PolygonWithHoles, Position, RESIZE_HANDLES, Rect, RectShape, ReflowDisplacementOptions, RegularPolygonShape, ResizeHandle, SHAPE_DATA_KEY, SHAPE_KINDS, SHAPE_NODE_TYPE, SHAPE_OPERATIONS, ShapeDescription, ShapeKind, ShapeNodePolygonOptions, ShapeOperation, ShapePaint, ShapeRenderData, ShapeSize, Side, SizeDimension, SnapGuidesOptions, SnapNodeResizeOptions, SnapNodeResizeResult, SnapResizeOptions, SnapResizeResult, SnapResult, StarShape, TrajectoryFunction, TrajectoryPoint, XYPosition, ZOrderOperation, alignNodes, applyConstraints, applyNodeUpdates, applyShapeCombination, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canCombineShapeNodes, canvasHeight, centerNodes, centre, clampLayoutSize, combineShapeNodes, computeNodesBoundingBox, computeSnapGuides, connectedOnly, createBezierTrajectory, createCanvasAutoLayoutController, createCanvasScenesStore, createFanOutTrajectory, createGuideIndex, createNodeGuideIndex, cubicPointAt, cubicsToPathData, defaultEasing, distributeNodes, dividePolygons, ensureLayout, estimateCanvasHeight, estimateNodeSize, findConnectorSnap, fitCubicRun, fitCubics, fitFreehandPath, fitPathData, fitViewportToNodes, fitViewportToRect, flattenSvgPath, flowSide, getAbsolutePosition, getAutoLayout, getAutoLayoutGrid, getAutoLayoutInsertTarget, getCenteredNodePosition, getChildLayout, getFlowChildren, getLayoutParent, getLayoutSizing, getLayoutedNodes, getNodeRect, getNodeShape, getNodeSize, getResizingNodeRect, getShapeRenderData, getShapeSvg, handlePoint, inferResizeHandle, intersectPolygons, invertNodeUpdates, isAutoLayoutFrame, isEventFromTextInput, isLocked, isMeasureModifierHeld, isShapeDescription, isShapeNode, isStraightCubic, isValidCanvasNode, isValidUrl, layoutAll, layoutBounds, layoutFrame, layoutUp, layoutUpMany, linearPositionTrajectory, linearTrajectory, lockNodes, makeSizingCoherent, matchArrangeShortcut, matchSize, measureBetween, measureLabel, measureSelection, measureToLine, mergeNodeUpdates, moveLayoutChild, multiPolygonArea, multiPolygonBounds, nearestHandlePositions, oppositePosition, overlaps, parseCanvasClipboardData, parseCanvasScenes, parseSvgPath, placeBeside, pointInMultiPolygon, pointInRings, polygonArea, polygonBoolean, polygonToSvgPath, positionToSide, readStyleSize, realClock, relayoutUpdates, remapPastedNodes, reorderNodes, repositionNodesTo, resizeHandleAxes, resolvePadding, revertShapeCombination, ringSignedArea, runMultiNodeTransition, serializeCanvasNodes, shapeNodeToPolygon, shapeToPolygon, sideToPosition, simplifyRing, snapNodeDrag, snapNodeResize, snapResize, snapToGrid, subtractPolygons, toggleLockNodes, unionPolygons, unlockNodes, withStyleSize, xorPolygons } from '@pixerate/editor/canvas';
6
7
 
7
8
  interface AgentPresenceLayerProps {
8
9
  presences: AgentPresence[];
@@ -12,7 +13,7 @@ interface AgentPresenceLayerProps {
12
13
  * Visual multiplayer and agent choreography presence layer for React Canvas.
13
14
  * Renders floating cursor indicators, agent name tags, and active status tooltips.
14
15
  */
15
- declare function AgentPresenceLayer({ presences, className }: AgentPresenceLayerProps): React$1.JSX.Element | null;
16
+ declare function AgentPresenceLayer({ presences, className }: AgentPresenceLayerProps): React__default.JSX.Element | null;
16
17
 
17
18
  interface UseStreamingCanvasOptions<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
18
19
  throttleMs?: number;
@@ -163,6 +164,8 @@ interface UseCanvasArrangeOptions<TNode extends CanvasNode = CanvasNode> {
163
164
  /** Turns drag snapping off (default `true`). */
164
165
  snapping?: boolean;
165
166
  rectOptions?: NodeRectOptions;
167
+ /** Re-run auto layout around arranged nodes in the same undo step (see `useCanvasAutoLayout`). */
168
+ autoLayout?: boolean | AutoLayoutOptions;
166
169
  }
167
170
  /**
168
171
  * React hook for Freeform-style arrangement on React Flow: align, distribute, make same size,
@@ -198,6 +201,10 @@ declare function useCanvasArrange<TNode extends CanvasNode = CanvasNode>(options
198
201
  beginDrag(ids?: Iterable<string>): void;
199
202
  drag(ids?: Iterable<string>): _pixerate_editor_canvas.SnapNodeDragResult | null;
200
203
  snapPositionChanges<TChange extends _pixerate_editor_canvas.PositionChangeLike>(changes: TChange[]): TChange[];
204
+ beginResize(id: string): void;
205
+ resize(id: string, handle?: _pixerate_editor_canvas.ResizeHandle): _pixerate_editor_canvas.SnapNodeResizeResult | null;
206
+ endResize(): void;
207
+ snapResizeChanges<TChange extends _pixerate_editor_canvas.PositionChangeLike>(changes: TChange[]): TChange[];
201
208
  endDrag(): void;
202
209
  };
203
210
  type CanvasArrange = ReturnType<typeof useCanvasArrange>;
@@ -280,13 +287,56 @@ interface CanvasGuidesLayerProps {
280
287
  color?: string;
281
288
  /** Colour of equal-spacing guides. */
282
289
  spacingColor?: string;
290
+ /** Colour of measuring lines, their labels and extension lines. */
291
+ measureColor?: string;
283
292
  className?: string;
284
293
  }
285
294
  /**
286
295
  * Smart-guide overlay for React Flow. Place it inside the flow container (it is absolutely
287
296
  * positioned over the whole pane) and pass the live viewport.
288
297
  */
289
- declare function CanvasGuidesLayer({ guides, viewport, color, spacingColor, className }: CanvasGuidesLayerProps): React$1.JSX.Element | null;
298
+ declare function CanvasGuidesLayer({ guides, viewport, color, spacingColor, measureColor, className }: CanvasGuidesLayerProps): React__default.JSX.Element | null;
299
+
300
+ interface UseCanvasMeasureOptions<TNode extends CanvasNode = CanvasNode> {
301
+ nodes: TNode[];
302
+ /** Ids measured from (default: nodes with `selected: true`). */
303
+ getSelectedIds?: () => string[];
304
+ /** Turns measuring off (default `true`). */
305
+ enabled?: boolean;
306
+ /** Measure only while Alt / Option is held (default `true`); `false` always measures. */
307
+ requireModifier?: boolean;
308
+ /** Element receiving the Alt key events (default `window`). */
309
+ targetElement?: HTMLElement | Window | null;
310
+ rectOptions?: NodeRectOptions;
311
+ }
312
+ /**
313
+ * Alt-hover distance measuring for React Flow: hold Alt / Option and hover a node to see
314
+ * red distance lines with labels from the selection to it (or to the selection's parent
315
+ * when hovering the selection or empty space). Wire `onNodeMouseEnter` / `onNodeMouseLeave`
316
+ * to `<ReactFlow>` and render `guides` with `<CanvasGuidesLayer>` (concatenate them with
317
+ * `arrange.guides` to share one layer).
318
+ */
319
+ declare function useCanvasMeasure<TNode extends CanvasNode = CanvasNode>(options: UseCanvasMeasureOptions<TNode>): {
320
+ /** Measuring lines (flow coordinates) to pass to `<CanvasGuidesLayer>`. */
321
+ guides: _pixerate_editor_canvas.MeasureGuide[];
322
+ /** The box measured to (outline it), or `null`. */
323
+ target: _pixerate_editor_canvas.Rect | null;
324
+ /** Whether measuring is showing (enabled and Alt held, unless `requireModifier: false`). */
325
+ active: boolean;
326
+ hoveredId: string | null;
327
+ setHoveredId: React$1.Dispatch<React$1.SetStateAction<string | null>>;
328
+ /** Sets the modifier state by hand (e.g. from a toolbar toggle). */
329
+ setModifier: React$1.Dispatch<React$1.SetStateAction<boolean>>;
330
+ onNodeMouseEnter: (event: {
331
+ altKey?: boolean;
332
+ } | null, node: {
333
+ id: string;
334
+ }) => void;
335
+ onNodeMouseLeave: (_event: unknown, node: {
336
+ id: string;
337
+ }) => void;
338
+ };
339
+ type CanvasMeasure = ReturnType<typeof useCanvasMeasure>;
290
340
 
291
341
  interface ShapeNodeProps {
292
342
  /** Node data; `data.shape` holds the shape description. */
@@ -300,7 +350,7 @@ interface ShapeNodeProps {
300
350
  selected?: boolean;
301
351
  className?: string;
302
352
  /** Rendered over the shape, e.g. React Flow `<Handle>`s or a label. */
303
- children?: React$1.ReactNode;
353
+ children?: React__default.ReactNode;
304
354
  [key: string]: any;
305
355
  }
306
356
  /**
@@ -309,6 +359,60 @@ interface ShapeNodeProps {
309
359
  * to add handles. Strokes keep their width when the node is resized
310
360
  * (`vector-effect: non-scaling-stroke`). Renders nothing when `data.shape` is missing.
311
361
  */
312
- declare function ShapeNode({ data, width, height, selected, className, children }: ShapeNodeProps): React$1.JSX.Element | null;
362
+ declare function ShapeNode({ data, width, height, selected, className, children }: ShapeNodeProps): React__default.JSX.Element | null;
363
+
364
+ interface UseCanvasAutoLayoutOptions<TNode extends CanvasNode = CanvasNode> {
365
+ nodes: TNode[];
366
+ setNodes: (updater: TNode[] | ((prev: TNode[]) => TNode[])) => void;
367
+ /** When set, the hook's actions (add / remove / resize / reorder / apply) are undoable steps. */
368
+ history?: ArrangeHistoryTarget;
369
+ /** Turns automatic relayout off (`applyAutoLayout` still works). Default `true`. */
370
+ enabled?: boolean;
371
+ /** Reorder flow children by dragging them within their frame (default `true`). */
372
+ dragReorder?: boolean;
373
+ /** Text measuring and size hooks (default: xyflow `measured` sizes). */
374
+ measure?: AutoLayoutMeasure;
375
+ rectOptions?: NodeRectOptions;
376
+ }
377
+ /**
378
+ * React hook for Figma-style auto layout on React Flow sub-flows. Frames are nodes with
379
+ * `data.layout`; their children (`parentId`) are stacked, wrapped or placed on a grid, with
380
+ * hug / fill / fixed sizing, min / max, padding, alignment and constraints.
381
+ *
382
+ * Pass every `onNodesChange` batch through `noteChanges` before applying it
383
+ * (`onNodesChange={(c) => setNodes((n) => applyNodeChanges(autoLayout.noteChanges(c), n))}`):
384
+ * after the nodes update the hook relayouts frames whose children were measured, resized,
385
+ * added or removed, and turns drags of a flow child inside its frame into a reorder (one
386
+ * undoable step). Render `guides` (the drop marker) with `<CanvasGuidesLayer>`.
387
+ */
388
+ declare function useCanvasAutoLayout<TNode extends CanvasNode = CanvasNode>(options: UseCanvasAutoLayoutOptions<TNode>): {
389
+ /** Drop marker of the active reorder drag (flow coordinates). */
390
+ guides: GuideLine[];
391
+ hasPending: boolean;
392
+ applyAutoLayout(frameId?: string): _pixerate_editor_canvas.CanvasNodeUpdate[];
393
+ layoutUpdates(ids: Iterable<string>): _pixerate_editor_canvas.CanvasNodeUpdate[];
394
+ relayout(ids: Iterable<string>): _pixerate_editor_canvas.CanvasNodeUpdate[];
395
+ addNode(node: TNode, addOptions?: {
396
+ index?: number;
397
+ }): _pixerate_editor_canvas.CanvasNodeUpdate[];
398
+ removeNodes(ids: Iterable<string>): _pixerate_editor_canvas.CanvasNodeUpdate[];
399
+ resizeNode(id: string, size: {
400
+ width?: number;
401
+ height?: number;
402
+ }): _pixerate_editor_canvas.CanvasNodeUpdate[];
403
+ moveChild(childId: string, index: number): _pixerate_editor_canvas.CanvasNodeUpdate[];
404
+ getInsertTarget(id: string, point?: _pixerate_editor_canvas.XYPosition): _pixerate_editor_canvas.AutoLayoutInsertTarget | undefined;
405
+ beginReorderDrag(id: string): void;
406
+ dragReorder(id: string, point?: _pixerate_editor_canvas.XYPosition): _pixerate_editor_canvas.AutoLayoutInsertTarget | undefined;
407
+ endReorderDrag(id: string, point?: _pixerate_editor_canvas.XYPosition): _pixerate_editor_canvas.CanvasNodeUpdate[];
408
+ noteChanges<TChange extends _pixerate_editor_canvas.PositionChangeLike>(changes: TChange[]): TChange[];
409
+ noteRemoved(removed: Iterable<{
410
+ id: string;
411
+ parentId?: string;
412
+ }>): void;
413
+ flush(): _pixerate_editor_canvas.CanvasNodeUpdate[];
414
+ isFrame: (id: string) => boolean;
415
+ };
416
+ type CanvasAutoLayout = ReturnType<typeof useCanvasAutoLayout>;
313
417
 
314
- export { AgentPresenceLayer, type AgentPresenceLayerProps, type CanvasArrange, type CanvasGraphTarget, CanvasGuidesLayer, type CanvasGuidesLayerProps, type CanvasScenes, ShapeNode, type ShapeNodeProps, type UseCanvasArrangeOptions, type UseCanvasArrangeShortcutsOptions, type UseCanvasClipboardOptions, type UseCanvasDockingOptions, type UseCanvasGraphOptions, type UseCanvasLayoutOptions, type UseCanvasScenesOptions, type UseCanvasShortcutsOptions, type UseStreamingCanvasOptions, useCanvasArrange, useCanvasArrangeShortcuts, useCanvasClipboard, useCanvasDocking, useCanvasExplosion, useCanvasGraph, useCanvasLayout, useCanvasScenes, useCanvasShortcuts, useStreamingCanvas };
418
+ export { AgentPresenceLayer, type AgentPresenceLayerProps, type CanvasArrange, type CanvasAutoLayout, type CanvasGraphTarget, CanvasGuidesLayer, type CanvasGuidesLayerProps, type CanvasMeasure, type CanvasScenes, ShapeNode, type ShapeNodeProps, type UseCanvasArrangeOptions, type UseCanvasArrangeShortcutsOptions, type UseCanvasAutoLayoutOptions, type UseCanvasClipboardOptions, type UseCanvasDockingOptions, type UseCanvasGraphOptions, type UseCanvasLayoutOptions, type UseCanvasMeasureOptions, type UseCanvasScenesOptions, type UseCanvasShortcutsOptions, type UseStreamingCanvasOptions, useCanvasArrange, useCanvasArrangeShortcuts, useCanvasAutoLayout, useCanvasClipboard, useCanvasDocking, useCanvasExplosion, useCanvasGraph, useCanvasLayout, useCanvasMeasure, useCanvasScenes, useCanvasShortcuts, useStreamingCanvas };
@@ -791,6 +791,9 @@ function useCanvasArrange(options) {
791
791
  get rectOptions() {
792
792
  return optionsRef.current.rectOptions;
793
793
  },
794
+ get autoLayout() {
795
+ return optionsRef.current.autoLayout;
796
+ },
794
797
  onGuidesChange: setGuides
795
798
  }),
796
799
  []
@@ -891,19 +894,20 @@ function useCanvasScenes(options = {}) {
891
894
  }
892
895
 
893
896
  // src/canvas/CanvasGuidesLayer.tsx
894
- import { jsx as jsx2 } from "react/jsx-runtime";
897
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
895
898
  var DEFAULT_VIEWPORT = { x: 0, y: 0, zoom: 1 };
896
899
  function CanvasGuidesLayer({
897
900
  guides,
898
901
  viewport = DEFAULT_VIEWPORT,
899
902
  color = "#f59e0b",
900
903
  spacingColor = "#ec4899",
904
+ measureColor = "#ef4444",
901
905
  className = ""
902
906
  }) {
903
907
  if (!guides || guides.length === 0) return null;
904
908
  const sx = (x) => x * viewport.zoom + viewport.x;
905
909
  const sy = (y) => y * viewport.zoom + viewport.y;
906
- return /* @__PURE__ */ jsx2(
910
+ return /* @__PURE__ */ jsxs2(
907
911
  "svg",
908
912
  {
909
913
  className: `pixerate-canvas-guides ${className}`,
@@ -917,26 +921,141 @@ function CanvasGuidesLayer({
917
921
  zIndex: 10
918
922
  },
919
923
  "aria-hidden": "true",
920
- children: guides.map((guide, i) => /* @__PURE__ */ jsx2(
921
- "line",
922
- {
923
- "data-kind": guide.kind,
924
- x1: sx(guide.x1),
925
- y1: sy(guide.y1),
926
- x2: sx(guide.x2),
927
- y2: sy(guide.y2),
928
- stroke: guide.kind === "spacing" ? spacingColor : color,
929
- strokeWidth: 1,
930
- strokeDasharray: guide.kind === "centre" ? "4 3" : void 0,
931
- shapeRendering: "crispEdges"
932
- },
933
- i
934
- ))
924
+ children: [
925
+ guides.map((guide, i) => {
926
+ const measuring = guide.kind === "measure" || guide.kind === "extension";
927
+ return /* @__PURE__ */ jsx2(
928
+ "line",
929
+ {
930
+ "data-kind": guide.kind,
931
+ x1: sx(guide.x1),
932
+ y1: sy(guide.y1),
933
+ x2: sx(guide.x2),
934
+ y2: sy(guide.y2),
935
+ stroke: measuring ? measureColor : guide.kind === "spacing" ? spacingColor : color,
936
+ strokeWidth: 1,
937
+ strokeDasharray: guide.kind === "centre" ? "4 3" : guide.kind === "extension" ? "3 3" : void 0,
938
+ shapeRendering: "crispEdges"
939
+ },
940
+ i
941
+ );
942
+ }),
943
+ guides.map((guide, i) => {
944
+ if (!guide.label) return null;
945
+ const x = sx((guide.x1 + guide.x2) / 2);
946
+ const y = sy((guide.y1 + guide.y2) / 2);
947
+ const vertical = guide.orientation === "vertical";
948
+ const width = guide.label.length * 6.5 + 8;
949
+ return /* @__PURE__ */ jsxs2(
950
+ "g",
951
+ {
952
+ className: "pixerate-canvas-guides__label",
953
+ "data-label": guide.label,
954
+ transform: `translate(${vertical ? x + 4 : x - width / 2} ${vertical ? y - 8 : y + 4})`,
955
+ children: [
956
+ /* @__PURE__ */ jsx2("rect", { width, height: 16, rx: 3, fill: measureColor }),
957
+ /* @__PURE__ */ jsx2(
958
+ "text",
959
+ {
960
+ x: width / 2,
961
+ y: 11.5,
962
+ textAnchor: "middle",
963
+ fontSize: 11,
964
+ fontFamily: "system-ui, sans-serif",
965
+ fill: "#fff",
966
+ children: guide.label
967
+ }
968
+ )
969
+ ]
970
+ },
971
+ `label-${i}`
972
+ );
973
+ })
974
+ ]
935
975
  }
936
976
  );
937
977
  }
938
978
 
979
+ // src/canvas/useCanvasMeasure.ts
980
+ import { useCallback as useCallback7, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef7, useState as useState3 } from "react";
981
+ import {
982
+ isMeasureModifierHeld,
983
+ measureSelection
984
+ } from "@pixerate/editor/canvas";
985
+ var EMPTY = { guides: [], target: null, selection: null };
986
+ function useCanvasMeasure(options) {
987
+ const { nodes, enabled = true, requireModifier = true, targetElement, rectOptions } = options;
988
+ const [hoveredId, setHoveredId] = useState3(null);
989
+ const [modifier, setModifier] = useState3(false);
990
+ const optionsRef = useRef7(options);
991
+ optionsRef.current = options;
992
+ useEffect4(() => {
993
+ if (!enabled) return;
994
+ const target = targetElement ?? (typeof window !== "undefined" ? window : null);
995
+ if (!target) return;
996
+ const onKey = (event) => setModifier(isMeasureModifierHeld(event));
997
+ const onBlur = () => setModifier(false);
998
+ target.addEventListener("keydown", onKey);
999
+ target.addEventListener("keyup", onKey);
1000
+ const win = typeof window !== "undefined" ? window : null;
1001
+ win?.addEventListener("blur", onBlur);
1002
+ return () => {
1003
+ target.removeEventListener("keydown", onKey);
1004
+ target.removeEventListener("keyup", onKey);
1005
+ win?.removeEventListener("blur", onBlur);
1006
+ };
1007
+ }, [enabled, targetElement]);
1008
+ const active = enabled && (!requireModifier || modifier);
1009
+ const result = useMemo3(() => {
1010
+ if (!active) return EMPTY;
1011
+ const ids = optionsRef.current.getSelectedIds?.() ?? nodes.filter((n) => n.selected).map((n) => n.id);
1012
+ return measureSelection(nodes, ids, hoveredId, rectOptions);
1013
+ }, [active, nodes, hoveredId, rectOptions]);
1014
+ const onNodeMouseEnter = useCallback7((event, node) => {
1015
+ setHoveredId(node.id);
1016
+ if (event && typeof event.altKey === "boolean") setModifier(event.altKey);
1017
+ }, []);
1018
+ const onNodeMouseLeave = useCallback7((_event, node) => {
1019
+ setHoveredId((current) => current === node.id ? null : current);
1020
+ }, []);
1021
+ return {
1022
+ /** Measuring lines (flow coordinates) to pass to `<CanvasGuidesLayer>`. */
1023
+ guides: result.guides,
1024
+ /** The box measured to (outline it), or `null`. */
1025
+ target: result.target,
1026
+ /** Whether measuring is showing (enabled and Alt held, unless `requireModifier: false`). */
1027
+ active,
1028
+ hoveredId,
1029
+ setHoveredId,
1030
+ /** Sets the modifier state by hand (e.g. from a toolbar toggle). */
1031
+ setModifier,
1032
+ onNodeMouseEnter,
1033
+ onNodeMouseLeave
1034
+ };
1035
+ }
1036
+
939
1037
  // src/canvas/index.ts
1038
+ import {
1039
+ measureBetween,
1040
+ measureToLine,
1041
+ measureSelection as measureSelection2,
1042
+ measureLabel,
1043
+ isMeasureModifierHeld as isMeasureModifierHeld2,
1044
+ snapToGrid,
1045
+ snapResize,
1046
+ snapNodeResize,
1047
+ inferResizeHandle,
1048
+ resizeHandleAxes,
1049
+ getResizingNodeRect,
1050
+ RESIZE_HANDLES,
1051
+ fitCubics,
1052
+ fitCubicRun,
1053
+ fitPathData,
1054
+ fitFreehandPath,
1055
+ cubicsToPathData,
1056
+ cubicPointAt,
1057
+ isStraightCubic
1058
+ } from "@pixerate/editor/canvas";
940
1059
  import {
941
1060
  alignNodes,
942
1061
  distributeNodes,
@@ -975,12 +1094,12 @@ import {
975
1094
 
976
1095
  // src/canvas/ShapeNode.tsx
977
1096
  import { getShapeRenderData, isShapeDescription } from "@pixerate/editor/canvas";
978
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1097
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
979
1098
  function ShapeNode({ data, width, height, selected, className = "", children }) {
980
1099
  const shape = data?.shape;
981
1100
  if (!isShapeDescription(shape)) return null;
982
1101
  const render = getShapeRenderData(shape, { width, height });
983
- return /* @__PURE__ */ jsxs2(
1102
+ return /* @__PURE__ */ jsxs3(
984
1103
  "div",
985
1104
  {
986
1105
  className: `pixerate-shape-node ${className}`.trim(),
@@ -1087,19 +1206,100 @@ import {
1087
1206
  blendLayout,
1088
1207
  connectedOnly
1089
1208
  } from "@pixerate/editor/canvas";
1209
+ import {
1210
+ layoutFrame,
1211
+ layoutAll,
1212
+ layoutUp,
1213
+ layoutUpMany,
1214
+ applyConstraints,
1215
+ getAutoLayout,
1216
+ getChildLayout,
1217
+ getLayoutSizing,
1218
+ getAutoLayoutGrid,
1219
+ getAutoLayoutInsertTarget,
1220
+ getFlowChildren,
1221
+ getLayoutParent,
1222
+ isAutoLayoutFrame,
1223
+ makeSizingCoherent,
1224
+ moveLayoutChild,
1225
+ mergeNodeUpdates,
1226
+ relayoutUpdates,
1227
+ resolvePadding,
1228
+ clampLayoutSize,
1229
+ createCanvasAutoLayoutController as createCanvasAutoLayoutController2,
1230
+ AUTO_LAYOUT_DATA_KEY,
1231
+ CHILD_LAYOUT_DATA_KEY
1232
+ } from "@pixerate/editor/canvas";
1233
+
1234
+ // src/canvas/useCanvasAutoLayout.ts
1235
+ import { useLayoutEffect, useMemo as useMemo4, useRef as useRef8, useState as useState4 } from "react";
1236
+ import {
1237
+ createCanvasAutoLayoutController
1238
+ } from "@pixerate/editor/canvas";
1239
+ function useCanvasAutoLayout(options) {
1240
+ const [guides, setGuides] = useState4([]);
1241
+ const nodesRef = useRef8(options.nodes);
1242
+ nodesRef.current = options.nodes;
1243
+ const optionsRef = useRef8(options);
1244
+ optionsRef.current = options;
1245
+ const controller = useMemo4(
1246
+ () => createCanvasAutoLayoutController({
1247
+ getNodes: () => nodesRef.current,
1248
+ setNodes: (next) => {
1249
+ nodesRef.current = next;
1250
+ optionsRef.current.setNodes(next);
1251
+ },
1252
+ get history() {
1253
+ return optionsRef.current.history;
1254
+ },
1255
+ get enabled() {
1256
+ return optionsRef.current.enabled;
1257
+ },
1258
+ get dragReorder() {
1259
+ return optionsRef.current.dragReorder;
1260
+ },
1261
+ get measure() {
1262
+ return optionsRef.current.measure;
1263
+ },
1264
+ get rectOptions() {
1265
+ return optionsRef.current.rectOptions;
1266
+ },
1267
+ onGuidesChange: setGuides
1268
+ }),
1269
+ []
1270
+ );
1271
+ useLayoutEffect(() => {
1272
+ if (controller.hasPending) controller.flush();
1273
+ }, [options.nodes, controller]);
1274
+ return useMemo4(
1275
+ () => ({
1276
+ ...controller,
1277
+ /** Drop marker of the active reorder drag (flow coordinates). */
1278
+ guides,
1279
+ get hasPending() {
1280
+ return controller.hasPending;
1281
+ }
1282
+ }),
1283
+ [controller, guides]
1284
+ );
1285
+ }
1090
1286
  export {
1287
+ AUTO_LAYOUT_DATA_KEY,
1091
1288
  AgentPresenceLayer,
1289
+ CHILD_LAYOUT_DATA_KEY,
1092
1290
  CONNECTION_LINE_TYPES,
1093
1291
  CanvasGuidesLayer,
1094
1292
  CanvasScenesStore2 as CanvasScenesStore,
1095
1293
  DEFAULT_ARRANGE_SHORTCUTS,
1096
1294
  ManualClock,
1295
+ RESIZE_HANDLES,
1097
1296
  SHAPE_DATA_KEY,
1098
1297
  SHAPE_KINDS,
1099
1298
  SHAPE_NODE_TYPE,
1100
1299
  SHAPE_OPERATIONS,
1101
1300
  ShapeNode,
1102
1301
  alignNodes,
1302
+ applyConstraints,
1103
1303
  applyNodeUpdates,
1104
1304
  applyShapeCombination,
1105
1305
  blendLayout,
@@ -1110,15 +1310,19 @@ export {
1110
1310
  canvasHeight,
1111
1311
  centerNodes2 as centerNodes,
1112
1312
  centre,
1313
+ clampLayoutSize,
1113
1314
  combineShapeNodes,
1114
1315
  computeNodesBoundingBox,
1115
1316
  computeSnapGuides,
1116
1317
  connectedOnly,
1117
1318
  createBezierTrajectory,
1319
+ createCanvasAutoLayoutController2 as createCanvasAutoLayoutController,
1118
1320
  createCanvasScenesStore,
1119
1321
  createFanOutTrajectory2 as createFanOutTrajectory,
1120
1322
  createGuideIndex,
1121
1323
  createNodeGuideIndex,
1324
+ cubicPointAt,
1325
+ cubicsToPathData,
1122
1326
  defaultEasing,
1123
1327
  distributeNodes,
1124
1328
  dividePolygons,
@@ -1126,33 +1330,60 @@ export {
1126
1330
  estimateCanvasHeight,
1127
1331
  estimateNodeSize,
1128
1332
  findConnectorSnap,
1333
+ fitCubicRun,
1334
+ fitCubics,
1335
+ fitFreehandPath,
1336
+ fitPathData,
1129
1337
  fitViewportToNodes2 as fitViewportToNodes,
1130
1338
  fitViewportToRect,
1131
1339
  flattenSvgPath,
1132
1340
  flowSide,
1133
1341
  getAbsolutePosition,
1342
+ getAutoLayout,
1343
+ getAutoLayoutGrid,
1344
+ getAutoLayoutInsertTarget,
1134
1345
  getCenteredNodePosition2 as getCenteredNodePosition,
1346
+ getChildLayout,
1347
+ getFlowChildren,
1348
+ getLayoutParent,
1349
+ getLayoutSizing,
1135
1350
  getLayoutedNodes2 as getLayoutedNodes,
1136
1351
  getNodeRect,
1137
1352
  getNodeShape,
1138
1353
  getNodeSize,
1354
+ getResizingNodeRect,
1139
1355
  getShapeRenderData2 as getShapeRenderData,
1140
1356
  getShapeSvg,
1141
1357
  handlePoint,
1358
+ inferResizeHandle,
1142
1359
  intersectPolygons,
1143
1360
  invertNodeUpdates,
1361
+ isAutoLayoutFrame,
1144
1362
  isEventFromTextInput3 as isEventFromTextInput,
1145
1363
  isLocked,
1364
+ isMeasureModifierHeld2 as isMeasureModifierHeld,
1146
1365
  isShapeDescription2 as isShapeDescription,
1147
1366
  isShapeNode,
1367
+ isStraightCubic,
1148
1368
  isValidCanvasNode,
1149
1369
  isValidUrl2 as isValidUrl,
1370
+ layoutAll,
1150
1371
  layoutBounds,
1372
+ layoutFrame,
1373
+ layoutUp,
1374
+ layoutUpMany,
1151
1375
  linearPositionTrajectory2 as linearPositionTrajectory,
1152
1376
  linearTrajectory,
1153
1377
  lockNodes,
1378
+ makeSizingCoherent,
1154
1379
  matchArrangeShortcut2 as matchArrangeShortcut,
1155
1380
  matchSize,
1381
+ measureBetween,
1382
+ measureLabel,
1383
+ measureSelection2 as measureSelection,
1384
+ measureToLine,
1385
+ mergeNodeUpdates,
1386
+ moveLayoutChild,
1156
1387
  multiPolygonArea,
1157
1388
  multiPolygonBounds,
1158
1389
  nearestHandlePositions,
@@ -1170,9 +1401,12 @@ export {
1170
1401
  positionToSide,
1171
1402
  readStyleSize,
1172
1403
  realClock,
1404
+ relayoutUpdates,
1173
1405
  remapPastedNodes2 as remapPastedNodes,
1174
1406
  reorderNodes,
1175
1407
  repositionNodesTo,
1408
+ resizeHandleAxes,
1409
+ resolvePadding,
1176
1410
  revertShapeCombination,
1177
1411
  ringSignedArea,
1178
1412
  runMultiNodeTransition2 as runMultiNodeTransition,
@@ -1182,17 +1416,22 @@ export {
1182
1416
  sideToPosition,
1183
1417
  simplifyRing,
1184
1418
  snapNodeDrag,
1419
+ snapNodeResize,
1420
+ snapResize,
1421
+ snapToGrid,
1185
1422
  subtractPolygons,
1186
1423
  toggleLockNodes,
1187
1424
  unionPolygons,
1188
1425
  unlockNodes,
1189
1426
  useCanvasArrange,
1190
1427
  useCanvasArrangeShortcuts,
1428
+ useCanvasAutoLayout,
1191
1429
  useCanvasClipboard,
1192
1430
  useCanvasDocking,
1193
1431
  useCanvasExplosion,
1194
1432
  useCanvasGraph,
1195
1433
  useCanvasLayout,
1434
+ useCanvasMeasure,
1196
1435
  useCanvasScenes,
1197
1436
  useCanvasShortcuts,
1198
1437
  useStreamingCanvas,