framer-motion 7.6.4 → 7.6.6

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 (39) hide show
  1. package/dist/cjs/index.js +789 -850
  2. package/dist/es/animation/use-animated-state.mjs +29 -17
  3. package/dist/es/gestures/drag/VisualElementDragControls.mjs +14 -10
  4. package/dist/es/gestures/use-focus-gesture.mjs +1 -1
  5. package/dist/es/gestures/use-tap-gesture.mjs +1 -1
  6. package/dist/es/index.mjs +1 -1
  7. package/dist/es/motion/features/viewport/use-viewport.mjs +2 -2
  8. package/dist/es/motion/utils/use-visual-element.mjs +3 -3
  9. package/dist/es/projection/node/create-projection-node.mjs +74 -60
  10. package/dist/es/render/VisualElement.mjs +480 -0
  11. package/dist/es/render/dom/DOMVisualElement.mjs +49 -0
  12. package/dist/es/render/dom/create-visual-element.mjs +4 -4
  13. package/dist/es/render/dom/utils/css-variables-conversion.mjs +2 -2
  14. package/dist/es/render/dom/utils/unit-conversion.mjs +4 -4
  15. package/dist/es/render/html/HTMLVisualElement.mjs +41 -0
  16. package/dist/es/render/svg/{visual-element.mjs → SVGVisualElement.mjs} +21 -15
  17. package/dist/es/render/utils/animation.mjs +4 -4
  18. package/dist/es/render/utils/motion-values.mjs +1 -1
  19. package/dist/es/render/utils/resolve-dynamic-variants.mjs +2 -2
  20. package/dist/es/render/utils/setters.mjs +2 -1
  21. package/dist/es/value/index.mjs +1 -1
  22. package/dist/framer-motion.dev.js +789 -850
  23. package/dist/framer-motion.js +1 -1
  24. package/dist/index.d.ts +2101 -1931
  25. package/dist/projection.dev.js +1053 -1136
  26. package/dist/size-rollup-dom-animation-m.js +1 -1
  27. package/dist/size-rollup-dom-animation.js +1 -1
  28. package/dist/size-rollup-dom-max-assets.js +1 -1
  29. package/dist/size-rollup-dom-max.js +1 -1
  30. package/dist/size-rollup-m.js +1 -1
  31. package/dist/size-rollup-motion.js +1 -1
  32. package/dist/size-webpack-dom-animation.js +1 -1
  33. package/dist/size-webpack-dom-max.js +1 -1
  34. package/dist/size-webpack-m.js +1 -1
  35. package/dist/three-entry.d.ts +1956 -1745
  36. package/package.json +8 -8
  37. package/dist/es/render/html/visual-element.mjs +0 -109
  38. package/dist/es/render/index.mjs +0 -515
  39. package/dist/es/render/utils/lifecycles.mjs +0 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framer-motion",
3
- "version": "7.6.4",
3
+ "version": "7.6.6",
4
4
  "description": "A simple and powerful React animation library",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/es/index.mjs",
@@ -40,7 +40,7 @@
40
40
  "test": "yarn test-server && yarn test-client",
41
41
  "test-ci": "yarn test",
42
42
  "test-client": "jest --config jest.config.json --max-workers=2",
43
- "test-server": "jest --config jest.config.ssr.json",
43
+ "test-server": "jest --config jest.config.ssr.json ",
44
44
  "test-watch": "jest --watch --coverage --coverageReporters=lcov --config jest.config.json",
45
45
  "test-projection": "yarn run collect-projection-tests && start-server-and-test 'pushd ../../; python -m SimpleHTTPServer; popd' http://0.0.0.0:8000 'cypress run -s cypress/integration/projection.chrome.ts --config baseUrl=http://localhost:8000/'",
46
46
  "test-e2e-chrome": "start-server-and-test start-dev-server http://localhost:9990 'cypress run --headless --browser chrome --spec \"cypress/integration/layout-relative.chrome.ts\"'",
