stickyflow 0.4.0 → 0.6.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 (65) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +51 -5
  3. package/dist/binding/index.cjs +34 -0
  4. package/dist/binding/index.cjs.map +1 -0
  5. package/dist/binding/index.d.cts +11 -0
  6. package/dist/binding/index.d.ts +11 -0
  7. package/dist/binding/index.js +5 -0
  8. package/dist/binding/index.js.map +1 -0
  9. package/dist/{chunk-BYMIYXP5.js → chunk-4G2R7PEL.js} +513 -61
  10. package/dist/chunk-4G2R7PEL.js.map +1 -0
  11. package/dist/{chunk-HFOGKSNU.cjs → chunk-4LENHH6C.cjs} +15 -15
  12. package/dist/{chunk-HFOGKSNU.cjs.map → chunk-4LENHH6C.cjs.map} +1 -1
  13. package/dist/{chunk-65IVT4GK.js → chunk-FVHVOJS2.js} +1333 -650
  14. package/dist/chunk-FVHVOJS2.js.map +1 -0
  15. package/dist/chunk-JIJMZMGY.cjs +1189 -0
  16. package/dist/chunk-JIJMZMGY.cjs.map +1 -0
  17. package/dist/{chunk-UXDWH2JC.cjs → chunk-KTNCDNDB.cjs} +1165 -1118
  18. package/dist/chunk-KTNCDNDB.cjs.map +1 -0
  19. package/dist/chunk-MFNUJA26.js +1182 -0
  20. package/dist/chunk-MFNUJA26.js.map +1 -0
  21. package/dist/{chunk-XEN5QIIJ.js → chunk-ULQZ6CZW.js} +3 -3
  22. package/dist/{chunk-XEN5QIIJ.js.map → chunk-ULQZ6CZW.js.map} +1 -1
  23. package/dist/{chunk-DDCTNLLD.cjs → chunk-WQRT5PVT.cjs} +1837 -1155
  24. package/dist/chunk-WQRT5PVT.cjs.map +1 -0
  25. package/dist/{chunk-CSXQD3ON.js → chunk-WRDVNMFS.js} +1128 -1081
  26. package/dist/chunk-WRDVNMFS.js.map +1 -0
  27. package/dist/{chunk-CXL254BT.cjs → chunk-XJ4W6TW4.cjs} +528 -60
  28. package/dist/chunk-XJ4W6TW4.cjs.map +1 -0
  29. package/dist/index.cjs +73 -1013
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +67 -14
  32. package/dist/index.d.ts +67 -14
  33. package/dist/index.js +6 -993
  34. package/dist/index.js.map +1 -1
  35. package/dist/interaction/index.cjs +246 -236
  36. package/dist/interaction/index.cjs.map +1 -1
  37. package/dist/interaction/index.d.cts +3 -2
  38. package/dist/interaction/index.d.ts +3 -2
  39. package/dist/interaction/index.js +18 -8
  40. package/dist/interaction/index.js.map +1 -1
  41. package/dist/{render-C5X74hds.d.cts → render-Db0eSz_s.d.cts} +216 -118
  42. package/dist/{render-C5X74hds.d.ts → render-Db0eSz_s.d.ts} +216 -118
  43. package/dist/runtime-BhivvBeL.d.cts +10 -0
  44. package/dist/runtime-n2yG-_j-.d.ts +10 -0
  45. package/dist/{runtimeTypes-yTSAvtCn.d.cts → runtimeTypes-CrkMHvVi.d.cts} +10 -5
  46. package/dist/{runtimeTypes-D8hPZ62T.d.ts → runtimeTypes-DnI7mRF5.d.ts} +10 -5
  47. package/dist/stickyflow-diagram.global.js +35 -35
  48. package/dist/stickyflow-diagram.global.js.map +1 -1
  49. package/dist/{types-CdgGdtoD.d.ts → types-BHfUKT4s.d.cts} +3 -2
  50. package/dist/{types-BDKDf4zr.d.cts → types-D4cH4f1a.d.ts} +3 -2
  51. package/dist/viewer/index.cjs +9 -9
  52. package/dist/viewer/index.d.cts +4 -4
  53. package/dist/viewer/index.d.ts +4 -4
  54. package/dist/viewer/index.js +4 -4
  55. package/dist/web-component/index.cjs +6 -6
  56. package/dist/web-component/index.d.cts +2 -2
  57. package/dist/web-component/index.d.ts +2 -2
  58. package/dist/web-component/index.js +4 -4
  59. package/package.json +6 -1
  60. package/dist/chunk-65IVT4GK.js.map +0 -1
  61. package/dist/chunk-BYMIYXP5.js.map +0 -1
  62. package/dist/chunk-CSXQD3ON.js.map +0 -1
  63. package/dist/chunk-CXL254BT.cjs.map +0 -1
  64. package/dist/chunk-DDCTNLLD.cjs.map +0 -1
  65. package/dist/chunk-UXDWH2JC.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -17,6 +17,49 @@ Two things count as breaking here that are easy to overlook:
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [0.6.0] - 2026-10-22
21
+
22
+ ### Added
23
+
24
+ - An `Isometric` block takes a `symbol`. The outline of the `Symbol` is extruded by the height, and every wall that faces the viewer is shaded on its own. It works for any closed outline of three or more points that does not cross itself.
25
+ - `cornerRadius` in the style of an `Isometric` block rounds the vertical edges of the box or of an extruded symbol.
26
+ - `shape: sphere` draws an `Isometric` block as a shaded ball that sits in the center of its box.
27
+ - A point of a `Path` or a `Symbol` can carry a third value, its own tension. `0` makes the point a corner, so one outline can mix corners and curves. A point without one takes the `tension` of the whole path.
28
+ - `pathToSymbol()` turns a `Path` into a `Symbol`, and `symbolToPath()` turns it back. `pathBounds()` and `flattenPath()` give the box of a path and the points of its curve as short straight edges. The types `PathFrame`, `PathPoint` and `PathSymbol` are exported.
29
+ - The `Dimension` block draws a measure line with an arrow at each end, extension lines and a label. `start` and `end` are the two measured points, and `offset` is the distance of the line, positive to the left of the direction. Without `text` the label is the measured length, rounded to one decimal place, followed by `unit`. `isDimensionObject()` and the types `Dimension` and `SflDimensionObject` are exported, and `RenderInput` takes `dimensions`.
30
+
31
+ ### Changed
32
+
33
+ - Moving a path through `applyMoveChange` keeps the tension of its points.
34
+ - An `Isometric` block with a `symbol` that has curved points uses the curve as many short straight edges.
35
+
36
+ ## [0.5.0] - 2026-10-18
37
+
38
+ ### Added
39
+
40
+ - The entry `stickyflow/binding` with `createDataSource`, `createBindingRuntime`, `buildBindingGraph`, `renderBound` and `interactiveElements`. The same names stay exported from `stickyflow` for now.
41
+ - The components `switch`, `checkbox`, `toggleButton` and `button`. A switch, a checkbox and a toggle button hold a boolean value, a button fires `onTap`. They are drawn from scene nodes, so they render without a DOM, and they carry `role`, `aria-checked` or `aria-pressed` and `aria-disabled`.
42
+ - `value: <-> source.field` binds the value of a component to a field of a record source in both directions. A change by the user writes the field. A value bound with `<-` cannot be changed by the user.
43
+ - `onChange` runs when the user changes the value of a component. A binding or another handler never fires it.
44
+ - The states `focused` and `value` of a component are readable in expressions, and `disabled` can be set and bound. `runtime.change(id, value)` and `runtime.activate(id)` do from code what a tap and the keyboard do.
45
+ - `onTap` also fires when a component that can take focus is activated with Enter or Space. `connectInteraction` handles focus and the keyboard.
46
+ - `defineComponent()` adds a component type from outside the library, with its description and its drawing. `getComponentDescriptor()` reads a description.
47
+ - A type of component that is not known draws a dashed placeholder with its name, and is reported as before.
48
+
49
+ ### Changed
50
+
51
+ - The `Widget` block is now called `Component`. Both names are read, so existing documents render as before. The types follow the new name (`Component`, `ComponentType`, `RollingNumberComponent`, `TickScaleComponent`, `RulerComponent`) and `viewer.setComponentValue()` replaces `viewer.setWidgetValue()`. `RenderInput` takes `components`. The old names remain as aliases for now.
52
+ - The diagnostic `unsupported-widget-type` is now `unsupported-component-type`.
53
+ - `sflToRenderInput()` returns the components as `components` and no longer as `widgets`. `BoundProperty.ownerKind` is `'Component'` for a `Component` and for a `Widget` block, and a binding is keyed `Component.value`.
54
+ - `Component` now also covers components that are not one of the three built-in types. Narrow with `isGenericComponent()` before reading `parameters` or `style`.
55
+ - The component types are listed in one place, `COMPONENT_TYPES`, as the shape and chart types are, and no longer repeated in the code that reads them.
56
+
57
+ ### Fixed
58
+
59
+ - The number next to the knob of a ruler fades to the `peak` color and no longer always to white, so it stays readable on a light canvas.
60
+
61
+ The DOM contract is unchanged. The attributes `data-sf-widget*`, the role `widget` and the scene ids keep their names.
62
+
20
63
  ## [0.4.0] - 2026-10-17
