stickyflow 0.6.0 → 0.8.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/CHANGELOG.md +39 -0
- package/dist/binding/index.cjs +9 -9
- package/dist/binding/index.d.cts +4 -4
- package/dist/binding/index.d.ts +4 -4
- package/dist/binding/index.js +3 -3
- package/dist/{chunk-MFNUJA26.js → chunk-CZW3ARXQ.js} +156 -23
- package/dist/chunk-CZW3ARXQ.js.map +1 -0
- package/dist/{chunk-WRDVNMFS.js → chunk-EDOPENSE.js} +848 -38
- package/dist/chunk-EDOPENSE.js.map +1 -0
- package/dist/{chunk-4LENHH6C.cjs → chunk-FQ7GMLCM.cjs} +15 -15
- package/dist/{chunk-4LENHH6C.cjs.map → chunk-FQ7GMLCM.cjs.map} +1 -1
- package/dist/{chunk-4G2R7PEL.js → chunk-GLZVHUSW.js} +220 -12
- package/dist/chunk-GLZVHUSW.js.map +1 -0
- package/dist/{chunk-KTNCDNDB.cjs → chunk-IR2T47NW.cjs} +876 -66
- package/dist/chunk-IR2T47NW.cjs.map +1 -0
- package/dist/{chunk-ULQZ6CZW.js → chunk-LFEGZJWC.js} +3 -3
- package/dist/{chunk-ULQZ6CZW.js.map → chunk-LFEGZJWC.js.map} +1 -1
- package/dist/{chunk-XJ4W6TW4.cjs → chunk-LNW5VIEA.cjs} +225 -11
- package/dist/chunk-LNW5VIEA.cjs.map +1 -0
- package/dist/{chunk-FVHVOJS2.js → chunk-MAPNY7MJ.js} +872 -174
- package/dist/chunk-MAPNY7MJ.js.map +1 -0
- package/dist/{chunk-WQRT5PVT.cjs → chunk-VOYX6JMW.cjs} +1479 -780
- package/dist/chunk-VOYX6JMW.cjs.map +1 -0
- package/dist/{chunk-JIJMZMGY.cjs → chunk-XPM3E7NV.cjs} +170 -37
- package/dist/chunk-XPM3E7NV.cjs.map +1 -0
- package/dist/index.cjs +42 -34
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +5 -5
- package/dist/interaction/index.cjs +266 -235
- package/dist/interaction/index.cjs.map +1 -1
- package/dist/interaction/index.d.cts +2 -2
- package/dist/interaction/index.d.ts +2 -2
- package/dist/interaction/index.js +42 -11
- package/dist/interaction/index.js.map +1 -1
- package/dist/{render-Db0eSz_s.d.cts → render-Bp2FLEzv.d.cts} +14 -1
- package/dist/{render-Db0eSz_s.d.ts → render-Bp2FLEzv.d.ts} +14 -1
- package/dist/{runtime-n2yG-_j-.d.ts → runtime-CWIGxRcL.d.ts} +2 -2
- package/dist/{runtime-BhivvBeL.d.cts → runtime-DIag-XBa.d.cts} +2 -2
- package/dist/{runtimeTypes-DnI7mRF5.d.ts → runtimeTypes-BYODuxHk.d.cts} +2 -1
- package/dist/{runtimeTypes-CrkMHvVi.d.cts → runtimeTypes-C7sSLfOK.d.ts} +2 -1
- package/dist/stickyflow-diagram.global.js +490 -36
- package/dist/stickyflow-diagram.global.js.map +1 -1
- package/dist/{types-D4cH4f1a.d.ts → types-B9QM_H3R.d.ts} +1 -1
- package/dist/{types-BHfUKT4s.d.cts → types-D2w6D_wG.d.cts} +1 -1
- package/dist/viewer/index.cjs +9 -9
- package/dist/viewer/index.d.cts +5 -4
- package/dist/viewer/index.d.ts +5 -4
- package/dist/viewer/index.js +4 -4
- package/dist/web-component/index.cjs +6 -6
- package/dist/web-component/index.d.cts +2 -2
- package/dist/web-component/index.d.ts +2 -2
- package/dist/web-component/index.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-4G2R7PEL.js.map +0 -1
- package/dist/chunk-FVHVOJS2.js.map +0 -1
- package/dist/chunk-JIJMZMGY.cjs.map +0 -1
- package/dist/chunk-KTNCDNDB.cjs.map +0 -1
- package/dist/chunk-MFNUJA26.js.map +0 -1
- package/dist/chunk-WQRT5PVT.cjs.map +0 -1
- package/dist/chunk-WRDVNMFS.js.map +0 -1
- package/dist/chunk-XJ4W6TW4.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,44 @@ Two things count as breaking here that are easy to overlook:
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [0.8.0] - 2026-10-28
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- The shader program `glowCard`, the surface of a card: dark glass with a thin edge and colored lights low in the card that curl like smoke, fade out from the side set by `angle` and turn white at that edge, with grit in the lit parts. Parameters are `colorA`, `colorB`, `colorC`, `baseColor`, `glowHeight`, `glowSpread`, `angle`, `core`, `rim`, `grain`, `warp`, `intensity`, `cornerRadius` and `speed`. It draws its own rectangle.
|
|
25
|
+
- The names and the color bar of a heatmap can stand on any side of its grid. `rowLabelSide` is `left` or `right`, `columnLabelSide` is `top` or `bottom`, and `legendSide` is `top`, `bottom`, `left` or `right`. `legendGap` sets the distance between the grid and the color bar, and `axisLabelSpace` sets how much room the names get beside the data. Left out, the room is as much as the longest name needs. The names of a heatmap follow the font, size and color of the axis.
|
|
26
|
+
- `xLabelGap` and `yLabelGap` set how far the labels stand from the graphic, in pixels, along the x axis and along the y axis.
|
|
27
|
+
- `titleAlign` and `axisLabelAlign` align the title over a chart and the names beside the data to `left`, `center` or `right`.
|
|
28
|
+
- `axisLabelAngle` stands the labels of heatmap columns, bar categories and boxplot boxes up, from `0` for flat to `90` for upright.
|
|
29
|
+
- `data-sf-snap-distance` on the svg sets in pixels how close a shape has to come to another before it snaps. Without it the distance stays 20.
|
|
30
|
+
- Round charts (`pie`, `radar`, `radial`, `radialBar` and `polarArea`) keep their proportions while they are resized, and any shape does while Shift is held.
|
|
31
|
+
|
|
32
|
+
## [0.7.0] - 2026-10-25
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- The components `slider`, `progress` and `segmented`. A `slider` takes a value between `min` and `max` from the pointer, in steps of `step` if set. A `progress` shows a value as a bar or, with `variant: "ring"`, as a ring, and can write the share or the value into itself with `display`. A `segmented` shows the labels of `options`, separated by commas, and its value is the number of the chosen one, counted from 0.
|
|
37
|
+
- Three shader programs for backgrounds, which draw a rectangle or a rounded rectangle of their own, as `reactivePanel` does. `ledMatrix` is a wall of small pill-shaped lights with a glow that rises and drifts. `lightBand` is a band of light with a glow that runs through three colors. `silkFolds` is a folded cloth of satin with thin bright edges. Each one has `cornerRadius`, as a share of the shorter side, and `speed`, where 0 gives a still picture. `ledMatrix` and `silkFolds` react to the pointer, and `reaction` sets how strongly. On `ledMatrix` the places the pointer has been dim down behind it, and `trail` is how many seconds that takes. `pointerSize` sets how wide that stripe is. Its light can be moved with `originX` and `originY`, sized with `spread` and put out with 0, and `drift` sets how far it sways.
|
|
38
|
+
- A shader program can read `uWake`, 16 places the pointer has been over its surface, each as x, y and how much of it is left, when it has a number parameter `trail`, the seconds a place takes to fade out.
|
|
39
|
+
- A shader program can read `uPointer`, where the pointer is over its surface from 0 to 1 and counted from the lower left, and `uHover`, which glides to 1 while the pointer is over the surface and back to 0 when it leaves.
|
|
40
|
+
- The component `range`, a slider with two thumbs. `value` is the lower end and `valueEnd` the upper end, and both can be bound with `<->`, each to a field of its own. The nearer thumb follows the pointer, and the thumbs do not pass each other. It takes the `variant`, `direction` and `ticks` of the slider. Its interaction is `range`.
|
|
41
|
+
- `valueEnd` is a bindable property of a component that has a number property of that name. `runtime.slide(id, x, y)` takes the position as fractions of the width and the height.
|
|
42
|
+
- `componentTypes()` is exported from the main entry.
|
|
43
|
+
- `category` on a component descriptor, and `COMPONENT_CATEGORIES`, the list of the shelves a component is filed on: actions, selection, value input, text input, indicators, instruments, navigation and containers. The built-in components name their shelf.
|
|
44
|
+
- The component `knob`, a dial with an arc that fills up to the value. The pointer sets the value by its angle round the dial, between `min` and `max`, in steps of `step`. `start` and `sweep` set where the arc begins and how far it runs, and `display`, `thickness`, `face` and `dot` style it. Its interaction is `turn`.
|
|
45
|
+
- `direction: "vertical"` on a `slider` and on a `progress` bar stands them upright, and they fill from below. `ticks` on a `slider` draws that many marks along it, the two ends included, and `tickColor` colors them.
|
|
46
|
+
- `variant: "field"` on a `slider` draws a field that fills up to the value, with a thin handle at its end, the `label` at the left and the value at the right (`display` is `value`, `percent` or `none`). `surface`, `fill`, `radius`, `textColor` and `fontSize` style it.
|
|
47
|
+
- The component interactions `slide` and `pick`, and `runtime.slide(id, fraction)` on a binding runtime, which turns a position along the width of a component into its value.
|
|
48
|
+
- `animate` on `switch`, `checkbox`, `toggleButton` and `button`, and on the new components. It is the number of milliseconds a change of position, size, color or opacity takes to show. The default is 160 for the first four, 0 for `slider`, 300 for `progress` and 200 for `segmented`. A scene style can carry the same as `transition`, and the viewer patches the elements in place, so the browser does the animation.
|
|
49
|
+
- The shader program `reactivePanel` draws a rounded panel that can send light into the scene and receive it. A panel with `emission` lights the edges of the panels near it on the side that faces it. `reception` sets how much a panel takes in, `emitterFill`, `grain` and `grainScale` light and texture the inside of an emitter, and `glowRadius`, `borderWidth` and `cornerRadius` shape the glow and the border.
|
|
50
|
+
- `surfacePadding` on a `Shader` adds room around the shape for an outer glow, in canvas units. It is not a parameter of the program.
|
|
51
|
+
- A shader on a `rectangle` or a `rounded_rectangle` is drawn when its program draws a rectangle of its own. Today that is `reactivePanel`. Every other program still needs a `circle` or an `oval`.
|
|
52
|
+
- `self.id` in an expression is the id of the element the expression belongs to. In a binding of a `Shader` it is read separately for every shape that uses the shader, so one shader can light the tapped panel and no other. In an element handler it is the element that was pressed, so `onTap: glow.active <- self.id` works for any number of elements.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Every shader surface in the SVG carries `data-sf-shader-padding`, `0` when there is no padding.
|
|
57
|
+
|
|
20
58
|
## [0.6.0] - 2026-10-22
|
|
21
59
|
|
|
22
60
|
### Added
|
|
@@ -235,4 +273,5 @@ First versioned release. Not yet published to npm.
|
|
|
235
273
|
across machines. Now a locale-independent code-point compare.
|
|
236
274
|
|
|
237
275
|
[Unreleased]: https://github.com/D-Queck/stickyflow.js/compare/v0.1.0...HEAD
|
|
276
|
+
[0.7.0]: https://github.com/D-Queck/stickyflow.js/releases/tag/v0.7.0
|
|
238
277
|
[0.1.0]: https://github.com/D-Queck/stickyflow.js/releases/tag/v0.1.0
|
package/dist/binding/index.cjs
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
3
|
+
var chunkXPM3E7NV_cjs = require('../chunk-XPM3E7NV.cjs');
|
|
4
|
+
require('../chunk-VOYX6JMW.cjs');
|
|
5
|
+
require('../chunk-LNW5VIEA.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
Object.defineProperty(exports, "buildBindingGraph", {
|
|
10
10
|
enumerable: true,
|
|
11
|
-
get: function () { return
|
|
11
|
+
get: function () { return chunkXPM3E7NV_cjs.buildBindingGraph; }
|
|
12
12
|
});
|
|
13
13
|
Object.defineProperty(exports, "collectContracts", {
|
|
14
14
|
enumerable: true,
|
|
15
|
-
get: function () { return
|
|
15
|
+
get: function () { return chunkXPM3E7NV_cjs.collectContracts; }
|
|
16
16
|
});
|
|
17
17
|
Object.defineProperty(exports, "createBindingRuntime", {
|
|
18
18
|
enumerable: true,
|
|
19
|
-
get: function () { return
|
|
19
|
+
get: function () { return chunkXPM3E7NV_cjs.createBindingRuntime; }
|
|
20
20
|
});
|
|
21
21
|
Object.defineProperty(exports, "createDataSource", {
|
|
22
22
|
enumerable: true,
|
|
23
|
-
get: function () { return
|
|
23
|
+
get: function () { return chunkXPM3E7NV_cjs.createDataSource; }
|
|
24
24
|
});
|
|
25
25
|
Object.defineProperty(exports, "interactiveElements", {
|
|
26
26
|
enumerable: true,
|
|
27
|
-
get: function () { return
|
|
27
|
+
get: function () { return chunkXPM3E7NV_cjs.interactiveElements; }
|
|
28
28
|
});
|
|
29
29
|
Object.defineProperty(exports, "renderBound", {
|
|
30
30
|
enumerable: true,
|
|
31
|
-
get: function () { return
|
|
31
|
+
get: function () { return chunkXPM3E7NV_cjs.renderBound; }
|
|
32
32
|
});
|
|
33
33
|
//# sourceMappingURL=index.cjs.map
|
|
34
34
|
//# sourceMappingURL=index.cjs.map
|
package/dist/binding/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-
|
|
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-
|
|
3
|
-
export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-
|
|
4
|
-
import '../render-
|
|
1
|
+
import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-BYODuxHk.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-BYODuxHk.cjs';
|
|
3
|
+
export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-DIag-XBa.cjs';
|
|
4
|
+
import '../render-Bp2FLEzv.cjs';
|
|
5
5
|
|
|
6
6
|
declare function collectContracts(sflDocument: SflDocument): {
|
|
7
7
|
contracts: Map<string, DataSourceContract>;
|
package/dist/binding/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-
|
|
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-
|
|
3
|
-
export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-
|
|
4
|
-
import '../render-
|
|
1
|
+
import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-C7sSLfOK.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-C7sSLfOK.js';
|
|
3
|
+
export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-CWIGxRcL.js';
|
|
4
|
+
import '../render-Bp2FLEzv.js';
|
|
5
5
|
|
|
6
6
|
declare function collectContracts(sflDocument: SflDocument): {
|
|
7
7
|
contracts: Map<string, DataSourceContract>;
|
package/dist/binding/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { buildBindingGraph, collectContracts, createBindingRuntime, createDataSource, interactiveElements, renderBound } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { buildBindingGraph, collectContracts, createBindingRuntime, createDataSource, interactiveElements, renderBound } from '../chunk-CZW3ARXQ.js';
|
|
2
|
+
import '../chunk-MAPNY7MJ.js';
|
|
3
|
+
import '../chunk-GLZVHUSW.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { renderCanvas, sflToRenderInput } from './chunk-
|
|
2
|
-
import { getComponentDescriptor, parseSource, isGenericComponent, isBuiltInComponentType } from './chunk-
|
|
1
|
+
import { renderCanvas, sflToRenderInput, sliderReach } from './chunk-MAPNY7MJ.js';
|
|
2
|
+
import { getComponentDescriptor, parseSource, isGenericComponent, isBuiltInComponentType } from './chunk-GLZVHUSW.js';
|
|
3
3
|
|
|
4
4
|
// src/binding/types.ts
|
|
5
5
|
var DECLARED = {
|
|
@@ -98,7 +98,7 @@ function createDataSource(initial) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
// src/binding/componentBinding.ts
|
|
101
|
-
var BINDABLE_COMPONENT_PROPERTIES = ["value", "disabled"];
|
|
101
|
+
var BINDABLE_COMPONENT_PROPERTIES = ["value", "valueEnd", "disabled"];
|
|
102
102
|
function acceptsUserChange(componentType) {
|
|
103
103
|
return getComponentDescriptor(componentType)?.value?.writable === true;
|
|
104
104
|
}
|
|
@@ -116,6 +116,9 @@ function componentPropertyType(componentType, property) {
|
|
|
116
116
|
if (property === "disabled") {
|
|
117
117
|
return "boolean";
|
|
118
118
|
}
|
|
119
|
+
if (property === "valueEnd") {
|
|
120
|
+
return getComponentDescriptor(componentType)?.properties.valueEnd?.type === "number" ? "number" : void 0;
|
|
121
|
+
}
|
|
119
122
|
return property === "value" ? getComponentDescriptor(componentType)?.value?.type : void 0;
|
|
120
123
|
}
|
|
121
124
|
function twoWayTargetProblem(key, expr, contracts) {
|
|
@@ -260,7 +263,7 @@ function inferType(expr, scope, report) {
|
|
|
260
263
|
const name = expr.path.join(".");
|
|
261
264
|
report(
|
|
262
265
|
"unknown-reference",
|
|
263
|
-
name === "time.delta" ? "'time.delta' is only available in an onTick handler." : `Unknown reference '${name}'. Use <DataSource>.<field>, or <element>.pressed / hovered / pointer.`
|
|
266
|
+
name === "time.delta" ? "'time.delta' is only available in an onTick handler." : `Unknown reference '${name}'. Use <DataSource>.<field>, self.id, or <element>.pressed / hovered / pointer.`
|
|
264
267
|
);
|
|
265
268
|
}
|
|
266
269
|
return type;
|
|
@@ -429,12 +432,15 @@ function elementStateType(element, state) {
|
|
|
429
432
|
}
|
|
430
433
|
return element.kind === "Component" ? componentStateType(element.componentType, state) : void 0;
|
|
431
434
|
}
|
|
432
|
-
function createScope(contracts, elements, ticking = false) {
|
|
435
|
+
function createScope(contracts, elements, ticking = false, selfAvailable = false) {
|
|
433
436
|
return {
|
|
434
437
|
resolve(path) {
|
|
435
438
|
if (path.length !== 2) {
|
|
436
439
|
return void 0;
|
|
437
440
|
}
|
|
441
|
+
if (selfAvailable && path[0] === "self" && path[1] === "id") {
|
|
442
|
+
return "string";
|
|
443
|
+
}
|
|
438
444
|
const contract = contracts.get(path[0]);
|
|
439
445
|
if (contract) {
|
|
440
446
|
return fieldType(contract, path[1]);
|
|
@@ -542,7 +548,7 @@ function bindHandler(site, contracts, elements, diagnostics) {
|
|
|
542
548
|
report("tick-needs-record", `DataSource '${name}' has to be a record source to change its fields on every tick.`);
|
|
543
549
|
return void 0;
|
|
544
550
|
}
|
|
545
|
-
const scope = createScope(contracts, elements, ticking);
|
|
551
|
+
const scope = createScope(contracts, elements, ticking, !ticking);
|
|
546
552
|
const assignments = handler.assignments.flatMap(
|
|
547
553
|
(assignment) => bindAssignment(assignment, name, own, contracts, scope, report) ?? []
|
|
548
554
|
);
|
|
@@ -581,7 +587,7 @@ function expectedType(site, elements) {
|
|
|
581
587
|
}
|
|
582
588
|
function canBindTwoWay(site, elements) {
|
|
583
589
|
const { kind, path, binding } = site;
|
|
584
|
-
return kind === "Component" && binding.key === "value" && acceptsUserChange(elements.get(path[0])?.componentType);
|
|
590
|
+
return kind === "Component" && (binding.key === "value" || binding.key === "valueEnd") && acceptsUserChange(elements.get(path[0])?.componentType);
|
|
585
591
|
}
|
|
586
592
|
function rejectedOperator(site, elements, contracts) {
|
|
587
593
|
const { binding } = site;
|
|
@@ -648,7 +654,7 @@ function buildBindingGraph(sflDocument) {
|
|
|
648
654
|
const { contracts, diagnostics } = collectContracts(sflDocument);
|
|
649
655
|
const elements = collectElements(sflDocument);
|
|
650
656
|
warnNameCollisions(contracts, elements, diagnostics);
|
|
651
|
-
const scope = createScope(contracts, elements);
|
|
657
|
+
const scope = createScope(contracts, elements, false, true);
|
|
652
658
|
const sites = [];
|
|
653
659
|
collectSites(sflDocument.blocks, [], sites);
|
|
654
660
|
const bindings = sites.flatMap((site) => bindProperty(site, scope, elements, contracts, diagnostics) ?? []);
|
|
@@ -659,7 +665,7 @@ function buildBindingGraph(sflDocument) {
|
|
|
659
665
|
}
|
|
660
666
|
|
|
661
667
|
// src/binding/interactive.ts
|
|
662
|
-
var OPERATED = /* @__PURE__ */ new Set(["toggle", "press"]);
|
|
668
|
+
var OPERATED = /* @__PURE__ */ new Set(["toggle", "press", "slide", "pick", "turn", "range"]);
|
|
663
669
|
function interactiveElements(graph) {
|
|
664
670
|
const pressable = /* @__PURE__ */ new Set();
|
|
665
671
|
const scales = /* @__PURE__ */ new Set();
|
|
@@ -733,6 +739,12 @@ function writeComponentValue(input, id, value) {
|
|
|
733
739
|
}
|
|
734
740
|
component.value = isGenericComponent(component) ? value : String(value);
|
|
735
741
|
}
|
|
742
|
+
function writeComponentValueEnd(input, id, value) {
|
|
743
|
+
const component = findComponent(input, id);
|
|
744
|
+
if (component && isGenericComponent(component)) {
|
|
745
|
+
component.properties.valueEnd = value;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
736
748
|
function writeComponentDisabled(input, id, disabled) {
|
|
737
749
|
const component = findComponent(input, id);
|
|
738
750
|
if (component && isGenericComponent(component)) {
|
|
@@ -775,13 +787,17 @@ var APPLY = {
|
|
|
775
787
|
"Shape.textColor": (input, path, value) => setShape(input, path, (shape) => shape.textColor = value),
|
|
776
788
|
"Shape.opacity": (input, path, value) => setShape(input, path, (shape) => shape.opacity = value),
|
|
777
789
|
"Component.value": (input, path, value) => writeComponentValue(input, path[0], value),
|
|
790
|
+
"Component.valueEnd": (input, path, value) => writeComponentValueEnd(input, path[0], value),
|
|
778
791
|
"Component.disabled": (input, path, value) => writeComponentDisabled(input, path[0], value === true)
|
|
779
792
|
};
|
|
780
|
-
function applyShader(input, binding, value) {
|
|
793
|
+
function applyShader(input, binding, value, ownerId) {
|
|
781
794
|
const owners = [];
|
|
782
795
|
for (const shape of input.shapes) {
|
|
783
|
-
if (shape.shader?.name === binding.ownerPath[0]) {
|
|
784
|
-
shape.shader
|
|
796
|
+
if (shape.shader?.name === binding.ownerPath[0] && (ownerId === void 0 || shape.id === ownerId)) {
|
|
797
|
+
shape.shader = {
|
|
798
|
+
...shape.shader,
|
|
799
|
+
parameters: { ...shape.shader.parameters, [binding.property]: value }
|
|
800
|
+
};
|
|
785
801
|
owners.push(shape.id);
|
|
786
802
|
}
|
|
787
803
|
}
|
|
@@ -846,7 +862,7 @@ function readValue(state, path) {
|
|
|
846
862
|
return Array.isArray(data) ? data.map((row) => row[field]) : data[field];
|
|
847
863
|
}
|
|
848
864
|
function missingSource(state, binding) {
|
|
849
|
-
return binding.dependencies.map((dependency) => dependency.split(".")[0]).find((name) => !state.sources.has(name) && !state.elementState.has(name));
|
|
865
|
+
return binding.dependencies.map((dependency) => dependency.split(".")[0]).find((name) => name !== "self" && !state.sources.has(name) && !state.elementState.has(name));
|
|
850
866
|
}
|
|
851
867
|
|
|
852
868
|
// src/binding/evaluation.ts
|
|
@@ -888,7 +904,32 @@ function evaluateBinding(state, binding) {
|
|
|
888
904
|
warnMissingSource(state, binding, missing);
|
|
889
905
|
return false;
|
|
890
906
|
}
|
|
891
|
-
const
|
|
907
|
+
const readsSelf = binding.dependencies.includes("self.id");
|
|
908
|
+
if (binding.ownerKind === "Shader" && readsSelf) {
|
|
909
|
+
const owners = state.input.shapes.filter((shape) => shape.shader?.name === binding.ownerPath[0]);
|
|
910
|
+
for (const owner of owners) {
|
|
911
|
+
const value2 = evaluate(binding.expr, {
|
|
912
|
+
read: (path) => path[0] === "self" && path[1] === "id" ? owner.id : readValue(state, path)
|
|
913
|
+
});
|
|
914
|
+
const appliedId = `${binding.id}.${owner.id}`;
|
|
915
|
+
const key2 = JSON.stringify(value2);
|
|
916
|
+
if (state.applied.get(appliedId) === key2) {
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
state.applied.set(appliedId, key2);
|
|
920
|
+
applyShader(state.input, binding, value2, owner.id);
|
|
921
|
+
announce(state, appliedId, {
|
|
922
|
+
kind: "shader",
|
|
923
|
+
owners: [owner.id],
|
|
924
|
+
parameters: { [binding.property]: value2 }
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
const selfId = binding.ownerKind === "Shader" ? void 0 : binding.ownerPath[0];
|
|
930
|
+
const value = evaluate(binding.expr, {
|
|
931
|
+
read: (path) => path[0] === "self" && path[1] === "id" && selfId ? selfId : readValue(state, path)
|
|
932
|
+
});
|
|
892
933
|
const key = JSON.stringify(value);
|
|
893
934
|
if (state.applied.get(binding.id) === key) {
|
|
894
935
|
return false;
|
|
@@ -946,14 +987,22 @@ function markDirty(state, name) {
|
|
|
946
987
|
}
|
|
947
988
|
|
|
948
989
|
// src/binding/handlers.ts
|
|
949
|
-
function runHandler(state, handler, delta) {
|
|
990
|
+
function runHandler(state, handler, delta, selfId) {
|
|
950
991
|
const env = {
|
|
951
|
-
read: (path) =>
|
|
992
|
+
read: (path) => {
|
|
993
|
+
if (path[0] === "time" && path[1] === "delta") {
|
|
994
|
+
return delta ?? 0;
|
|
995
|
+
}
|
|
996
|
+
if (path[0] === "self" && path[1] === "id" && selfId) {
|
|
997
|
+
return selfId;
|
|
998
|
+
}
|
|
999
|
+
return readValue(state, path);
|
|
1000
|
+
}
|
|
952
1001
|
};
|
|
953
1002
|
for (const assignment of handler.assignments) {
|
|
954
1003
|
const target = state.sources.get(assignment.source);
|
|
955
1004
|
const readable = collectRefs(assignment.expr).every(
|
|
956
|
-
([name]) => name === "time" || state.sources.has(name) || state.elementState.has(name)
|
|
1005
|
+
([name]) => name === "time" || name === "self" && Boolean(selfId) || state.sources.has(name) || state.elementState.has(name)
|
|
957
1006
|
);
|
|
958
1007
|
if (!target || !("set" in target) || !readable) {
|
|
959
1008
|
continue;
|
|
@@ -974,7 +1023,7 @@ function runHandler(state, handler, delta) {
|
|
|
974
1023
|
function dispatch(state, id, event) {
|
|
975
1024
|
for (const handler of state.graph.handlers) {
|
|
976
1025
|
if (handler.event === event && handler.ownerKind !== "DataSource" && handler.ownerPath[0] === id) {
|
|
977
|
-
runHandler(state, handler);
|
|
1026
|
+
runHandler(state, handler, void 0, id);
|
|
978
1027
|
}
|
|
979
1028
|
}
|
|
980
1029
|
}
|
|
@@ -1000,9 +1049,9 @@ function descriptorOf(state, id) {
|
|
|
1000
1049
|
const info = state.graph.elements.get(id);
|
|
1001
1050
|
return info?.kind === "Component" ? getComponentDescriptor(info.componentType) : void 0;
|
|
1002
1051
|
}
|
|
1003
|
-
function valueBinding(state, id) {
|
|
1052
|
+
function valueBinding(state, id, property = "value") {
|
|
1004
1053
|
return state.graph.bindings.find(
|
|
1005
|
-
(binding) => binding.ownerKind === "Component" && binding.ownerPath[0] === id && binding.property ===
|
|
1054
|
+
(binding) => binding.ownerKind === "Component" && binding.ownerPath[0] === id && binding.property === property
|
|
1006
1055
|
);
|
|
1007
1056
|
}
|
|
1008
1057
|
function writeBack(state, binding, value) {
|
|
@@ -1016,7 +1065,30 @@ function writeBack(state, binding, value) {
|
|
|
1016
1065
|
source.set({ ...row, [target[1]]: value });
|
|
1017
1066
|
}
|
|
1018
1067
|
}
|
|
1019
|
-
function
|
|
1068
|
+
function changeValueEnd(state, id, next) {
|
|
1069
|
+
const component = findComponent(state.input, id);
|
|
1070
|
+
if (!component || !isGenericComponent(component) || component.properties.valueEnd === next || isComponentDisabled(state.input, id)) {
|
|
1071
|
+
return false;
|
|
1072
|
+
}
|
|
1073
|
+
const binding = valueBinding(state, id, "valueEnd");
|
|
1074
|
+
if (binding && binding.operator !== "<->") {
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1077
|
+
writeComponentValueEnd(state.input, id, next);
|
|
1078
|
+
state.renderNeeded = true;
|
|
1079
|
+
if (binding) {
|
|
1080
|
+
state.applied.set(binding.id, JSON.stringify(next));
|
|
1081
|
+
writeBack(state, binding, next);
|
|
1082
|
+
}
|
|
1083
|
+
markDirty(state, id);
|
|
1084
|
+
dispatch(state, id, CHANGE_EVENT);
|
|
1085
|
+
schedule(state);
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
function changeComponentValue(state, id, next, property = "value") {
|
|
1089
|
+
if (property === "valueEnd") {
|
|
1090
|
+
return typeof next === "number" && changeValueEnd(state, id, next);
|
|
1091
|
+
}
|
|
1020
1092
|
const spec = descriptorOf(state, id)?.value;
|
|
1021
1093
|
const element = state.elementState.get(id);
|
|
1022
1094
|
if (!spec?.writable || !element || typeof next !== spec.type || element.value === next) {
|
|
@@ -1041,6 +1113,64 @@ function changeComponentValue(state, id, next) {
|
|
|
1041
1113
|
schedule(state);
|
|
1042
1114
|
return true;
|
|
1043
1115
|
}
|
|
1116
|
+
var TAU = Math.PI * 2;
|
|
1117
|
+
var grabbed = /* @__PURE__ */ new WeakMap();
|
|
1118
|
+
var within = (value) => Math.min(1, Math.max(0, value));
|
|
1119
|
+
function slideAlong(properties, width, height, x, y) {
|
|
1120
|
+
const vertical = properties.direction === "vertical";
|
|
1121
|
+
const length = vertical ? height : width;
|
|
1122
|
+
const reach = sliderReach(properties.variant, vertical ? width : height);
|
|
1123
|
+
const position = vertical ? 1 - y : x;
|
|
1124
|
+
return length > reach * 2 ? within((position * length - reach) / (length - reach * 2)) : position;
|
|
1125
|
+
}
|
|
1126
|
+
function turnAlong(properties, width, height, x, y) {
|
|
1127
|
+
const start = Number(properties.start ?? 225) * Math.PI / 180;
|
|
1128
|
+
const sweep = Number(properties.sweep ?? 270) * Math.PI / 180;
|
|
1129
|
+
const gap = TAU - sweep;
|
|
1130
|
+
const angle = Math.atan2(-(y - 0.5) * height, (x - 0.5) * width);
|
|
1131
|
+
const shifted = start - angle + gap / 2;
|
|
1132
|
+
return within(((shifted % TAU + TAU) % TAU - gap / 2) / sweep);
|
|
1133
|
+
}
|
|
1134
|
+
function slideElement(state, id, x, y = 0) {
|
|
1135
|
+
const component = findComponent(state.input, id);
|
|
1136
|
+
if (!component || !isGenericComponent(component)) {
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
const kind = descriptorOf(state, id)?.interaction;
|
|
1140
|
+
const { properties } = component;
|
|
1141
|
+
if (kind === "pick") {
|
|
1142
|
+
const count = String(properties.options ?? "").split(",").filter((option) => option.trim()).length;
|
|
1143
|
+
if (count > 0) {
|
|
1144
|
+
changeComponentValue(state, id, Math.min(count - 1, Math.floor(x * count)));
|
|
1145
|
+
}
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
const along = kind === "turn" ? turnAlong(properties, component.width, component.height, x, y) : slideAlong(properties, component.width, component.height, x, y);
|
|
1149
|
+
const min = Number(properties.min ?? 0);
|
|
1150
|
+
const max = Number(properties.max ?? 100);
|
|
1151
|
+
const step = Number(properties.step ?? 0);
|
|
1152
|
+
let value = min + along * (max - min);
|
|
1153
|
+
if (step > 0) {
|
|
1154
|
+
value = min + Math.round((value - min) / step) * step;
|
|
1155
|
+
}
|
|
1156
|
+
const taken = Number(Math.min(max, Math.max(min, value)).toFixed(6));
|
|
1157
|
+
if (kind !== "range") {
|
|
1158
|
+
changeComponentValue(state, id, taken);
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
const low = Number(component.value);
|
|
1162
|
+
const high = Number(properties.valueEnd ?? max);
|
|
1163
|
+
const holds = grabbed.get(state) ?? /* @__PURE__ */ new Map();
|
|
1164
|
+
grabbed.set(state, holds);
|
|
1165
|
+
if (!holds.has(id)) {
|
|
1166
|
+
holds.set(id, taken >= high || taken > low && taken - low > high - taken ? "end" : "start");
|
|
1167
|
+
}
|
|
1168
|
+
if (holds.get(id) === "start") {
|
|
1169
|
+
changeComponentValue(state, id, Math.min(taken, high));
|
|
1170
|
+
} else {
|
|
1171
|
+
changeComponentValue(state, id, Math.max(taken, low), "valueEnd");
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1044
1174
|
function reactToActivation(state, id) {
|
|
1045
1175
|
const element = state.elementState.get(id);
|
|
1046
1176
|
const descriptor = descriptorOf(state, id);
|
|
@@ -1049,6 +1179,7 @@ function reactToActivation(state, id) {
|
|
|
1049
1179
|
}
|
|
1050
1180
|
}
|
|
1051
1181
|
function pressElement(state, id) {
|
|
1182
|
+
grabbed.get(state)?.delete(id);
|
|
1052
1183
|
if (isComponentDisabled(state.input, id)) {
|
|
1053
1184
|
return;
|
|
1054
1185
|
}
|
|
@@ -1056,6 +1187,7 @@ function pressElement(state, id) {
|
|
|
1056
1187
|
dispatch(state, id, "onPress");
|
|
1057
1188
|
}
|
|
1058
1189
|
function releaseElement(state, id, tapped) {
|
|
1190
|
+
grabbed.get(state)?.delete(id);
|
|
1059
1191
|
setElementState(state, id, { pressed: false });
|
|
1060
1192
|
if (isComponentDisabled(state.input, id)) {
|
|
1061
1193
|
return;
|
|
@@ -1152,6 +1284,7 @@ function createBindingRuntime(sfl, options = {}) {
|
|
|
1152
1284
|
release: (id, tapped) => releaseElement(state, id, tapped),
|
|
1153
1285
|
activate: (id) => activateElement(state, id),
|
|
1154
1286
|
change: (id, value) => changeComponentValue(state, id, value),
|
|
1287
|
+
slide: (id, x, y) => slideElement(state, id, x, y),
|
|
1155
1288
|
drag(id, pointer) {
|
|
1156
1289
|
if (pointer !== void 0) {
|
|
1157
1290
|
setElementState(state, id, { pointer });
|
|
@@ -1178,5 +1311,5 @@ function renderBound(sfl, options = {}) {
|
|
|
1178
1311
|
}
|
|
1179
1312
|
|
|
1180
1313
|
export { buildBindingGraph, collectContracts, createBindingRuntime, createDataSource, interactiveElements, renderBound };
|
|
1181
|
-
//# sourceMappingURL=chunk-
|
|
1182
|
-
//# sourceMappingURL=chunk-
|
|
1314
|
+
//# sourceMappingURL=chunk-CZW3ARXQ.js.map
|
|
1315
|
+
//# sourceMappingURL=chunk-CZW3ARXQ.js.map
|