@@ -73,7 +73,7 @@
73
73
  "bundlesize": [
74
74
  {
75
75
  "path": "./dist/size-rollup-motion.js",
76
- "maxSize": "29.40 kB"
76
+ "maxSize": "29.35 kB"
77
77
  },
78
78
  {
79
79
  "path": "./dist/size-rollup-m.js",
@@ -81,11 +81,11 @@
81
81
  },
82
82
  {
83
83
  "path": "./dist/size-rollup-dom-animation.js",
84
- "maxSize": "16.75 kB"
84
+ "maxSize": "14.9 kB"
85
85
  },
86
86
  {
87
87
  "path": "./dist/size-rollup-dom-max.js",
88
- "maxSize": "27.2 kB"
88
+ "maxSize": "25.32 kB"
89
89
  },
90
90
  {
91
91
  "path": "./dist/size-webpack-m.js",
@@ -93,12 +93,12 @@
93
93
  },
94
94
  {
95
95
  "path": "./dist/size-webpack-dom-animation.js",
96
- "maxSize": "19.25 kB"
96
+ "maxSize": "19.20 kB"
97
97
  },
98
98
  {
99
99
  "path": "./dist/size-webpack-dom-max.js",
100
- "maxSize": "30.5kB"
100
+ "maxSize": "30.55kB"
101
101
  }
102
102
  ],
103
- "gitHead": "25bf2c6ccabb835f11e4877ffa8521b2697c8ccf"
103
+ "gitHead": "f67f6f7d14639379b15f465e98575fa1cece7a8e"
104
104
  }
