framer-motion 5.0.0-rc.1 → 5.0.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 (32) hide show
  1. package/README.md +3 -3
  2. package/dist/es/components/Reorder/Group.mjs +10 -2
  3. package/dist/es/components/Reorder/Item.mjs +3 -1
  4. package/dist/es/gestures/drag/VisualElementDragControls.mjs +9 -0
  5. package/dist/es/motion/features/animations.mjs +3 -2
  6. package/dist/es/motion/features/layout/MeasureLayout.mjs +19 -4
  7. package/dist/es/motion/utils/VisualElementHandler.mjs +3 -3
  8. package/dist/es/projection/node/create-projection-node.mjs +38 -18
  9. package/dist/es/projection/shared/stack.mjs +5 -1
  10. package/dist/es/render/html/utils/render.mjs +2 -2
  11. package/dist/es/render/index.mjs +2 -1
  12. package/dist/es/render/utils/lifecycles.mjs +6 -2
  13. package/dist/framer-motion.cjs.js +1572 -1510
  14. package/dist/framer-motion.dev.js +1581 -1510
  15. package/dist/framer-motion.js +1 -1
  16. package/dist/projection.dev.js +118 -64
  17. package/dist/size-rollup-dom-animation.js +1 -1
  18. package/dist/size-rollup-dom-max.js +1 -1
  19. package/dist/size-rollup-m.js +1 -1
  20. package/dist/size-webpack-dom-animation.js +1 -1
  21. package/dist/size-webpack-dom-max.js +1 -1
  22. package/dist/size-webpack-m.js +1 -1
  23. package/package.json +6 -6
  24. package/types/components/Reorder/Group.d.ts +37 -2
  25. package/types/components/Reorder/Item.d.ts +10 -0
  26. package/types/motion/utils/VisualElementHandler.d.ts +3 -1
  27. package/types/projection/node/DocumentProjectionNode.d.ts +3 -1
  28. package/types/projection/node/HTMLProjectionNode.d.ts +3 -1
  29. package/types/projection/node/create-projection-node.d.ts +4 -1
  30. package/types/projection/node/types.d.ts +4 -1
  31. package/types/render/html/utils/render.d.ts +2 -1
  32. package/types/render/types.d.ts +3 -2
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <p align="center">
2
- <img src="https://misc.framerstatic.com/motion/motion-readme-4.gif" width="400" height="250" alt="Framer Motion" />
2
+ <img src="https://user-images.githubusercontent.com/22095598/123793419-f5528800-d8e1-11eb-8c5f-e2dad45a9c81.png" width="108" height="108" alt="Framer Motion" />
3
3
  </p>
4
-
4
+ <h1 align="center">Framer Motion</h1>
5
5
  <h3 align="center">
6
6
  An open source and production-ready motion<br>library for React on the web.
7
7
  </h3>
