@foblex/flow 19.0.0 → 19.1.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.
package/AI.md CHANGED
@@ -5,16 +5,13 @@ Use this file as a strict control layer for code generation. Prefer verified pac
5
5
  ## What This Library Is
6
6
 
7
7
  `@foblex/flow` is an Angular-native library for building node-based editors, workflow builders, and interactive graph UIs.
8
- It provides rendering, connectors, interactions, selection, zoom, and connection drawing. Your app still owns the graph data.
8
+ It provides rendering, connectors, interactions, selection, zoom, and connection drawing. By default your app owns the graph data; the optional `withFlowState()` feature can own the data bookkeeping and undo/redo for an editor.
9
9
 
10
10
  ## Core Mental Model
11
11
 
12
- - The library does **not** own your graph state.
13
- - Your app owns nodes, groups, connections, ids, validation, and persistence.
14
- - Angular templates render the current state.
15
- - User actions emit events from `fDraggable` or model outputs.
16
- - Your app updates state.
17
- - Angular rerenders.
12
+ - **Classic mode (default):** your app owns nodes, groups, connections, validation and persistence. User actions emit events; your handlers update app state; Angular rerenders.
13
+ - **Managed mode (opt-in):** `provideFFlow(withFlowState())` provides `FFlowState`; supported completed gestures update its signals and history automatically. Your app still owns domain fields, validation policy and persistence.
14
+ - Both modes render records through normal Angular templates. `withFlowState()` is optional and does not change classic event behavior when absent.
18
15
 
19
16
  ## Minimal Working Setup
20
17
 