21
64
 
22
65
  ### Added
package/README.md CHANGED
@@ -104,16 +104,17 @@ const { svg, width, height, diagnostics } = render(sfl)
104
104
  // A complete, deterministic SVG string. render() never touches the DOM.
105
105
  ```
106
106
 
107
- ## Four entry points
107
+ ## Five entry points
108
108
 
109
109
  | Import | What it is |
110
110
  |---|---|
111
111
  | `stickyflow` | Static tier. SFL text in, SVG string out. Node, SSR, CLI. |
112
- | `stickyflow/viewer` | Read-only viewer in the DOM: select, hover, pan, zoom, typed events. |
112
+ | `stickyflow/viewer` | Viewer in the DOM: select, hover, pan, zoom, typed events, and live input for components such as a switch or a button. |
113
113
  | `stickyflow/interaction` | Editing gestures on a viewer. Reports what changed; the host applies the patch to the SFL text. |
114
+ | `stickyflow/binding` | Data sources, bindings and handlers. `createDataSource`, `createBindingRuntime`, `renderBound`. No DOM. |
114
115
  | `stickyflow/web-component` | `<stickyflow-diagram>` custom element in Shadow DOM, no build step. |
115
116
 
116
- Each tier only depends on the one below it; `test/boundary.test.ts` enforces that.
117
+ Each entry only depends on the ones below it; `test/architecture` enforces that.
117
118
 
118
119
  ```ts
