@pyreon/flow 0.11.5 → 0.11.7

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.
@@ -1,8 +1,8 @@
1
- import type { VNodeChild } from "@pyreon/core"
1
+ import type { VNodeChild } from '@pyreon/core'
2
2
 
3
3
  export interface NodeToolbarProps {
4
4
  /** Position relative to node — default: 'top' */
5
- position?: "top" | "bottom" | "left" | "right"
5
+ position?: 'top' | 'bottom' | 'left' | 'right'
6
6
  /** Offset from node in px — default: 8 */
7
7
  offset?: number
8
8
  /** Only show when node is selected — default: true */
@@ -15,10 +15,10 @@ export interface NodeToolbarProps {
15
15
  }
16
16
 
17
17
  const positionStyles: Record<string, string> = {
18
- top: "bottom: 100%; left: 50%; transform: translateX(-50%);",
19
- bottom: "top: 100%; left: 50%; transform: translateX(-50%);",
20
- left: "right: 100%; top: 50%; transform: translateY(-50%);",
21
- right: "left: 100%; top: 50%; transform: translateY(-50%);",
18
+ top: 'bottom: 100%; left: 50%; transform: translateX(-50%);',
19
+ bottom: 'top: 100%; left: 50%; transform: translateX(-50%);',
20
+ left: 'right: 100%; top: 50%; transform: translateY(-50%);',
21
+ right: 'left: 100%; top: 50%; transform: translateY(-50%);',
22
22
  }
23
23
 
24
24
  /**
@@ -41,24 +41,24 @@ const positionStyles: Record<string, string> = {
41
41
  * ```
42
42
  */
43
43
  export function NodeToolbar(props: NodeToolbarProps): VNodeChild {
44
- const { position = "top", offset = 8, showOnSelect = true, selected = false, children } = props
44
+ const { position = 'top', offset = 8, showOnSelect = true, selected = false, children } = props
45
45
 
46
46
  if (showOnSelect && !selected) return null
47
47
 
48
48
  const posStyle = positionStyles[position] ?? positionStyles.top
49
49
  const marginProp =
50
- position === "top"
50
+ position === 'top'
51
51
  ? `margin-bottom: ${offset}px;`
52
- : position === "bottom"
52
+ : position === 'bottom'
53
53
  ? `margin-top: ${offset}px;`
54
- : position === "left"
54
+ : position === 'left'
55
55
  ? `margin-right: ${offset}px;`
56
56
  : `margin-left: ${offset}px;`
57
57
 
58
- const baseStyle = `position: absolute; ${posStyle} ${marginProp} z-index: 10; display: flex; gap: 4px; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); ${props.style ?? ""}`
58
+ const baseStyle = `position: absolute; ${posStyle} ${marginProp} z-index: 10; display: flex; gap: 4px; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); ${props.style ?? ''}`
59
59
 
60
60
  return (
61
- <div class={`pyreon-flow-node-toolbar ${props.class ?? ""}`} style={baseStyle}>
61
+ <div class={`pyreon-flow-node-toolbar ${props.class ?? ''}`} style={baseStyle}>
62
62
  {children}
63
63
  </div>
64
64
  )
@@ -1,11 +1,11 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import type { PanelProps } from "../types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import type { PanelProps } 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
  /**
@@ -21,12 +21,12 @@ const positionStyles: Record<string, string> = {
21
21
  * ```
22
22
  */
23
23
  export function Panel(props: PanelProps): VNodeChild {
24
- const { position = "top-left", style = "", children } = props
25
- const posStyle = positionStyles[position] ?? positionStyles["top-left"]
24
+ const { position = 'top-left', style = '', children } = props
25
+ const posStyle = positionStyles[position] ?? positionStyles['top-left']
26
26
  const baseStyle = `position: absolute; ${posStyle} z-index: 5; ${style}`
27
27
 
28
28
  return (
29
- <div class={`pyreon-flow-panel ${props.class ?? ""}`} style={baseStyle}>
29
+ <div class={`pyreon-flow-panel ${props.class ?? ''}`} style={baseStyle}>
30
30
  {children}
31
31
  </div>
32
32
  )
package/src/edges.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { EdgePathResult, FlowNode, XYPosition } from "./types"
2
- import { Position } from "./types"
1
+ import type { EdgePathResult, FlowNode, XYPosition } from './types'
2
+ import { Position } from './types'
3
3
 
4
4
  /**
5
5
  * Auto-detect the best handle position based on relative node positions.
@@ -280,7 +280,7 @@ export function getWaypointPath(params: {
280
280
  const allPoints = [{ x: sourceX, y: sourceY }, ...waypoints, { x: targetX, y: targetY }]
281
281
 
282
282
  const segments = allPoints.map((p) => `${p.x},${p.y}`)
283
- const path = `M${segments.join(" L")}`
283
+ const path = `M${segments.join(' L')}`
284
284
 
285
285
  // Label at the middle waypoint
286
286
  const midIdx = Math.floor(waypoints.length / 2)
@@ -305,7 +305,7 @@ export function getEdgePath(
305
305
  targetPosition: Position,
306
306
  ): EdgePathResult {
307
307
  switch (type) {
308
- case "smoothstep":
308
+ case 'smoothstep':
309
309
  return getSmoothStepPath({
310
310
  sourceX,
311
311
  sourceY,
@@ -314,9 +314,9 @@ export function getEdgePath(
314
314
  targetY,
315
315
  targetPosition,
316
316
  })
317
- case "straight":
317
+ case 'straight':
318
318
  return getStraightPath({ sourceX, sourceY, targetX, targetY })
319
- case "step":
319
+ case 'step':
320
320
  return getStepPath({
321
321
  sourceX,
322
322
  sourceY,
package/src/flow.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { batch, computed, signal } from "@pyreon/reactivity"
2
- import { computeLayout } from "./layout"
1
+ import { batch, computed, signal } from '@pyreon/reactivity'
2
+ import { computeLayout } from './layout'
3
3
  import type {
4
4
  Connection,
5
5
  FlowConfig,
@@ -10,15 +10,15 @@ import type {
10
10
  LayoutOptions,
11
11
  NodeChange,
12
12
  XYPosition,
13
- } from "./types"
13
+ } from './types'
14
14
 
15
15
  /**
16
16
  * Generate a unique edge id from source/target.
17
17
  */
18
18
  function edgeId(edge: FlowEdge): string {
19
19
  if (edge.id) return edge.id
20
- const sh = edge.sourceHandle ? `-${edge.sourceHandle}` : ""
21
- const th = edge.targetHandle ? `-${edge.targetHandle}` : ""
20
+ const sh = edge.sourceHandle ? `-${edge.sourceHandle}` : ''
21
+ const th = edge.targetHandle ? `-${edge.targetHandle}` : ''
22
22
  return `e-${edge.source}${sh}-${edge.target}${th}`
23
23
  }
24
24
 
@@ -51,7 +51,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
51
51
  const {
52
52
  nodes: initialNodes = [],
53
53
  edges: initialEdges = [],
54
- defaultEdgeType = "bezier",
54
+ defaultEdgeType = 'bezier',
55
55
  minZoom = 0.1,
56
56
  maxZoom = 4,
57
57
  snapToGrid = false,
@@ -119,7 +119,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
119
119
  return next
120
120
  })
121
121
  })