@@ -65,7 +65,7 @@ export const MyComponent = ({ isVisible }) => (
65
65
 
66
66
  ### Docs
67
67
 
68
- Check out [our documentation](https://framer.com/api/motion) for guides and a full API reference.
68
+ Check out [our documentation](https://www.framer.com/docs/) for guides and a full API reference.
69
69
 
70
70
  Or checkout [our examples](https://framer.com/motion) for inspiration.
71
71
 
@@ -1,4 +1,5 @@
1
1
  import { __rest, __assign } from 'tslib';
2
+ import { invariant } from 'hey-listen';
2
3
  import * as React from 'react';
3
4
  import { forwardRef, useRef, useEffect } from 'react';
4
5
  import { ReorderContext } from '../../context/ReorderContext.mjs';
@@ -7,10 +8,11 @@ import { useConstant } from '../../utils/use-constant.mjs';
7
8
  import { checkReorder } from './utils/check-reorder.mjs';
8
9
 
9
10
  function ReorderGroup(_a, externalRef) {
10
- var children = _a.children, _b = _a.as, as = _b === void 0 ? "ul" : _b, _c = _a.axis, axis = _c === void 0 ? "y" : _c, onReorder = _a.onReorder, props = __rest(_a, ["children", "as", "axis", "onReorder"]);
11
+ var children = _a.children, _b = _a.as, as = _b === void 0 ? "ul" : _b, _c = _a.axis, axis = _c === void 0 ? "y" : _c, onReorder = _a.onReorder, values = _a.values, props = __rest(_a, ["children", "as", "axis", "onReorder", "values"]);
11
12
  var Component = useConstant(function () { return motion(as); });
12
13
  var order = [];
13
14
  var isReordering = useRef(false);
15
+ invariant(Boolean(values), "Reorder.Group must be provided a values prop");
14
16
  var context = {
15
17
  axis: axis,
16
18
  registerItem: function (value, layout) {
@@ -20,6 +22,7 @@ function ReorderGroup(_a, externalRef) {
20
22
  if (layout &&
21
23
  order.findIndex(function (entry) { return value === entry.value; }) === -1) {
22
24
  order.push({ value: value, layout: layout[axis] });
25
+ order.sort(compareMin);
23
26
  }
24
27
  },
25
28
  updateOrder: function (id, offset, velocity) {
@@ -28,7 +31,9 @@ function ReorderGroup(_a, externalRef) {
28
31
  var newOrder = checkReorder(order, id, offset, velocity);
29
32
  if (order !== newOrder) {
30
33
  isReordering.current = true;
31
- onReorder(newOrder.map(getValue));
34
+ onReorder(newOrder
35
+ .map(getValue)
36
+ .filter(function (value) { return values.indexOf(value) !== -1; }));
32
37
  }
33
38
  },
34
39
  };
@@ -42,5 +47,8 @@ var Group = forwardRef(ReorderGroup);
42
47
  function getValue(item) {
43
48
  return item.value;
44
49
  }
50
+ function compareMin(a, b) {
51
+ return a.layout.min - b.layout.min;
52
+ }
45
53
 
46
54
  export { Group, ReorderGroup };
@@ -35,7 +35,9 @@ function ReorderItem(_a, externalRef) {
35
35
  var velocity = _a.velocity;
36
36
  velocity[axis] &&
37
37
  updateOrder(value, point[axis].get(), velocity[axis]);
38
- }, onLayoutMeasure: function (measured) { return (layout.current = measured); }, ref: externalRef }), children));
38
+ }, onLayoutMeasure: function (measured) {
39
+ layout.current = measured;
40
+ }, ref: externalRef }), children));
39
41
  }
40
42
  var Item = forwardRef(ReorderItem);
41
43
 
