framer-motion 7.2.0 → 7.3.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.
- package/dist/cjs/index.js +762 -627
- package/dist/es/animation/use-animated-state.mjs +3 -5
- package/dist/es/animation/utils/default-transitions.mjs +1 -1
- package/dist/es/animation/utils/transitions.mjs +28 -26
- package/dist/es/components/AnimatePresence/PopChild.mjs +3 -2
- package/dist/es/components/AnimatePresence/PresenceChild.mjs +5 -2
- package/dist/es/components/AnimatePresence/use-presence.mjs +1 -1
- package/dist/es/components/LayoutGroup/index.mjs +4 -5
- package/dist/es/components/LazyMotion/index.mjs +3 -5
- package/dist/es/components/MotionConfig/index.mjs +2 -4
- package/dist/es/components/Reorder/Group.mjs +2 -4
- package/dist/es/components/Reorder/Item.mjs +6 -8
- package/dist/es/context/MotionContext/utils.mjs +3 -2
- package/dist/es/gestures/PanSession.mjs +2 -2
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +16 -4
- package/dist/es/gestures/use-focus-gesture.mjs +3 -4
- package/dist/es/gestures/use-hover-gesture.mjs +4 -3
- package/dist/es/gestures/use-tap-gesture.mjs +9 -10
- package/dist/es/index.mjs +2 -1
- package/dist/es/motion/features/animations.mjs +8 -3
- package/dist/es/motion/features/definitions.mjs +1 -13
- package/dist/es/motion/features/layout/MeasureLayout.mjs +12 -6
- package/dist/es/motion/features/load-features.mjs +14 -0
- package/dist/es/motion/features/viewport/observers.mjs +4 -7
- package/dist/es/motion/features/viewport/use-viewport.mjs +8 -6
- package/dist/es/motion/index.mjs +23 -23
- package/dist/es/motion/utils/VisualElementHandler.mjs +2 -5
- package/dist/es/motion/utils/is-forced-motion-value.mjs +3 -3
- package/dist/es/motion/utils/use-motion-ref.mjs +1 -2
- package/dist/es/motion/utils/use-visual-element.mjs +14 -12
- package/dist/es/motion/utils/use-visual-state.mjs +19 -16
- package/dist/es/motion/utils/valid-prop.mjs +22 -17
- package/dist/es/projection/geometry/utils.mjs +10 -1
- package/dist/es/projection/node/HTMLProjectionNode.mjs +1 -1
- package/dist/es/projection/node/create-projection-node.mjs +62 -20
- package/dist/es/projection/use-instant-layout-transition.mjs +2 -2
- package/dist/es/render/dom/features-animation.mjs +5 -1
- package/dist/es/render/dom/features-max.mjs +6 -1
- package/dist/es/render/dom/motion.mjs +6 -1
- package/dist/es/render/dom/use-render.mjs +5 -1
- package/dist/es/render/dom/utils/camel-to-dash.mjs +1 -3
- package/dist/es/render/dom/utils/create-config.mjs +7 -2
- package/dist/es/render/dom/utils/css-variables-conversion.mjs +5 -7
- package/dist/es/render/dom/utils/unit-conversion.mjs +4 -4
- package/dist/es/render/dom/value-types/defaults.mjs +15 -3
- package/dist/es/render/dom/value-types/type-int.mjs +4 -1
- package/dist/es/render/html/config-motion.mjs +1 -1
- package/dist/es/render/html/use-props.mjs +5 -9
- package/dist/es/render/html/utils/build-styles.mjs +17 -15
- package/dist/es/render/html/utils/build-transform.mjs +8 -18
- package/dist/es/render/html/utils/transform.mjs +21 -30
- package/dist/es/render/html/visual-element.mjs +8 -9
- package/dist/es/render/index.mjs +118 -40
- package/dist/es/render/svg/use-props.mjs +5 -2
- package/dist/es/render/svg/utils/build-attrs.mjs +3 -5
- package/dist/es/render/svg/utils/create-render-state.mjs +4 -1
- package/dist/es/render/svg/visual-element.mjs +8 -4
- package/dist/es/render/utils/animation-state.mjs +12 -9
- package/dist/es/render/utils/animation.mjs +14 -8
- package/dist/es/render/utils/is-controlling-variants.mjs +22 -0
- package/dist/es/render/utils/is-variant-label.mjs +8 -0
- package/dist/es/render/utils/motion-values.mjs +3 -3
- package/dist/es/render/utils/resolve-dynamic-variants.mjs +24 -0
- package/dist/es/render/utils/resolve-variants.mjs +26 -0
- package/dist/es/render/utils/setters.mjs +12 -9
- package/dist/es/utils/reduced-motion/index.mjs +19 -0
- package/dist/es/utils/reduced-motion/state.mjs +5 -0
- package/dist/es/utils/reduced-motion/use-reduced-motion-config.mjs +19 -0
- package/dist/es/utils/reduced-motion/use-reduced-motion.mjs +43 -0
- package/dist/es/utils/transform.mjs +4 -1
- package/dist/es/utils/use-in-view.mjs +1 -2
- package/dist/es/value/index.mjs +1 -1
- package/dist/es/value/use-scroll.mjs +6 -4
- package/dist/es/value/use-spring.mjs +7 -1
- package/dist/es/value/use-will-change/index.mjs +4 -4
- package/dist/es/value/utils/is-motion-value.mjs +1 -3
- package/dist/framer-motion.dev.js +806 -670
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +60 -54
- package/dist/projection.dev.js +402 -213
- package/dist/size-rollup-dom-animation-assets.js +1 -0
- package/dist/size-rollup-dom-animation-m.js +1 -0
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -0
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-rollup-motion.js +1 -0
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/dist/size-webpack-m.js +1 -1
- package/dist/three-entry.d.ts +41 -22
- package/package.json +12 -8
- package/dist/es/motion/features/use-features.mjs +0 -40
- package/dist/es/motion/features/use-projection.mjs +0 -33
- package/dist/es/render/utils/variants.mjs +0 -73
- package/dist/es/utils/use-reduced-motion.mjs +0 -73
package/dist/es/render/index.mjs
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
import { __rest } from 'tslib';
|
|
2
1
|
import sync, { cancelSync } from 'framesync';
|
|
2
|
+
import { initPrefersReducedMotion } from '../utils/reduced-motion/index.mjs';
|
|
3
|
+
import { hasReducedMotionListener, prefersReducedMotion } from '../utils/reduced-motion/state.mjs';
|
|
3
4
|
import { motionValue } from '../value/index.mjs';
|
|
4
5
|
import { isWillChangeMotionValue } from '../value/use-will-change/is.mjs';
|
|
5
6
|
import { isMotionValue } from '../value/utils/is-motion-value.mjs';
|
|
6
7
|
import { variantPriorityOrder } from './utils/animation-state.mjs';
|
|
8
|
+
import { isVariantLabel } from './utils/is-variant-label.mjs';
|
|
7
9
|
import { createLifecycles } from './utils/lifecycles.mjs';
|
|
8
10
|
import { updateMotionValuesFromProps } from './utils/motion-values.mjs';
|
|
9
|
-
import {
|
|
11
|
+
import { isControllingVariants, isVariantNode } from './utils/is-controlling-variants.mjs';
|
|
12
|
+
import { env } from '../utils/process.mjs';
|
|
13
|
+
import { invariant } from 'hey-listen';
|
|
14
|
+
import { featureDefinitions } from '../motion/features/definitions.mjs';
|
|
15
|
+
import { createElement } from 'react';
|
|
16
|
+
import { isRefObject } from '../utils/is-ref-object.mjs';
|
|
10
17
|
|
|
11
|
-
const
|
|
18
|
+
const featureNames = Object.keys(featureDefinitions);
|
|
19
|
+
const numFeatures = featureNames.length;
|
|
20
|
+
const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatable, measureViewportBox, render: renderInstance, readValueFromInstance, removeValueFromRenderState, sortNodePosition, scrapeMotionValuesFromProps, }) => ({ parent, props, presenceId, blockInitialAnimation, visualState, reducedMotionConfig, }, options = {}) => {
|
|
12
21
|
let isMounted = false;
|
|
13
22
|
const { latestValues, renderState } = visualState;
|
|
14
23
|
/**
|
|
@@ -44,7 +53,9 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
44
53
|
* When values are removed from all animation props we need to search
|
|
45
54
|
* for a fallback value to animate to. These values are tracked in baseTarget.
|
|
46
55
|
*/
|
|
47
|
-
const baseTarget =
|
|
56
|
+
const baseTarget = {
|
|
57
|
+
...latestValues,
|
|
58
|
+
};
|
|
48
59
|
// Internal methods ========================
|
|
49
60
|
/**
|
|
50
61
|
* On mount, this will be hydrated with a callback to disconnect
|
|
@@ -91,7 +102,7 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
91
102
|
* Doing so will break some tests but this isn't neccessarily a breaking change,
|
|
92
103
|
* more a reflection of the test.
|
|
93
104
|
*/
|
|
94
|
-
const
|
|
105
|
+
const { willChange, ...initialMotionValues } = scrapeMotionValuesFromProps(props);
|
|
95
106
|
for (const key in initialMotionValues) {
|
|
96
107
|
const value = initialMotionValues[key];
|
|
97
108
|
if (latestValues[key] !== undefined && isMotionValue(value)) {
|
|
@@ -104,36 +115,39 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
104
115
|
/**
|
|
105
116
|
* Determine what role this visual element should take in the variant tree.
|
|
106
117
|
*/
|
|
107
|
-
const isControllingVariants =
|
|
108
|
-
const isVariantNode =
|
|
109
|
-
const element =
|
|
118
|
+
const isControllingVariants$1 = isControllingVariants(props);
|
|
119
|
+
const isVariantNode$1 = isVariantNode(props);
|
|
120
|
+
const element = {
|
|
121
|
+
treeType,
|
|
110
122
|
/**
|
|
111
123
|
* This is a mirror of the internal instance prop, which keeps
|
|
112
124
|
* VisualElement type-compatible with React's RefObject.
|
|
113
125
|
*/
|
|
114
|
-
current: null,
|
|
126
|
+
current: null,
|
|
115
127
|
/**
|
|
116
128
|
* The depth of this visual element within the visual element tree.
|
|
117
129
|
*/
|
|
118
|
-
depth: parent ? parent.depth + 1 : 0,
|
|
130
|
+
depth: parent ? parent.depth + 1 : 0,
|
|
131
|
+
parent,
|
|
132
|
+
children: new Set(),
|
|
119
133
|
/**
|
|
120
134
|
*
|
|
121
135
|
*/
|
|
122
136
|
presenceId,
|
|
123
|
-
shouldReduceMotion,
|
|
137
|
+
shouldReduceMotion: null,
|
|
124
138
|
/**
|
|
125
139
|
* If this component is part of the variant tree, it should track
|
|
126
140
|
* any children that are also part of the tree. This is essentially
|
|
127
141
|
* a shadow tree to simplify logic around how to stagger over children.
|
|
128
142
|
*/
|
|
129
|
-
variantChildren: isVariantNode ? new Set() : undefined,
|
|
143
|
+
variantChildren: isVariantNode$1 ? new Set() : undefined,
|
|
130
144
|
/**
|
|
131
145
|
* Whether this instance is visible. This can be changed imperatively
|
|
132
146
|
* by the projection tree, is analogous to CSS's visibility in that
|
|
133
147
|
* hidden elements should take up layout, and needs enacting by the configured
|
|
134
148
|
* render function.
|
|
135
149
|
*/
|
|
136
|
-
isVisible: undefined,
|
|
150
|
+
isVisible: undefined,
|
|
137
151
|
/**
|
|
138
152
|
* Normally, if a component is controlled by a parent's variants, it can
|
|
139
153
|
* rely on that ancestor to trigger animations further down the tree.
|
|
@@ -142,27 +156,37 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
142
156
|
*
|
|
143
157
|
* TODO: This might be better replaced with a method isParentMounted
|
|
144
158
|
*/
|
|
145
|
-
manuallyAnimateOnMount: Boolean(parent === null || parent === void 0 ? void 0 : parent.isMounted()),
|
|
159
|
+
manuallyAnimateOnMount: Boolean(parent === null || parent === void 0 ? void 0 : parent.isMounted()),
|
|
146
160
|
/**
|
|
147
161
|
* This can be set by AnimatePresence to force components that mount
|
|
148
162
|
* at the same time as it to mount as if they have initial={false} set.
|
|
149
163
|
*/
|
|
150
|
-
blockInitialAnimation,
|
|
164
|
+
blockInitialAnimation,
|
|
151
165
|
/**
|
|
152
166
|
* Determine whether this component has mounted yet. This is mostly used
|
|
153
167
|
* by variant children to determine whether they need to trigger their
|
|
154
168
|
* own animations on mount.
|
|
155
169
|
*/
|
|
156
|
-
isMounted: () => Boolean(instance),
|
|
170
|
+
isMounted: () => Boolean(instance),
|
|
171
|
+
mount(newInstance) {
|
|
157
172
|
isMounted = true;
|
|
158
173
|
instance = element.current = newInstance;
|
|
159
174
|
if (element.projection) {
|
|
160
175
|
element.projection.mount(newInstance);
|
|
161
176
|
}
|
|
162
|
-
if (isVariantNode && parent && !isControllingVariants) {
|
|
177
|
+
if (isVariantNode$1 && parent && !isControllingVariants$1) {
|
|
163
178
|
removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
|
|
164
179
|
}
|
|
165
180
|
values.forEach((value, key) => bindToMotionValue(key, value));
|
|
181
|
+
if (!hasReducedMotionListener.current) {
|
|
182
|
+
initPrefersReducedMotion();
|
|
183
|
+
}
|
|
184
|
+
element.shouldReduceMotion =
|
|
185
|
+
reducedMotionConfig === "never"
|
|
186
|
+
? false
|
|
187
|
+
: reducedMotionConfig === "always"
|
|
188
|
+
? true
|
|
189
|
+
: prefersReducedMotion.current;
|
|
166
190
|
parent === null || parent === void 0 ? void 0 : parent.children.add(element);
|
|
167
191
|
element.setProps(props);
|
|
168
192
|
},
|
|
@@ -181,6 +205,55 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
181
205
|
instance = undefined;
|
|
182
206
|
isMounted = false;
|
|
183
207
|
},
|
|
208
|
+
loadFeatures(renderedProps, isStrict, preloadedFeatures, projectionId, ProjectionNodeConstructor, initialLayoutGroupConfig) {
|
|
209
|
+
const features = [];
|
|
210
|
+
/**
|
|
211
|
+
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
212
|
+
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
213
|
+
*/
|
|
214
|
+
if (env !== "production" && preloadedFeatures && isStrict) {
|
|
215
|
+
invariant(false, "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.");
|
|
216
|
+
}
|
|
217
|
+
for (let i = 0; i < numFeatures; i++) {
|
|
218
|
+
const name = featureNames[i];
|
|
219
|
+
const { isEnabled, Component } = featureDefinitions[name];
|
|
220
|
+
/**
|
|
221
|
+
* It might be possible in the future to use this moment to
|
|
222
|
+
* dynamically request functionality. In initial tests this
|
|
223
|
+
* was producing a lot of duplication amongst bundles.
|
|
224
|
+
*/
|
|
225
|
+
if (isEnabled(props) && Component) {
|
|
226
|
+
features.push(createElement(Component, {
|
|
227
|
+
key: name,
|
|
228
|
+
...renderedProps,
|
|
229
|
+
visualElement: element,
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (!element.projection && ProjectionNodeConstructor) {
|
|
234
|
+
element.projection = new ProjectionNodeConstructor(projectionId, element.getLatestValues(), parent && parent.projection);
|
|
235
|
+
const { layoutId, layout, drag, dragConstraints, layoutScroll, } = renderedProps;
|
|
236
|
+
element.projection.setOptions({
|
|
237
|
+
layoutId,
|
|
238
|
+
layout,
|
|
239
|
+
alwaysMeasureLayout: Boolean(drag) ||
|
|
240
|
+
(dragConstraints && isRefObject(dragConstraints)),
|
|
241
|
+
visualElement: element,
|
|
242
|
+
scheduleRender: () => element.scheduleRender(),
|
|
243
|
+
/**
|
|
244
|
+
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
245
|
+
* to update by the time layout animations run.
|
|
246
|
+
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
247
|
+
* ensuring it gets called if there's no potential layout animations.
|
|
248
|
+
*
|
|
249
|
+
*/
|
|
250
|
+
animationType: typeof layout === "string" ? layout : "both",
|
|
251
|
+
initialPromotionConfig: initialLayoutGroupConfig,
|
|
252
|
+
layoutScroll,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return features;
|
|
256
|
+
},
|
|
184
257
|
/**
|
|
185
258
|
* Add a child visual element to our set of children.
|
|
186
259
|
*/
|
|
@@ -199,30 +272,31 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
199
272
|
if (!sortNodePosition || treeType !== other.treeType)
|
|
200
273
|
return 0;
|
|
201
274
|
return sortNodePosition(element.getInstance(), other.getInstance());
|
|
202
|
-
},
|
|
275
|
+
},
|
|
203
276
|
/**
|
|
204
277
|
* Returns the closest variant node in the tree starting from
|
|
205
278
|
* this visual element.
|
|
206
279
|
*/
|
|
207
|
-
getClosestVariantNode: () => isVariantNode ? element : parent === null || parent === void 0 ? void 0 : parent.getClosestVariantNode(),
|
|
280
|
+
getClosestVariantNode: () => isVariantNode$1 ? element : parent === null || parent === void 0 ? void 0 : parent.getClosestVariantNode(),
|
|
208
281
|
/**
|
|
209
282
|
* Expose the latest layoutId prop.
|
|
210
283
|
*/
|
|
211
|
-
getLayoutId: () => props.layoutId,
|
|
284
|
+
getLayoutId: () => props.layoutId,
|
|
212
285
|
/**
|
|
213
286
|
* Returns the current instance.
|
|
214
287
|
*/
|
|
215
|
-
getInstance: () => instance,
|
|
288
|
+
getInstance: () => instance,
|
|
216
289
|
/**
|
|
217
290
|
* Get/set the latest static values.
|
|
218
291
|
*/
|
|
219
|
-
getStaticValue: (key) => latestValues[key],
|
|
292
|
+
getStaticValue: (key) => latestValues[key],
|
|
293
|
+
setStaticValue: (key, value) => (latestValues[key] = value),
|
|
220
294
|
/**
|
|
221
295
|
* Returns the latest motion value state. Currently only used to take
|
|
222
296
|
* a snapshot of the visual element - perhaps this can return the whole
|
|
223
297
|
* visual state
|
|
224
298
|
*/
|
|
225
|
-
getLatestValues: () => latestValues,
|
|
299
|
+
getLatestValues: () => latestValues,
|
|
226
300
|
/**
|
|
227
301
|
* Set the visiblity of the visual element. If it's changed, schedule
|
|
228
302
|
* a render to reflect these changes.
|
|
@@ -273,11 +347,11 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
273
347
|
valueSubscriptions.delete(key);
|
|
274
348
|
delete latestValues[key];
|
|
275
349
|
removeValueFromRenderState(key, renderState);
|
|
276
|
-
},
|
|
350
|
+
},
|
|
277
351
|
/**
|
|
278
352
|
* Check whether we have a motion value for this key
|
|
279
353
|
*/
|
|
280
|
-
hasValue: (key) => values.has(key),
|
|
354
|
+
hasValue: (key) => values.has(key),
|
|
281
355
|
/**
|
|
282
356
|
* Get a motion value for this key. If called with a default
|
|
283
357
|
* value, we'll create one if none exists.
|
|
@@ -289,20 +363,19 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
289
363
|
element.addValue(key, value);
|
|
290
364
|
}
|
|
291
365
|
return value;
|
|
292
|
-
},
|
|
366
|
+
},
|
|
293
367
|
/**
|
|
294
368
|
* Iterate over our motion values.
|
|
295
369
|
*/
|
|
296
|
-
forEachValue: (callback) => values.forEach(callback),
|
|
370
|
+
forEachValue: (callback) => values.forEach(callback),
|
|
297
371
|
/**
|
|
298
372
|
* If we're trying to animate to a previously unencountered value,
|
|
299
373
|
* we need to check for it in our state and as a last resort read it
|
|
300
374
|
* directly from the instance (which might have performance implications).
|
|
301
375
|
*/
|
|
302
|
-
readValue: (key) =>
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
},
|
|
376
|
+
readValue: (key) => latestValues[key] !== undefined
|
|
377
|
+
? latestValues[key]
|
|
378
|
+
: readValueFromInstance(instance, key, options),
|
|
306
379
|
/**
|
|
307
380
|
* Set the base target to later animate back to. This is currently
|
|
308
381
|
* only hydrated on creation and when we first read a value.
|
|
@@ -321,7 +394,9 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
321
394
|
return target;
|
|
322
395
|
}
|
|
323
396
|
return baseTarget[key];
|
|
324
|
-
}
|
|
397
|
+
},
|
|
398
|
+
// Lifecyles ========================
|
|
399
|
+
...lifecycles,
|
|
325
400
|
/**
|
|
326
401
|
* Build the renderer state based on the latest visual state.
|
|
327
402
|
*/
|
|
@@ -334,14 +409,14 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
334
409
|
*/
|
|
335
410
|
scheduleRender() {
|
|
336
411
|
sync.render(render, false, true);
|
|
337
|
-
},
|
|
412
|
+
},
|
|
338
413
|
/**
|
|
339
414
|
* Synchronously fire render. It's prefered that we batch renders but
|
|
340
415
|
* in many circumstances, like layout measurement, we need to run this
|
|
341
416
|
* synchronously. However in those instances other measures should be taken
|
|
342
417
|
* to batch reads/writes.
|
|
343
418
|
*/
|
|
344
|
-
syncRender: render,
|
|
419
|
+
syncRender: render,
|
|
345
420
|
/**
|
|
346
421
|
* Update the provided props. Ensure any newly-added motion values are
|
|
347
422
|
* added to our map, old ones removed, and listeners updated.
|
|
@@ -353,25 +428,27 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
353
428
|
props = newProps;
|
|
354
429
|
lifecycles.updatePropListeners(newProps);
|
|
355
430
|
prevMotionValues = updateMotionValuesFromProps(element, scrapeMotionValuesFromProps(props), prevMotionValues);
|
|
356
|
-
},
|
|
431
|
+
},
|
|
432
|
+
getProps: () => props,
|
|
357
433
|
// Variants ==============================
|
|
358
434
|
/**
|
|
359
435
|
* Returns the variant definition with a given name.
|
|
360
436
|
*/
|
|
361
|
-
getVariant: (name) => { var _a; return (_a = props.variants) === null || _a === void 0 ? void 0 : _a[name]; },
|
|
437
|
+
getVariant: (name) => { var _a; return (_a = props.variants) === null || _a === void 0 ? void 0 : _a[name]; },
|
|
362
438
|
/**
|
|
363
439
|
* Returns the defined default transition on this component.
|
|
364
440
|
*/
|
|
365
|
-
getDefaultTransition: () => props.transition,
|
|
441
|
+
getDefaultTransition: () => props.transition,
|
|
442
|
+
getTransformPagePoint: () => {
|
|
366
443
|
return props.transformPagePoint;
|
|
367
|
-
},
|
|
444
|
+
},
|
|
368
445
|
/**
|
|
369
446
|
* Used by child variant nodes to get the closest ancestor variant props.
|
|
370
447
|
*/
|
|
371
448
|
getVariantContext(startAtParent = false) {
|
|
372
449
|
if (startAtParent)
|
|
373
450
|
return parent === null || parent === void 0 ? void 0 : parent.getVariantContext();
|
|
374
|
-
if (!isControllingVariants) {
|
|
451
|
+
if (!isControllingVariants$1) {
|
|
375
452
|
const context = (parent === null || parent === void 0 ? void 0 : parent.getVariantContext()) || {};
|
|
376
453
|
if (props.initial !== undefined) {
|
|
377
454
|
context.initial = props.initial;
|
|
@@ -387,7 +464,8 @@ const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatab
|
|
|
387
464
|
}
|
|
388
465
|
}
|
|
389
466
|
return context;
|
|
390
|
-
}
|
|
467
|
+
},
|
|
468
|
+
};
|
|
391
469
|
return element;
|
|
392
470
|
};
|
|
393
471
|
const variantProps = ["initial", ...variantPriorityOrder];
|
|
@@ -7,12 +7,15 @@ function useSVGProps(props, visualState) {
|
|
|
7
7
|
const visualProps = useMemo(() => {
|
|
8
8
|
const state = createSvgRenderState();
|
|
9
9
|
buildSVGAttrs(state, visualState, { enableHardwareAcceleration: false }, props.transformTemplate);
|
|
10
|
-
return
|
|
10
|
+
return {
|
|
11
|
+
...state.attrs,
|
|
12
|
+
style: { ...state.style },
|
|
13
|
+
};
|
|
11
14
|
}, [visualState]);
|
|
12
15
|
if (props.style) {
|
|
13
16
|
const rawStyles = {};
|
|
14
17
|
copyRawValuesOnly(rawStyles, props.style, props);
|
|
15
|
-
visualProps.style =
|
|
18
|
+
visualProps.style = { ...rawStyles, ...visualProps.style };
|
|
16
19
|
}
|
|
17
20
|
return visualProps;
|
|
18
21
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { __rest } from 'tslib';
|
|
2
1
|
import { buildHTMLStyles } from '../../html/utils/build-styles.mjs';
|
|
3
2
|
import { calcSVGTransformOrigin } from './transform-origin.mjs';
|
|
4
3
|
import { buildSVGPath } from './path.mjs';
|
|
@@ -6,10 +5,9 @@ import { buildSVGPath } from './path.mjs';
|
|
|
6
5
|
/**
|
|
7
6
|
* Build SVG visual attrbutes, like cx and style.transform
|
|
8
7
|
*/
|
|
9
|
-
function buildSVGAttrs(state,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
latest = __rest(_a, ["attrX", "attrY", "originX", "originY", "pathLength", "pathSpacing", "pathOffset"]);
|
|
8
|
+
function buildSVGAttrs(state, { attrX, attrY, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
|
|
9
|
+
// This is object creation, which we try to avoid per-frame.
|
|
10
|
+
...latest }, options, transformTemplate) {
|
|
13
11
|
buildHTMLStyles(state, latest, options, transformTemplate);
|
|
14
12
|
state.attrs = state.style;
|
|
15
13
|
state.style = {};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { createHtmlRenderState } from '../../html/utils/create-render-state.mjs';
|
|
2
2
|
|
|
3
|
-
const createSvgRenderState = () => (
|
|
3
|
+
const createSvgRenderState = () => ({
|
|
4
|
+
...createHtmlRenderState(),
|
|
5
|
+
attrs: {},
|
|
6
|
+
});
|
|
4
7
|
|
|
5
8
|
export { createSvgRenderState };
|
|
@@ -4,16 +4,18 @@ import { htmlConfig } from '../html/visual-element.mjs';
|
|
|
4
4
|
import { buildSVGAttrs } from './utils/build-attrs.mjs';
|
|
5
5
|
import { camelToDash } from '../dom/utils/camel-to-dash.mjs';
|
|
6
6
|
import { camelCaseAttributes } from './utils/camel-case-attrs.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import { transformProps } from '../html/utils/transform.mjs';
|
|
8
8
|
import { renderSVG } from './utils/render.mjs';
|
|
9
9
|
import { getDefaultValueType } from '../dom/value-types/defaults.mjs';
|
|
10
10
|
|
|
11
|
-
const svgVisualElement = visualElement(
|
|
11
|
+
const svgVisualElement = visualElement({
|
|
12
|
+
...htmlConfig,
|
|
13
|
+
getBaseTarget(props, key) {
|
|
12
14
|
return props[key];
|
|
13
15
|
},
|
|
14
16
|
readValueFromInstance(domElement, key) {
|
|
15
17
|
var _a;
|
|
16
|
-
if (
|
|
18
|
+
if (transformProps.has(key)) {
|
|
17
19
|
return ((_a = getDefaultValueType(key)) === null || _a === void 0 ? void 0 : _a.default) || 0;
|
|
18
20
|
}
|
|
19
21
|
key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
|
|
@@ -22,6 +24,8 @@ const svgVisualElement = visualElement(Object.assign(Object.assign({}, htmlConfi
|
|
|
22
24
|
scrapeMotionValuesFromProps,
|
|
23
25
|
build(_element, renderState, latestValues, options, props) {
|
|
24
26
|
buildSVGAttrs(renderState, latestValues, options, props.transformTemplate);
|
|
25
|
-
},
|
|
27
|
+
},
|
|
28
|
+
render: renderSVG,
|
|
29
|
+
});
|
|
26
30
|
|
|
27
31
|
export { svgVisualElement };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { __rest } from 'tslib';
|
|
2
1
|
import { isAnimationControls } from '../../animation/utils/is-animation-controls.mjs';
|
|
3
2
|
import { isKeyframesTarget } from '../../animation/utils/is-keyframes-target.mjs';
|
|
4
3
|
import { shallowCompare } from '../../utils/shallow-compare.mjs';
|
|
5
4
|
import { animateVisualElement } from './animation.mjs';
|
|
5
|
+
import { isVariantLabel } from './is-variant-label.mjs';
|
|
6
6
|
import { AnimationType } from './types.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import { resolveVariant } from './resolve-dynamic-variants.mjs';
|
|
8
8
|
|
|
9
9
|
const variantPriorityOrder = [
|
|
10
10
|
AnimationType.Animate,
|
|
@@ -31,8 +31,8 @@ function createAnimationState(visualElement) {
|
|
|
31
31
|
const buildResolvedTypeValues = (acc, definition) => {
|
|
32
32
|
const resolved = resolveVariant(visualElement, definition);
|
|
33
33
|
if (resolved) {
|
|
34
|
-
const { transition, transitionEnd
|
|
35
|
-
acc =
|
|
34
|
+
const { transition, transitionEnd, ...target } = resolved;
|
|
35
|
+
acc = { ...acc, ...target, ...transitionEnd };
|
|
36
36
|
}
|
|
37
37
|
return acc;
|
|
38
38
|
};
|
|
@@ -115,7 +115,7 @@ function createAnimationState(visualElement) {
|
|
|
115
115
|
* Set all encountered keys so far as the protected keys for this type. This will
|
|
116
116
|
* be any key that has been animated or otherwise handled by active, higher-priortiy types.
|
|
117
117
|
*/
|
|
118
|
-
typeState.protectedKeys =
|
|
118
|
+
typeState.protectedKeys = { ...encounteredKeys };
|
|
119
119
|
// Check if we can skip analysing this prop early
|
|
120
120
|
if (
|
|
121
121
|
// If it isn't active and hasn't *just* been set as inactive
|
|
@@ -163,7 +163,10 @@ function createAnimationState(visualElement) {
|
|
|
163
163
|
* needs adding to the type's protectedKeys list.
|
|
164
164
|
*/
|
|
165
165
|
const { prevResolvedValues = {} } = typeState;
|
|
166
|
-
const allKeys =
|
|
166
|
+
const allKeys = {
|
|
167
|
+
...prevResolvedValues,
|
|
168
|
+
...resolvedValues,
|
|
169
|
+
};
|
|
167
170
|
const markToAnimate = (key) => {
|
|
168
171
|
shouldAnimateType = true;
|
|
169
172
|
removedKeys.delete(key);
|
|
@@ -229,7 +232,7 @@ function createAnimationState(visualElement) {
|
|
|
229
232
|
*
|
|
230
233
|
*/
|
|
231
234
|
if (typeState.isActive) {
|
|
232
|
-
encounteredKeys =
|
|
235
|
+
encounteredKeys = { ...encounteredKeys, ...resolvedValues };
|
|
233
236
|
}
|
|
234
237
|
if (isInitialRender && visualElement.blockInitialAnimation) {
|
|
235
238
|
shouldAnimateType = false;
|
|
@@ -242,7 +245,7 @@ function createAnimationState(visualElement) {
|
|
|
242
245
|
if (shouldAnimateType && !isInherited) {
|
|
243
246
|
animations.push(...definitionList.map((animation) => ({
|
|
244
247
|
animation: animation,
|
|
245
|
-
options:
|
|
248
|
+
options: { type, ...options },
|
|
246
249
|
})));
|
|
247
250
|
}
|
|
248
251
|
}
|
|
@@ -298,7 +301,7 @@ function checkVariantsDidChange(prev, next) {
|
|
|
298
301
|
if (typeof next === "string") {
|
|
299
302
|
return next !== prev;
|
|
300
303
|
}
|
|
301
|
-
else if (
|
|
304
|
+
else if (Array.isArray(next)) {
|
|
302
305
|
return !shallowCompare(next, prev);
|
|
303
306
|
}
|
|
304
307
|
return false;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { __rest } from 'tslib';
|
|
2
1
|
import { startAnimation } from '../../animation/utils/transitions.mjs';
|
|
3
2
|
import { setTarget } from './setters.mjs';
|
|
4
|
-
import { resolveVariant } from './variants.mjs';
|
|
5
|
-
import {
|
|
3
|
+
import { resolveVariant } from './resolve-dynamic-variants.mjs';
|
|
4
|
+
import { transformProps } from '../html/utils/transform.mjs';
|
|
6
5
|
import { isWillChangeMotionValue } from '../../value/use-will-change/is.mjs';
|
|
7
6
|
|
|
8
7
|
function animateVisualElement(visualElement, definition, options = {}) {
|
|
@@ -67,7 +66,7 @@ function animateVariant(visualElement, variant, options = {}) {
|
|
|
67
66
|
*/
|
|
68
67
|
function animateTarget(visualElement, definition, { delay = 0, transitionOverride, type } = {}) {
|
|
69
68
|
var _a;
|
|
70
|
-
let
|
|
69
|
+
let { transition = visualElement.getDefaultTransition(), transitionEnd, ...target } = visualElement.makeTargetAnimatable(definition);
|
|
71
70
|
const willChange = visualElement.getValue("willChange");
|
|
72
71
|
if (transitionOverride)
|
|
73
72
|
transition = transitionOverride;
|
|
@@ -82,12 +81,16 @@ function animateTarget(visualElement, definition, { delay = 0, transitionOverrid
|
|
|
82
81
|
shouldBlockAnimation(animationTypeState, key))) {
|
|
83
82
|
continue;
|
|
84
83
|
}
|
|
85
|
-
let valueTransition =
|
|
84
|
+
let valueTransition = { delay, ...transition };
|
|
86
85
|
/**
|
|
87
86
|
* Make animation instant if this is a transform prop and we should reduce motion.
|
|
88
87
|
*/
|
|
89
|
-
if (visualElement.shouldReduceMotion &&
|
|
90
|
-
valueTransition =
|
|
88
|
+
if (visualElement.shouldReduceMotion && transformProps.has(key)) {
|
|
89
|
+
valueTransition = {
|
|
90
|
+
...valueTransition,
|
|
91
|
+
type: false,
|
|
92
|
+
delay: 0,
|
|
93
|
+
};
|
|
91
94
|
}
|
|
92
95
|
let animation = startAnimation(key, value, valueTarget, valueTransition);
|
|
93
96
|
if (isWillChangeMotionValue(willChange)) {
|
|
@@ -109,7 +112,10 @@ function animateChildren(visualElement, variant, delayChildren = 0, staggerChild
|
|
|
109
112
|
Array.from(visualElement.variantChildren)
|
|
110
113
|
.sort(sortByTreeOrder)
|
|
111
114
|
.forEach((child, i) => {
|
|
112
|
-
animations.push(animateVariant(child, variant,
|
|
115
|
+
animations.push(animateVariant(child, variant, {
|
|
116
|
+
...options,
|
|
117
|
+
delay: delayChildren + generateStaggerDuration(i),
|
|
118
|
+
}).then(() => child.notifyAnimationComplete(variant)));
|
|
113
119
|
});
|
|
114
120
|
return Promise.all(animations);
|
|
115
121
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isAnimationControls } from '../../animation/utils/is-animation-controls.mjs';
|
|
2
|
+
import { isVariantLabel } from './is-variant-label.mjs';
|
|
3
|
+
|
|
4
|
+
const variantProps = [
|
|
5
|
+
"initial",
|
|
6
|
+
"animate",
|
|
7
|
+
"exit",
|
|
8
|
+
"whileHover",
|
|
9
|
+
"whileDrag",
|
|
10
|
+
"whileTap",
|
|
11
|
+
"whileFocus",
|
|
12
|
+
"whileInView",
|
|
13
|
+
];
|
|
14
|
+
function isControllingVariants(props) {
|
|
15
|
+
return (isAnimationControls(props.animate) ||
|
|
16
|
+
variantProps.some((name) => isVariantLabel(props[name])));
|
|
17
|
+
}
|
|
18
|
+
function isVariantNode(props) {
|
|
19
|
+
return Boolean(isControllingVariants(props) || props.variants);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { isControllingVariants, isVariantNode };
|
|
@@ -4,7 +4,6 @@ import { motionValue } from '../../value/index.mjs';
|
|
|
4
4
|
import { isMotionValue } from '../../value/utils/is-motion-value.mjs';
|
|
5
5
|
|
|
6
6
|
function updateMotionValuesFromProps(element, next, prev) {
|
|
7
|
-
var _a;
|
|
8
7
|
const { willChange } = next;
|
|
9
8
|
for (const key in next) {
|
|
10
9
|
const nextValue = next[key];
|
|
@@ -23,7 +22,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
23
22
|
* and warn against mismatches.
|
|
24
23
|
*/
|
|
25
24
|
if (process.env.NODE_ENV === "development") {
|
|
26
|
-
warnOnce(nextValue.version === "7.
|
|
25
|
+
warnOnce(nextValue.version === "7.3.1", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.3.1 may not work as expected.`);
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
else if (isMotionValue(prevValue)) {
|
|
@@ -48,7 +47,8 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
48
47
|
!existingValue.hasAnimated && existingValue.set(nextValue);
|
|
49
48
|
}
|
|
50
49
|
else {
|
|
51
|
-
|
|
50
|
+
const latestValue = element.getStaticValue(key);
|
|
51
|
+
element.addValue(key, motionValue(latestValue !== undefined ? latestValue : nextValue));
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { resolveVariantFromProps } from './resolve-variants.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates an object containing the latest state of every MotionValue on a VisualElement
|
|
5
|
+
*/
|
|
6
|
+
function getCurrent(visualElement) {
|
|
7
|
+
const current = {};
|
|
8
|
+
visualElement.forEachValue((value, key) => (current[key] = value.get()));
|
|
9
|
+
return current;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates an object containing the latest velocity of every MotionValue on a VisualElement
|
|
13
|
+
*/
|
|
14
|
+
function getVelocity(visualElement) {
|
|
15
|
+
const velocity = {};
|
|
16
|
+
visualElement.forEachValue((value, key) => (velocity[key] = value.getVelocity()));
|
|
17
|
+
return velocity;
|
|
18
|
+
}
|
|
19
|
+
function resolveVariant(visualElement, definition, custom) {
|
|
20
|
+
const props = visualElement.getProps();
|
|
21
|
+
return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, getCurrent(visualElement), getVelocity(visualElement));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { resolveVariant };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function resolveVariantFromProps(props, definition, custom, currentValues = {}, currentVelocity = {}) {
|
|
2
|
+
/**
|
|
3
|
+
* If the variant definition is a function, resolve.
|
|
4
|
+
*/
|
|
5
|
+
if (typeof definition === "function") {
|
|
6
|
+
definition = definition(custom !== undefined ? custom : props.custom, currentValues, currentVelocity);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* If the variant definition is a variant label, or
|
|
10
|
+
* the function returned a variant label, resolve.
|
|
11
|
+
*/
|
|
12
|
+
if (typeof definition === "string") {
|
|
13
|
+
definition = props.variants && props.variants[definition];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* At this point we've resolved both functions and variant labels,
|
|
17
|
+
* but the resolved variant label might itself have been a function.
|
|
18
|
+
* If so, resolve. This can only have returned a valid target object.
|
|
19
|
+
*/
|
|
20
|
+
if (typeof definition === "function") {
|
|
21
|
+
definition = definition(custom !== undefined ? custom : props.custom, currentValues, currentVelocity);
|
|
22
|
+
}
|
|
23
|
+
return definition;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { resolveVariantFromProps };
|