122
- emitNodeChanges([{ type: "remove", id }])
122
+ emitNodeChanges([{ type: 'remove', id }])
123
123
  }
124
124
 
125
125
  function updateNode(id: string, update: Partial<FlowNode>): void {
@@ -139,7 +139,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
139
139
  pos = clampToExtent(pos, node?.width, node?.height)
140
140
 
141
141
  nodes.update((nds) => nds.map((n) => (n.id === id ? { ...n, position: pos } : n)))
142
- emitNodeChanges([{ type: "position", id, position: pos }])
142
+ emitNodeChanges([{ type: 'position', id, position: pos }])
143
143
  }
144
144
 
145
145
  // ── Edge operations ──────────────────────────────────────────────────────
@@ -187,7 +187,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
187
187
  const sourceNode = getNode(connection.source)
188
188
  if (!sourceNode) return false
189
189
 
190
- const sourceType = sourceNode.type ?? "default"
190
+ const sourceType = sourceNode.type ?? 'default'
191
191
  const rule = connectionRules[sourceType]
192
192
  if (!rule) return true // no rule = allow
193
193
 
@@ -195,7 +195,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
195
195
  const targetNode = getNode(connection.target)
196
196
  if (!targetNode) return false
197
197
 
198
- const targetType = targetNode.type ?? "default"
198
+ const targetType = targetNode.type ?? 'default'
199
199
  return rule.outputs.includes(targetType)