119
120
  import { createViewer } from 'stickyflow/viewer'
@@ -128,9 +129,52 @@ editing.on('moveChange', (event) => {
128
129
  })
129
130
  ```
130
131
 
132
+ ## Components and data binding
133
+
134
+ A component is an interface element with a value, a look and a behavior. Seven are built in. RollingNumber, TickScale and Ruler show a value. Switch, Checkbox, ToggleButton and Button are operated by the user. An application adds its own type with `defineComponent()`.
135
+
136
+ A document declares a data source and binds to it. `<-` makes a property follow the data. `<->` also writes the data when the user changes a component value, and `onChange` runs for each change by the user.
137
+
138
+ ```text
139
+ DataSource lamp {
140
+ mode: record
141
+ fields {
142
+ on: boolean
143
+ }
144
+ }
145
+
146
+ Model demo {
147
+ Component power {
148
+ type: switch
149
+ value: <-> lamp.on
150
+ layout {
151
+ position: 0, 0
152
+ size: 104, 60
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ ```ts
159
+ import { createBindingRuntime, createDataSource } from 'stickyflow/binding'
160
+ import { connectInteraction, createViewer } from 'stickyflow/viewer'
161
+
162
+ const viewer = createViewer({ container, source: sfl, interactive: true })
163
+ const runtime = createBindingRuntime(sfl)
164
+ const lamp = createDataSource({ on: false })
165
+
166
+ runtime.registerSource('lamp', lamp)
167
+ runtime.attach(viewer)
168
+ connectInteraction(viewer, runtime)
169
+
170
+ lamp.set({ on: true }) // the switch follows
171
+ ```
172
+
173
+ Binding and live input need only `stickyflow/binding` and `stickyflow/viewer`. Editing with `stickyflow/interaction` is separate.
174
+
131
175
  ## What it draws
132
176
 
133
- Shapes, links, frames, swimlanes, paths and text. Fifteen chart types. Isometric objects. Shader surfaces and widgets. Data sources with bindings, and events with handlers, so a document can react to data and input.
177
+ Shapes, links, frames, swimlanes, paths and text. Fifteen chart types. Isometric objects. Shader surfaces and components. Data sources with bindings, and events with handlers, so a document can react to data and input.
134
178
 
135
179
  ## Principles
136
180
 
@@ -140,11 +184,13 @@ Shapes, links, frames, swimlanes, paths and text. Fifteen chart types. Isometric
140
184
 
141
185
  ```
142
186
  src/
187
+ model/ types and registries for shapes, charts, components
143
188
  sflLanguage/ AST, lexer, parser, canonical emitter
144
189
  sflSemantic/ SFL AST to canvas state
145
190
  renderInput/ renderer contract and style decoding
146
191
  renderScene/ deterministic scene construction
147
192
  svg/ SVG serialization and the DOM contract
193
+ binding/ data sources, bindings and handlers
148
194
  runtime/ viewer, interaction, web component
149
195
  ```
150
196
 
@@ -155,7 +201,7 @@ npm run ci # lint, typecheck, tests, build, smoke
155
201
  npm run build # tsup
156
202
  ```
157
203
 
158
- How the package and its neighbours fit together: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Adding a new placeable object: [docs/ADDING_CANVAS_OBJECT.md](docs/ADDING_CANVAS_OBJECT.md). Changes: [CHANGELOG.md](CHANGELOG.md).
204
+ How the package and its neighbours fit together: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Adding a new placeable object: [docs/ADDING_CANVAS_OBJECT.md](docs/ADDING_CANVAS_OBJECT.md). Adding a component: [docs/ADDING_COMPONENT.md](docs/ADDING_COMPONENT.md). Changes: [CHANGELOG.md](CHANGELOG.md).
159
205
 
160
206
  ## More
161
207
 
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var chunkJIJMZMGY_cjs = require('../chunk-JIJMZMGY.cjs');
4
+ require('../chunk-WQRT5PVT.cjs');
5
+ require('../chunk-XJ4W6TW4.cjs');
6
+
7
+
8
+
9
+ Object.defineProperty(exports, "buildBindingGraph", {
10
+ enumerable: true,
11
+ get: function () { return chunkJIJMZMGY_cjs.buildBindingGraph; }
12
+ });
13
+ Object.defineProperty(exports, "collectContracts", {
14
+ enumerable: true,
15
+ get: function () { return chunkJIJMZMGY_cjs.collectContracts; }
16
+ });
17
+ Object.defineProperty(exports, "createBindingRuntime", {
18
+ enumerable: true,
19
+ get: function () { return chunkJIJMZMGY_cjs.createBindingRuntime; }
20
+ });
21
+ Object.defineProperty(exports, "createDataSource", {
22
+ enumerable: true,
23
+ get: function () { return chunkJIJMZMGY_cjs.createDataSource; }
24
+ });
25
+ Object.defineProperty(exports, "interactiveElements", {
26
+ enumerable: true,
27
+ get: function () { return chunkJIJMZMGY_cjs.interactiveElements; }
28
+ });
29
+ Object.defineProperty(exports, "renderBound", {
30
+ enumerable: true,
31
+ get: function () { return chunkJIJMZMGY_cjs.renderBound; }
32
+ });
33
+ //# sourceMappingURL=index.cjs.map
34
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
@@ -0,0 +1,11 @@
1
+ import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-CrkMHvVi.cjs';
2
+ export { a as BindingGraph, b as BindingRuntime, c as BindingRuntimeOptions, d as BindingTarget, e as BindingType, f as BindingValue, g as BoundAssignment, h as BoundHandler, i as BoundProperty, j as DataSource, E as ElementInfo, k as ElementState, I as InteractiveElements, M as MutableDataSource, l as buildBindingGraph, m as createDataSource, n as interactiveElements } from '../runtimeTypes-CrkMHvVi.cjs';
3
+ export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-BhivvBeL.cjs';
4
+ import '../render-Db0eSz_s.cjs';
5
+
6
+ declare function collectContracts(sflDocument: SflDocument): {
7
+ contracts: Map<string, DataSourceContract>;
8
+ diagnostics: BindingDiagnostic[];
9
+ };
10
+
11
+ export { BindingDiagnostic, DataSourceContract, collectContracts };
@@ -0,0 +1,11 @@
1
+ import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-DnI7mRF5.js';
2
+ export { a as BindingGraph, b as BindingRuntime, c as BindingRuntimeOptions, d as BindingTarget, e as BindingType, f as BindingValue, g as BoundAssignment, h as BoundHandler, i as BoundProperty, j as DataSource, E as ElementInfo, k as ElementState, I as InteractiveElements, M as MutableDataSource, l as buildBindingGraph, m as createDataSource, n as interactiveElements } from '../runtimeTypes-DnI7mRF5.js';
3
+ export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-n2yG-_j-.js';
4
+ import '../render-Db0eSz_s.js';
5
+
6
+ declare function collectContracts(sflDocument: SflDocument): {
7
+ contracts: Map<string, DataSourceContract>;
8
+ diagnostics: BindingDiagnostic[];
9
+ };
10
+
11
+ export { BindingDiagnostic, DataSourceContract, collectContracts };
@@ -0,0 +1,5 @@
1
+ export { buildBindingGraph, collectContracts, createBindingRuntime, createDataSource, interactiveElements, renderBound } from '../chunk-MFNUJA26.js';
2
+ import '../chunk-FVHVOJS2.js';
3
+ import '../chunk-4G2R7PEL.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}