@wardic/dom 0.0.0-stage → 1.0.0-rc.2
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/LICENSE +21 -0
- package/README.md +8 -2
- package/THIRD_PARTY_NOTICES.md +145 -0
- package/dist/Appear.d.ts +24 -0
- package/dist/Appear.d.ts.map +1 -0
- package/dist/Appear.js +25 -0
- package/dist/Appear.js.map +1 -0
- package/dist/Color.d.ts +14 -0
- package/dist/Color.d.ts.map +1 -0
- package/dist/Color.js +16 -0
- package/dist/Color.js.map +1 -0
- package/dist/DomAnnouncer.d.ts +13 -0
- package/dist/DomAnnouncer.d.ts.map +1 -0
- package/dist/DomAnnouncer.js +14 -0
- package/dist/DomAnnouncer.js.map +1 -0
- package/dist/DomClock.d.ts +11 -0
- package/dist/DomClock.d.ts.map +1 -0
- package/dist/DomClock.js +12 -0
- package/dist/DomClock.js.map +1 -0
- package/dist/DomDefaultTransition.d.ts +12 -0
- package/dist/DomDefaultTransition.d.ts.map +1 -0
- package/dist/DomDefaultTransition.js +13 -0
- package/dist/DomDefaultTransition.js.map +1 -0
- package/dist/DomInput.d.ts +13 -0
- package/dist/DomInput.d.ts.map +1 -0
- package/dist/DomInput.js +15 -0
- package/dist/DomInput.js.map +1 -0
- package/dist/DomInterpolators.d.ts +13 -0
- package/dist/DomInterpolators.d.ts.map +1 -0
- package/dist/DomInterpolators.js +14 -0
- package/dist/DomInterpolators.js.map +1 -0
- package/dist/DomKeyRules.d.ts +13 -0
- package/dist/DomKeyRules.d.ts.map +1 -0
- package/dist/DomKeyRules.js +14 -0
- package/dist/DomKeyRules.js.map +1 -0
- package/dist/DomPositionalKeys.d.ts +13 -0
- package/dist/DomPositionalKeys.d.ts.map +1 -0
- package/dist/DomPositionalKeys.js +14 -0
- package/dist/DomPositionalKeys.js.map +1 -0
- package/dist/DomProbe.d.ts +13 -0
- package/dist/DomProbe.d.ts.map +1 -0
- package/dist/DomProbe.js +14 -0
- package/dist/DomProbe.js.map +1 -0
- package/dist/DomProjectionSystem.d.ts +28 -0
- package/dist/DomProjectionSystem.d.ts.map +1 -0
- package/dist/DomProjectionSystem.js +41 -0
- package/dist/DomProjectionSystem.js.map +1 -0
- package/dist/DomRenderer.d.ts +13 -0
- package/dist/DomRenderer.d.ts.map +1 -0
- package/dist/DomRenderer.js +15 -0
- package/dist/DomRenderer.js.map +1 -0
- package/dist/FlushGate.d.ts +48 -0
- package/dist/FlushGate.d.ts.map +1 -0
- package/dist/FlushGate.js +62 -0
- package/dist/FlushGate.js.map +1 -0
- package/dist/MeasuredPair.d.ts +14 -0
- package/dist/MeasuredPair.d.ts.map +1 -0
- package/dist/MeasuredPair.js +16 -0
- package/dist/MeasuredPair.js.map +1 -0
- package/dist/OwnValues.d.ts +14 -0
- package/dist/OwnValues.d.ts.map +1 -0
- package/dist/OwnValues.js +15 -0
- package/dist/OwnValues.js.map +1 -0
- package/dist/ProjectionSystem.d.ts +34 -0
- package/dist/ProjectionSystem.d.ts.map +1 -0
- package/dist/ProjectionSystem.js +29 -0
- package/dist/ProjectionSystem.js.map +1 -0
- package/dist/ReorderController.d.ts +41 -0
- package/dist/ReorderController.d.ts.map +1 -0
- package/dist/ReorderController.js +44 -0
- package/dist/ReorderController.js.map +1 -0
- package/dist/Report.d.ts +12 -0
- package/dist/Report.d.ts.map +1 -0
- package/dist/Report.js +13 -0
- package/dist/Report.js.map +1 -0
- package/dist/ScrollOffset.d.ts +34 -0
- package/dist/ScrollOffset.d.ts.map +1 -0
- package/dist/ScrollOffset.js +42 -0
- package/dist/ScrollOffset.js.map +1 -0
- package/dist/Style.d.ts +15 -0
- package/dist/Style.d.ts.map +1 -0
- package/dist/Style.js +17 -0
- package/dist/Style.js.map +1 -0
- package/dist/Svg.d.ts +13 -0
- package/dist/Svg.d.ts.map +1 -0
- package/dist/Svg.js +14 -0
- package/dist/Svg.js.map +1 -0
- package/dist/Variables.d.ts +13 -0
- package/dist/Variables.d.ts.map +1 -0
- package/dist/Variables.js +14 -0
- package/dist/Variables.js.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/announcer.d.ts +50 -0
- package/dist/internal/announcer.d.ts.map +1 -0
- package/dist/internal/announcer.js +115 -0
- package/dist/internal/announcer.js.map +1 -0
- package/dist/internal/appear.d.ts +169 -0
- package/dist/internal/appear.d.ts.map +1 -0
- package/dist/internal/appear.js +499 -0
- package/dist/internal/appear.js.map +1 -0
- package/dist/internal/auto-scroll.d.ts +24 -0
- package/dist/internal/auto-scroll.d.ts.map +1 -0
- package/dist/internal/auto-scroll.js +124 -0
- package/dist/internal/auto-scroll.js.map +1 -0
- package/dist/internal/clock.d.ts +19 -0
- package/dist/internal/clock.d.ts.map +1 -0
- package/dist/internal/clock.js +39 -0
- package/dist/internal/clock.js.map +1 -0
- package/dist/internal/colors.d.ts +45 -0
- package/dist/internal/colors.d.ts.map +1 -0
- package/dist/internal/colors.js +193 -0
- package/dist/internal/colors.js.map +1 -0
- package/dist/internal/complex.d.ts +24 -0
- package/dist/internal/complex.d.ts.map +1 -0
- package/dist/internal/complex.js +28 -0
- package/dist/internal/complex.js.map +1 -0
- package/dist/internal/content-watch.d.ts +20 -0
- package/dist/internal/content-watch.d.ts.map +1 -0
- package/dist/internal/content-watch.js +76 -0
- package/dist/internal/content-watch.js.map +1 -0
- package/dist/internal/default-transition.d.ts +25 -0
- package/dist/internal/default-transition.d.ts.map +1 -0
- package/dist/internal/default-transition.js +41 -0
- package/dist/internal/default-transition.js.map +1 -0
- package/dist/internal/drag-defaults.d.ts +18 -0
- package/dist/internal/drag-defaults.d.ts.map +1 -0
- package/dist/internal/drag-defaults.js +38 -0
- package/dist/internal/drag-defaults.js.map +1 -0
- package/dist/internal/gate.d.ts +186 -0
- package/dist/internal/gate.d.ts.map +1 -0
- package/dist/internal/gate.js +453 -0
- package/dist/internal/gate.js.map +1 -0
- package/dist/internal/input.d.ts +41 -0
- package/dist/internal/input.d.ts.map +1 -0
- package/dist/internal/input.js +476 -0
- package/dist/internal/input.js.map +1 -0
- package/dist/internal/interpolators.d.ts +19 -0
- package/dist/internal/interpolators.d.ts.map +1 -0
- package/dist/internal/interpolators.js +30 -0
- package/dist/internal/interpolators.js.map +1 -0
- package/dist/internal/key-rules.d.ts +11 -0
- package/dist/internal/key-rules.d.ts.map +1 -0
- package/dist/internal/key-rules.js +244 -0
- package/dist/internal/key-rules.js.map +1 -0
- package/dist/internal/measure.d.ts +150 -0
- package/dist/internal/measure.d.ts.map +1 -0
- package/dist/internal/measure.js +278 -0
- package/dist/internal/measure.js.map +1 -0
- package/dist/internal/measured-pairs.d.ts +38 -0
- package/dist/internal/measured-pairs.d.ts.map +1 -0
- package/dist/internal/measured-pairs.js +251 -0
- package/dist/internal/measured-pairs.js.map +1 -0
- package/dist/internal/own-values.d.ts +35 -0
- package/dist/internal/own-values.d.ts.map +1 -0
- package/dist/internal/own-values.js +117 -0
- package/dist/internal/own-values.js.map +1 -0
- package/dist/internal/pass-ends.d.ts +21 -0
- package/dist/internal/pass-ends.d.ts.map +1 -0
- package/dist/internal/pass-ends.js +14 -0
- package/dist/internal/pass-ends.js.map +1 -0
- package/dist/internal/positional-keys.d.ts +16 -0
- package/dist/internal/positional-keys.d.ts.map +1 -0
- package/dist/internal/positional-keys.js +21 -0
- package/dist/internal/positional-keys.js.map +1 -0
- package/dist/internal/probe.d.ts +10 -0
- package/dist/internal/probe.d.ts.map +1 -0
- package/dist/internal/probe.js +117 -0
- package/dist/internal/probe.js.map +1 -0
- package/dist/internal/projection-defaults.d.ts +34 -0
- package/dist/internal/projection-defaults.d.ts.map +1 -0
- package/dist/internal/projection-defaults.js +21 -0
- package/dist/internal/projection-defaults.js.map +1 -0
- package/dist/internal/projection.d.ts +529 -0
- package/dist/internal/projection.d.ts.map +1 -0
- package/dist/internal/projection.js +4990 -0
- package/dist/internal/projection.js.map +1 -0
- package/dist/internal/renderer.d.ts +86 -0
- package/dist/internal/renderer.d.ts.map +1 -0
- package/dist/internal/renderer.js +616 -0
- package/dist/internal/renderer.js.map +1 -0
- package/dist/internal/reorder.d.ts +159 -0
- package/dist/internal/reorder.d.ts.map +1 -0
- package/dist/internal/reorder.js +437 -0
- package/dist/internal/reorder.js.map +1 -0
- package/dist/internal/report.d.ts +30 -0
- package/dist/internal/report.d.ts.map +1 -0
- package/dist/internal/report.js +60 -0
- package/dist/internal/report.js.map +1 -0
- package/dist/internal/require-global.d.ts +11 -0
- package/dist/internal/require-global.d.ts.map +1 -0
- package/dist/internal/require-global.js +31 -0
- package/dist/internal/require-global.js.map +1 -0
- package/dist/internal/reveal.d.ts +16 -0
- package/dist/internal/reveal.d.ts.map +1 -0
- package/dist/internal/reveal.js +66 -0
- package/dist/internal/reveal.js.map +1 -0
- package/dist/internal/runner.d.ts +21 -0
- package/dist/internal/runner.d.ts.map +1 -0
- package/dist/internal/runner.js +48 -0
- package/dist/internal/runner.js.map +1 -0
- package/dist/internal/scale-correction.d.ts +80 -0
- package/dist/internal/scale-correction.d.ts.map +1 -0
- package/dist/internal/scale-correction.js +227 -0
- package/dist/internal/scale-correction.js.map +1 -0
- package/dist/internal/scroll.d.ts +35 -0
- package/dist/internal/scroll.d.ts.map +1 -0
- package/dist/internal/scroll.js +244 -0
- package/dist/internal/scroll.js.map +1 -0
- package/dist/internal/scrollers.d.ts +35 -0
- package/dist/internal/scrollers.d.ts.map +1 -0
- package/dist/internal/scrollers.js +38 -0
- package/dist/internal/scrollers.js.map +1 -0
- package/dist/internal/starting-style.d.ts +141 -0
- package/dist/internal/starting-style.d.ts.map +1 -0
- package/dist/internal/starting-style.js +300 -0
- package/dist/internal/starting-style.js.map +1 -0
- package/dist/internal/svg.d.ts +60 -0
- package/dist/internal/svg.d.ts.map +1 -0
- package/dist/internal/svg.js +257 -0
- package/dist/internal/svg.js.map +1 -0
- package/dist/internal/variables.d.ts +45 -0
- package/dist/internal/variables.d.ts.map +1 -0
- package/dist/internal/variables.js +92 -0
- package/dist/internal/variables.js.map +1 -0
- package/package.json +65 -4
- package/src/Appear.ts +45 -0
- package/src/Color.ts +24 -0
- package/src/DomAnnouncer.ts +22 -0
- package/src/DomClock.ts +13 -0
- package/src/DomDefaultTransition.ts +16 -0
- package/src/DomInput.ts +22 -0
- package/src/DomInterpolators.ts +16 -0
- package/src/DomKeyRules.ts +17 -0
- package/src/DomPositionalKeys.ts +16 -0
- package/src/DomProbe.ts +15 -0
- package/src/DomProjectionSystem.ts +44 -0
- package/src/DomRenderer.ts +26 -0
- package/src/FlushGate.ts +81 -0
- package/src/MeasuredPair.ts +15 -0
- package/src/OwnValues.ts +19 -0
- package/src/ProjectionSystem.ts +51 -0
- package/src/ReorderController.ts +72 -0
- package/src/Report.ts +17 -0
- package/src/ScrollOffset.ts +54 -0
- package/src/Style.ts +37 -0
- package/src/Svg.ts +21 -0
- package/src/Variables.ts +17 -0
- package/src/index.ts +106 -0
- package/src/internal/announcer.ts +132 -0
- package/src/internal/appear.ts +739 -0
- package/src/internal/auto-scroll.ts +176 -0
- package/src/internal/clock.ts +45 -0
- package/src/internal/colors.ts +258 -0
- package/src/internal/complex.ts +29 -0
- package/src/internal/content-watch.ts +84 -0
- package/src/internal/culori.d.ts +58 -0
- package/src/internal/default-transition.ts +50 -0
- package/src/internal/drag-defaults.ts +54 -0
- package/src/internal/gate.ts +593 -0
- package/src/internal/input.ts +579 -0
- package/src/internal/interpolators.ts +33 -0
- package/src/internal/key-rules.ts +357 -0
- package/src/internal/measure.ts +357 -0
- package/src/internal/measured-pairs.ts +297 -0
- package/src/internal/own-values.ts +166 -0
- package/src/internal/pass-ends.ts +23 -0
- package/src/internal/positional-keys.ts +24 -0
- package/src/internal/probe.ts +176 -0
- package/src/internal/projection-defaults.ts +45 -0
- package/src/internal/projection.ts +5999 -0
- package/src/internal/renderer.ts +646 -0
- package/src/internal/reorder.ts +604 -0
- package/src/internal/report.ts +69 -0
- package/src/internal/require-global.ts +46 -0
- package/src/internal/reveal.ts +69 -0
- package/src/internal/runner.ts +64 -0
- package/src/internal/scale-correction.ts +310 -0
- package/src/internal/scroll.ts +356 -0
- package/src/internal/scrollers.ts +51 -0
- package/src/internal/starting-style.ts +396 -0
- package/src/internal/svg.ts +300 -0
- package/src/internal/variables.ts +145 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import * as Arr from "effect/Array";
|
|
2
|
+
import * as Bool from "effect/Boolean";
|
|
3
|
+
import { dual } from "effect/Function";
|
|
4
|
+
import * as Match from "effect/Match";
|
|
5
|
+
import * as Option from "effect/Option";
|
|
6
|
+
import * as Predicate from "effect/Predicate";
|
|
7
|
+
import * as Rec from "effect/Record";
|
|
8
|
+
import * as UndefinedOr from "effect/UndefinedOr";
|
|
9
|
+
import { project } from "./renderer.js";
|
|
10
|
+
import { dashCase, splitPatchForTag } from "./svg.js";
|
|
11
|
+
/**
|
|
12
|
+
* A values map with only the keys an animation can take: numbers and strings (custom
|
|
13
|
+
* properties included). `undefined` and anything else drop out, so the engine never sees
|
|
14
|
+
* them.
|
|
15
|
+
*/
|
|
16
|
+
export const toValues = (v) => UndefinedOr.match(v, {
|
|
17
|
+
onUndefined: () => ({}),
|
|
18
|
+
onDefined: (values) => Rec.filter(values, isAnimatable),
|
|
19
|
+
});
|
|
20
|
+
/** Whether a value is one an animation can take: a number or a string. */
|
|
21
|
+
const isAnimatable = Predicate.or(Predicate.isNumber, Predicate.isString);
|
|
22
|
+
/** Whether a stop is one an animation can take, or `null`. */
|
|
23
|
+
const isStop = Predicate.or(isAnimatable, Predicate.isNull);
|
|
24
|
+
/**
|
|
25
|
+
* A Keyframes value's stop (#429): its first, as Motion's `initial` reads it (`use-visual-state.ts`),
|
|
26
|
+
* or its last that isn't `null`, where it rests (Motion's final keyframe, `fill-wildcards.ts`'s).
|
|
27
|
+
* `null` or `undefined` when it has none.
|
|
28
|
+
*/
|
|
29
|
+
const stopOf = (stops, at) => Bool.match(at === "first", { onTrue: () => stops[0], onFalse: () => Option.getOrUndefined(Arr.findLast(stops, Predicate.isNotNull)) });
|
|
30
|
+
/** Whether a value is Keyframes an animation can take (#429): an array of stops, one of them not `null`. */
|
|
31
|
+
const isStops = (value) => {
|
|
32
|
+
if (Bool.not(Arr.isArray(value)))
|
|
33
|
+
return false;
|
|
34
|
+
const stops = value;
|
|
35
|
+
return Bool.and(Arr.every(stops, isStop), Arr.some(stops, Predicate.isNotNull));
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The Keyframes {@link keepAnimatable} set aside while it filtered a values map (#452): written by it,
|
|
39
|
+
* read and cleared right after, never across a call. A target with none leaves it `undefined`.
|
|
40
|
+
*/
|
|
41
|
+
// Module state (#460, Q7): scratch within one synchronous call, never held across one.
|
|
42
|
+
let setAside;
|
|
43
|
+
/**
|
|
44
|
+
* A values map's filter (#452): a value an animation can take stays, and Keyframes go aside, into
|
|
45
|
+
* {@link setAside}, so one pass over the keys finds both. Built once, at module load.
|
|
46
|
+
*/
|
|
47
|
+
const keepAnimatable = (value, key) => {
|
|
48
|
+
if (Bool.not(Arr.isArray(value)))
|
|
49
|
+
return isAnimatable(value);
|
|
50
|
+
if (isStops(value)) {
|
|
51
|
+
if (Predicate.isUndefined(setAside))
|
|
52
|
+
setAside = {};
|
|
53
|
+
setAside[key] = value;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
};
|
|
57
|
+
/** A values map's numbers and strings, its Keyframes set aside (#452, {@link keepAnimatable}): {@link toValues}' one pass. */
|
|
58
|
+
const filtered = (v) => {
|
|
59
|
+
// Per element at mount (#540): statements and a loop.
|
|
60
|
+
setAside = undefined;
|
|
61
|
+
const out = {};
|
|
62
|
+
if (Predicate.isUndefined(v))
|
|
63
|
+
return out;
|
|
64
|
+
const values = v;
|
|
65
|
+
for (const key of Object.keys(values)) {
|
|
66
|
+
const value = values[key];
|
|
67
|
+
// `keepAnimatable` keeps numbers and strings alone, as `isAnimatable` does.
|
|
68
|
+
if (keepAnimatable(value, key))
|
|
69
|
+
out[key] = value;
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
};
|
|
73
|
+
/** The Keyframes the last {@link filtered} set aside, taken: `undefined` with none. */
|
|
74
|
+
const takeSetAside = () => {
|
|
75
|
+
const taken = setAside;
|
|
76
|
+
setAside = undefined;
|
|
77
|
+
return taken;
|
|
78
|
+
};
|
|
79
|
+
/** `values` with each of `keyframes` at one of its stops (#429), one with no such stop left out. */
|
|
80
|
+
const withStops = (values, keyframes, at) => ({
|
|
81
|
+
...values,
|
|
82
|
+
...toValues(Rec.map(keyframes, (stops) => stopOf(stops, at))),
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* A values map's values, each keyframes value read at one of its stops, and its keyframes, in one pass
|
|
86
|
+
* over its keys: a target's resolution reads both, and a target with no keyframes makes nothing
|
|
87
|
+
* `toValues` doesn't.
|
|
88
|
+
*/
|
|
89
|
+
// **Keyframes** (#429); one pass (#452).
|
|
90
|
+
export const splitValues = (v, at) => {
|
|
91
|
+
const values = filtered(v);
|
|
92
|
+
const keyframes = takeSetAside();
|
|
93
|
+
if (Predicate.isUndefined(keyframes))
|
|
94
|
+
return { values, keyframes: Option.none() };
|
|
95
|
+
return { values: withStops(values, keyframes, at), keyframes: Option.some(keyframes) };
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* A values map with only the keys an animation can take, each keyframes value read at one of its stops:
|
|
99
|
+
* `initial`'s first, a target's last. A keyframes value with no such stop drops out, as does an array
|
|
100
|
+
* `keyframesOf` doesn't take, and anything that isn't a number or a string. One pass over its keys, as
|
|
101
|
+
* `toValues`'.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* Style.valuesAt({ opacity: [0, 0.5, 1], x: 10 }, "first") // { x: 10, opacity: 0 }
|
|
105
|
+
*/
|
|
106
|
+
// **Keyframes** (#429); one pass (#452).
|
|
107
|
+
export const valuesAt = (v, at) => {
|
|
108
|
+
const values = filtered(v);
|
|
109
|
+
const keyframes = takeSetAside();
|
|
110
|
+
if (Predicate.isUndefined(keyframes))
|
|
111
|
+
return values;
|
|
112
|
+
return withStops(values, keyframes, at);
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* A values map's keyframes values: each array of stops an animation can take, one with a stop that isn't
|
|
116
|
+
* `null`. None when it has none, so a target without any makes nothing.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* Style.keyframesOf({ opacity: [0, 0.5, 1], x: 10 }) // { opacity: [0, 0.5, 1] }
|
|
120
|
+
*/
|
|
121
|
+
// **Keyframes** (#429).
|
|
122
|
+
export const keyframesOf = (v) => splitValues(v, "last").keyframes;
|
|
123
|
+
/** Whether an entry is a list of names (#297): an array, which a values map never is. */
|
|
124
|
+
const isList = (entry) => Arr.isArray(entry);
|
|
125
|
+
/**
|
|
126
|
+
* A values map, or the `variants` entry a name names (an unknown name is empty), or nothing.
|
|
127
|
+
* Built once, at module load: every element reads its own at setup (#69).
|
|
128
|
+
*/
|
|
129
|
+
const entryOf = Match.type().pipe(Match.when({ entry: Match.undefined }, () => ({})), Match.when({ entry: Match.string }, ({ entry, variants, at }) => valuesAt(UndefinedOr.map(variants, (byName) => byName[entry]), at)),
|
|
130
|
+
// A list's names merged in order, a later one's winning a key both set (#297, Motion's).
|
|
131
|
+
Match.when({ entry: isList }, ({ entry, variants, at }) => Arr.reduce(entry, {}, (merged, name) => ({ ...merged, ...valuesAt(UndefinedOr.map(variants, (byName) => byName[name]), at) }))), Match.orElse(({ entry, at }) => valuesAt(entry, at)));
|
|
132
|
+
/**
|
|
133
|
+
* The values an element starts from: its `initial` values, or the `variants` entries its `initial` names,
|
|
134
|
+
* an unknown name empty, or nothing. With `initial: false`, its `animate`, resolved the same way, so it
|
|
135
|
+
* starts at its target and nothing animates at mount, as Motion's. A keyframes value starts at its first
|
|
136
|
+
* stop, or, with `initial: false`, at `animate`'s last, where the animation it skips would end. Read once,
|
|
137
|
+
* at setup: the starting style is where it starts, never a live target.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* Style.resolveInitial({ initial: false, animate: { opacity: 1 } }) // { opacity: 1 }
|
|
141
|
+
*/
|
|
142
|
+
// #134, Motion's `initial={false}`; **Keyframes** (#429, Motion's `use-visual-state.ts`).
|
|
143
|
+
export const resolveInitial = (config) => {
|
|
144
|
+
// Per element at mount (#540): statements.
|
|
145
|
+
if (config.initial === false)
|
|
146
|
+
return entryOf({ entry: config.animate, variants: config.variants, at: "last" });
|
|
147
|
+
return entryOf({ entry: config.initial, variants: config.variants, at: "first" });
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* A CSS declaration list (`"color: red; background: url(a;b)"`) as `{ property: value }`.
|
|
151
|
+
* A `;` inside parentheses or quotes doesn't end a declaration. Internal (not in the
|
|
152
|
+
* package index): `own-values.ts`'s style lookup shares it.
|
|
153
|
+
*/
|
|
154
|
+
export const parseCssText = (text) => {
|
|
155
|
+
const out = {};
|
|
156
|
+
// A counted scan over UTF-16 units, as `slice` counts: a `;` outside parentheses and quotes ends a
|
|
157
|
+
// declaration, and a backslash in a quote escapes the next unit (#618, F6: a reduce built a scan
|
|
158
|
+
// state and a matcher each character, 15-25 times as slow).
|
|
159
|
+
let depth = 0;
|
|
160
|
+
let quote = 0;
|
|
161
|
+
let escaped = false;
|
|
162
|
+
let start = 0;
|
|
163
|
+
for (let i = 0; i < text.length; i++) {
|
|
164
|
+
const c = text.charCodeAt(i);
|
|
165
|
+
if (escaped) {
|
|
166
|
+
escaped = false;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (quote !== 0) {
|
|
170
|
+
if (c === BACKSLASH)
|
|
171
|
+
escaped = true;
|
|
172
|
+
if (c === quote)
|
|
173
|
+
quote = 0;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (c === DOUBLE_QUOTE || c === SINGLE_QUOTE)
|
|
177
|
+
quote = c;
|
|
178
|
+
if (c === OPEN)
|
|
179
|
+
depth++;
|
|
180
|
+
if (c === CLOSE)
|
|
181
|
+
depth = Math.max(0, depth - 1);
|
|
182
|
+
if (c === SEMICOLON && depth === 0) {
|
|
183
|
+
takeDeclaration(text, start, i, out);
|
|
184
|
+
start = i + 1;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
takeDeclaration(text, start, text.length, out);
|
|
188
|
+
return out;
|
|
189
|
+
};
|
|
190
|
+
const BACKSLASH = 92;
|
|
191
|
+
const DOUBLE_QUOTE = 34;
|
|
192
|
+
const SINGLE_QUOTE = 39;
|
|
193
|
+
const OPEN = 40;
|
|
194
|
+
const CLOSE = 41;
|
|
195
|
+
const SEMICOLON = 59;
|
|
196
|
+
/** The declaration in `text` from `start` to `end` into `out`: its property and value, trimmed, when it has both. */
|
|
197
|
+
const takeDeclaration = (text, start, end, out) => {
|
|
198
|
+
const declaration = text.slice(start, end);
|
|
199
|
+
const colon = declaration.indexOf(":");
|
|
200
|
+
if (colon <= 0)
|
|
201
|
+
return;
|
|
202
|
+
const key = declaration.slice(0, colon).trim();
|
|
203
|
+
const value = declaration.slice(colon + 1).trim();
|
|
204
|
+
if (key !== "" && value !== "")
|
|
205
|
+
out[key] = value;
|
|
206
|
+
};
|
|
207
|
+
/** A style given as CSS text, parsed; a record as it is. */
|
|
208
|
+
const recordOf = (input) => {
|
|
209
|
+
// Per element at mount (#540): statements.
|
|
210
|
+
if (Predicate.isString(input))
|
|
211
|
+
return parseCssText(input);
|
|
212
|
+
return input;
|
|
213
|
+
};
|
|
214
|
+
/** A style given as CSS text, parsed; a record as it is; none, an empty record. */
|
|
215
|
+
const recordOfInput = (input) => {
|
|
216
|
+
// Per element at mount (#540): statements.
|
|
217
|
+
if (Predicate.isUndefined(input))
|
|
218
|
+
return {};
|
|
219
|
+
return recordOf(input);
|
|
220
|
+
};
|
|
221
|
+
const setsKey = (key) => (style) => Predicate.isNotUndefined(style[key]);
|
|
222
|
+
/**
|
|
223
|
+
* Whether a style sets `user-select` and not `-webkit-user-select`, and the reverse. Chromium has
|
|
224
|
+
* one property under both names, so a value set under one is the value for both.
|
|
225
|
+
*/
|
|
226
|
+
const setsOnlyUserSelect = Predicate.and(setsKey("user-select"), Predicate.not(setsKey("-webkit-user-select")));
|
|
227
|
+
const setsOnlyWebkitUserSelect = Predicate.and(setsKey("-webkit-user-select"), Predicate.not(setsKey("user-select")));
|
|
228
|
+
/** `self` laid over `that`: both present. */
|
|
229
|
+
const layered = (self, that) => {
|
|
230
|
+
const merged = { ...that, ...self };
|
|
231
|
+
// `self`'s value for either name is the value for both, or `that`'s left on the other wins.
|
|
232
|
+
if (setsOnlyUserSelect(self))
|
|
233
|
+
merged["-webkit-user-select"] = self["user-select"];
|
|
234
|
+
if (setsOnlyWebkitUserSelect(self))
|
|
235
|
+
merged["user-select"] = self["-webkit-user-select"];
|
|
236
|
+
return merged;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* `self` laid over `that`: `self`'s keys win, and `that`'s others stay. A chain reads from the top layer
|
|
240
|
+
* down: an element's style is its drag defaults, under its base, under the app's, under what Wardic
|
|
241
|
+
* animates. A side given as CSS text is parsed, so a framework never writes `cssText` over the keys
|
|
242
|
+
* Wardic holds, and a side that's `undefined` leaves the other as it is, the same object. Whatever `self`
|
|
243
|
+
* sets for `user-select` or `-webkit-user-select` it sets for both: one property in Chromium.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* // Before the first commit: the starting style over the app's, over a base and a drag element's defaults.
|
|
247
|
+
* pipe(starting, Style.over(user), Style.over(base), Style.over(Style.dragDefaults("x")))
|
|
248
|
+
*/
|
|
249
|
+
// `dual`, `self` first (ADR-0041, decision 5). The layering: ADR-0019 *Amendment (Reorder)*.
|
|
250
|
+
export const over = dual(2, (self, that) => {
|
|
251
|
+
// Per element at mount (#540): statements.
|
|
252
|
+
if (Predicate.isUndefined(that))
|
|
253
|
+
return recordOfInput(self);
|
|
254
|
+
if (Predicate.isUndefined(self))
|
|
255
|
+
return recordOf(that);
|
|
256
|
+
return layered(recordOf(self), recordOf(that));
|
|
257
|
+
});
|
|
258
|
+
/** Whether `key`, a CSS property, is one of the gate's held patch keys: by its name, or its name dash-cased. */
|
|
259
|
+
const isHeld = (held, key) => {
|
|
260
|
+
// Per element at mount (#540): a loop.
|
|
261
|
+
for (const patchKey of held) {
|
|
262
|
+
if (patchKey === key || dashCase(patchKey) === key)
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
return false;
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* `self` without the keys the flush gate holds on the element (`held`, by patch key, matched by CSS
|
|
269
|
+
* property): the style once its first frame is committed. Wardic writes those while it drives them, and
|
|
270
|
+
* the app's `style` is their fallback, so a key the gate lets go of comes back.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* pipe(user, Style.over(base), Style.without(held))
|
|
274
|
+
*/
|
|
275
|
+
// ADR-0034.
|
|
276
|
+
export const without = dual(2, (self, held) => {
|
|
277
|
+
// Per element at mount (#540): a loop.
|
|
278
|
+
const record = recordOfInput(self);
|
|
279
|
+
const out = {};
|
|
280
|
+
for (const key of Object.keys(record)) {
|
|
281
|
+
if (!isHeld(held, key))
|
|
282
|
+
out[key] = record[key];
|
|
283
|
+
}
|
|
284
|
+
return out;
|
|
285
|
+
});
|
|
286
|
+
/**
|
|
287
|
+
* Whether the keys the flush gate holds, changing from `prev` to `next`, change `self`'s `without`:
|
|
288
|
+
* whether a key taken or let go of is one `self` sets, by its name or its name dash-cased. Most changes
|
|
289
|
+
* touch none, and a binding then leaves its `style` alone.
|
|
290
|
+
*/
|
|
291
|
+
// ADR-0034.
|
|
292
|
+
export const heldTouches = dual(3, (self, prev, next) => Arr.some([...Arr.difference(prev, next), ...Arr.difference(next, prev)], (key) => Arr.some([key, dashCase(key)], (name) => Object.hasOwn(self, name))));
|
|
293
|
+
/**
|
|
294
|
+
* The starting style of a `tag` element starting from `values`: projected as the renderer projects a
|
|
295
|
+
* Frame, then split by tag, an SVG element's keys inside an `<svg>` as attributes, and the rest as style.
|
|
296
|
+
* `undefined` is an HTML element, as for a spread that doesn't know its tag.
|
|
297
|
+
*/
|
|
298
|
+
// The Starting style; routed by tag (ADR-0014). The spread: a `createWard` spread.
|
|
299
|
+
export const startingStyle = (tag, values) => splitPatchForTag(tag, project(values));
|
|
300
|
+
//# sourceMappingURL=starting-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starting-style.js","sourceRoot":"","sources":["../../src/internal/starting-style.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG realization for the DOM renderer (ADR-0014). The core value pipeline +
|
|
3
|
+
* the pure `project` stay AGNOSTIC and flat: SVG numeric attrs (`cx`/`r`/…)
|
|
4
|
+
* already spring as numbers and `fill`/`stroke` already interpolate as colors.
|
|
5
|
+
* This module is the DOM-API ROUTING layer — the one place that decides whether
|
|
6
|
+
* a resolved value is written as a CSS `style` or an `setAttribute`, plus the
|
|
7
|
+
* SVG-specific shaping (`transform-box`, `pathLength`→dash). It is the seam a
|
|
8
|
+
* non-DOM SVG renderer (e.g. react-native-svg) would replace wholesale; nothing
|
|
9
|
+
* here is shared with `@wardic/core`.
|
|
10
|
+
*
|
|
11
|
+
* Model (Motion's `buildSVGAttrs`): for an svg-INNER element every key is an
|
|
12
|
+
* ATTRIBUTE except `transform`/`transformOrigin`/`transformBox` + the CSS
|
|
13
|
+
* motion-path props, which stay STYLE, and a custom property (`--…`), which is style
|
|
14
|
+
* under its own name on every element (#151). For an HTML element or the `<svg>` ROOT
|
|
15
|
+
* everything is style (the root has a CSS box; only `viewBox` would be an attr —
|
|
16
|
+
* deferred). So the HTML path is unchanged: its attribute map is always empty.
|
|
17
|
+
*/
|
|
18
|
+
import type * as Renderer from "@wardic/core/Renderer";
|
|
19
|
+
import * as Option from "effect/Option";
|
|
20
|
+
/**
|
|
21
|
+
* camelCase → dash-case for a CSS/attribute name (`transformBox` → `transform-box`); a
|
|
22
|
+
* custom property keeps its name (`--brandColor`).
|
|
23
|
+
*/
|
|
24
|
+
export declare const dashCase: (key: string) => string;
|
|
25
|
+
/** Whether a key collapses into the stroke dash: `pathLength`, `pathSpacing` or `pathOffset`. */
|
|
26
|
+
export declare const isPathKey: (key: string) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The attribute an svg-inner element's `key` is written as (the routing below), or
|
|
29
|
+
* `None` for a key that stays style ({@link SVG_STYLE_KEYS}, a custom property) or collapses into the
|
|
30
|
+
* stroke dash (`pathLength` / `pathSpacing` / `pathOffset`). Internal: the Own-value read
|
|
31
|
+
* reads the attribute a key is written as (ADR-0022).
|
|
32
|
+
*/
|
|
33
|
+
export declare const svgAttrNameOf: (key: string) => Option.Option<string>;
|
|
34
|
+
/** Whether `el` is an `<svg>` root, which is styled as HTML is: it has a CSS box. */
|
|
35
|
+
export declare const isSvgRoot: (el: unknown) => boolean;
|
|
36
|
+
/** Whether `el` is an SVG element inside an `<svg>`: any SVG element but the root. */
|
|
37
|
+
export declare const isSvgInner: (el: unknown) => boolean;
|
|
38
|
+
/** A style patch, split: the keys written as CSS, and the ones written as attributes. */
|
|
39
|
+
export interface SplitPatch {
|
|
40
|
+
/** The keys written as CSS: the whole patch for HTML and an `<svg>` root, the very object given. */
|
|
41
|
+
readonly style: Readonly<Record<string, unknown>>;
|
|
42
|
+
/** The keys written with `setAttribute`: none for HTML and an `<svg>` root. */
|
|
43
|
+
readonly attrs: Readonly<Record<string, string>>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A style patch split for `el`: an HTML element's, or an `<svg>` root's, is all style. An SVG element
|
|
47
|
+
* inside one takes every key as an attribute but the keys CSS styles and a custom property; `attrX`,
|
|
48
|
+
* `attrY` and `attrScale` as its `x`, `y` and `scale` attributes; a `transform` with `transform-box:
|
|
49
|
+
* fill-box` and `transform-origin: 50% 50%`, unless the values set them, so it turns about its own centre
|
|
50
|
+
* as an HTML element does; and `pathLength`, `pathSpacing` and `pathOffset` as a normalised
|
|
51
|
+
* `stroke-dasharray` and `stroke-dashoffset`, with `pathLength="1"`.
|
|
52
|
+
*/
|
|
53
|
+
export declare const splitPatch: (el: unknown, patch: Renderer.Patch) => SplitPatch;
|
|
54
|
+
/** Whether `tag` names an SVG element inside an `<svg>`, by its name alone. */
|
|
55
|
+
export declare const isSvgInnerTag: (tag: string) => boolean;
|
|
56
|
+
/** `splitPatch` by tag name, for where there's no element yet: a server render, a starting style. `undefined` is an HTML element. */
|
|
57
|
+
export declare const splitPatchForTag: (tag: string | undefined, patch: Renderer.Patch) => SplitPatch;
|
|
58
|
+
/** Writes each attribute onto `el` with `setAttribute`; nothing for an empty map. */
|
|
59
|
+
export declare const setSvgAttrs: (el: Element, attrs: Readonly<Record<string, string>>) => void;
|
|
60
|
+
//# sourceMappingURL=svg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/internal/svg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AAEtD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAwEvC;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAS,MAAM,KAAG,MAStC,CAAA;AAQD,iGAAiG;AACjG,eAAO,MAAM,SAAS,QAAS,MAAM,KAAG,OAAgF,CAAA;AAExH;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAO5D,CAAA;AAEJ,qFAAqF;AACrF,eAAO,MAAM,SAAS,OAAQ,OAAO,KAAG,OAIvC,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,UAAU,OAAQ,OAAO,KAAG,OAGxC,CAAA;AAED,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,oGAAoG;IACpG,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACjD;AAKD;;;;;;;GAOG;AAEH,eAAO,MAAM,UAAU,OAAQ,OAAO,SAAS,QAAQ,CAAC,KAAK,KAAG,UAG/D,CAAA;AAoCD,+EAA+E;AAC/E,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,OAA+E,CAAA;AAE3H,qIAAqI;AAErI,eAAO,MAAM,gBAAgB,QAAS,MAAM,GAAG,SAAS,SAAS,QAAQ,CAAC,KAAK,KAAG,UAI9E,CAAA;AAqFJ,qFAAqF;AACrF,eAAO,MAAM,WAAW,OAAQ,OAAO,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,IAElF,CAAA"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import * as Bool from "effect/Boolean";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import * as Predicate from "effect/Predicate";
|
|
4
|
+
/**
|
|
5
|
+
* Keys that remain CSS `style` on an svg-inner element; everything else routes
|
|
6
|
+
* to an attribute. `transform` is applied as a CSS transform (with `transform-box`
|
|
7
|
+
* below); the motion-path props are CSS-only on SVG too (Motion parity).
|
|
8
|
+
*/
|
|
9
|
+
const SVG_STYLE_KEYS = new Set([
|
|
10
|
+
"transform",
|
|
11
|
+
"transformOrigin",
|
|
12
|
+
"transform-origin",
|
|
13
|
+
"transformBox",
|
|
14
|
+
"transform-box",
|
|
15
|
+
"offsetDistance",
|
|
16
|
+
"offsetPath",
|
|
17
|
+
"offsetRotate",
|
|
18
|
+
"offsetAnchor",
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* SVG attribute names always written camelCase (never dash-cased) — Motion's
|
|
22
|
+
* `camelCaseAttributes`. Everything else is dash-cased (`strokeWidth` →
|
|
23
|
+
* `stroke-width`).
|
|
24
|
+
*/
|
|
25
|
+
const CAMEL_CASE_ATTRS = new Set([
|
|
26
|
+
"baseFrequency",
|
|
27
|
+
"diffuseConstant",
|
|
28
|
+
"kernelMatrix",
|
|
29
|
+
"kernelUnitLength",
|
|
30
|
+
"keySplines",
|
|
31
|
+
"keyTimes",
|
|
32
|
+
"limitingConeAngle",
|
|
33
|
+
"markerHeight",
|
|
34
|
+
"markerWidth",
|
|
35
|
+
"numOctaves",
|
|
36
|
+
"targetX",
|
|
37
|
+
"targetY",
|
|
38
|
+
"surfaceScale",
|
|
39
|
+
"specularConstant",
|
|
40
|
+
"specularExponent",
|
|
41
|
+
"stdDeviation",
|
|
42
|
+
"tableValues",
|
|
43
|
+
"viewBox",
|
|
44
|
+
"gradientTransform",
|
|
45
|
+
"pathLength",
|
|
46
|
+
"startOffset",
|
|
47
|
+
"textLength",
|
|
48
|
+
"lengthAdjust",
|
|
49
|
+
]);
|
|
50
|
+
/**
|
|
51
|
+
* Escape hatches: `x`/`y` are transform shorthands in Wardic (translateX/Y), so
|
|
52
|
+
* the SVG geometry ATTRIBUTE form is the explicit `attr*` key (Motion's
|
|
53
|
+
* `attrX`/`attrY`/`attrScale`). Maps to the bare attribute name.
|
|
54
|
+
*/
|
|
55
|
+
const ATTR_ALIASES = { attrX: "x", attrY: "y", attrScale: "scale" };
|
|
56
|
+
/**
|
|
57
|
+
* Each key's dash-cased name, computed once (ADR-0034): the commit dash-cases every key of
|
|
58
|
+
* every patch, each frame. Keys come from animation configs, so the set stays small.
|
|
59
|
+
*/
|
|
60
|
+
// Module state (#460, Q7): a cache keyed by what it caches: a bounded set of names.
|
|
61
|
+
const DASHED = new Map();
|
|
62
|
+
/**
|
|
63
|
+
* Whether `key` is a CSS custom property (`--brandColor`): it keeps its name, which is
|
|
64
|
+
* case-sensitive, and is always a style property, on SVG too (ADR-0014, *Amendment (#151)*;
|
|
65
|
+
* Motion's `isCSSVariableName`).
|
|
66
|
+
*/
|
|
67
|
+
const isCustomProperty = (key) => key.startsWith("--");
|
|
68
|
+
/**
|
|
69
|
+
* camelCase → dash-case for a CSS/attribute name (`transformBox` → `transform-box`); a
|
|
70
|
+
* custom property keeps its name (`--brandColor`).
|
|
71
|
+
*/
|
|
72
|
+
export const dashCase = (key) => {
|
|
73
|
+
const cached = DASHED.get(key);
|
|
74
|
+
if (Predicate.isNotUndefined(cached))
|
|
75
|
+
return cached;
|
|
76
|
+
const dashed = Bool.match(isCustomProperty(key), {
|
|
77
|
+
onTrue: () => key,
|
|
78
|
+
onFalse: () => key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`),
|
|
79
|
+
});
|
|
80
|
+
DASHED.set(key, dashed);
|
|
81
|
+
return dashed;
|
|
82
|
+
};
|
|
83
|
+
/** The attribute name for an engine key: dash-cased unless it's a known camelCase attr. */
|
|
84
|
+
const attrName = (key) => {
|
|
85
|
+
if (CAMEL_CASE_ATTRS.has(key))
|
|
86
|
+
return key;
|
|
87
|
+
return dashCase(key);
|
|
88
|
+
};
|
|
89
|
+
/** Whether a key collapses into the stroke dash: `pathLength`, `pathSpacing` or `pathOffset`. */
|
|
90
|
+
export const isPathKey = (key) => key === "pathLength" || key === "pathSpacing" || key === "pathOffset";
|
|
91
|
+
/**
|
|
92
|
+
* The attribute an svg-inner element's `key` is written as (the routing below), or
|
|
93
|
+
* `None` for a key that stays style ({@link SVG_STYLE_KEYS}, a custom property) or collapses into the
|
|
94
|
+
* stroke dash (`pathLength` / `pathSpacing` / `pathOffset`). Internal: the Own-value read
|
|
95
|
+
* reads the attribute a key is written as (ADR-0022).
|
|
96
|
+
*/
|
|
97
|
+
export const svgAttrNameOf = (key) => Bool.match(isPathKey(key) || isCustomProperty(key), {
|
|
98
|
+
onTrue: () => Option.none(),
|
|
99
|
+
onFalse: () => Option.orElse(Option.fromUndefinedOr(ATTR_ALIASES[key]), () => Option.map(Option.liftPredicate(key, (k) => Bool.not(SVG_STYLE_KEYS.has(k))), attrName)),
|
|
100
|
+
});
|
|
101
|
+
/** Whether `el` is an `<svg>` root, which is styled as HTML is: it has a CSS box. */
|
|
102
|
+
export const isSvgRoot = (el) => {
|
|
103
|
+
// No SVG classes on a server. Per frame (a flush's split): plain checks.
|
|
104
|
+
const SvgRoot = globalThis.SVGSVGElement;
|
|
105
|
+
return Predicate.isNotUndefined(SvgRoot) && el instanceof SvgRoot;
|
|
106
|
+
};
|
|
107
|
+
/** Whether `el` is an SVG element inside an `<svg>`: any SVG element but the root. */
|
|
108
|
+
export const isSvgInner = (el) => {
|
|
109
|
+
const Svg = globalThis.SVGElement;
|
|
110
|
+
return Predicate.isNotUndefined(Svg) && el instanceof Svg && !isSvgRoot(el);
|
|
111
|
+
};
|
|
112
|
+
/** An HTML element's attributes from a patch: none, one shared frozen record (#618: one a split). */
|
|
113
|
+
const NO_ATTRS = Object.freeze({});
|
|
114
|
+
/**
|
|
115
|
+
* A style patch split for `el`: an HTML element's, or an `<svg>` root's, is all style. An SVG element
|
|
116
|
+
* inside one takes every key as an attribute but the keys CSS styles and a custom property; `attrX`,
|
|
117
|
+
* `attrY` and `attrScale` as its `x`, `y` and `scale` attributes; a `transform` with `transform-box:
|
|
118
|
+
* fill-box` and `transform-origin: 50% 50%`, unless the values set them, so it turns about its own centre
|
|
119
|
+
* as an HTML element does; and `pathLength`, `pathSpacing` and `pathOffset` as a normalised
|
|
120
|
+
* `stroke-dasharray` and `stroke-dashoffset`, with `pathLength="1"`.
|
|
121
|
+
*/
|
|
122
|
+
// The CSS keys: `SVG_STYLE_KEYS`.
|
|
123
|
+
export const splitPatch = (el, patch) => {
|
|
124
|
+
if (isSvgInner(el))
|
|
125
|
+
return routeSvgInner(patch);
|
|
126
|
+
return { style: patch, attrs: NO_ATTRS };
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* SVG's element names that HTML doesn't share, lowercase (Motion's list,
|
|
130
|
+
* framer-motion/src/render/svg/lowercase-elements.ts @ 16c6122, without the `svg` root).
|
|
131
|
+
* A name with a capital letter (`clipPath`, `linearGradient`, `feGaussianBlur` …) is SVG
|
|
132
|
+
* too, as Motion's `isSVGComponent` decides; `a`, `script`, `style` and `title` count as
|
|
133
|
+
* HTML, since a server has no namespace to tell them apart.
|
|
134
|
+
*/
|
|
135
|
+
const SVG_INNER_TAGS = new Set([
|
|
136
|
+
"animate",
|
|
137
|
+
"circle",
|
|
138
|
+
"defs",
|
|
139
|
+
"desc",
|
|
140
|
+
"ellipse",
|
|
141
|
+
"g",
|
|
142
|
+
"image",
|
|
143
|
+
"line",
|
|
144
|
+
"filter",
|
|
145
|
+
"marker",
|
|
146
|
+
"mask",
|
|
147
|
+
"metadata",
|
|
148
|
+
"path",
|
|
149
|
+
"pattern",
|
|
150
|
+
"polygon",
|
|
151
|
+
"polyline",
|
|
152
|
+
"rect",
|
|
153
|
+
"stop",
|
|
154
|
+
"switch",
|
|
155
|
+
"symbol",
|
|
156
|
+
"text",
|
|
157
|
+
"tspan",
|
|
158
|
+
"use",
|
|
159
|
+
"view",
|
|
160
|
+
]);
|
|
161
|
+
/** Whether `tag` names an SVG element inside an `<svg>`, by its name alone. */
|
|
162
|
+
export const isSvgInnerTag = (tag) => !tag.includes("-") && (SVG_INNER_TAGS.has(tag) || /[A-Z]/.test(tag));
|
|
163
|
+
/** `splitPatch` by tag name, for where there's no element yet: a server render, a starting style. `undefined` is an HTML element. */
|
|
164
|
+
// ADR-0021.
|
|
165
|
+
export const splitPatchForTag = (tag, patch) => Bool.match(Predicate.isNotUndefined(tag) && isSvgInnerTag(tag), {
|
|
166
|
+
onTrue: () => routeSvgInner(patch),
|
|
167
|
+
onFalse: () => ({ style: patch, attrs: NO_ATTRS }),
|
|
168
|
+
});
|
|
169
|
+
/** The svg-inner routing {@link splitPatch} and {@link splitPatchForTag} share. */
|
|
170
|
+
const routeSvgInner = (patch) => {
|
|
171
|
+
const style = {};
|
|
172
|
+
const attrs = {};
|
|
173
|
+
let hasTransform = false;
|
|
174
|
+
let pathLength;
|
|
175
|
+
let pathSpacing;
|
|
176
|
+
let pathOffset;
|
|
177
|
+
for (const key in patch) {
|
|
178
|
+
const value = patch[key];
|
|
179
|
+
if (Predicate.isUndefined(value))
|
|
180
|
+
continue;
|
|
181
|
+
if (key === "pathLength") {
|
|
182
|
+
pathLength = value;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (key === "pathSpacing") {
|
|
186
|
+
pathSpacing = value;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (key === "pathOffset") {
|
|
190
|
+
pathOffset = value;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const alias = ATTR_ALIASES[key];
|
|
194
|
+
if (Predicate.isNotUndefined(alias)) {
|
|
195
|
+
attrs[alias] = String(value);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (SVG_STYLE_KEYS.has(key)) {
|
|
199
|
+
style[key] = value;
|
|
200
|
+
if (key === "transform")
|
|
201
|
+
hasTransform = true;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
// A custom property is a style property (ADR-0014, *Amendment (#151)*).
|
|
205
|
+
if (isCustomProperty(key)) {
|
|
206
|
+
style[key] = value;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
attrs[attrName(key)] = String(value);
|
|
210
|
+
}
|
|
211
|
+
// SVG's transform-origin defaults to the document origin (0 0), not the element
|
|
212
|
+
// centre — so a CSS transform on SVG reads differently from HTML. `fill-box` +
|
|
213
|
+
// a centred origin restore HTML-like semantics (Motion). User-set wins.
|
|
214
|
+
if (hasTransform) {
|
|
215
|
+
if (Predicate.isUndefined(style["transformBox"]) && Predicate.isUndefined(style["transform-box"])) {
|
|
216
|
+
style["transform-box"] = "fill-box";
|
|
217
|
+
}
|
|
218
|
+
if (Predicate.isUndefined(style["transformOrigin"]) && Predicate.isUndefined(style["transform-origin"])) {
|
|
219
|
+
style["transform-origin"] = "50% 50%";
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// pathLength → normalised stroke dash (Motion's buildSVGPath). Unitless: Safari
|
|
223
|
+
// mis-scales px dash values when the page is zoomed.
|
|
224
|
+
if (Predicate.isNotUndefined(pathLength)) {
|
|
225
|
+
attrs["pathLength"] = "1";
|
|
226
|
+
attrs["stroke-dasharray"] = `${pathLength} ${spacingOf(pathSpacing)}`;
|
|
227
|
+
attrs["stroke-dashoffset"] = String(dashOffsetOf(offsetOf(pathOffset)));
|
|
228
|
+
}
|
|
229
|
+
return { style, attrs };
|
|
230
|
+
};
|
|
231
|
+
// The stroke dash's parts, per frame: early returns.
|
|
232
|
+
/** `pathSpacing`, 1 when none is given. */
|
|
233
|
+
const spacingOf = (spacing) => {
|
|
234
|
+
if (Predicate.isNullish(spacing))
|
|
235
|
+
return 1;
|
|
236
|
+
return spacing;
|
|
237
|
+
};
|
|
238
|
+
/** `pathOffset` as a number, 0 when none is given. */
|
|
239
|
+
const offsetOf = (offset) => {
|
|
240
|
+
if (Predicate.isNumber(offset))
|
|
241
|
+
return offset;
|
|
242
|
+
if (Predicate.isNullish(offset))
|
|
243
|
+
return 0;
|
|
244
|
+
return Number(offset);
|
|
245
|
+
};
|
|
246
|
+
/** The dash offset an offset draws: its negation, 0 for one that isn't finite. */
|
|
247
|
+
const dashOffsetOf = (offset) => {
|
|
248
|
+
if (Number.isFinite(offset))
|
|
249
|
+
return -offset;
|
|
250
|
+
return 0;
|
|
251
|
+
};
|
|
252
|
+
/** Writes each attribute onto `el` with `setAttribute`; nothing for an empty map. */
|
|
253
|
+
export const setSvgAttrs = (el, attrs) => {
|
|
254
|
+
for (const name in attrs)
|
|
255
|
+
el.setAttribute(name, attrs[name]);
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=svg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg.js","sourceRoot":"","sources":["../../src/internal/svg.ts"],"names":[],"mappings":"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"}
|