200
200
  }
201
201
 
@@ -354,7 +354,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
354
354
  // ── Layout ───────────────────────────────────────────────────────────────
355
355
 
356
356
  async function layout(
357
- algorithm: LayoutAlgorithm = "layered",
357
+ algorithm: LayoutAlgorithm = 'layered',
358
358
  options: LayoutOptions = {},
359
359
  ): Promise<void> {
360
360
  const currentNodes = nodes.peek()
package/src/index.ts CHANGED
@@ -24,18 +24,18 @@
24
24
  * ```
25
25
  */
26
26
 
27
- export { Background } from "./components/background"
28
- export { Controls } from "./components/controls"
29
- export type { FlowComponentProps } from "./components/flow-component"
27
+ export { Background } from './components/background'
28
+ export { Controls } from './components/controls'
29
+ export type { FlowComponentProps } from './components/flow-component'
30
30
  // Components
31
- export { Flow } from "./components/flow-component"
32
- export { Handle } from "./components/handle"
33
- export { MiniMap } from "./components/minimap"
34
- export type { NodeResizerProps } from "./components/node-resizer"
35
- export { NodeResizer } from "./components/node-resizer"
36
- export type { NodeToolbarProps } from "./components/node-toolbar"
37
- export { NodeToolbar } from "./components/node-toolbar"
38
- export { Panel } from "./components/panel"
31
+ export { Flow } from './components/flow-component'
32
+ export { Handle } from './components/handle'
33
+ export { MiniMap } from './components/minimap'
34
+ export type { NodeResizerProps } from './components/node-resizer'
35
+ export { NodeResizer } from './components/node-resizer'
36
+ export type { NodeToolbarProps } from './components/node-toolbar'
37
+ export { NodeToolbar } from './components/node-toolbar'
38
+ export { Panel } from './components/panel'
39
39
  // Edge path utilities
40
40
  export {
41
41
  getBezierPath,
@@ -46,13 +46,13 @@ export {
46
46
  getStepPath,
47
47
  getStraightPath,
48
48
  getWaypointPath,
49
- } from "./edges"
49
+ } from './edges'
50
50
  // Core
51
- export { createFlow } from "./flow"
51
+ export { createFlow } from './flow'
52
52
  // Layout
53
- export { computeLayout } from "./layout"
53
+ export { computeLayout } from './layout'
54
54
  // Styles
55
- export { flowStyles } from "./styles"
55
+ export { flowStyles } from './styles'
56
56
  export type {
57
57
  BackgroundProps,
58
58
  Connection,
@@ -78,6 +78,6 @@ export type {
78
78
  Rect,
79
79
  Viewport,
80
80
  XYPosition,
81
- } from "./types"
81
+ } from './types'
82
82
  // Types
83
- export { Position } from "./types"
83
+ export { Position } from './types'
package/src/layout.ts CHANGED
@@ -1,22 +1,22 @@
1
- import type { FlowEdge, FlowNode, LayoutAlgorithm, LayoutOptions } from "./types"
1
+ import type { FlowEdge, FlowNode, LayoutAlgorithm, LayoutOptions } from './types'
2
2
 
3
3
  // ─── ELK algorithm mapping ───────────────────────────────────────────────────
4
4
 
5
5
  const ELK_ALGORITHMS: Record<LayoutAlgorithm, string> = {
6
- layered: "org.eclipse.elk.layered",
7
- force: "org.eclipse.elk.force",
8
- stress: "org.eclipse.elk.stress",
9
- tree: "org.eclipse.elk.mrtree",
10
- radial: "org.eclipse.elk.radial",
11
- box: "org.eclipse.elk.box",
12
- rectpacking: "org.eclipse.elk.rectpacking",
6
+ layered: 'org.eclipse.elk.layered',
7
+ force: 'org.eclipse.elk.force',
8
+ stress: 'org.eclipse.elk.stress',
9
+ tree: 'org.eclipse.elk.mrtree',
10
+ radial: 'org.eclipse.elk.radial',
11
+ box: 'org.eclipse.elk.box',
12
+ rectpacking: 'org.eclipse.elk.rectpacking',
13
13
  }
14
14
 
15
15
  const ELK_DIRECTIONS: Record<string, string> = {
16
- UP: "UP",
17
- DOWN: "DOWN",
18
- LEFT: "LEFT",
19
- RIGHT: "RIGHT",
16
+ UP: 'UP',
17
+ DOWN: 'DOWN',
18
+ LEFT: 'LEFT',
19
+ RIGHT: 'RIGHT',
20
20
  }
21
21
 
22
22
  // ─── Lazy-loaded ELK instance ────────────────────────────────────────────────
@@ -28,7 +28,7 @@ async function getELK(): Promise<any> {
28
28
  if (elkInstance) return elkInstance
29
29
  if (elkPromise) return elkPromise
30
30
 
31
- elkPromise = import("elkjs/lib/elk.bundled.js").then((mod) => {
31
+ elkPromise = import('elkjs/lib/elk.bundled.js').then((mod) => {
32
32
  const ELK = mod.default || mod
33
33
  elkInstance = new ELK()
34
34
  return elkInstance
@@ -69,32 +69,32 @@ function toElkGraph(
69
69
  options: LayoutOptions,
70
70
  ): ElkGraph {
71
71
  const layoutOptions: Record<string, string> = {
72
- "elk.algorithm": ELK_ALGORITHMS[algorithm] ?? ELK_ALGORITHMS.layered,
72
+ 'elk.algorithm': ELK_ALGORITHMS[algorithm] ?? ELK_ALGORITHMS.layered,
73
73
  }
74
74
 
75
75
  if (options.direction) {
76
- layoutOptions["elk.direction"] = ELK_DIRECTIONS[options.direction] ?? "DOWN"
76
+ layoutOptions['elk.direction'] = ELK_DIRECTIONS[options.direction] ?? 'DOWN'
77
77
  }
78
78
 
79
79
  if (options.nodeSpacing !== undefined) {
80
- layoutOptions["elk.spacing.nodeNode"] = String(options.nodeSpacing)
80
+ layoutOptions['elk.spacing.nodeNode'] = String(options.nodeSpacing)
81
81
  }
82
82
 
83
83
  if (options.layerSpacing !== undefined) {
84
- layoutOptions["elk.layered.spacing.nodeNodeBetweenLayers"] = String(options.layerSpacing)
84
+ layoutOptions['elk.layered.spacing.nodeNodeBetweenLayers'] = String(options.layerSpacing)
85
85
  }
86
86
 
87
87
  if (options.edgeRouting) {
88
88
  const routingMap: Record<string, string> = {
89
- orthogonal: "ORTHOGONAL",
90
- splines: "SPLINES",
91
- polyline: "POLYLINE",
89
+ orthogonal: 'ORTHOGONAL',
90
+ splines: 'SPLINES',
91
+ polyline: 'POLYLINE',
92
92
  }
93
- layoutOptions["elk.edgeRouting"] = routingMap[options.edgeRouting] ?? "ORTHOGONAL"
93
+ layoutOptions['elk.edgeRouting'] = routingMap[options.edgeRouting] ?? 'ORTHOGONAL'
94
94
  }
95
95
 
96
96
  return {
97
- id: "root",
97
+ id: 'root',
98
98
  layoutOptions,
99
99
  children: nodes.map((node) => ({
100
100
  id: node.id,
@@ -130,7 +130,7 @@ function toElkGraph(
130
130
  export async function computeLayout(
131
131
  nodes: FlowNode[],
132
132
  edges: FlowEdge[],
133
- algorithm: LayoutAlgorithm = "layered",
133
+ algorithm: LayoutAlgorithm = 'layered',
134
134
  options: LayoutOptions = {},
135
135
  ): Promise<Array<{ id: string; position: { x: number; y: number } }>> {
136
136
  const elk = await getELK()