@@ -1,109 +0,0 @@
1
- import { visualElement } from '../index.mjs';
2
- import { getOrigin, checkTargetForNewValues } from '../utils/setters.mjs';
3
- import { buildHTMLStyles } from './utils/build-styles.mjs';
4
- import { isCSSVariable } from '../dom/utils/is-css-variable.mjs';
5
- import { parseDomVariant } from '../dom/utils/parse-dom-variant.mjs';
6
- import { transformProps } from './utils/transform.mjs';
7
- import { scrapeMotionValuesFromProps } from './utils/scrape-motion-values.mjs';
8
- import { renderHTML } from './utils/render.mjs';
9
- import { getDefaultValueType } from '../dom/value-types/defaults.mjs';
10
- import { measureViewportBox } from '../../projection/utils/measure.mjs';
11
-
12
- function getComputedStyle(element) {
13
- return window.getComputedStyle(element);
14
- }
15
- const htmlConfig = {
16
- treeType: "dom",
17
- readValueFromInstance(domElement, key) {
18
- if (transformProps.has(key)) {
19
- const defaultType = getDefaultValueType(key);
20
- return defaultType ? defaultType.default || 0 : 0;
21
- }
22
- else {
23
- const computedStyle = getComputedStyle(domElement);
24
- const value = (isCSSVariable(key)
25
- ? computedStyle.getPropertyValue(key)
26
- : computedStyle[key]) || 0;
27
- return typeof value === "string" ? value.trim() : value;
28
- }
29
- },
30
- sortNodePosition(a, b) {
31
- /**
32
- * compareDocumentPosition returns a bitmask, by using the bitwise &
33
- * we're returning true if 2 in that bitmask is set to true. 2 is set
34
- * to true if b preceeds a.
35
- */
36
- return a.compareDocumentPosition(b) & 2 ? 1 : -1;
37
- },
38
- getBaseTarget(props, key) {
39
- var _a;
40
- return (_a = props.style) === null || _a === void 0 ? void 0 : _a[key];
41
- },
42
- measureViewportBox(element, { transformPagePoint }) {
43
- return measureViewportBox(element, transformPagePoint);
44
- },
45
- /**
46
- * Reset the transform on the current Element. This is called as part
47
- * of a batched process across the entire layout tree. To remove this write
48
- * cycle it'd be interesting to see if it's possible to "undo" all the current
49
- * layout transforms up the tree in the same way this.getBoundingBoxWithoutTransforms
50
- * works
51
- */
52
- resetTransform(element, domElement, props) {
53
- const { transformTemplate } = props;
54
- domElement.style.transform = transformTemplate
55
- ? transformTemplate({}, "")
56
- : "none";
57
- // Ensure that whatever happens next, we restore our transform on the next frame
58
- element.scheduleRender();
59
- },
60
- restoreTransform(instance, mutableState) {
61
- instance.style.transform = mutableState.style.transform;
62
- },
63
- removeValueFromRenderState(key, { vars, style }) {
64
- delete vars[key];
65
- delete style[key];
66
- },
67
- /**
68
- * Ensure that HTML and Framer-specific value types like `px`->`%` and `Color`
69
- * can be animated by Motion.
70
- */
71
- makeTargetAnimatable(element, { transition, transitionEnd, ...target }, { transformValues }, isMounted = true) {
72
- let origin = getOrigin(target, transition || {}, element);
73
- /**
74
- * If Framer has provided a function to convert `Color` etc value types, convert them
75
- */
76
- if (transformValues) {
77
- if (transitionEnd)
78
- transitionEnd = transformValues(transitionEnd);
79
- if (target)
80
- target = transformValues(target);
81
- if (origin)
82
- origin = transformValues(origin);
83
- }
84
- if (isMounted) {
85
- checkTargetForNewValues(element, target, origin);
86
- const parsed = parseDomVariant(element, target, origin, transitionEnd);
87
- transitionEnd = parsed.transitionEnd;
88
- target = parsed.target;
89
- }
90
- return {
91
- transition,
92
- transitionEnd,
93
- ...target,
94
- };
95
- },
96
- scrapeMotionValuesFromProps,
97
- build(element, renderState, latestValues, options, props) {
98
- if (element.isVisible !== undefined) {
99
- renderState.style.visibility = element.isVisible
100
- ? "visible"
101
- : "hidden";
102
- }
103
- buildHTMLStyles(renderState, latestValues, options, props.transformTemplate);
104
- },
105
- render: renderHTML,
106
- };
107
- const htmlVisualElement = visualElement(htmlConfig);
108
-
109
- export { getComputedStyle, htmlConfig, htmlVisualElement };
@@ -1,515 +0,0 @@
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';
4
- import { motionValue } from '../value/index.mjs';
5
- import { isWillChangeMotionValue } from '../value/use-will-change/is.mjs';
6
- import { isMotionValue } from '../value/utils/is-motion-value.mjs';
7
- import { variantPriorityOrder } from './utils/animation-state.mjs';
8
- import { isVariantLabel } from './utils/is-variant-label.mjs';
9
- import { createLifecycles } from './utils/lifecycles.mjs';
10
- import { updateMotionValuesFromProps } from './utils/motion-values.mjs';
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';
17
- import { resolveVariantFromProps } from './utils/resolve-variants.mjs';
18
-
19
- const featureNames = Object.keys(featureDefinitions);
20
- const numFeatures = featureNames.length;
21
- const visualElement = ({ treeType = "", build, getBaseTarget, makeTargetAnimatable, measureViewportBox, render: renderInstance, readValueFromInstance, removeValueFromRenderState, sortNodePosition, scrapeMotionValuesFromProps, }) => ({ parent, props, presenceId, blockInitialAnimation, visualState, reducedMotionConfig, }, options = {}) => {
22
- let isMounted = false;
23
- const { latestValues, renderState } = visualState;
24
- /**
25
- * The instance of the render-specific node that will be hydrated by the
26
- * exposed React ref. So for example, this visual element can host a
27
- * HTMLElement, plain object, or Three.js object. The functions provided
28
- * in VisualElementConfig allow us to interface with this instance.
29
- */
30
- let instance;
31
- /**
32
- * Manages the subscriptions for a visual element's lifecycle, for instance
33
- * onRender
34
- */
35
- const lifecycles = createLifecycles();
36
- /**
37
- * A map of all motion values attached to this visual element. Motion
38
- * values are source of truth for any given animated value. A motion
39
- * value might be provided externally by the component via props.
40
- */
41
- const values = new Map();
42
- /**
43
- * A map of every subscription that binds the provided or generated
44
- * motion values onChange listeners to this visual element.
45
- */
46
- const valueSubscriptions = new Map();
47
- /**
48
- * A reference to the previously-provided motion values as returned
49
- * from scrapeMotionValuesFromProps. We use the keys in here to determine
50
- * if any motion values need to be removed after props are updated.
51
- */
52
- let prevMotionValues = {};
53
- /**
54
- * When values are removed from all animation props we need to search
55
- * for a fallback value to animate to. These values are tracked in baseTarget.
56
- */
57
- const baseTarget = {
58
- ...latestValues,
59
- };
60
- /**
61
- * Create an object of the values we initially animated from (if initial prop present).
62
- */
63
- const initialValues = props.initial ? { ...latestValues } : {};
64
- // Internal methods ========================
65
- /**
66
- * On mount, this will be hydrated with a callback to disconnect
67
- * this visual element from its parent on unmount.
68
- */
69
- let removeFromVariantTree;
70
- /**
71
- * Render the element with the latest styles outside of the React
72
- * render lifecycle
73
- */
74
- function render() {
75
- if (!instance || !isMounted)
76
- return;
77
- triggerBuild();
78
- renderInstance(instance, renderState, props.style, element.projection);
79
- }
80
- function triggerBuild() {
81
- build(element, renderState, latestValues, options, props);
82
- }
83
- function update() {
84
- lifecycles.notifyUpdate(latestValues);
85
- }
86
- /**
87
- *
88
- */
89
- function bindToMotionValue(key, value) {
90
- const removeOnChange = value.onChange((latestValue) => {
91
- latestValues[key] = latestValue;
92
- props.onUpdate && sync.update(update, false, true);
93
- });
94
- const removeOnRenderRequest = value.onRenderRequest(element.scheduleRender);
95
- valueSubscriptions.set(key, () => {
96
- removeOnChange();
97
- removeOnRenderRequest();
98
- });
99
- }
100
- /**
101
- * Any motion values that are provided to the element when created
102
- * aren't yet bound to the element, as this would technically be impure.
103
- * However, we iterate through the motion values and set them to the
104
- * initial values for this component.
105
- *
106
- * TODO: This is impure and we should look at changing this to run on mount.
107
- * Doing so will break some tests but this isn't neccessarily a breaking change,
108
- * more a reflection of the test.
109
- */
110
- const { willChange, ...initialMotionValues } = scrapeMotionValuesFromProps(props);
111
- for (const key in initialMotionValues) {
112
- const value = initialMotionValues[key];
113
- if (latestValues[key] !== undefined && isMotionValue(value)) {
114
- value.set(latestValues[key], false);
115
- if (isWillChangeMotionValue(willChange)) {
116
- willChange.add(key);
117
- }
118
- }
119
- }
120
- /**
121
- * Update external values with initial values
122
- */
123
- if (props.values) {
124
- for (const key in props.values) {
125
- const value = props.values[key];
126
- if (latestValues[key] !== undefined && isMotionValue(value)) {
127
- value.set(latestValues[key]);
128
- }
129
- }
130
- }
131
- /**
132
- * Determine what role this visual element should take in the variant tree.
133
- */
134
- const isControllingVariants$1 = isControllingVariants(props);
135
- const isVariantNode$1 = isVariantNode(props);
136
- const element = {
137
- treeType,
138
- /**
139
- * This is a mirror of the internal instance prop, which keeps
140
- * VisualElement type-compatible with React's RefObject.
141
- */
142
- current: null,
143
- /**
144
- * The depth of this visual element within the visual element tree.
145
- */
146
- depth: parent ? parent.depth + 1 : 0,
147
- parent,
148
- children: new Set(),
149
- /**
150
- *
151
- */
152
- presenceId,
153
- shouldReduceMotion: null,
154
- /**
155
- * If this component is part of the variant tree, it should track
156
- * any children that are also part of the tree. This is essentially
157
- * a shadow tree to simplify logic around how to stagger over children.
158
- */
159
- variantChildren: isVariantNode$1 ? new Set() : undefined,
160
- /**
161
- * Whether this instance is visible. This can be changed imperatively
162
- * by the projection tree, is analogous to CSS's visibility in that
163
- * hidden elements should take up layout, and needs enacting by the configured
164
- * render function.
165
- */
166
- isVisible: undefined,
167
- /**
168
- * Normally, if a component is controlled by a parent's variants, it can
169
- * rely on that ancestor to trigger animations further down the tree.
170
- * However, if a component is created after its parent is mounted, the parent
171
- * won't trigger that mount animation so the child needs to.
172
- *
173
- * TODO: This might be better replaced with a method isParentMounted
174
- */
175
- manuallyAnimateOnMount: Boolean(parent === null || parent === void 0 ? void 0 : parent.isMounted()),
176
- /**
177
- * This can be set by AnimatePresence to force components that mount
178
- * at the same time as it to mount as if they have initial={false} set.
179
- */
180
- blockInitialAnimation,
181
- /**
182
- * Determine whether this component has mounted yet. This is mostly used
183
- * by variant children to determine whether they need to trigger their
184
- * own animations on mount.
185
- */
186
- isMounted: () => Boolean(instance),
187
- mount(newInstance) {
188
- isMounted = true;
189
- instance = element.current = newInstance;
190
- if (element.projection) {
191
- element.projection.mount(newInstance);
192
- }
193
- if (isVariantNode$1 && parent && !isControllingVariants$1) {
194
- removeFromVariantTree = parent === null || parent === void 0 ? void 0 : parent.addVariantChild(element);
195
- }
196
- values.forEach((value, key) => bindToMotionValue(key, value));
197
- if (!hasReducedMotionListener.current) {
198
- initPrefersReducedMotion();
199
- }
200
- element.shouldReduceMotion =
201
- reducedMotionConfig === "never"
202
- ? false
203
- : reducedMotionConfig === "always"
204
- ? true
205
- : prefersReducedMotion.current;
206
- parent === null || parent === void 0 ? void 0 : parent.children.add(element);
207
- element.setProps(props);
208
- },
209
- /**
210
- *
211
- */
212
- unmount() {
213
- var _a;
214
- (_a = element.projection) === null || _a === void 0 ? void 0 : _a.unmount();
215
- cancelSync.update(update);
216
- cancelSync.render(render);
217
- valueSubscriptions.forEach((remove) => remove());
218
- removeFromVariantTree === null || removeFromVariantTree === void 0 ? void 0 : removeFromVariantTree();
219
- parent === null || parent === void 0 ? void 0 : parent.children.delete(element);
220
- lifecycles.clearAllListeners();
221
- instance = undefined;
222
- isMounted = false;
223
- },
224
- loadFeatures(renderedProps, isStrict, preloadedFeatures, projectionId, ProjectionNodeConstructor, initialLayoutGroupConfig) {
225
- const features = [];
226
- /**
227
- * If we're in development mode, check to make sure we're not rendering a motion component
228
- * as a child of LazyMotion, as this will break the file-size benefits of using it.
229
- */
230
- if (env !== "production" && preloadedFeatures && isStrict) {
231
- invariant(false, "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.");
232
- }
233
- for (let i = 0; i < numFeatures; i++) {
234
- const name = featureNames[i];
235
- const { isEnabled, Component } = featureDefinitions[name];
236
- /**
237
- * It might be possible in the future to use this moment to
238
- * dynamically request functionality. In initial tests this
239
- * was producing a lot of duplication amongst bundles.
240
- */
241
- if (isEnabled(renderedProps) && Component) {
242
- features.push(createElement(Component, {
243
- key: name,
244
- ...renderedProps,
245
- visualElement: element,
246
- }));
247
- }
248
- }
249
- if (!element.projection && ProjectionNodeConstructor) {
250
- element.projection = new ProjectionNodeConstructor(projectionId, element.getLatestValues(), parent && parent.projection);
251
- const { layoutId, layout, drag, dragConstraints, layoutScroll, } = renderedProps;
252
- element.projection.setOptions({
253
- layoutId,
254
- layout,
255
- alwaysMeasureLayout: Boolean(drag) ||
256
- (dragConstraints && isRefObject(dragConstraints)),
257
- visualElement: element,
258
- scheduleRender: () => element.scheduleRender(),
259
- /**
260
- * TODO: Update options in an effect. This could be tricky as it'll be too late
261
- * to update by the time layout animations run.
262
- * We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
263
- * ensuring it gets called if there's no potential layout animations.
264
- *
265
- */
266
- animationType: typeof layout === "string" ? layout : "both",
267
- initialPromotionConfig: initialLayoutGroupConfig,
268
- layoutScroll,
269
- });
270
- }
271
- return features;
272
- },
273
- /**
274
- * Add a child visual element to our set of children.
275
- */
276
- addVariantChild(child) {
277
- var _a;
278
- const closestVariantNode = element.getClosestVariantNode();
279
- if (closestVariantNode) {
280
- (_a = closestVariantNode.variantChildren) === null || _a === void 0 ? void 0 : _a.add(child);
281
- return () => closestVariantNode.variantChildren.delete(child);
282
- }
283
- },
284
- sortNodePosition(other) {
285
- /**
286
- * If these nodes aren't even of the same type we can't compare their depth.
287
- */
288
- if (!sortNodePosition || treeType !== other.treeType)
289
- return 0;
290
- return sortNodePosition(element.getInstance(), other.getInstance());
291
- },
292
- /**
293
- * Returns the closest variant node in the tree starting from
294
- * this visual element.
295
- */
296
- getClosestVariantNode: () => isVariantNode$1 ? element : parent === null || parent === void 0 ? void 0 : parent.getClosestVariantNode(),
297
- /**
298
- * Expose the latest layoutId prop.
299
- */
300
- getLayoutId: () => props.layoutId,
301
- /**
302
- * Returns the current instance.
303
- */
304
- getInstance: () => instance,
305
- /**
306
- * Get/set the latest static values.
307
- */
308
- getStaticValue: (key) => latestValues[key],
309
- setStaticValue: (key, value) => (latestValues[key] = value),
310
- /**
311
- * Returns the latest motion value state. Currently only used to take
312
- * a snapshot of the visual element - perhaps this can return the whole
313
- * visual state
314
- */
315
- getLatestValues: () => latestValues,
316
- /**
317
- * Set the visiblity of the visual element. If it's changed, schedule
318
- * a render to reflect these changes.
319
- */
320
- setVisibility(visibility) {
321
- if (element.isVisible === visibility)
322
- return;
323
- element.isVisible = visibility;
324
- element.scheduleRender();
325
- },
326
- /**
327
- * Make a target animatable by Popmotion. For instance, if we're
328
- * trying to animate width from 100px to 100vw we need to measure 100vw
329
- * in pixels to determine what we really need to animate to. This is also
330
- * pluggable to support Framer's custom value types like Color,
331
- * and CSS variables.
332
- */
333
- makeTargetAnimatable(target, canMutate = true) {
334
- return makeTargetAnimatable(element, target, props, canMutate);
335
- },
336
- /**
337
- * Measure the current viewport box with or without transforms.
338
- * Only measures axis-aligned boxes, rotate and skew must be manually
339
- * removed with a re-render to work.
340
- */
341
- measureViewportBox() {
342
- return measureViewportBox(instance, props);
343
- },
344
- // Motion values ========================
345
- /**
346
- * Add a motion value and bind it to this visual element.
347
- */
348
- addValue(key, value) {
349
- // Remove existing value if it exists
350
- if (element.hasValue(key))
351
- element.removeValue(key);
352
- values.set(key, value);
353
- latestValues[key] = value.get();
354
- bindToMotionValue(key, value);
355
- },
356
- /**
357
- * Remove a motion value and unbind any active subscriptions.
358
- */
359
- removeValue(key) {
360
- var _a;
361
- values.delete(key);
362
- (_a = valueSubscriptions.get(key)) === null || _a === void 0 ? void 0 : _a();
363
- valueSubscriptions.delete(key);
364
- delete latestValues[key];
365
- removeValueFromRenderState(key, renderState);
366
- },
367
- /**
368
- * Check whether we have a motion value for this key
369
- */
370
- hasValue: (key) => values.has(key),
371
- /**
372
- * Get a motion value for this key. If called with a default
373
- * value, we'll create one if none exists.
374
- */
375
- getValue(key, defaultValue) {
376
- if (props.values && props.values[key]) {
377
- return props.values[key];
378
- }
379
- let value = values.get(key);
380
- if (value === undefined && defaultValue !== undefined) {
381
- value = motionValue(defaultValue);
382
- element.addValue(key, value);
383
- }
384
- return value;
385
- },
386
- /**
387
- * Iterate over our motion values.
388
- */
389
- forEachValue: (callback) => values.forEach(callback),
390
- /**
391
- * If we're trying to animate to a previously unencountered value,
392
- * we need to check for it in our state and as a last resort read it
393
- * directly from the instance (which might have performance implications).
394
- */
395
- readValue: (key) => latestValues[key] !== undefined
396
- ? latestValues[key]
397
- : readValueFromInstance(instance, key, options),
398
- /**
399
- * Set the base target to later animate back to. This is currently
400
- * only hydrated on creation and when we first read a value.
401
- */
402
- setBaseTarget(key, value) {
403
- baseTarget[key] = value;
404
- },
405
- /**
406
- * Find the base target for a value thats been removed from all animation
407
- * props.
408
- */
409
- getBaseTarget(key) {
410
- var _a;
411
- const { initial } = props;
412
- const valueFromInitial = typeof initial === "string" || typeof initial === "object"
413
- ? (_a = resolveVariantFromProps(props, initial)) === null || _a === void 0 ? void 0 : _a[key]
414
- : undefined;
415
- /**
416
- * If this value still exists in the current initial variant, read that.
417
- */
418
- if (initial && valueFromInitial !== undefined) {
419
- return valueFromInitial;
420
- }
421
- /**
422
- * Alternatively, if this VisualElement config has defined a getBaseTarget
423
- * so we can read the value from an alternative source, try that.
424
- */
425
- if (getBaseTarget) {
426
- const target = getBaseTarget(props, key);
427
- if (target !== undefined && !isMotionValue(target))
428
- return target;
429
- }
430
- /**
431
- * If the value was initially defined on initial, but it doesn't any more,
432
- * return undefined. Otherwise return the value as initially read from the DOM.
433
- */
434
- return initialValues[key] !== undefined &&
435
- valueFromInitial === undefined
436
- ? undefined
437
- : baseTarget[key];
438
- },
439
- // Lifecyles ========================
440
- ...lifecycles,
441
- /**
442
- * Build the renderer state based on the latest visual state.
443
- */
444
- build() {
445
- triggerBuild();
446
- return renderState;
447
- },
448
- /**
449
- * Schedule a render on the next animation frame.
450
- */
451
- scheduleRender() {
452
- sync.render(render, false, true);
453
- },
454
- /**
455
- * Synchronously fire render. It's prefered that we batch renders but
456
- * in many circumstances, like layout measurement, we need to run this
457
- * synchronously. However in those instances other measures should be taken
458
- * to batch reads/writes.
459
- */
460
- syncRender: render,
461
- /**
462
- * Update the provided props. Ensure any newly-added motion values are
463
- * added to our map, old ones removed, and listeners updated.
464
- */
465
- setProps(newProps) {
466
- if (newProps.transformTemplate || props.transformTemplate) {
467
- element.scheduleRender();
468
- }
469
- props = newProps;
470
- lifecycles.updatePropListeners(newProps);
471
- prevMotionValues = updateMotionValuesFromProps(element, scrapeMotionValuesFromProps(props), prevMotionValues);
472
- },
473
- getProps: () => props,
474
- // Variants ==============================
475
- /**
476
- * Returns the variant definition with a given name.
477
- */
478
- getVariant: (name) => { var _a; return (_a = props.variants) === null || _a === void 0 ? void 0 : _a[name]; },
479
- /**
480
- * Returns the defined default transition on this component.
481
- */
482
- getDefaultTransition: () => props.transition,
483
- getTransformPagePoint: () => {
484
- return props.transformPagePoint;
485
- },
486
- /**
487
- * Used by child variant nodes to get the closest ancestor variant props.
488
- */
489
- getVariantContext(startAtParent = false) {
490
- if (startAtParent)
491
- return parent === null || parent === void 0 ? void 0 : parent.getVariantContext();
492
- if (!isControllingVariants$1) {
493
- const context = (parent === null || parent === void 0 ? void 0 : parent.getVariantContext()) || {};
494
- if (props.initial !== undefined) {
495
- context.initial = props.initial;
496
- }
497
- return context;
498
- }
499
- const context = {};
500
- for (let i = 0; i < numVariantProps; i++) {
501
- const name = variantProps[i];
502
- const prop = props[name];
503
- if (isVariantLabel(prop) || prop === false) {
504
- context[name] = prop;
505
- }
506
- }
507
- return context;
508
- },
509
- };
510
- return element;
511
- };
512
- const variantProps = ["initial", ...variantPriorityOrder];
513
- const numVariantProps = variantProps.length;
514
-
515
- export { visualElement };