@@ -43,6 +43,11 @@ var VisualElementDragControls = /** @class */ (function () {
43
43
  VisualElementDragControls.prototype.start = function (originEvent, _a) {
44
44
  var _this = this;
45
45
  var _b = _a === void 0 ? {} : _a, _c = _b.snapToCursor, snapToCursor = _c === void 0 ? false : _c;
46
+ /**
47
+ * Don't start dragging if this component is exiting
48
+ */
49
+ if (this.visualElement.isPresent === false)
50
+ return;
46
51
  var onSessionStart = function (event) {
47
52
  // Stop any animations on both axis values immediately. This allows the user to throw and catch
48
53
  // the component.
@@ -67,6 +72,7 @@ var VisualElementDragControls = /** @class */ (function () {
67
72
  _this.currentDirection = null;
68
73
  _this.resolveConstraints();
69
74
  if (_this.visualElement.projection) {
75
+ _this.visualElement.projection.isAnimationBlocked = true;
70
76
  _this.visualElement.projection.target = undefined;
71
77
  }
72
78
  /**
@@ -134,6 +140,9 @@ var VisualElementDragControls = /** @class */ (function () {
134
140
  VisualElementDragControls.prototype.cancel = function () {
135
141
  var _a, _b;
136
142
  this.isDragging = false;
143
+ if (this.visualElement.projection) {
144
+ this.visualElement.projection.isAnimationBlocked = false;
145
+ }
137
146
  (_a = this.panSession) === null || _a === void 0 ? void 0 : _a.end();
138
147
  this.panSession = undefined;
139
148
  var dragPropagation = this.getProps().dragPropagation;
@@ -25,12 +25,13 @@ var animations = {
25
25
  }),
26
26
  exit: makeRenderlessComponent(function (props) {
27
27
  var custom = props.custom, visualElement = props.visualElement;
28
- var _a = __read(usePresence(), 2), isPresent = _a[0], onExitComplete = _a[1];
28
+ var _a = __read(usePresence(), 2), isPresent = _a[0], safeToRemove = _a[1];
29
29
  var presenceContext = useContext(PresenceContext);
30
30
  useEffect(function () {
31
31
  var _a, _b;
32
+ visualElement.isPresent = isPresent;
32
33
  var animation = (_a = visualElement.animationState) === null || _a === void 0 ? void 0 : _a.setActive(AnimationType.Exit, !isPresent, { custom: (_b = presenceContext === null || presenceContext === void 0 ? void 0 : presenceContext.custom) !== null && _b !== void 0 ? _b : custom });
33
- !isPresent && (animation === null || animation === void 0 ? void 0 : animation.then(onExitComplete));
34
+ !isPresent && (animation === null || animation === void 0 ? void 0 : animation.then(safeToRemove));
34
35
  }, [isPresent]);
35
36
  }),
36
37
  };
@@ -1,4 +1,5 @@
1
1
  import { __extends, __assign, __read } from 'tslib';
2
+ import sync from 'framesync';
2
3
  import React__default, { useContext } from 'react';
3
4
  import { usePresence } from '../../../components/AnimatePresence/use-presence.mjs';
4
5
  import { LayoutGroupContext } from '../../../context/LayoutGroupContext.mjs';
@@ -38,6 +39,7 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
38
39
  globalProjectionState.hasEverUpdated = true;
39
40
  };
40
41
  MeasureLayoutWithContext.prototype.getSnapshotBeforeUpdate = function (prevProps) {
42
+ var _this = this;
41
43
  var _a = this.props, layoutDependency = _a.layoutDependency, visualElement = _a.visualElement, drag = _a.drag, isPresent = _a.isPresent;
42
44
  var projection = visualElement.projection;
43
45
  if (!projection)
@@ -55,12 +57,25 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
55
57
  layoutDependency === undefined) {
56
58
  projection.willUpdate();
57
59
  }
60
+ else {
61
+ this.safeToRemove();
62
+ }
58
63
  if (prevProps.isPresent !== isPresent) {
59
64
  if (isPresent) {
60
65
  projection.promote();
61
66
  }
62
- else {
63
- projection.relegate();
67
+ else if (!projection.relegate()) {
68
+ /**
69
+ * If there's another stack member taking over from this one,
70
+ * it's in charge of the exit animation and therefore should
71
+ * be in charge of the safe to remove. Otherwise we call it here.
72
+ */
73
+ sync.postRender(function () {
74
+ var _a;
75
+ if (!((_a = projection.getStack()) === null || _a === void 0 ? void 0 : _a.members.length)) {
76
+ _this.safeToRemove();
77
+ }
78
+ });
64
79
  }
65
80
  }
66
81
  return null;
@@ -86,8 +101,8 @@ var MeasureLayoutWithContext = /** @class */ (function (_super) {
86
101
  }
87
102
  };
88
103
  MeasureLayoutWithContext.prototype.safeToRemove = function () {
89
- var _a, _b;
90
- (_b = (_a = this.props).safeToRemove) === null || _b === void 0 ? void 0 : _b.call(_a);
104
+ var safeToRemove = this.props.safeToRemove;
105
+ safeToRemove === null || safeToRemove === void 0 ? void 0 : safeToRemove();
91
106
  };
92
107
  MeasureLayoutWithContext.prototype.render = function () {
93
108
  return null;
@@ -6,9 +6,9 @@ var VisualElementHandler = /** @class */ (function (_super) {
6
6
  function VisualElementHandler() {
7
7
  return _super !== null && _super.apply(this, arguments) || this;
8
8
  }
9
- VisualElementHandler.prototype.componentDidMount = function () {
10
- this.updateProps();
11
- };
9
+ /**
10
+ * Update visual element props as soon as we know this update is going to be commited.
11
+ */
12
12
  VisualElementHandler.prototype.getSnapshotBeforeUpdate = function () {
13
13
  this.updateProps();
14
14
  return null;
@@ -18,7 +18,7 @@ import { eachAxis } from '../utils/each-axis.mjs';
18
18
  import { hasTransform, hasScale } from '../utils/has-transform.mjs';
19
19
  import { transformAxes } from '../../render/html/utils/transform.mjs';
20
20
  import { FlatTree } from '../../render/utils/flat-tree.mjs';
21
- import { elementDragControls } from '../../gestures/drag/VisualElementDragControls.mjs';
21
+ import { resolveMotionValue } from '../../value/utils/resolve-motion-value.mjs';
22
22
 
23
23
  /**
24
24
  * We use 1000 as the animation target as 0-1000 maps better to pixels than 0-1
@@ -67,6 +67,7 @@ function createProjectionNode(_a) {
67
67
  * until all their parents stop performing layout animations.
68
68
  */
69
69
  this.isTreeAnimating = false;
70
+ this.isAnimationBlocked = false;
70
71
  /**
71
72
  * Flag to true if we think this layout has been changed. We can't always know this,
72
73
  * currently we set it to true every time a component renders, or if it has a layoutDependency
@@ -211,11 +212,13 @@ function createProjectionNode(_a) {
211
212
  visualElement &&
212
213
  (layoutId || layout)) {
213
214
  this.addEventListener("didUpdate", function (_a) {
214
- var _b, _c, _d;
215
+ var _b, _c, _d, _e, _f;
215
216
  var delta = _a.delta, hasLayoutChanged = _a.hasLayoutChanged, hasRelativeTargetChanged = _a.hasRelativeTargetChanged, newLayout = _a.layout;
216
- var dragControls = elementDragControls.get(visualElement);
217
- if (dragControls === null || dragControls === void 0 ? void 0 : dragControls.isDragging)
217
+ if (_this.isTreeAnimationBlocked()) {
218
+ _this.target = undefined;
219
+ _this.relativeTarget = undefined;
218
220
  return;
221
+ }
219
222
  // TODO: Check here if an animation exists
220
223
  var layoutTransition = (_c = (_b = _this.options.transition) !== null && _b !== void 0 ? _b : visualElement.getDefaultTransition()) !== null && _c !== void 0 ? _c : defaultLayoutTransition;
221
224
  var onLayoutAnimationComplete = visualElement.getProps().onLayoutAnimationComplete;
@@ -243,6 +246,9 @@ function createProjectionNode(_a) {
243
246
  _this.setAnimationOrigin(delta, hasOnlyRelativeTargetChanged);
244
247
  _this.startAnimation(__assign(__assign({}, getValueTransition(layoutTransition, "layout")), { onComplete: onLayoutAnimationComplete }));
245
248
  }
249
+ else {
250
+ _this.isLead() && ((_f = (_e = _this.options).onExitComplete) === null || _f === void 0 ? void 0 : _f.call(_e));
251
+ }
246
252
  _this.targetLayout = newLayout;
247
253
  });
248
254
  }
@@ -266,6 +272,12 @@ function createProjectionNode(_a) {
266
272
  ProjectionNode.prototype.isUpdateBlocked = function () {
267
273
  return this.updateManuallyBlocked || this.updateBlockedByResize;
268
274
  };
275
+ ProjectionNode.prototype.isTreeAnimationBlocked = function () {
276
+ var _a;
277
+ return (this.isAnimationBlocked ||
278
+ ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.isTreeAnimationBlocked()) ||
279
+ false);
280
+ };
269
281
  // Note: currently only running on root node
270
282
  ProjectionNode.prototype.startUpdate = function () {
271
283
  var _a;
@@ -275,10 +287,12 @@ function createProjectionNode(_a) {
275
287
  (_a = this.nodes) === null || _a === void 0 ? void 0 : _a.forEach(resetRotation);
276
288
  };
277
289
  ProjectionNode.prototype.willUpdate = function (shouldNotifyListeners) {
278
- var _a;
290
+ var _a, _b, _c;
279
291
  if (shouldNotifyListeners === void 0) { shouldNotifyListeners = true; }
280
- if (this.root.isUpdateBlocked())
292
+ if (this.root.isUpdateBlocked()) {
293
+ (_b = (_a = this.options).onExitComplete) === null || _b === void 0 ? void 0 : _b.call(_a);
281
294
  return;
295
+ }
282
296
  !this.root.isUpdating && this.root.startUpdate();
283
297
  if (this.isLayoutDirty)
284
298
  return;
@@ -292,10 +306,10 @@ function createProjectionNode(_a) {
292
306
  */
293
307
  node.updateScroll();
294
308
  }
295
- var _b = this.options, layoutId = _b.layoutId, layout = _b.layout;
309
+ var _d = this.options, layoutId = _d.layoutId, layout = _d.layout;
296
310
  if (!layoutId && !layout)
297
311
  return;
298
- var transformTemplate = (_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.getProps().transformTemplate;
312
+ var transformTemplate = (_c = this.options.visualElement) === null || _c === void 0 ? void 0 : _c.getProps().transformTemplate;
299
313
  this.prevTransformTemplateValue = transformTemplate === null || transformTemplate === void 0 ? void 0 : transformTemplate(this.latestValues, "");
300
314
  this.updateSnapshot();
301
315
  shouldNotifyListeners && this.notifyListeners("willUpdate");
@@ -565,8 +579,8 @@ function createProjectionNode(_a) {
565
579
  }
566
580
  }
567
581
  /**
568
- * If we have no relative target or no target delta we can't perform projection
569
- * so early return.
582
+ * If we have no relative target or no target delta our target isn't valid
583
+ * for this frame.
570
584
  */
571
585
  if (!this.relativeTarget && !this.targetDelta)
572
586
  return;
@@ -782,11 +796,11 @@ function createProjectionNode(_a) {
782
796
  this.resumingFrom.currentAnimation = undefined;
783
797
  this.resumingFrom.preserveOpacity = undefined;
784
798
  }
799
+ (_a = this.getStack()) === null || _a === void 0 ? void 0 : _a.exitAnimationComplete();
785
800
  this.resumingFrom =
786
801
  this.currentAnimation =
787
802
  this.animationValues =
788
803
  undefined;
789
- (_a = this.getStack()) === null || _a === void 0 ? void 0 : _a.exitAnimationComplete();
790
804
  };
791
805
  ProjectionNode.prototype.finishAnimation = function () {
792
806
  var _a;
@@ -920,7 +934,8 @@ function createProjectionNode(_a) {
920
934
  if (this.needsReset) {
921
935
  this.needsReset = false;
922
936
  styles.opacity = "";
923
- styles.pointerEvents = styleProp.pointerEvents || "";
937
+ styles.pointerEvents =
938
+ resolveMotionValue(styleProp.pointerEvents) || "";
924
939
  styles.transform = transformTemplate
925
940
  ? transformTemplate(this.latestValues, "")
926
941
  : "none";
@@ -931,7 +946,8 @@ function createProjectionNode(_a) {
931
946
  var emptyStyles = {};
932
947
  if (this.options.layoutId) {
933
948
  emptyStyles.opacity = (_b = this.latestValues.opacity) !== null && _b !== void 0 ? _b : 1;
934
- emptyStyles.pointerEvents = styleProp.pointerEvents || "";
949
+ emptyStyles.pointerEvents =
950
+ resolveMotionValue(styleProp.pointerEvents) || "";
935
951
  }
936
952
  if (this.hasProjected && !hasTransform(this.latestValues)) {
937
953
  emptyStyles.transform = transformTemplate
@@ -947,7 +963,6 @@ function createProjectionNode(_a) {
947
963
  if (transformTemplate) {
948
964
  styles.transform = transformTemplate(valuesToRender, styles.transform);
949
965
  }
950
- // TODO Move into stand-alone, testable function
951
966
  var _g = this.projectionDelta, x = _g.x, y = _g.y;
952
967
  styles.transformOrigin = x.origin * 100 + "% " + y.origin * 100 + "% 0";
953
968
  if (lead.animationValues) {
@@ -997,7 +1012,9 @@ function createProjectionNode(_a) {
997
1012
  */
998
1013
  if (this.options.layoutId) {
999
1014
  styles.pointerEvents =
1000
- lead === this ? styleProp.pointerEvents || "" : "none";
1015
+ lead === this
1016
+ ? resolveMotionValue(styleProp.pointerEvents) || ""
1017
+ : "none";
1001
1018
  }
1002
1019
  return styles;
1003
1020
  };
@@ -1017,13 +1034,13 @@ function updateLayout(node) {
1017
1034
  node.updateLayout();
1018
1035
  }
1019
1036
  function notifyLayoutUpdate(node) {
1020
- var _a, _b;
1037
+ var _a, _b, _c, _d;
1021
1038
  var snapshot = (_b = (_a = node.resumeFrom) === null || _a === void 0 ? void 0 : _a.snapshot) !== null && _b !== void 0 ? _b : node.snapshot;
1022
1039
  if (node.isLead() &&
1023
1040
  node.layout &&
1024
1041
  snapshot &&
1025
1042
  node.hasListeners("didUpdate")) {
1026
- var _c = node.layout, layout_1 = _c.actual, measuredLayout = _c.measured;
1043
+ var _e = node.layout, layout_1 = _e.actual, measuredLayout = _e.measured;
1027
1044
  // TODO Maybe we want to also resize the layout snapshot so we don't trigger
1028
1045
  // animations for instance if layout="size" and an element has only changed position
1029
1046
  if (node.options.animationType === "size") {
@@ -1063,7 +1080,7 @@ function notifyLayoutUpdate(node) {
1063
1080
  * the relative snapshot is not relavent
1064
1081
  */
1065
1082
  if (node.relativeParent && !node.relativeParent.resumeFrom) {
1066
- var _d = node.relativeParent, parentSnapshot = _d.snapshot, parentLayout = _d.layout;
1083
+ var _f = node.relativeParent, parentSnapshot = _f.snapshot, parentLayout = _f.layout;
1067
1084
  if (parentSnapshot && parentLayout) {
1068
1085
  var relativeSnapshot = createBox();
1069
1086
  calcRelativePosition(relativeSnapshot, snapshot.layout, parentSnapshot.layout);
@@ -1084,6 +1101,9 @@ function notifyLayoutUpdate(node) {
1084
1101
  hasRelativeTargetChanged: hasRelativeTargetChanged,
1085
1102
  });
1086
1103
  }
1104
+ else if (node.isLead()) {
1105
+ (_d = (_c = node.options).onExitComplete) === null || _d === void 0 ? void 0 : _d.call(_c);
1106
+ }
1087
1107
  /**
1088
1108
  * Clearing transition
1089
1109
  * TODO: Investigate why this transition is being passed in as {type: false } from Framer
@@ -86,7 +86,11 @@ var NodeStack = /** @class */ (function () {
86
86
  }
87
87
  };
88
88
  NodeStack.prototype.exitAnimationComplete = function () {
89
- this.members.forEach(function (node) { var _a, _b; return (_b = (_a = node.options).onExitComplete) === null || _b === void 0 ? void 0 : _b.call(_a); });
89
+ this.members.forEach(function (node) {
90
+ var _a, _b, _c, _d, _e;
91
+ (_b = (_a = node.options).onExitComplete) === null || _b === void 0 ? void 0 : _b.call(_a);
92
+ (_e = (_c = node.resumingFrom) === null || _c === void 0 ? void 0 : (_d = _c.options).onExitComplete) === null || _e === void 0 ? void 0 : _e.call(_d);
93
+ });
90
94
  };
91
95
  NodeStack.prototype.scheduleRender = function () {
92
96
  this.members.forEach(function (node) {
@@ -1,6 +1,6 @@
1
- function renderHTML(element, _a, projection) {
1
+ function renderHTML(element, _a, styleProp, projection) {
2
2
  var style = _a.style, vars = _a.vars;
3
- Object.assign(element.style, style, projection && projection.getProjectionStyles(style));
3
+ Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
4
4
  // Loop over any CSS variables and assign those.
5
5
  for (var key in vars) {
6
6
  element.style.setProperty(key, vars[key]);
@@ -62,7 +62,7 @@ var visualElement = function (_a) {
62
62
  if (!instance || !isMounted)
63
63
  return;
64
64
  triggerBuild();
65
- renderInstance(instance, renderState, element.projection);
65
+ renderInstance(instance, renderState, props.style, element.projection);
66
66
  }
67
67
  function triggerBuild() {
68
68
  build(element, renderState, latestValues, options, props);
@@ -162,6 +162,7 @@ var visualElement = function (_a) {
162
162
  removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
163
163
  }
164
164
  parent === null || parent === void 0 ? void 0 : parent.children.add(element);
165
+ element.setProps(props);
165
166
  },
166
167
  /**
167
168
  *
@@ -20,9 +20,13 @@ function createLifecycles() {
20
20
  var lifecycles = {
21
21
  clearAllListeners: function () { return managers.forEach(function (manager) { return manager.clear(); }); },
22
22
  updatePropListeners: function (props) {
23
- return names.forEach(function (name) {
23
+ names.forEach(function (name) {
24
+ var _a;
24
25
  var on = "on" + name;
25
26
  var propListener = props[on];
27
+ // Unsubscribe existing subscription
28
+ (_a = propSubscriptions[name]) === null || _a === void 0 ? void 0 : _a.call(propSubscriptions);
29
+ // Add new subscription
26
30
  if (propListener) {
27
31
  propSubscriptions[name] = lifecycles[on](propListener);
28
32
  }
@@ -36,7 +40,7 @@ function createLifecycles() {
36
40
  for (var _i = 0; _i < arguments.length; _i++) {
37
41
  args[_i] = arguments[_i];
38
42
  }
39
- return manager.notify.apply(manager, __spreadArray([], __read(args), false));
43
+ manager.notify.apply(manager, __spreadArray([], __read(args), false));
40
44
  };
41
45
  });
42
46
  return lifecycles;