framer-motion 11.2.10 → 12.0.0-alpha.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/dist/cjs/{dom-entry-Dvf42Jkp.js → dom-entry-BZuxIay2.js} +49 -102
- package/dist/cjs/dom-entry.js +1 -1
- package/dist/cjs/index.js +123 -37
- package/dist/dom.js +1 -1
- package/dist/es/animation/optimized-appear/handoff.mjs +1 -0
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +3 -3
- package/dist/es/motion/features/animation/index.mjs +6 -3
- package/dist/es/motion/index.mjs +33 -13
- package/dist/es/motion/utils/use-motion-ref.mjs +6 -3
- package/dist/es/motion/utils/use-visual-element.mjs +55 -4
- package/dist/es/projection/node/create-projection-node.mjs +2 -1
- package/dist/es/projection-entry.mjs +11 -0
- package/dist/es/render/VisualElement.mjs +30 -78
- package/dist/es/render/utils/animation-state.mjs +5 -1
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/utils/use-instant-transition.mjs +1 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/es/value/types/color/rgba.mjs +1 -1
- package/dist/framer-motion.dev.js +165 -131
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +239 -383
- package/dist/three-entry.d.ts +61 -74
- package/package.json +12 -26
- package/dist/projection.dev.js +0 -6665
|
@@ -179,12 +179,6 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
|
179
179
|
return { schedule, cancel, state, steps };
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
function isRefObject(ref) {
|
|
183
|
-
return (ref &&
|
|
184
|
-
typeof ref === "object" &&
|
|
185
|
-
Object.prototype.hasOwnProperty.call(ref, "current"));
|
|
186
|
-
}
|
|
187
|
-
|
|
188
182
|
/**
|
|
189
183
|
* Decides if the supplied variable is variant label
|
|
190
184
|
*/
|
|
@@ -244,6 +238,23 @@ for (const key in featureProps) {
|
|
|
244
238
|
};
|
|
245
239
|
}
|
|
246
240
|
|
|
241
|
+
const noop = (any) => any;
|
|
242
|
+
|
|
243
|
+
exports.warning = noop;
|
|
244
|
+
exports.invariant = noop;
|
|
245
|
+
if (process.env.NODE_ENV !== "production") {
|
|
246
|
+
exports.warning = (check, message) => {
|
|
247
|
+
if (!check && typeof console !== "undefined") {
|
|
248
|
+
console.warn(message);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
exports.invariant = (check, message) => {
|
|
252
|
+
if (!check) {
|
|
253
|
+
throw new Error(message);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
247
258
|
const scaleCorrectors = {};
|
|
248
259
|
function addScaleCorrector(correctors) {
|
|
249
260
|
Object.assign(scaleCorrectors, correctors);
|
|
@@ -755,8 +766,6 @@ const resolveFinalValueInKeyframes = (v) => {
|
|
|
755
766
|
return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v;
|
|
756
767
|
};
|
|
757
768
|
|
|
758
|
-
const noop = (any) => any;
|
|
759
|
-
|
|
760
769
|
const { schedule: frame, cancel: cancelFrame, state: frameData, steps, } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
|
|
761
770
|
|
|
762
771
|
/**
|
|
@@ -893,21 +902,6 @@ function isNone(value) {
|
|
|
893
902
|
}
|
|
894
903
|
}
|
|
895
904
|
|
|
896
|
-
exports.warning = noop;
|
|
897
|
-
exports.invariant = noop;
|
|
898
|
-
if (process.env.NODE_ENV !== "production") {
|
|
899
|
-
exports.warning = (check, message) => {
|
|
900
|
-
if (!check && typeof console !== "undefined") {
|
|
901
|
-
console.warn(message);
|
|
902
|
-
}
|
|
903
|
-
};
|
|
904
|
-
exports.invariant = (check, message) => {
|
|
905
|
-
if (!check) {
|
|
906
|
-
throw new Error(message);
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
|
|
911
905
|
/**
|
|
912
906
|
* Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
|
|
913
907
|
*/
|
|
@@ -3553,7 +3547,7 @@ class MotionValue {
|
|
|
3553
3547
|
* This will be replaced by the build step with the latest version number.
|
|
3554
3548
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
3555
3549
|
*/
|
|
3556
|
-
this.version = "
|
|
3550
|
+
this.version = "12.0.0-alpha.0";
|
|
3557
3551
|
/**
|
|
3558
3552
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
3559
3553
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -4233,7 +4227,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
4233
4227
|
* and warn against mismatches.
|
|
4234
4228
|
*/
|
|
4235
4229
|
if (process.env.NODE_ENV === "development") {
|
|
4236
|
-
warnOnce(nextValue.version === "
|
|
4230
|
+
warnOnce(nextValue.version === "12.0.0-alpha.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 12.0.0-alpha.0 may not work as expected.`);
|
|
4237
4231
|
}
|
|
4238
4232
|
}
|
|
4239
4233
|
else if (isMotionValue(prevValue)) {
|
|
@@ -4284,8 +4278,6 @@ const valueTypes = [...dimensionValueTypes, color, complex];
|
|
|
4284
4278
|
*/
|
|
4285
4279
|
const findValueType = (v) => valueTypes.find(testValueType(v));
|
|
4286
4280
|
|
|
4287
|
-
const featureNames = Object.keys(featureDefinitions);
|
|
4288
|
-
const numFeatures = featureNames.length;
|
|
4289
4281
|
const propEventHandlers = [
|
|
4290
4282
|
"AnimationStart",
|
|
4291
4283
|
"AnimationComplete",
|
|
@@ -4296,13 +4288,6 @@ const propEventHandlers = [
|
|
|
4296
4288
|
"LayoutAnimationComplete",
|
|
4297
4289
|
];
|
|
4298
4290
|
const numVariantProps = variantProps.length;
|
|
4299
|
-
function getClosestProjectingNode(visualElement) {
|
|
4300
|
-
if (!visualElement)
|
|
4301
|
-
return undefined;
|
|
4302
|
-
return visualElement.options.allowProjection !== false
|
|
4303
|
-
? visualElement.projection
|
|
4304
|
-
: getClosestProjectingNode(visualElement.parent);
|
|
4305
|
-
}
|
|
4306
4291
|
/**
|
|
4307
4292
|
* A VisualElement is an imperative abstraction around UI elements such as
|
|
4308
4293
|
* HTMLElement, SVGElement, Three.Object3D etc.
|
|
@@ -4454,7 +4439,6 @@ class VisualElement {
|
|
|
4454
4439
|
this.update(this.props, this.presenceContext);
|
|
4455
4440
|
}
|
|
4456
4441
|
unmount() {
|
|
4457
|
-
var _a;
|
|
4458
4442
|
visualElementStore.delete(this.current);
|
|
4459
4443
|
this.projection && this.projection.unmount();
|
|
4460
4444
|
cancelFrame(this.notifyUpdate);
|
|
@@ -4466,7 +4450,11 @@ class VisualElement {
|
|
|
4466
4450
|
this.events[key].clear();
|
|
4467
4451
|
}
|
|
4468
4452
|
for (const key in this.features) {
|
|
4469
|
-
|
|
4453
|
+
const feature = this.features[key];
|
|
4454
|
+
if (feature) {
|
|
4455
|
+
feature.unmount();
|
|
4456
|
+
feature.isMounted = false;
|
|
4457
|
+
}
|
|
4470
4458
|
}
|
|
4471
4459
|
this.current = null;
|
|
4472
4460
|
}
|
|
@@ -4498,73 +4486,33 @@ class VisualElement {
|
|
|
4498
4486
|
}
|
|
4499
4487
|
return this.sortInstanceNodePosition(this.current, other.current);
|
|
4500
4488
|
}
|
|
4501
|
-
loadFeatures({ children, ...renderedProps }, isStrict, preloadedFeatures, initialLayoutGroupConfig) {
|
|
4502
|
-
let ProjectionNodeConstructor;
|
|
4503
|
-
let MeasureLayout;
|
|
4504
|
-
/**
|
|
4505
|
-
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
4506
|
-
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
4507
|
-
*/
|
|
4508
|
-
if (process.env.NODE_ENV !== "production" &&
|
|
4509
|
-
preloadedFeatures &&
|
|
4510
|
-
isStrict) {
|
|
4511
|
-
const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
|
|
4512
|
-
renderedProps.ignoreStrict
|
|
4513
|
-
? exports.warning(false, strictMessage)
|
|
4514
|
-
: exports.invariant(false, strictMessage);
|
|
4515
|
-
}
|
|
4516
|
-
for (let i = 0; i < numFeatures; i++) {
|
|
4517
|
-
const name = featureNames[i];
|
|
4518
|
-
const { isEnabled, Feature: FeatureConstructor, ProjectionNode, MeasureLayout: MeasureLayoutComponent, } = featureDefinitions[name];
|
|
4519
|
-
if (ProjectionNode)
|
|
4520
|
-
ProjectionNodeConstructor = ProjectionNode;
|
|
4521
|
-
if (isEnabled(renderedProps)) {
|
|
4522
|
-
if (!this.features[name] && FeatureConstructor) {
|
|
4523
|
-
this.features[name] = new FeatureConstructor(this);
|
|
4524
|
-
}
|
|
4525
|
-
if (MeasureLayoutComponent) {
|
|
4526
|
-
MeasureLayout = MeasureLayoutComponent;
|
|
4527
|
-
}
|
|
4528
|
-
}
|
|
4529
|
-
}
|
|
4530
|
-
if ((this.type === "html" || this.type === "svg") &&
|
|
4531
|
-
!this.projection &&
|
|
4532
|
-
ProjectionNodeConstructor) {
|
|
4533
|
-
const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = renderedProps;
|
|
4534
|
-
this.projection = new ProjectionNodeConstructor(this.latestValues, renderedProps["data-framer-portal-id"]
|
|
4535
|
-
? undefined
|
|
4536
|
-
: getClosestProjectingNode(this.parent));
|
|
4537
|
-
this.projection.setOptions({
|
|
4538
|
-
layoutId,
|
|
4539
|
-
layout,
|
|
4540
|
-
alwaysMeasureLayout: Boolean(drag) ||
|
|
4541
|
-
(dragConstraints && isRefObject(dragConstraints)),
|
|
4542
|
-
visualElement: this,
|
|
4543
|
-
scheduleRender: () => this.scheduleRender(),
|
|
4544
|
-
/**
|
|
4545
|
-
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
4546
|
-
* to update by the time layout animations run.
|
|
4547
|
-
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
4548
|
-
* ensuring it gets called if there's no potential layout animations.
|
|
4549
|
-
*
|
|
4550
|
-
*/
|
|
4551
|
-
animationType: typeof layout === "string" ? layout : "both",
|
|
4552
|
-
initialPromotionConfig: initialLayoutGroupConfig,
|
|
4553
|
-
layoutScroll,
|
|
4554
|
-
layoutRoot,
|
|
4555
|
-
});
|
|
4556
|
-
}
|
|
4557
|
-
return MeasureLayout;
|
|
4558
|
-
}
|
|
4559
4489
|
updateFeatures() {
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4490
|
+
let key = "animation";
|
|
4491
|
+
for (key in featureDefinitions) {
|
|
4492
|
+
const featureDefinition = featureDefinitions[key];
|
|
4493
|
+
if (!featureDefinition)
|
|
4494
|
+
continue;
|
|
4495
|
+
const { isEnabled, Feature: FeatureConstructor } = featureDefinition;
|
|
4496
|
+
/**
|
|
4497
|
+
* If this feature is enabled but not active, make a new instance.
|
|
4498
|
+
*/
|
|
4499
|
+
if (!this.features[key] &&
|
|
4500
|
+
FeatureConstructor &&
|
|
4501
|
+
isEnabled(this.props)) {
|
|
4502
|
+
this.features[key] = new FeatureConstructor(this);
|
|
4564
4503
|
}
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4504
|
+
/**
|
|
4505
|
+
* If we have a feature, mount or update it.
|
|
4506
|
+
*/
|
|
4507
|
+
if (this.features[key]) {
|
|
4508
|
+
const feature = this.features[key];
|
|
4509
|
+
if (feature.isMounted) {
|
|
4510
|
+
feature.update();
|
|
4511
|
+
}
|
|
4512
|
+
else {
|
|
4513
|
+
feature.mount();
|
|
4514
|
+
feature.isMounted = true;
|
|
4515
|
+
}
|
|
4568
4516
|
}
|
|
4569
4517
|
}
|
|
4570
4518
|
}
|
|
@@ -5964,7 +5912,6 @@ exports.isCustomValue = isCustomValue;
|
|
|
5964
5912
|
exports.isForcedMotionValue = isForcedMotionValue;
|
|
5965
5913
|
exports.isKeyframesTarget = isKeyframesTarget;
|
|
5966
5914
|
exports.isMotionValue = isMotionValue;
|
|
5967
|
-
exports.isRefObject = isRefObject;
|
|
5968
5915
|
exports.isSVGElement = isSVGElement;
|
|
5969
5916
|
exports.isSVGTag = isSVGTag;
|
|
5970
5917
|
exports.isVariantLabel = isVariantLabel;
|
package/dist/cjs/dom-entry.js
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var React = require('react');
|
|
7
|
-
var domEntry = require('./dom-entry-
|
|
7
|
+
var domEntry = require('./dom-entry-BZuxIay2.js');
|
|
8
8
|
|
|
9
9
|
function _interopNamespaceDefault(e) {
|
|
10
10
|
var n = Object.create(null);
|
|
@@ -47,12 +47,24 @@ const LazyContext = React.createContext({ strict: false });
|
|
|
47
47
|
|
|
48
48
|
const { schedule: microtask, cancel: cancelMicrotask } = domEntry.createRenderBatcher(queueMicrotask, false);
|
|
49
49
|
|
|
50
|
-
function
|
|
50
|
+
function isRefObject(ref) {
|
|
51
|
+
return (ref &&
|
|
52
|
+
typeof ref === "object" &&
|
|
53
|
+
Object.prototype.hasOwnProperty.call(ref, "current"));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Internal, exported only for usage in Framer
|
|
58
|
+
*/
|
|
59
|
+
const SwitchLayoutGroupContext = React.createContext({});
|
|
60
|
+
|
|
61
|
+
let scheduleHandoffComplete = false;
|
|
62
|
+
function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor) {
|
|
51
63
|
const { visualElement: parent } = React.useContext(MotionContext);
|
|
52
64
|
const lazyContext = React.useContext(LazyContext);
|
|
53
65
|
const presenceContext = React.useContext(PresenceContext);
|
|
54
66
|
const reducedMotionConfig = React.useContext(MotionConfigContext).reducedMotion;
|
|
55
|
-
const visualElementRef = React.useRef();
|
|
67
|
+
const visualElementRef = React.useRef(undefined);
|
|
56
68
|
/**
|
|
57
69
|
* If we haven't preloaded a renderer, check to see if we have one lazy-loaded
|
|
58
70
|
*/
|
|
@@ -70,6 +82,17 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
70
82
|
});
|
|
71
83
|
}
|
|
72
84
|
const visualElement = visualElementRef.current;
|
|
85
|
+
/**
|
|
86
|
+
* Load Motion gesture and animation features. These are rendered as renderless
|
|
87
|
+
* components so each feature can optionally make use of React lifecycle methods.
|
|
88
|
+
*/
|
|
89
|
+
const initialLayoutGroupConfig = React.useContext(SwitchLayoutGroupContext);
|
|
90
|
+
if (visualElement &&
|
|
91
|
+
!visualElement.projection &&
|
|
92
|
+
ProjectionNodeConstructor &&
|
|
93
|
+
(visualElement.type === "html" || visualElement.type === "svg")) {
|
|
94
|
+
createProjectionNode$1(visualElementRef.current, props, ProjectionNodeConstructor, initialLayoutGroupConfig);
|
|
95
|
+
}
|
|
73
96
|
React.useInsertionEffect(() => {
|
|
74
97
|
visualElement && visualElement.update(props, presenceContext);
|
|
75
98
|
});
|
|
@@ -82,6 +105,7 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
82
105
|
useIsomorphicLayoutEffect(() => {
|
|
83
106
|
if (!visualElement)
|
|
84
107
|
return;
|
|
108
|
+
visualElement.updateFeatures();
|
|
85
109
|
microtask.render(visualElement.render);
|
|
86
110
|
/**
|
|
87
111
|
* Ideally this function would always run in a useEffect.
|
|
@@ -100,18 +124,54 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
100
124
|
React.useEffect(() => {
|
|
101
125
|
if (!visualElement)
|
|
102
126
|
return;
|
|
103
|
-
visualElement.updateFeatures();
|
|
104
127
|
if (!wantsHandoff.current && visualElement.animationState) {
|
|
105
128
|
visualElement.animationState.animateChanges();
|
|
106
129
|
}
|
|
107
130
|
if (wantsHandoff.current) {
|
|
108
131
|
wantsHandoff.current = false;
|
|
109
132
|
// This ensures all future calls to animateChanges() will run in useEffect
|
|
110
|
-
|
|
133
|
+
if (!scheduleHandoffComplete) {
|
|
134
|
+
scheduleHandoffComplete = true;
|
|
135
|
+
queueMicrotask(completeHandoff);
|
|
136
|
+
}
|
|
111
137
|
}
|
|
112
138
|
});
|
|
113
139
|
return visualElement;
|
|
114
140
|
}
|
|
141
|
+
function completeHandoff() {
|
|
142
|
+
window.HandoffComplete = true;
|
|
143
|
+
}
|
|
144
|
+
function createProjectionNode$1(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
|
|
145
|
+
const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = props;
|
|
146
|
+
visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"]
|
|
147
|
+
? undefined
|
|
148
|
+
: getClosestProjectingNode(visualElement.parent));
|
|
149
|
+
visualElement.projection.setOptions({
|
|
150
|
+
layoutId,
|
|
151
|
+
layout,
|
|
152
|
+
alwaysMeasureLayout: Boolean(drag) || (dragConstraints && isRefObject(dragConstraints)),
|
|
153
|
+
visualElement,
|
|
154
|
+
scheduleRender: () => visualElement.scheduleRender(),
|
|
155
|
+
/**
|
|
156
|
+
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
157
|
+
* to update by the time layout animations run.
|
|
158
|
+
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
159
|
+
* ensuring it gets called if there's no potential layout animations.
|
|
160
|
+
*
|
|
161
|
+
*/
|
|
162
|
+
animationType: typeof layout === "string" ? layout : "both",
|
|
163
|
+
initialPromotionConfig,
|
|
164
|
+
layoutScroll,
|
|
165
|
+
layoutRoot,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function getClosestProjectingNode(visualElement) {
|
|
169
|
+
if (!visualElement)
|
|
170
|
+
return undefined;
|
|
171
|
+
return visualElement.options.allowProjection !== false
|
|
172
|
+
? visualElement.projection
|
|
173
|
+
: getClosestProjectingNode(visualElement.parent);
|
|
174
|
+
}
|
|
115
175
|
|
|
116
176
|
/**
|
|
117
177
|
* Creates a ref function that, when called, hydrates the provided
|
|
@@ -121,15 +181,18 @@ function useMotionRef(visualState, visualElement, externalRef) {
|
|
|
121
181
|
return React.useCallback((instance) => {
|
|
122
182
|
instance && visualState.mount && visualState.mount(instance);
|
|
123
183
|
if (visualElement) {
|
|
124
|
-
instance
|
|
125
|
-
|
|
126
|
-
|
|
184
|
+
if (instance) {
|
|
185
|
+
visualElement.mount(instance);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
visualElement.unmount();
|
|
189
|
+
}
|
|
127
190
|
}
|
|
128
191
|
if (externalRef) {
|
|
129
192
|
if (typeof externalRef === "function") {
|
|
130
193
|
externalRef(instance);
|
|
131
194
|
}
|
|
132
|
-
else if (
|
|
195
|
+
else if (isRefObject(externalRef)) {
|
|
133
196
|
externalRef.current = instance;
|
|
134
197
|
}
|
|
135
198
|
}
|
|
@@ -174,11 +237,6 @@ function loadFeatures(features) {
|
|
|
174
237
|
|
|
175
238
|
const LayoutGroupContext = React.createContext({});
|
|
176
239
|
|
|
177
|
-
/**
|
|
178
|
-
* Internal, exported only for usage in Framer
|
|
179
|
-
*/
|
|
180
|
-
const SwitchLayoutGroupContext = React.createContext({});
|
|
181
|
-
|
|
182
240
|
const motionComponentSymbol = Symbol.for("motionComponentSymbol");
|
|
183
241
|
|
|
184
242
|
/**
|
|
@@ -207,24 +265,16 @@ function createMotionComponent({ preloadedFeatures, createVisualElement, useRend
|
|
|
207
265
|
const context = useCreateMotionContext(props);
|
|
208
266
|
const visualState = useVisualState(props, isStatic);
|
|
209
267
|
if (!isStatic && domEntry.isBrowser) {
|
|
268
|
+
useStrictMode(configAndProps, preloadedFeatures);
|
|
269
|
+
const layoutProjection = getProjectionFunctionality(configAndProps);
|
|
270
|
+
MeasureLayout = layoutProjection.MeasureLayout;
|
|
210
271
|
/**
|
|
211
272
|
* Create a VisualElement for this component. A VisualElement provides a common
|
|
212
273
|
* interface to renderer-specific APIs (ie DOM/Three.js etc) as well as
|
|
213
274
|
* providing a way of rendering to these APIs outside of the React render loop
|
|
214
275
|
* for more performant animations and interactions
|
|
215
276
|
*/
|
|
216
|
-
context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement);
|
|
217
|
-
/**
|
|
218
|
-
* Load Motion gesture and animation features. These are rendered as renderless
|
|
219
|
-
* components so each feature can optionally make use of React lifecycle methods.
|
|
220
|
-
*/
|
|
221
|
-
const initialLayoutGroupConfig = React.useContext(SwitchLayoutGroupContext);
|
|
222
|
-
const isStrict = React.useContext(LazyContext).strict;
|
|
223
|
-
if (context.visualElement) {
|
|
224
|
-
MeasureLayout = context.visualElement.loadFeatures(
|
|
225
|
-
// Note: Pass the full new combined props to correctly re-render dynamic feature components.
|
|
226
|
-
configAndProps, isStrict, preloadedFeatures, initialLayoutGroupConfig);
|
|
227
|
-
}
|
|
277
|
+
context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode);
|
|
228
278
|
}
|
|
229
279
|
/**
|
|
230
280
|
* The mount order and hierarchy is specific to ensure our element ref
|
|
@@ -242,6 +292,33 @@ function useLayoutId({ layoutId }) {
|
|
|
242
292
|
? layoutGroupId + "-" + layoutId
|
|
243
293
|
: layoutId;
|
|
244
294
|
}
|
|
295
|
+
function useStrictMode(configAndProps, preloadedFeatures) {
|
|
296
|
+
const isStrict = React.useContext(LazyContext).strict;
|
|
297
|
+
/**
|
|
298
|
+
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
299
|
+
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
300
|
+
*/
|
|
301
|
+
if (process.env.NODE_ENV !== "production" &&
|
|
302
|
+
preloadedFeatures &&
|
|
303
|
+
isStrict) {
|
|
304
|
+
const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
|
|
305
|
+
configAndProps.ignoreStrict
|
|
306
|
+
? domEntry.warning(false, strictMessage)
|
|
307
|
+
: domEntry.invariant(false, strictMessage);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function getProjectionFunctionality(props) {
|
|
311
|
+
const { drag, layout } = domEntry.featureDefinitions;
|
|
312
|
+
if (!drag && !layout)
|
|
313
|
+
return {};
|
|
314
|
+
const combined = { ...drag, ...layout };
|
|
315
|
+
return {
|
|
316
|
+
MeasureLayout: (drag === null || drag === void 0 ? void 0 : drag.isEnabled(props)) || (layout === null || layout === void 0 ? void 0 : layout.isEnabled(props))
|
|
317
|
+
? combined.MeasureLayout
|
|
318
|
+
: undefined,
|
|
319
|
+
ProjectionNode: combined.ProjectionNode,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
245
322
|
|
|
246
323
|
/**
|
|
247
324
|
* Convert any React component into a `motion` component. The provided component
|
|
@@ -1245,7 +1322,7 @@ function animateList(visualElement) {
|
|
|
1245
1322
|
}
|
|
1246
1323
|
function createAnimationState(visualElement) {
|
|
1247
1324
|
let animate = animateList(visualElement);
|
|
1248
|
-
|
|
1325
|
+
let state = createState();
|
|
1249
1326
|
let isInitialRender = true;
|
|
1250
1327
|
/**
|
|
1251
1328
|
* This function will be used to reduce the animation definitions for
|
|
@@ -1522,6 +1599,10 @@ function createAnimationState(visualElement) {
|
|
|
1522
1599
|
setActive,
|
|
1523
1600
|
setAnimateFunction,
|
|
1524
1601
|
getState: () => state,
|
|
1602
|
+
reset: () => {
|
|
1603
|
+
state = createState();
|
|
1604
|
+
isInitialRender = true;
|
|
1605
|
+
},
|
|
1525
1606
|
};
|
|
1526
1607
|
}
|
|
1527
1608
|
function checkVariantsDidChange(prev, next) {
|
|
@@ -1565,9 +1646,8 @@ class AnimationFeature extends Feature {
|
|
|
1565
1646
|
}
|
|
1566
1647
|
updateAnimationControlsSubscription() {
|
|
1567
1648
|
const { animate } = this.node.getProps();
|
|
1568
|
-
this.unmount();
|
|
1569
1649
|
if (domEntry.isAnimationControls(animate)) {
|
|
1570
|
-
this.
|
|
1650
|
+
this.unmountControls = animate.subscribe(this.node);
|
|
1571
1651
|
}
|
|
1572
1652
|
}
|
|
1573
1653
|
/**
|
|
@@ -1583,7 +1663,11 @@ class AnimationFeature extends Feature {
|
|
|
1583
1663
|
this.updateAnimationControlsSubscription();
|
|
1584
1664
|
}
|
|
1585
1665
|
}
|
|
1586
|
-
unmount() {
|
|
1666
|
+
unmount() {
|
|
1667
|
+
var _a;
|
|
1668
|
+
this.node.animationState.reset();
|
|
1669
|
+
(_a = this.unmountControls) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
1670
|
+
}
|
|
1587
1671
|
}
|
|
1588
1672
|
|
|
1589
1673
|
let id$2 = 0;
|
|
@@ -2125,7 +2209,7 @@ class VisualElementDragControls {
|
|
|
2125
2209
|
? this.visualElement.projection.measure(false)
|
|
2126
2210
|
: (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout;
|
|
2127
2211
|
const prevConstraints = this.constraints;
|
|
2128
|
-
if (dragConstraints &&
|
|
2212
|
+
if (dragConstraints && isRefObject(dragConstraints)) {
|
|
2129
2213
|
if (!this.constraints) {
|
|
2130
2214
|
this.constraints = this.resolveRefConstraints();
|
|
2131
2215
|
}
|
|
@@ -2157,7 +2241,7 @@ class VisualElementDragControls {
|
|
|
2157
2241
|
}
|
|
2158
2242
|
resolveRefConstraints() {
|
|
2159
2243
|
const { dragConstraints: constraints, onMeasureDragConstraints } = this.getProps();
|
|
2160
|
-
if (!constraints || !
|
|
2244
|
+
if (!constraints || !isRefObject(constraints))
|
|
2161
2245
|
return false;
|
|
2162
2246
|
const constraintsElement = constraints.current;
|
|
2163
2247
|
domEntry.invariant(constraintsElement !== null, "If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.");
|
|
@@ -2271,7 +2355,7 @@ class VisualElementDragControls {
|
|
|
2271
2355
|
return;
|
|
2272
2356
|
const { drag, dragConstraints } = this.getProps();
|
|
2273
2357
|
const { projection } = this.visualElement;
|
|
2274
|
-
if (!
|
|
2358
|
+
if (!isRefObject(dragConstraints) || !projection || !this.constraints)
|
|
2275
2359
|
return;
|
|
2276
2360
|
/**
|
|
2277
2361
|
* Stop current animations as there can be visual glitching if we try to do
|
|
@@ -2329,7 +2413,7 @@ class VisualElementDragControls {
|
|
|
2329
2413
|
});
|
|
2330
2414
|
const measureDragConstraints = () => {
|
|
2331
2415
|
const { dragConstraints } = this.getProps();
|
|
2332
|
-
if (
|
|
2416
|
+
if (isRefObject(dragConstraints) && dragConstraints.current) {
|
|
2333
2417
|
this.constraints = this.resolveRefConstraints();
|
|
2334
2418
|
}
|
|
2335
2419
|
};
|
|
@@ -2339,7 +2423,7 @@ class VisualElementDragControls {
|
|
|
2339
2423
|
projection.root && projection.root.updateScroll();
|
|
2340
2424
|
projection.updateLayout();
|
|
2341
2425
|
}
|
|
2342
|
-
measureDragConstraints
|
|
2426
|
+
domEntry.frame.read(measureDragConstraints);
|
|
2343
2427
|
/**
|
|
2344
2428
|
* Attach a window resize listener to scale the draggable target within its defined
|
|
2345
2429
|
* constraints as the window resizes.
|
|
@@ -2993,6 +3077,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
2993
3077
|
this.hasTreeAnimated = false;
|
|
2994
3078
|
// Note: Currently only running on root node
|
|
2995
3079
|
this.updateScheduled = false;
|
|
3080
|
+
this.scheduleUpdate = () => this.update();
|
|
2996
3081
|
this.projectionUpdateScheduled = false;
|
|
2997
3082
|
this.checkUpdateFailed = () => {
|
|
2998
3083
|
if (this.isUpdating) {
|
|
@@ -3281,7 +3366,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
3281
3366
|
didUpdate() {
|
|
3282
3367
|
if (!this.updateScheduled) {
|
|
3283
3368
|
this.updateScheduled = true;
|
|
3284
|
-
microtask.read(
|
|
3369
|
+
microtask.read(this.scheduleUpdate);
|
|
3285
3370
|
}
|
|
3286
3371
|
}
|
|
3287
3372
|
clearAllSnapshots() {
|
|
@@ -6049,7 +6134,7 @@ function startTransition(callback) {
|
|
|
6049
6134
|
function useInstantTransition() {
|
|
6050
6135
|
const [forceUpdate, forcedRenderCount] = useForceUpdate();
|
|
6051
6136
|
const startInstantLayoutTransition = useInstantLayoutTransition();
|
|
6052
|
-
const unlockOnFrameRef = React.useRef();
|
|
6137
|
+
const unlockOnFrameRef = React.useRef(undefined);
|
|
6053
6138
|
React.useEffect(() => {
|
|
6054
6139
|
/**
|
|
6055
6140
|
* Unblock after two animation frames, otherwise this will unblock too soon.
|
|
@@ -6113,6 +6198,7 @@ _value, frame) {
|
|
|
6113
6198
|
}
|
|
6114
6199
|
const { animation, startTime } = optimisedAnimation;
|
|
6115
6200
|
const cancelAnimation = () => {
|
|
6201
|
+
console.log("de;ete that shiz");
|
|
6116
6202
|
appearAnimationStore.delete(storeId);
|
|
6117
6203
|
if (frame) {
|
|
6118
6204
|
/**
|