motion 12.9.7 → 12.10.1

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.
@@ -0,0 +1,41 @@
1
+ import { frame, cancelFrame } from '../frameloop/frame.mjs';
2
+ import { numberValueTypes } from '../value/types/maps/number.mjs';
3
+ import { getValueAsType } from '../value/types/utils/get-as-type.mjs';
4
+
5
+ class MotionValueState {
6
+ constructor() {
7
+ this.latest = {};
8
+ this.values = new Map();
9
+ }
10
+ set(name, value, render, computed) {
11
+ const existingValue = this.values.get(name);
12
+ if (existingValue) {
13
+ existingValue.onRemove();
14
+ }
15
+ const onChange = () => {
16
+ this.latest[name] = getValueAsType(value.get(), numberValueTypes[name]);
17
+ render && frame.render(render);
18
+ };
19
+ onChange();
20
+ const cancelOnChange = value.on("change", onChange);
21
+ computed && value.addDependent(computed);
22
+ const remove = () => {
23
+ cancelOnChange();
24
+ render && cancelFrame(render);
25
+ this.values.delete(name);
26
+ computed && value.removeDependent(computed);
27
+ };
28
+ this.values.set(name, { value, onRemove: remove });
29
+ return remove;
30
+ }
31
+ get(name) {
32
+ return this.values.get(name)?.value;
33
+ }
34
+ destroy() {
35
+ for (const value of this.values.values()) {
36
+ value.onRemove();
37
+ }
38
+ }
39
+ }
40
+
41
+ export { MotionValueState };
@@ -0,0 +1,51 @@
1
+ import { isCSSVar } from '../../render/dom/is-css-var.mjs';
2
+ import { transformProps } from '../../render/utils/keys-transform.mjs';
3
+ import { resolveElements } from '../../utils/resolve-elements.mjs';
4
+ import { MotionValue } from '../../value/index.mjs';
5
+ import { MotionValueState } from '../MotionValueState.mjs';
6
+ import { buildTransform } from './transform.mjs';
7
+
8
+ const stateMap = new WeakMap();
9
+ function styleEffect(subject, values) {
10
+ const elements = resolveElements(subject);
11
+ const subscriptions = [];
12
+ for (let i = 0; i < elements.length; i++) {
13
+ const element = elements[i];
14
+ const state = stateMap.get(element) ?? new MotionValueState();
15
+ stateMap.set(element, state);
16
+ for (const key in values) {
17
+ const value = values[key];
18
+ const remove = addValue(element, state, key, value);
19
+ subscriptions.push(remove);
20
+ }
21
+ }
22
+ return () => {
23
+ for (const cancel of subscriptions)
24
+ cancel();
25
+ };
26
+ }
27
+ function addValue(element, state, key, value) {
28
+ let render = undefined;
29
+ let computed = undefined;
30
+ if (transformProps.has(key)) {
31
+ if (!state.get("transform")) {
32
+ state.set("transform", new MotionValue("none"), () => {
33
+ element.style.transform = buildTransform(state);
34
+ });
35
+ }
36
+ computed = state.get("transform");
37
+ }
38
+ else if (isCSSVar(key)) {
39
+ render = () => {
40
+ element.style.setProperty(key, state.latest[key]);
41
+ };
42
+ }
43
+ else {
44
+ render = () => {
45
+ element.style[key] = state.latest[key];
46
+ };
47
+ }
48
+ return state.set(key, value, render, computed);
49
+ }
50
+
51
+ export { styleEffect };
@@ -0,0 +1,38 @@
1
+ import { transformPropOrder } from '../../render/utils/keys-transform.mjs';
2
+
3
+ const translateAlias = {
4
+ x: "translateX",
5
+ y: "translateY",
6
+ z: "translateZ",
7
+ transformPerspective: "perspective",
8
+ };
9
+ function buildTransform(state) {
10
+ let transform = "";
11
+ let transformIsDefault = true;
12
+ /**
13
+ * Loop over all possible transforms in order, adding the ones that
14
+ * are present to the transform string.
15
+ */
16
+ for (let i = 0; i < transformPropOrder.length; i++) {
17
+ const key = transformPropOrder[i];
18
+ const value = state.latest[key];
19
+ if (value === undefined)
20
+ continue;
21
+ let valueIsDefault = true;
22
+ if (typeof value === "number") {
23
+ valueIsDefault = value === (key.startsWith("scale") ? 1 : 0);
24
+ }
25
+ else {
26
+ valueIsDefault = parseFloat(value) === 0;
27
+ }
28
+ if (!valueIsDefault) {
29
+ transformIsDefault = false;
30
+ const transformName = translateAlias[key] || key;
31
+ const valueToRender = state.latest[key];
32
+ transform += `${transformName}(${valueToRender}) `;
33
+ }
34
+ }
35
+ return transformIsDefault ? "none" : transform.trim();
36
+ }
37
+
38
+ export { buildTransform };
@@ -43,10 +43,12 @@ function press(targetOrSelector, onPressStart, options = {}) {
43
43
  const onPointerEnd = (endEvent, success) => {
44
44
  window.removeEventListener("pointerup", onPointerUp);
45
45
  window.removeEventListener("pointercancel", onPointerCancel);
46
- if (!isValidPressEvent(endEvent) || !isPressing.has(target)) {
46
+ if (isPressing.has(target)) {
47
+ isPressing.delete(target);
48
+ }
49
+ if (!isValidPressEvent(endEvent)) {
47
50
  return;
48
51
  }
49
- isPressing.delete(target);
50
52
  if (typeof onPressEnd === "function") {
51
53
  onPressEnd(endEvent, { success });
52
54
  }
@@ -60,6 +60,11 @@ class MotionValue {
60
60
  // Update update subscribers
61
61
  if (this.current !== this.prev) {
62
62
  this.events.change?.notify(this.current);
63
+ if (this.dependents) {
64
+ for (const dependent of this.dependents) {
65
+ dependent.dirty();
66
+ }
67
+ }
63
68
  }
64
69
  // Update render subscribers
65
70
  if (render) {
@@ -201,6 +206,20 @@ class MotionValue {
201
206
  if (this.stopPassiveEffect)
202
207
  this.stopPassiveEffect();
203
208
  }
209
+ dirty() {
210
+ this.events.change?.notify(this.current);
211
+ }
212
+ addDependent(dependent) {
213
+ if (!this.dependents) {
214
+ this.dependents = new Set();
215
+ }
216
+ this.dependents.add(dependent);
217
+ }
218
+ removeDependent(dependent) {
219
+ if (this.dependents) {
220
+ this.dependents.delete(dependent);
221
+ }
222
+ }
204
223
  /**
205
224
  * Returns the latest state of `MotionValue`
206
225
  *
@@ -299,6 +318,7 @@ class MotionValue {
299
318
  * @public
300
319
  */
301
320
  destroy() {
321
+ this.dependents?.clear();
302
322
  this.events.destroy?.notify();
303
323
  this.clearListeners();
304
324
  this.stop();