@pyreon/flow 0.11.5 → 0.11.6

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.
@@ -16,7 +16,7 @@ interface Viewport {
16
16
  y: number;
17
17
  zoom: number;
18
18
  }
19
- type HandleType = "source" | "target";
19
+ type HandleType = 'source' | 'target';
20
20
  declare enum Position {
21
21
  Top = "top",
22
22
  Right = "right",
@@ -54,7 +54,7 @@ interface FlowNode<TData = Record<string, unknown>> {
54
54
  /** Whether this node is a group */
55
55
  group?: boolean;
56
56
  }
57
- type EdgeType = "bezier" | "smoothstep" | "straight" | "step";
57
+ type EdgeType = 'bezier' | 'smoothstep' | 'straight' | 'step';
58
58
  interface FlowEdge {
59
59
  id?: string;
60
60
  source: string;
@@ -81,19 +81,19 @@ type ConnectionRule = Record<string, {
81
81
  outputs: string[];
82
82
  }>;
83
83
  type NodeChange = {
84
- type: "position";
84
+ type: 'position';
85
85
  id: string;
86
86
  position: XYPosition;
87
87
  } | {
88
- type: "dimensions";
88
+ type: 'dimensions';
89
89
  id: string;
90
90
  dimensions: Dimensions;
91
91
  } | {
92
- type: "select";
92
+ type: 'select';
93
93
  id: string;
94
94
  selected: boolean;
95
95
  } | {
96
- type: "remove";
96
+ type: 'remove';
97
97
  id: string;
98
98
  };
99
99
  interface EdgePathResult {
@@ -297,16 +297,16 @@ interface FlowInstance {
297
297
  /** Dispose all listeners and clean up */
298
298
  dispose: () => void;
299
299
  }
300
- type LayoutAlgorithm = "layered" | "force" | "stress" | "tree" | "radial" | "box" | "rectpacking";
300
+ type LayoutAlgorithm = 'layered' | 'force' | 'stress' | 'tree' | 'radial' | 'box' | 'rectpacking';
301
301
  interface LayoutOptions {
302
302
  /** Layout direction — default: 'DOWN' */
303
- direction?: "UP" | "DOWN" | "LEFT" | "RIGHT";
303
+ direction?: 'UP' | 'DOWN' | 'LEFT' | 'RIGHT';
304
304
  /** Spacing between nodes — default: 50 */
305
305
  nodeSpacing?: number;
306
306
  /** Spacing between layers — default: 80 */
307
307
  layerSpacing?: number;
308
308
  /** Edge routing — default: 'orthogonal' */
309
- edgeRouting?: "orthogonal" | "splines" | "polyline";
309
+ edgeRouting?: 'orthogonal' | 'splines' | 'polyline';
310
310
  /** Whether to animate the layout transition — default: true */
311
311
  animate?: boolean;
312
312
  /** Animation duration in ms — default: 300 */
@@ -319,7 +319,7 @@ interface FlowProps {
319
319
  children?: VNodeChild;
320
320
  }
321
321
  interface BackgroundProps {
322
- variant?: "dots" | "lines" | "cross";
322
+ variant?: 'dots' | 'lines' | 'cross';
323
323
  gap?: number;
324
324
  size?: number;
325
325
  color?: string;
@@ -337,10 +337,10 @@ interface ControlsProps {
337
337
  showZoomOut?: boolean;
338
338
  showFitView?: boolean;
339
339
  showLock?: boolean;
340
- position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
340
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
341
341
  }
342
342
  interface PanelProps {
343
- position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
343
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
344
344
  style?: string;
345
345
  class?: string;
346
346
  children?: VNodeChild;
@@ -503,7 +503,7 @@ declare function NodeResizer(props: NodeResizerProps): VNodeChild;
503
503
  //#region src/components/node-toolbar.d.ts
504
504
  interface NodeToolbarProps {
505
505
  /** Position relative to node — default: 'top' */
506
- position?: "top" | "bottom" | "left" | "right";
506
+ position?: 'top' | 'bottom' | 'left' | 'right';
507
507
  /** Offset from node in px — default: 8 */
508
508
  offset?: number;
509
509
  /** Only show when node is selected — default: true */
package/package.json CHANGED
@@ -1,20 +1,17 @@
1
1
  {
2
2
  "name": "@pyreon/flow",
3
- "version": "0.11.5",
3
+ "version": "0.11.6",
4
4
  "description": "Reactive flow diagrams for Pyreon — signal-native nodes, edges, pan/zoom, auto-layout",
5
+ "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/flow#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/pyreon/pyreon/issues"
8
+ },
5
9
  "license": "MIT",
6
10
  "repository": {
7
11
  "type": "git",
8
12
  "url": "https://github.com/pyreon/pyreon.git",
9
13
  "directory": "packages/fundamentals/flow"
10
14
  },
11
- "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/flow#readme",
12
- "bugs": {
13
- "url": "https://github.com/pyreon/pyreon/issues"
14
- },
15
- "publishConfig": {
16
- "access": "public"
17
- },
18
15
  "files": [
19
16
  "lib",
20
17
  "src",
@@ -22,6 +19,7 @@
22
19
  "LICENSE"
23
20
  ],
24
21
  "type": "module",
22
+ "sideEffects": false,
25
23
  "main": "./lib/index.js",
26
24
  "module": "./lib/index.js",
27
25
  "types": "./lib/types/index.d.ts",
@@ -32,25 +30,27 @@
32
30
  "types": "./lib/types/index.d.ts"
33
31
  }
34
32
  },
35
- "sideEffects": false,
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
36
  "scripts": {
37
37
  "build": "vl_rolldown_build",
38
38
  "dev": "vl_rolldown_build-watch",
39
39
  "test": "vitest run",
40
40
  "typecheck": "tsc --noEmit",
41
- "lint": "biome check ."
41
+ "lint": "oxlint ."
42
42
  },
43
43
  "dependencies": {
44
44
  "elkjs": "^0.9.3"
45
45
  },
46
- "peerDependencies": {
47
- "@pyreon/core": "^0.11.5",
48
- "@pyreon/reactivity": "^0.11.5"
49
- },
50
46
  "devDependencies": {
51
47
  "@happy-dom/global-registrator": "^20.8.3",
52
- "@pyreon/core": "^0.11.5",
53
- "@pyreon/reactivity": "^0.11.5",
48
+ "@pyreon/core": "^0.11.6",
49
+ "@pyreon/reactivity": "^0.11.6",
54
50
  "@vitus-labs/tools-lint": "^1.11.0"
51
+ },
52
+ "peerDependencies": {
53
+ "@pyreon/core": "^0.11.6",
54
+ "@pyreon/reactivity": "^0.11.6"
55
55
  }
56
56
  }
@@ -1,5 +1,5 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import type { BackgroundProps } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import type { BackgroundProps } from '../types'
3
3
 
4
4
  /**
5
5
  * Background pattern for the flow canvas.
@@ -13,11 +13,11 @@ import type { BackgroundProps } from "../types"
13
13
  * ```
14
14
  */
15
15
  export function Background(props: BackgroundProps): VNodeChild {
16
- const { variant = "dots", gap = 20, size = 1, color = "#ddd" } = props
16
+ const { variant = 'dots', gap = 20, size = 1, color = '#ddd' } = props
17
17
 
18
18
  const patternId = `flow-bg-${variant}`
19
19
 
20
- if (variant === "dots") {
20
+ if (variant === 'dots') {
21
21
  return (
22
22
  <svg
23
23
  role="img"
@@ -32,7 +32,7 @@ export function Background(props: BackgroundProps): VNodeChild {
32
32
  y="0"
33
33
  width={String(gap)}
34
34
  height={String(gap)}
35
- {...{ patternUnits: "userSpaceOnUse" }}
35
+ {...{ patternUnits: 'userSpaceOnUse' }}
36
36
  >
37
37
  <circle cx={String(size)} cy={String(size)} r={String(size)} fill={color} />
38
38
  </pattern>
@@ -42,7 +42,7 @@ export function Background(props: BackgroundProps): VNodeChild {
42
42
  )
43
43
  }
44
44
 
45
- if (variant === "lines") {
45
+ if (variant === 'lines') {
46
46
  return (
47
47
  <svg
48
48
  role="img"
@@ -57,7 +57,7 @@ export function Background(props: BackgroundProps): VNodeChild {
57
57
  y="0"
58
58
  width={String(gap)}
59
59
  height={String(gap)}
60
- {...{ patternUnits: "userSpaceOnUse" }}
60
+ {...{ patternUnits: 'userSpaceOnUse' }}
61
61
  >
62
62
  <line
63
63
  x1="0"
@@ -97,7 +97,7 @@ export function Background(props: BackgroundProps): VNodeChild {
97
97
  y="0"
98
98
  width={String(gap)}
99
99
  height={String(gap)}
100
- {...{ patternUnits: "userSpaceOnUse" }}
100
+ {...{ patternUnits: 'userSpaceOnUse' }}
101
101
  >
102
102
  <line
103
103
  x1={String(gap / 2 - size * 2)}
@@ -1,11 +1,11 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import type { ControlsProps, FlowInstance } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import type { ControlsProps, FlowInstance } from '../types'
3
3
 
4
4
  const positionStyles: Record<string, string> = {
5
- "top-left": "top: 10px; left: 10px;",
6
- "top-right": "top: 10px; right: 10px;",
7
- "bottom-left": "bottom: 10px; left: 10px;",
8
- "bottom-right": "bottom: 10px; right: 10px;",
5
+ 'top-left': 'top: 10px; left: 10px;',
6
+ 'top-right': 'top: 10px; right: 10px;',
7
+ 'bottom-left': 'bottom: 10px; left: 10px;',
8
+ 'bottom-right': 'bottom: 10px; right: 10px;',
9
9
  }
10
10
 
11
11
  // Simple SVG icons
@@ -86,15 +86,15 @@ export function Controls(props: ControlsProps & { instance?: FlowInstance }): VN
86
86
  showZoomOut = true,
87
87
  showFitView = true,
88
88
  showLock = false,
89
- position = "bottom-left",
89
+ position = 'bottom-left',
90
90
  instance,
91
91
  } = props
92
92
 
93
93
  if (!instance) return null
94
94
 
95
- const baseStyle = `position: absolute; ${positionStyles[position] ?? positionStyles["bottom-left"]} display: flex; flex-direction: column; gap: 2px; z-index: 5; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 2px; box-shadow: 0 1px 4px rgba(0,0,0,0.08);`
95
+ const baseStyle = `position: absolute; ${positionStyles[position] ?? positionStyles['bottom-left']} display: flex; flex-direction: column; gap: 2px; z-index: 5; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 2px; box-shadow: 0 1px 4px rgba(0,0,0,0.08);`
96
96
  const btnStyle =
97
- "width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border: none; background: transparent; border-radius: 4px; cursor: pointer; color: #555; padding: 0;"
97
+ 'width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border: none; background: transparent; border-radius: 4px; cursor: pointer; color: #555; padding: 0;'
98
98
 
99
99
  return () => {
100
100
  const zoomPercent = Math.round(instance.zoom() * 100)
@@ -1,8 +1,8 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import { signal } from "@pyreon/reactivity"
3
- import { getEdgePath, getHandlePosition, getSmartHandlePositions, getWaypointPath } from "../edges"
4
- import type { Connection, FlowInstance, FlowNode, NodeComponentProps } from "../types"
5
- import { Position } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import { signal } from '@pyreon/reactivity'
3
+ import { getEdgePath, getHandlePosition, getSmartHandlePositions, getWaypointPath } from '../edges'
4
+ import type { Connection, FlowInstance, FlowNode, NodeComponentProps } from '../types'
5
+ import { Position } from '../types'
6
6
 
7
7
  // ─── Node type registry ──────────────────────────────────────────────────────
8
8
 
@@ -12,8 +12,8 @@ type NodeTypeMap = Record<string, (props: NodeComponentProps<any>) => VNodeChild
12
12
  * Default node renderer — simple labeled box.
13
13
  */
14
14
  function DefaultNode(props: NodeComponentProps) {
15
- const borderColor = props.selected ? "#3b82f6" : "#ddd"
16
- const cursor = props.dragging ? "grabbing" : "grab"
15
+ const borderColor = props.selected ? '#3b82f6' : '#ddd'
16
+ const cursor = props.dragging ? 'grabbing' : 'grab'
17
17
  return (
18
18
  <div
19
19
  style={`padding: 8px 16px; background: white; border: 2px solid ${borderColor}; border-radius: 6px; font-size: 13px; min-width: 80px; text-align: center; cursor: ${cursor}; user-select: none;`}
@@ -38,8 +38,8 @@ interface ConnectionState {
38
38
 
39
39
  const emptyConnection: ConnectionState = {
40
40
  active: false,
41
- sourceNodeId: "",
42
- sourceHandleId: "",
41
+ sourceNodeId: '',
42
+ sourceHandleId: '',
43
43
  sourcePosition: Position.Right,
44
44
  sourceX: 0,
45
45
  sourceY: 0,
@@ -78,7 +78,7 @@ interface DragState {
78
78
 
79
79
  const emptyDrag: DragState = {
80
80
  active: false,
81
- nodeId: "",
81
+ nodeId: '',
82
82
  startX: 0,
83
83
  startY: 0,
84
84
  startPositions: new Map(),
@@ -110,11 +110,11 @@ function EdgeLayer(props: {
110
110
  <marker
111
111
  id="flow-arrowhead"
112
112
  {...{
113
- markerWidth: "10",
114
- markerHeight: "7",
115
- refX: "10",
116
- refY: "3.5",
117
- orient: "auto",
113
+ markerWidth: '10',
114
+ markerHeight: '7',
115
+ refX: '10',
116
+ refY: '3.5',
117
+ orient: 'auto',
118
118
  }}
119
119
  >
120
120
  <polygon points="0 0, 10 3.5, 0 7" fill="#999" />
@@ -156,7 +156,7 @@ function EdgeLayer(props: {
156
156
  waypoints: edge.waypoints,
157
157
  })
158
158
  : getEdgePath(
159
- edge.type ?? "bezier",
159
+ edge.type ?? 'bezier',
160
160
  sourcePos.x,
161
161
  sourcePos.y,
162
162
  sourcePosition,
@@ -190,11 +190,11 @@ function EdgeLayer(props: {
190
190
  <path
191
191
  d={path}
192
192
  fill="none"
193
- stroke={isSelected ? "#3b82f6" : "#999"}
194
- stroke-width={isSelected ? "2" : "1.5"}
193
+ stroke={isSelected ? '#3b82f6' : '#999'}
194
+ stroke-width={isSelected ? '2' : '1.5'}
195
195
  marker-end="url(#flow-arrowhead)"
196
- class={edge.animated ? "pyreon-flow-edge-animated" : ""}
197
- style={`pointer-events: stroke; cursor: pointer; ${edge.style ?? ""}`}
196
+ class={edge.animated ? 'pyreon-flow-edge-animated' : ''}
197
+ style={`pointer-events: stroke; cursor: pointer; ${edge.style ?? ''}`}
198
198
  onClick={() => {
199
199
  if (edge.id) instance.selectEdge(edge.id)
200
200
  instance._emit.edgeClick(edge)
@@ -218,7 +218,7 @@ function EdgeLayer(props: {
218
218
  <path
219
219
  d={
220
220
  getEdgePath(
221
- "bezier",
221
+ 'bezier',
222
222
  conn.sourceX,
223
223
  conn.sourceY,
224
224
  conn.sourcePosition,
@@ -270,8 +270,8 @@ function NodeLayer(props: {
270
270
  return (
271
271
  <div
272
272
  key={node.id}
273
- class={`pyreon-flow-node ${node.class ?? ""} ${isSelected ? "selected" : ""} ${isDragging ? "dragging" : ""}`}
274
- style={`position: absolute; transform: translate(${node.position.x}px, ${node.position.y}px); z-index: ${isDragging ? 1000 : isSelected ? 100 : 0}; ${node.style ?? ""}`}
273
+ class={`pyreon-flow-node ${node.class ?? ''} ${isSelected ? 'selected' : ''} ${isDragging ? 'dragging' : ''}`}
274
+ style={`position: absolute; transform: translate(${node.position.x}px, ${node.position.y}px); z-index: ${isDragging ? 1000 : isSelected ? 100 : 0}; ${node.style ?? ''}`}
275
275
  data-nodeid={node.id}
276
276
  onClick={(e: MouseEvent) => {
277
277
  e.stopPropagation()
@@ -285,12 +285,12 @@ function NodeLayer(props: {
285
285
  onPointerDown={(e: PointerEvent) => {
286
286
  // Check if clicking a handle
287
287
  const target = e.target as HTMLElement
288
- const handle = target.closest(".pyreon-flow-handle")
288
+ const handle = target.closest('.pyreon-flow-handle')
289
289
  if (handle) {
290
- const hType = handle.getAttribute("data-handletype") ?? "source"
291
- const hId = handle.getAttribute("data-handleid") ?? "source"
290
+ const hType = handle.getAttribute('data-handletype') ?? 'source'
291
+ const hId = handle.getAttribute('data-handleid') ?? 'source'
292
292
  const hPos =
293
- (handle.getAttribute("data-handleposition") as Position) ?? Position.Right
293
+ (handle.getAttribute('data-handleposition') as Position) ?? Position.Right
294
294
  onHandlePointerDown(e, node.id, hType, hId, hPos)
295
295
  return
296
296
  }
@@ -319,7 +319,7 @@ function NodeLayer(props: {
319
319
  type EdgeTypeMap = Record<
320
320
  string,
321
321
  (props: {
322
- edge: import("../types").FlowEdge
322
+ edge: import('../types').FlowEdge
323
323
  sourceX: number
324
324
  sourceY: number
325
325
  targetX: number
@@ -378,7 +378,7 @@ export function Flow(props: FlowComponentProps): VNodeChild {
378
378
  y: null,
379
379
  })
380
380
 
381
- const draggingNodeId = () => (dragState().active ? dragState().nodeId : "")
381
+ const draggingNodeId = () => (dragState().active ? dragState().nodeId : '')
382
382
 
383
383
  // ── Node dragging ──────────────────────────────────────────────────────
384
384
 
@@ -416,7 +416,7 @@ export function Flow(props: FlowComponentProps): VNodeChild {
416
416
 
417
417
  instance._emit.nodeDragStart(node)
418
418
 
419
- const container = (e.currentTarget as HTMLElement).closest(".pyreon-flow") as HTMLElement
419
+ const container = (e.currentTarget as HTMLElement).closest('.pyreon-flow') as HTMLElement
420
420
  if (container) container.setPointerCapture(e.pointerId)
421
421
  }
422
422
 
@@ -450,7 +450,7 @@ export function Flow(props: FlowComponentProps): VNodeChild {
450
450
  currentY: handlePos.y,
451
451
  })
452
452
 
453
- const container = (e.target as HTMLElement).closest(".pyreon-flow") as HTMLElement
453
+ const container = (e.target as HTMLElement).closest('.pyreon-flow') as HTMLElement
454
454
  if (container) container.setPointerCapture(e.pointerId)
455
455
  }
456
456
 
@@ -491,8 +491,8 @@ export function Flow(props: FlowComponentProps): VNodeChild {
491
491
  if (instance.config.pannable === false) return
492
492
 
493
493
  const target = e.target as HTMLElement
494
- if (target.closest(".pyreon-flow-node")) return
495
- if (target.closest(".pyreon-flow-handle")) return
494
+ if (target.closest('.pyreon-flow-node')) return
495
+ if (target.closest('.pyreon-flow-handle')) return
496
496
 
497
497
  // Shift+drag on empty space → selection box
498
498
  if (e.shiftKey && instance.config.multiSelect !== false) {
@@ -637,10 +637,10 @@ export function Flow(props: FlowComponentProps): VNodeChild {
637
637
  if (conn.active) {
638
638
  // Check if we released over a handle target
639
639
  const target = e.target as HTMLElement
640
- const handle = target.closest(".pyreon-flow-handle")
640
+ const handle = target.closest('.pyreon-flow-handle')
641
641
  if (handle) {
642
- const targetNodeId = handle.closest(".pyreon-flow-node")?.getAttribute("data-nodeid") ?? ""
643
- const targetHandleId = handle.getAttribute("data-handleid") ?? "target"
642
+ const targetNodeId = handle.closest('.pyreon-flow-node')?.getAttribute('data-nodeid') ?? ''
643
+ const targetHandleId = handle.getAttribute('data-handleid') ?? 'target'
644
644
 
645
645
  if (targetNodeId && targetNodeId !== conn.sourceNodeId) {
646
646
  const connection: Connection = {
@@ -670,31 +670,31 @@ export function Flow(props: FlowComponentProps): VNodeChild {
670
670
  // ── Keyboard ───────────────────────────────────────────────────────────
671
671
 
672
672
  const handleKeyDown = (e: KeyboardEvent) => {
673
- if (e.key === "Delete" || e.key === "Backspace") {
673
+ if (e.key === 'Delete' || e.key === 'Backspace') {
674
674
  const target = e.target as HTMLElement
675
- if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") return
675
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') return
676
676
  instance.pushHistory()
677
677
  instance.deleteSelected()
678
678
  }
679
- if (e.key === "Escape") {
679
+ if (e.key === 'Escape') {
680
680
  instance.clearSelection()
681
681
  connectionState.set({ ...emptyConnection })
682
682
  }
683
- if (e.key === "a" && (e.metaKey || e.ctrlKey)) {
683
+ if (e.key === 'a' && (e.metaKey || e.ctrlKey)) {
684
684
  e.preventDefault()
685
685
  instance.selectAll()
686
686
  }
687
- if (e.key === "c" && (e.metaKey || e.ctrlKey)) {
687
+ if (e.key === 'c' && (e.metaKey || e.ctrlKey)) {
688
688
  instance.copySelected()
689
689
  }
690
- if (e.key === "v" && (e.metaKey || e.ctrlKey)) {
690
+ if (e.key === 'v' && (e.metaKey || e.ctrlKey)) {
691
691
  instance.paste()
692
692
  }
693
- if (e.key === "z" && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
693
+ if (e.key === 'z' && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
694
694
  e.preventDefault()
695
695
  instance.undo()
696
696
  }
697
- if (e.key === "z" && (e.metaKey || e.ctrlKey) && e.shiftKey) {
697
+ if (e.key === 'z' && (e.metaKey || e.ctrlKey) && e.shiftKey) {
698
698
  e.preventDefault()
699
699
  instance.redo()
700
700
  }
@@ -780,12 +780,12 @@ export function Flow(props: FlowComponentProps): VNodeChild {
780
780
  resizeObserver.observe(el)
781
781
  }
782
782
 
783
- const containerStyle = `position: relative; width: 100%; height: 100%; overflow: hidden; outline: none; touch-action: none; ${props.style ?? ""}`
783
+ const containerStyle = `position: relative; width: 100%; height: 100%; overflow: hidden; outline: none; touch-action: none; ${props.style ?? ''}`
784
784
 
785
785
  return (
786
786
  <div
787
787
  ref={containerRef}
788
- class={`pyreon-flow ${props.class ?? ""}`}
788
+ class={`pyreon-flow ${props.class ?? ''}`}
789
789
  style={containerStyle}
790
790
  tabIndex={0}
791
791
  onWheel={handleWheel}
@@ -1,11 +1,11 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import type { HandleProps } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import type { HandleProps } from '../types'
3
3
 
4
4
  const positionOffset: Record<string, string> = {
5
- top: "top: -4px; left: 50%; transform: translateX(-50%);",
6
- right: "right: -4px; top: 50%; transform: translateY(-50%);",
7
- bottom: "bottom: -4px; left: 50%; transform: translateX(-50%);",
8
- left: "left: -4px; top: 50%; transform: translateY(-50%);",
5
+ top: 'top: -4px; left: 50%; transform: translateX(-50%);',
6
+ right: 'right: -4px; top: 50%; transform: translateY(-50%);',
7
+ bottom: 'bottom: -4px; left: 50%; transform: translateX(-50%);',
8
+ left: 'left: -4px; top: 50%; transform: translateY(-50%);',
9
9
  }
10
10
 
11
11
  /**
@@ -26,13 +26,13 @@ const positionOffset: Record<string, string> = {
26
26
  * ```
27
27
  */
28
28
  export function Handle(props: HandleProps): VNodeChild {
29
- const { type, position, id, style = "" } = props
29
+ const { type, position, id, style = '' } = props
30
30
  const posStyle = positionOffset[position] ?? positionOffset.bottom
31
31
  const baseStyle = `position: absolute; ${posStyle} width: 8px; height: 8px; background: #555; border: 2px solid white; border-radius: 50%; cursor: crosshair; z-index: 1; ${style}`
32
32
 
33
33
  return (
34
34
  <div
35
- class={`pyreon-flow-handle pyreon-flow-handle-${type} ${props.class ?? ""}`}
35
+ class={`pyreon-flow-handle pyreon-flow-handle-${type} ${props.class ?? ''}`}
36
36
  style={baseStyle}
37
37
  data-handletype={type}
38
38
  data-handleid={id ?? type}
@@ -1,5 +1,5 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import type { FlowInstance, MiniMapProps } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import type { FlowInstance, MiniMapProps } from '../types'
3
3
 
4
4
  /**
5
5
  * Miniature overview of the flow diagram showing all nodes
@@ -16,8 +16,8 @@ export function MiniMap(props: MiniMapProps & { instance?: FlowInstance }): VNod
16
16
  const {
17
17
  width = 200,
18
18
  height = 150,
19
- nodeColor = "#e2e8f0",
20
- maskColor = "rgba(0, 0, 0, 0.08)",
19
+ nodeColor = '#e2e8f0',
20
+ maskColor = 'rgba(0, 0, 0, 0.08)',
21
21
  instance,
22
22
  } = props
23
23
 
@@ -86,7 +86,7 @@ export function MiniMap(props: MiniMapProps & { instance?: FlowInstance }): VNod
86
86
  const h = (node.height ?? 40) * scale
87
87
  const x = (node.position.x - minX + padding) * scale
88
88
  const y = (node.position.y - minY + padding) * scale
89
- const color = typeof nodeColor === "function" ? nodeColor(node) : nodeColor
89
+ const color = typeof nodeColor === 'function' ? nodeColor(node) : nodeColor
90
90
 
91
91
  return (
92
92
  <rect
@@ -1,5 +1,5 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import type { FlowInstance } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import type { FlowInstance } from '../types'
3
3
 
4
4
  export interface NodeResizerProps {
5
5
  nodeId: string
@@ -14,28 +14,28 @@ export interface NodeResizerProps {
14
14
  showEdgeHandles?: boolean
15
15
  }
16
16
 
17
- type ResizeDirection = "nw" | "ne" | "sw" | "se" | "n" | "s" | "e" | "w"
17
+ type ResizeDirection = 'nw' | 'ne' | 'sw' | 'se' | 'n' | 's' | 'e' | 'w'
18
18
 
19
19
  const directionCursors: Record<ResizeDirection, string> = {
20
- nw: "nw-resize",
21
- ne: "ne-resize",
22
- sw: "sw-resize",
23
- se: "se-resize",
24
- n: "n-resize",
25
- s: "s-resize",
26
- e: "e-resize",
27
- w: "w-resize",
20
+ nw: 'nw-resize',
21
+ ne: 'ne-resize',
22
+ sw: 'sw-resize',
23
+ se: 'se-resize',
24
+ n: 'n-resize',
25
+ s: 's-resize',
26
+ e: 'e-resize',
27
+ w: 'w-resize',
28
28
  }
29
29
 
30
30
  const directionPositions: Record<ResizeDirection, string> = {
31
- nw: "top: -4px; left: -4px;",
32
- ne: "top: -4px; right: -4px;",
33
- sw: "bottom: -4px; left: -4px;",
34
- se: "bottom: -4px; right: -4px;",
35
- n: "top: -4px; left: 50%; transform: translateX(-50%);",
36
- s: "bottom: -4px; left: 50%; transform: translateX(-50%);",
37
- e: "right: -4px; top: 50%; transform: translateY(-50%);",
38
- w: "left: -4px; top: 50%; transform: translateY(-50%);",
31
+ nw: 'top: -4px; left: -4px;',
32
+ ne: 'top: -4px; right: -4px;',
33
+ sw: 'bottom: -4px; left: -4px;',
34
+ se: 'bottom: -4px; right: -4px;',
35
+ n: 'top: -4px; left: 50%; transform: translateX(-50%);',
36
+ s: 'bottom: -4px; left: 50%; transform: translateX(-50%);',
37
+ e: 'right: -4px; top: 50%; transform: translateY(-50%);',
38
+ w: 'left: -4px; top: 50%; transform: translateY(-50%);',
39
39
  }
40
40
 
41
41
  /**
@@ -67,8 +67,8 @@ export function NodeResizer(props: NodeResizerProps): VNodeChild {
67
67
  } = props
68
68
 
69
69
  const directions: ResizeDirection[] = showEdgeHandles
70
- ? ["nw", "ne", "sw", "se", "n", "s", "e", "w"]
71
- : ["nw", "ne", "sw", "se"]
70
+ ? ['nw', 'ne', 'sw', 'se', 'n', 's', 'e', 'w']
71
+ : ['nw', 'ne', 'sw', 'se']
72
72
 
73
73
  const createHandler = (dir: ResizeDirection) => {
74
74
  let startX = 0
@@ -112,19 +112,19 @@ export function NodeResizer(props: NodeResizerProps): VNodeChild {
112
112
  let newY = startNodeY
113
113
 
114
114
  // Horizontal
115
- if (dir === "e" || dir === "se" || dir === "ne") {
115
+ if (dir === 'e' || dir === 'se' || dir === 'ne') {
116
116
  newW = Math.max(minWidth, startWidth + dx)
117
117
  }
118
- if (dir === "w" || dir === "sw" || dir === "nw") {
118
+ if (dir === 'w' || dir === 'sw' || dir === 'nw') {
119
119
  newW = Math.max(minWidth, startWidth - dx)
120
120
  newX = startNodeX + startWidth - newW
121
121
  }
122
122
 
123
123
  // Vertical
124
- if (dir === "s" || dir === "se" || dir === "sw") {
124
+ if (dir === 's' || dir === 'se' || dir === 'sw') {
125
125
  newH = Math.max(minHeight, startHeight + dy)
126
126
  }
127
- if (dir === "n" || dir === "ne" || dir === "nw") {
127
+ if (dir === 'n' || dir === 'ne' || dir === 'nw') {
128
128
  newH = Math.max(minHeight, startHeight - dy)
129
129
  newY = startNodeY + startHeight - newH
130
130
  }