@@ -73,13 +70,13 @@ The default theme is wired by `ng add @foblex/flow` (adds `node_modules/@foblex/
73
70
  - `fDraggable` on `<f-flow>`: enables pointer interactions and emits interaction events.
74
71
  - `fZoom` on `<f-canvas>`: opt-in wheel / double-click / pinch zoom.
75
72
  - `<f-selection-area>`: opt-in rectangle multi-select.
76
- - `provideFFlow(...)` with features: `withConnectionFlow('click')` (click-to-connect gesture alongside drag; custom gestures implement `IFConnectionFlow` and drive `FCreateConnectionSession`), `withControlScheme(...)` (gesture-to-action mapping, presets `F_DEFAULT_CONTROL_SCHEME`, `F_SCROLL_PAN_CONTROL_SCHEME`, `F_DRAG_SELECT_CONTROL_SCHEME`), `withReflowOnResize(...)` (auto layout on node resize), `withFCanvas(...)` (canvas defaults such as layer order), `withA11y(...)` (enables the keyboard accessibility layer — spatial arrow navigation, grab-move, keyboard connection creation, `Delete` emits `fDeleteSelected`; configurable steps, key bindings `IFA11yKeys`, localizable announcements `IFA11yMessages`; ARIA semantics and the live region are always on even without the feature).
73
+ - `provideFFlow(...)` with features: `withConnectionFlow('click')` (click-to-connect gesture alongside drag; custom gestures implement `IFConnectionFlow` and drive `FCreateConnectionSession`), `withControlScheme(...)` (gesture-to-action mapping, presets `F_DEFAULT_CONTROL_SCHEME`, `F_SCROLL_PAN_CONTROL_SCHEME`, `F_DRAG_SELECT_CONTROL_SCHEME`), `withReflowOnResize(...)` (auto layout on node resize), `withFCanvas(...)` (canvas defaults such as layer order), `withA11y(...)` (keyboard accessibility), and `withFlowState(...)` (managed records plus undo/redo).
77
74
 
78
75
  ## Hard Rules
79
76
 
80
77
  - Never invent Inputs, Outputs, methods, directives, or selectors.
81
78
  - Do **not** assume React Flow style APIs such as `[nodes]`, `[edges]`, `setNodes()`, `addEdge()`, `useNodesState()`, `<Handle>`, `<Background>`, `<Controls>`, or similar patterns.
82
- - Do **not** assume a built-in graph store. The app owns state.
79
+ - Do **not** assume managed state unless the component explicitly installs `provideFFlow(withFlowState())`. Without it, the app owns state and handles events.
83
80
  - Connections are connector-to-connector, not generic node-to-node edges.
84
81
  - Template connections use `fSourceId -> fTargetId` referencing `fConnectorId` values (legacy: `fOutputId -> fInputId` referencing output/input ids).
85
82
  - Do **not** interpret `[fNodes]` or `[fConnections]` as graph-state inputs. They are content-projection slot markers used with `ngProjectAs` (see the nested control flow rule below).
@@ -102,11 +99,11 @@ The default theme is wired by `ng add @foblex/flow` (adds `node_modules/@foblex/
102
99
 
103
100
  Use `"[fNodes]"` for nodes, `"[fGroups]"` for groups, `"[fConnections]"` for connections. A single top-level `@for` / `@if` directly inside `<f-canvas>` needs no wrapper.
104
101
 
105
- - Examples may include app-specific state, layout logic, persistence, undo/redo, toolbars, or validation. Those are example implementations, not built-in package features.
102
+ - Examples may include app-specific layout logic, persistence, toolbars, or validation. Undo/redo is built in only when `withFlowState()` is installed; otherwise it remains application code.
106
103
  - Some exports are low-level, compatibility-oriented, or testing-oriented. Do not treat every export from `@foblex/flow` as the recommended app-facing API.
107
104
  - If a symbol, selector, event, or behavior is not confirmed in the installed package, say: `not found in @foblex/flow`.
108
105
 
109
- ## Correct Usage Pattern
106
+ ## Classic State Pattern
110
107
 
111
108
  - Render nodes and groups from your Angular state using normal Angular templates.
112
109
  - Put connectors on the node element itself or on child elements with `fConnector`.
@@ -116,6 +113,35 @@ The default theme is wired by `ng add @foblex/flow` (adds `node_modules/@foblex/
116
113
  - Update your own state in those handlers, then let Angular rerender.
117
114
  - Use node/group position bindings and change outputs to keep positions in app state when needed.
118
115
 
116
+ ## Managed State Pattern
117
+
118
+ Install the state feature at the same component injector as `provideFFlow`, load plain records, and render its signals:
119
+
120
+ ```typescript
121
+ interface EditorNode extends IFStateNode {
122
+ text: string;
123
+ }
124
+
125
+ @Component({
126
+ providers: [provideFFlow(withFlowState())],
127
+ })
128
+ export class Editor {
129
+ protected readonly state = injectFlowState<EditorNode>();
130
+
131
+ constructor() {
132
+ this.state.load({ nodes: [], groups: [], connections: [] });
133
+ }
134
+ }
135
+ ```
136
+
137
+ - Bind `state.nodes()`, `state.groups()` and `state.connections()` with `@for`; bind canvas `[position]` and `[scale]` to `state.transform()` when viewport undo/redo is enabled.
138
+ - Supported v1 gestures: create/reassign connection, move nodes/groups, delete selection, external-item creation, optional drop-to-group, selection, and canvas pan/zoom.
139
+ - Rotation, connection waypoint editing, and user resize are not captured by managed state in v1.
140
+ - `state.changes()` increments once when a standalone mutation or outer batch settles. A drag can emit selection at start and move/drop at end while remaining one history step and one `changes()` increment.
141
+ - Use `state.snapshot()` for persistence; `load()` replaces data and resets history.
142
+ - For initial or other application-driven viewport positioning, suppress the event at the canvas helper: `canvas.resetScaleAndCenter(false, false)`. The second `false` means `emitCanvasChange = false`, so managed history is untouched.
143
+ - Connection endpoints are connector ids. Automatic cascade from node/group deletion uses the rendered connector registry; before connectors render, remove known attached connection ids explicitly in the same `state.batch(...)`.
144
+
119
145
  ## Common Silent Failures — Check These First
120
146
 
121
147
  When the flow compiles but looks wrong, verify in this order:
@@ -133,6 +159,7 @@ When the flow compiles but looks wrong, verify in this order:
133
159
  11. **Node moves but its bindings never fire** (`FF1007`): an `fNode` element is nested inside another node element. One `fNode` per node; hierarchy is id-based (`fNodeParentId`), not DOM-based.
134
160
  12. **Group behaviors don't apply** (`FF1008`): `fNodeParentId` / `fGroupParentId` references an id no rendered group has.
135
161
  13. **Wrong initial viewport** (`FF1009`): `fitToScreen()` / `resetScaleAndCenter()` / `centerGroupOrNode()` called before nodes were rendered — call them from `(fNodesRendered)` (earliest safe) or `(fFullRendered)`.
162
+ 14. **Initial centering appears in managed undo history**: call `resetScaleAndCenter(false, false)` (or pass `emitCanvasChange: false` to another viewport helper) for an application-driven transform.
136
163
 
137
164
  To verify programmatically: listen to `(fFullRendered)` on `<f-flow>`, then call `flow.getState()` and assert every declared connection resolved to existing connectors.
138
165
 
@@ -167,6 +194,7 @@ See [STYLING.md](./STYLING.md).
167
194
  - Docs index for agents: https://flow.foblex.com/llms.txt
168
195
  - Human docs: https://flow.foblex.com/docs/get-started
169
196
  - Live examples with source: https://flow.foblex.com/examples/overview
197
+ - Managed state example and contract: https://flow.foblex.com/examples/state
170
198
 
171
199
  ## Fallback Rule
172
200
 
package/README.md CHANGED
@@ -11,6 +11,15 @@
11
11
  <a href="https://github.com/Foblex/f-flow/actions/workflows/tests-ci.yml">
12
12
  <img src="https://github.com/Foblex/f-flow/actions/workflows/tests-ci.yml/badge.svg" alt="Build Status"/>
13
13
  </a>
14
+ <a href="https://www.npmjs.com/package/@foblex/flow">
15
+ <img src="https://img.shields.io/npm/dw/@foblex/flow.svg?label=Downloads&color=blue" alt="NPM Weekly Downloads"/>
16
+ </a>
17
+ <a href="https://github.com/Foblex/f-flow/stargazers">
18
+ <img src="https://img.shields.io/github/stars/Foblex/f-flow.svg?label=Stars&color=gold" alt="GitHub Stars"/>
19
+ </a>
20
+ <a href="https://github.com/Foblex/f-flow/blob/main/LICENSE">
21
+ <img src="https://img.shields.io/npm/l/@foblex/flow.svg?label=License&color=green" alt="MIT License"/>
22
+ </a>
14
23
  </p>
15
24
 
16
25
  <h1 align="center">Foblex Flow</h1>
@@ -23,7 +32,13 @@ Foblex Flow gives Angular teams a simple way to start building graph-based produ
23
32
 
24
33
  Use it to create workflow builders, AI low-code tools, call-flow editors, UML diagrams, internal back-office tools, and other node-based interfaces while keeping your own state, validation, persistence, and domain logic.
25
34
 
26
- Current `18.x` releases target Angular `17.3+`. If your app is on Angular 12-17.2, check the [Angular Version Compatibility](https://flow.foblex.com/docs/angular-version-compatibility) guide first and pin the matching Foblex Flow line before installing.
35
+ <p align="center">
36
+ <a href="https://flow.foblex.com/examples/overview">
37
+ <img src="https://flow.foblex.com/previews/examples/reflow-on-resize.light.png" alt="Foblex Flow — Angular node editor with draggable nodes and connections" width="720"/>
38
+ </a>
39
+ </p>
40
+
41
+ Current `19.x` releases target Angular `17.3+`. If your app is on Angular 12-17.2, check the [Angular Version Compatibility](https://flow.foblex.com/docs/angular-version-compatibility) guide first and pin the matching Foblex Flow line before installing.
27
42
 
28
43
  ## Why Foblex Flow
29
44
 
@@ -35,6 +50,22 @@ Current `18.x` releases target Angular `17.3+`. If your app is on Angular 12-17.
35
50
  - Your app stays in control of graph state, validation rules, permissions, and persistence.
36
51
  - Suitable for both lightweight diagrams and full workflow-builder products.
37
52
 
53
+ ## Feature Overview
54
+
55
+ | Area | What ships out of the box |
56
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
57
+ | Editing | Drag & drop nodes and groups, drag/click/keyboard connection creation, reassign, waypoints, resize, rotate, snap & alignment guides, magnetic lines |
58
+ | Navigation | Pan, wheel/pinch/double-click zoom, minimap, auto-pan at edges, fit-to-screen, configurable control schemes (Miro-like, draw.io-like presets) |
59
+ | Selection | Click, marquee, multi-select, select-all, selection events — your app decides what selection means |
60
+ | Accessibility | ARIA semantics by default; opt-in keyboard layer: spatial navigation, move, delete, and connection creation without a mouse, screen-reader announcements, remappable keys |
61
+ | Layout | Dagre and ELK auto-layout packages, reflow-on-resize, layer ordering |
62
+ | Scale | Node virtualization, render caching, background workers — optional, for large scenes |
63
+ | Customization | Fully templated nodes/connections/connectors, themable via CSS tokens/SCSS mixins, custom markers, connection gradients and labels |
64
+ | Integration | Event-driven API (`fCreateConnection`, `fMoveNodes`, `fDeleteSelected`, …) — the library never mutates your data; SSR-safe, zoneless-ready |
65
+ | AI tooling | `llms.txt`, bundled `AI.md`, `ng add` writes agent rules, dev diagnostics with stable `FFxxxx` error codes |
66
+
67
+ Coming from React Flow? Read the honest comparison: [React Flow vs Foblex Flow for Angular teams](https://flow.foblex.com/docs/react-flow-vs-foblex-flow-for-angular-teams).
68
+
38
69
  ## What You Can Build
39
70
 
40
71
  - Angular node editors
@@ -52,9 +83,15 @@ Current `18.x` releases target Angular `17.3+`. If your app is on Angular 12-17.
52
83
  - [Tournament Bracket](https://flow.foblex.com/examples/tournament-bracket) - A specialized bracket UI built on the same node-based primitives.
53
84
  - [All Examples](https://flow.foblex.com/examples/overview) - Focused examples for connections, selection, minimap, layout, alignment, and other editor features.
54
85
 
86
+ ## Try It Online
87
+
88
+ No local setup needed — the minimal starter runs in the browser:
89
+
90
+ [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/Foblex/f-flow/tree/main/starters/minimal-flow)
91
+
55
92
  ## Install
56
93
 
57
- These install commands are for the current `18.x` line. For Angular 12-17.2 apps, use the [Angular Version Compatibility](https://flow.foblex.com/docs/angular-version-compatibility) guide first so you do not accidentally install a newer incompatible line.
94
+ These install commands are for the current `19.x` line. For Angular 12-17.2 apps, use the [Angular Version Compatibility](https://flow.foblex.com/docs/angular-version-compatibility) guide first so you do not accidentally install a newer incompatible line.
58
95
 
59
96
  ```bash
60
97
  ng add @foblex/flow
@@ -105,33 +142,23 @@ Full guide: [Default Theme and Styling](https://flow.foblex.com/docs/default-the
105
142
  ```html
106
143
  <f-flow fDraggable>
107
144
  <f-canvas>
108
- <f-connection fOutputId="output1" fInputId="input1"></f-connection>
109
-
110
- <div
111
- fNode
112
- fDragHandle
113
- [fNodePosition]="{ x: 24, y: 24 }"
114
- fNodeOutput
115
- fOutputId="output1"
116
- fOutputConnectableSide="right"
117
- >
145
+ <f-connection fSourceId="a-out" fTargetId="b-in"></f-connection>
146
+
147
+ <div fNode fDragHandle [fNodePosition]="{ x: 24, y: 24 }">
118
148
  Drag me
149
+ <div fConnector fConnectorType="source" fConnectorId="a-out"></div>
119
150
  </div>
120
151
 
121
- <div
122
- fNode
123
- fDragHandle
124
- [fNodePosition]="{ x: 244, y: 24 }"
125
- fNodeInput
126
- fInputId="input1"
127
- fInputConnectableSide="left"
128
- >
129
- Drag me
152
+ <div fNode fDragHandle [fNodePosition]="{ x: 244, y: 24 }">
153
+ Drag me too
154
+ <div fConnector fConnectorType="target" fConnectorId="b-in"></div>
130
155
  </div>
131
156
  </f-canvas>
132
157
  </f-flow>
133
158
  ```
134
159
 
160
+ That is the whole mental model: `f-flow` hosts the editor, `f-canvas` pans and zooms, any element becomes a node with `fNode`, connectors attach edges. Everything below is opt-in.
161
+
135
162
  ## Quick FAQ
136
163
 
137
164
  - **Is Foblex Flow hard to use?** No. The core setup is small and Angular-native.
package/STYLING.md CHANGED
@@ -14,6 +14,7 @@ Observed host/base classes in source include `.f-flow`, `.f-canvas`, `.f-node`,
14
14
  - Observed in source: `.f-node-output-connected` and `.f-node-input-connected` mark connectors that are currently connected.
15
15
  - Observed in source: `.f-node-output-not-connectable` and `.f-node-input-not-connectable` mark connectors that are present but currently not connectable.
16
16
  - Observed in source: `.f-grouping-drop-active` and `.f-grouping-over-boundary` are applied during drop-to-group interactions.
17
+ - Observed in source: `.f-drop-to-group` is a host modifier class applied to the flow while the drop-to-group gesture is enabled (the default; toggled by the `fDropToGroup` input). The `.f-grouping-drop-active` / `.f-grouping-over-boundary` highlight is scoped under it.
17
18
  - Observed in source: `.f-node-dragging-disabled`, `.f-node-selection-disabled`, `.f-group-dragging-disabled`, `.f-group-selection-disabled`, `.f-connection-reassign-disabled`, and `.f-connection-selection-disabled` are host modifier classes for disabled interaction states.
18
19
  - Observed in source: `.f-node-input-disabled`, `.f-node-output-disabled`, and `.f-node-outlet-disabled` are connector/outlet disabled-state classes.
19
20
  - Observed in source: `.f-node-input-multiple`, `.f-node-output-multiple`, and `.f-node-output-self-connectable` are connector capability/modifier classes.