framer-motion 12.0.5 → 12.0.8-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/client.js +283 -265
- package/dist/cjs/dom.js +43 -12
- package/dist/cjs/index.js +163 -145
- package/dist/cjs/m.js +494 -494
- package/dist/client.d.ts +8 -4
- package/dist/dom.js +1 -1
- package/dist/es/components/AnimatePresence/index.mjs +1 -1
- package/dist/es/projection/node/create-projection-node.mjs +6 -1
- package/dist/es/render/VisualElement.mjs +3 -0
- package/dist/es/render/components/create-factory.mjs +2 -2
- package/dist/es/render/svg/SVGVisualElement.mjs +12 -0
- package/dist/es/render/svg/config-motion.mjs +1 -1
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +163 -145
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +26 -5
- package/dist/m.d.ts +8 -4
- package/dist/three.d.ts +5 -0
- package/package.json +4 -4
package/dist/cjs/client.js
CHANGED
|
@@ -409,7 +409,7 @@ class MotionValue {
|
|
|
409
409
|
* This will be replaced by the build step with the latest version number.
|
|
410
410
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
411
411
|
*/
|
|
412
|
-
this.version = "12.0.
|
|
412
|
+
this.version = "12.0.8-alpha.0";
|
|
413
413
|
/**
|
|
414
414
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
415
415
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -5205,7 +5205,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
5205
5205
|
* and warn against mismatches.
|
|
5206
5206
|
*/
|
|
5207
5207
|
if (process.env.NODE_ENV === "development") {
|
|
5208
|
-
warnOnce(nextValue.version === "12.0.
|
|
5208
|
+
warnOnce(nextValue.version === "12.0.8-alpha.0", `Attempting to mix Motion versions ${nextValue.version} with 12.0.8-alpha.0 may not work as expected.`);
|
|
5209
5209
|
}
|
|
5210
5210
|
}
|
|
5211
5211
|
else if (isMotionValue(prevValue)) {
|
|
@@ -5427,6 +5427,9 @@ class VisualElement {
|
|
|
5427
5427
|
this.valueSubscriptions.get(key)();
|
|
5428
5428
|
}
|
|
5429
5429
|
const valueIsTransform = transformProps.has(key);
|
|
5430
|
+
if (valueIsTransform && this.onBindTransform) {
|
|
5431
|
+
this.onBindTransform();
|
|
5432
|
+
}
|
|
5430
5433
|
const removeOnChange = value.on("change", (latestValue) => {
|
|
5431
5434
|
this.latestValues[key] = latestValue;
|
|
5432
5435
|
this.props.onUpdate && frame.preRender(this.notifyUpdate);
|
|
@@ -5738,6 +5741,118 @@ class DOMVisualElement extends VisualElement {
|
|
|
5738
5741
|
}
|
|
5739
5742
|
}
|
|
5740
5743
|
|
|
5744
|
+
const MotionContext = react.createContext({});
|
|
5745
|
+
|
|
5746
|
+
/**
|
|
5747
|
+
* @public
|
|
5748
|
+
*/
|
|
5749
|
+
const PresenceContext = react.createContext(null);
|
|
5750
|
+
|
|
5751
|
+
/**
|
|
5752
|
+
* Creates a constant value over the lifecycle of a component.
|
|
5753
|
+
*
|
|
5754
|
+
* Even if `useMemo` is provided an empty array as its final argument, it doesn't offer
|
|
5755
|
+
* a guarantee that it won't re-run for performance reasons later on. By using `useConstant`
|
|
5756
|
+
* you can ensure that initialisers don't execute twice or more.
|
|
5757
|
+
*/
|
|
5758
|
+
function useConstant(init) {
|
|
5759
|
+
const ref = react.useRef(null);
|
|
5760
|
+
if (ref.current === null) {
|
|
5761
|
+
ref.current = init();
|
|
5762
|
+
}
|
|
5763
|
+
return ref.current;
|
|
5764
|
+
}
|
|
5765
|
+
|
|
5766
|
+
/**
|
|
5767
|
+
* If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
|
|
5768
|
+
*
|
|
5769
|
+
* TODO: Remove and move to library
|
|
5770
|
+
*/
|
|
5771
|
+
function resolveMotionValue(value) {
|
|
5772
|
+
const unwrappedValue = isMotionValue(value) ? value.get() : value;
|
|
5773
|
+
return isCustomValue(unwrappedValue)
|
|
5774
|
+
? unwrappedValue.toValue()
|
|
5775
|
+
: unwrappedValue;
|
|
5776
|
+
}
|
|
5777
|
+
|
|
5778
|
+
function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
|
|
5779
|
+
const state = {
|
|
5780
|
+
latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
|
|
5781
|
+
renderState: createRenderState(),
|
|
5782
|
+
};
|
|
5783
|
+
if (onUpdate) {
|
|
5784
|
+
/**
|
|
5785
|
+
* onMount works without the VisualElement because it could be
|
|
5786
|
+
* called before the VisualElement payload has been hydrated.
|
|
5787
|
+
* (e.g. if someone is using m components <m.circle />)
|
|
5788
|
+
*/
|
|
5789
|
+
state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
|
|
5790
|
+
state.onUpdate = (visualElement) => onUpdate(visualElement);
|
|
5791
|
+
}
|
|
5792
|
+
return state;
|
|
5793
|
+
}
|
|
5794
|
+
const makeUseVisualState = (config) => (props, isStatic) => {
|
|
5795
|
+
const context = react.useContext(MotionContext);
|
|
5796
|
+
const presenceContext = react.useContext(PresenceContext);
|
|
5797
|
+
const make = () => makeState(config, props, context, presenceContext);
|
|
5798
|
+
return isStatic ? make() : useConstant(make);
|
|
5799
|
+
};
|
|
5800
|
+
function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
|
5801
|
+
const values = {};
|
|
5802
|
+
const motionValues = scrapeMotionValues(props, {});
|
|
5803
|
+
for (const key in motionValues) {
|
|
5804
|
+
values[key] = resolveMotionValue(motionValues[key]);
|
|
5805
|
+
}
|
|
5806
|
+
let { initial, animate } = props;
|
|
5807
|
+
const isControllingVariants$1 = isControllingVariants(props);
|
|
5808
|
+
const isVariantNode$1 = isVariantNode(props);
|
|
5809
|
+
if (context &&
|
|
5810
|
+
isVariantNode$1 &&
|
|
5811
|
+
!isControllingVariants$1 &&
|
|
5812
|
+
props.inherit !== false) {
|
|
5813
|
+
if (initial === undefined)
|
|
5814
|
+
initial = context.initial;
|
|
5815
|
+
if (animate === undefined)
|
|
5816
|
+
animate = context.animate;
|
|
5817
|
+
}
|
|
5818
|
+
let isInitialAnimationBlocked = presenceContext
|
|
5819
|
+
? presenceContext.initial === false
|
|
5820
|
+
: false;
|
|
5821
|
+
isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
|
|
5822
|
+
const variantToSet = isInitialAnimationBlocked ? animate : initial;
|
|
5823
|
+
if (variantToSet &&
|
|
5824
|
+
typeof variantToSet !== "boolean" &&
|
|
5825
|
+
!isAnimationControls(variantToSet)) {
|
|
5826
|
+
const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
|
|
5827
|
+
for (let i = 0; i < list.length; i++) {
|
|
5828
|
+
const resolved = resolveVariantFromProps(props, list[i]);
|
|
5829
|
+
if (resolved) {
|
|
5830
|
+
const { transitionEnd, transition, ...target } = resolved;
|
|
5831
|
+
for (const key in target) {
|
|
5832
|
+
let valueTarget = target[key];
|
|
5833
|
+
if (Array.isArray(valueTarget)) {
|
|
5834
|
+
/**
|
|
5835
|
+
* Take final keyframe if the initial animation is blocked because
|
|
5836
|
+
* we want to initialise at the end of that blocked animation.
|
|
5837
|
+
*/
|
|
5838
|
+
const index = isInitialAnimationBlocked
|
|
5839
|
+
? valueTarget.length - 1
|
|
5840
|
+
: 0;
|
|
5841
|
+
valueTarget = valueTarget[index];
|
|
5842
|
+
}
|
|
5843
|
+
if (valueTarget !== null) {
|
|
5844
|
+
values[key] = valueTarget;
|
|
5845
|
+
}
|
|
5846
|
+
}
|
|
5847
|
+
for (const key in transitionEnd) {
|
|
5848
|
+
values[key] = transitionEnd[key];
|
|
5849
|
+
}
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
}
|
|
5853
|
+
return values;
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5741
5856
|
/**
|
|
5742
5857
|
* Provided a value and a ValueType, returns the value as that value type.
|
|
5743
5858
|
*/
|
|
@@ -5953,6 +6068,28 @@ function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathL
|
|
|
5953
6068
|
}
|
|
5954
6069
|
}
|
|
5955
6070
|
|
|
6071
|
+
const createHtmlRenderState = () => ({
|
|
6072
|
+
style: {},
|
|
6073
|
+
transform: {},
|
|
6074
|
+
transformOrigin: {},
|
|
6075
|
+
vars: {},
|
|
6076
|
+
});
|
|
6077
|
+
|
|
6078
|
+
const createSvgRenderState = () => ({
|
|
6079
|
+
...createHtmlRenderState(),
|
|
6080
|
+
attrs: {},
|
|
6081
|
+
});
|
|
6082
|
+
|
|
6083
|
+
const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
|
|
6084
|
+
|
|
6085
|
+
function renderHTML(element, { style, vars }, styleProp, projection) {
|
|
6086
|
+
Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
|
|
6087
|
+
// Loop over any CSS variables and assign those.
|
|
6088
|
+
for (const key in vars) {
|
|
6089
|
+
element.style.setProperty(key, vars[key]);
|
|
6090
|
+
}
|
|
6091
|
+
}
|
|
6092
|
+
|
|
5956
6093
|
/**
|
|
5957
6094
|
* A set of attribute names that are always read/written as camel case.
|
|
5958
6095
|
*/
|
|
@@ -5982,16 +6119,6 @@ const camelCaseAttributes = new Set([
|
|
|
5982
6119
|
"lengthAdjust",
|
|
5983
6120
|
]);
|
|
5984
6121
|
|
|
5985
|
-
const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
|
|
5986
|
-
|
|
5987
|
-
function renderHTML(element, { style, vars }, styleProp, projection) {
|
|
5988
|
-
Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
|
|
5989
|
-
// Loop over any CSS variables and assign those.
|
|
5990
|
-
for (const key in vars) {
|
|
5991
|
-
element.style.setProperty(key, vars[key]);
|
|
5992
|
-
}
|
|
5993
|
-
}
|
|
5994
|
-
|
|
5995
6122
|
function renderSVG(element, renderState, _styleProp, projection) {
|
|
5996
6123
|
renderHTML(element, renderState, undefined, projection);
|
|
5997
6124
|
for (const key in renderState.attrs) {
|
|
@@ -6046,12 +6173,80 @@ function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
|
|
|
6046
6173
|
return newValues;
|
|
6047
6174
|
}
|
|
6048
6175
|
|
|
6176
|
+
function updateSVGDimensions(instance, renderState) {
|
|
6177
|
+
try {
|
|
6178
|
+
renderState.dimensions =
|
|
6179
|
+
typeof instance.getBBox === "function"
|
|
6180
|
+
? instance.getBBox()
|
|
6181
|
+
: instance.getBoundingClientRect();
|
|
6182
|
+
}
|
|
6183
|
+
catch (e) {
|
|
6184
|
+
// Most likely trying to measure an unrendered element under Firefox
|
|
6185
|
+
renderState.dimensions = {
|
|
6186
|
+
x: 0,
|
|
6187
|
+
y: 0,
|
|
6188
|
+
width: 0,
|
|
6189
|
+
height: 0,
|
|
6190
|
+
};
|
|
6191
|
+
}
|
|
6192
|
+
}
|
|
6193
|
+
const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
|
|
6194
|
+
const svgMotionConfig = {
|
|
6195
|
+
useVisualState: makeUseVisualState({
|
|
6196
|
+
scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
|
|
6197
|
+
createRenderState: createSvgRenderState,
|
|
6198
|
+
onUpdate: ({ props, prevProps, current, renderState, latestValues, }) => {
|
|
6199
|
+
if (!current)
|
|
6200
|
+
return;
|
|
6201
|
+
let hasTransform = !!props.drag;
|
|
6202
|
+
if (!hasTransform) {
|
|
6203
|
+
for (const key in latestValues) {
|
|
6204
|
+
if (transformProps.has(key)) {
|
|
6205
|
+
hasTransform = true;
|
|
6206
|
+
break;
|
|
6207
|
+
}
|
|
6208
|
+
}
|
|
6209
|
+
}
|
|
6210
|
+
if (!hasTransform)
|
|
6211
|
+
return;
|
|
6212
|
+
let needsMeasure = !prevProps;
|
|
6213
|
+
if (prevProps) {
|
|
6214
|
+
/**
|
|
6215
|
+
* Check the layout props for changes, if any are found we need to
|
|
6216
|
+
* measure the element again.
|
|
6217
|
+
*/
|
|
6218
|
+
for (let i = 0; i < layoutProps.length; i++) {
|
|
6219
|
+
const key = layoutProps[i];
|
|
6220
|
+
if (props[key] !==
|
|
6221
|
+
prevProps[key]) {
|
|
6222
|
+
needsMeasure = true;
|
|
6223
|
+
}
|
|
6224
|
+
}
|
|
6225
|
+
}
|
|
6226
|
+
if (!needsMeasure)
|
|
6227
|
+
return;
|
|
6228
|
+
frame.read(() => {
|
|
6229
|
+
updateSVGDimensions(current, renderState);
|
|
6230
|
+
frame.render(() => {
|
|
6231
|
+
buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
|
|
6232
|
+
renderSVG(current, renderState);
|
|
6233
|
+
});
|
|
6234
|
+
});
|
|
6235
|
+
},
|
|
6236
|
+
}),
|
|
6237
|
+
};
|
|
6238
|
+
|
|
6049
6239
|
class SVGVisualElement extends DOMVisualElement {
|
|
6050
6240
|
constructor() {
|
|
6051
6241
|
super(...arguments);
|
|
6052
6242
|
this.type = "svg";
|
|
6053
6243
|
this.isSVGTag = false;
|
|
6054
6244
|
this.measureInstanceViewportBox = createBox;
|
|
6245
|
+
this.updateDimensions = () => {
|
|
6246
|
+
if (this.current && !this.renderState.dimensions) {
|
|
6247
|
+
updateSVGDimensions(this.current, this.renderState);
|
|
6248
|
+
}
|
|
6249
|
+
};
|
|
6055
6250
|
}
|
|
6056
6251
|
getBaseTargetFromProps(props, key) {
|
|
6057
6252
|
return props[key];
|
|
@@ -6067,6 +6262,11 @@ class SVGVisualElement extends DOMVisualElement {
|
|
|
6067
6262
|
scrapeMotionValuesFromProps(props, prevProps, visualElement) {
|
|
6068
6263
|
return scrapeMotionValuesFromProps(props, prevProps, visualElement);
|
|
6069
6264
|
}
|
|
6265
|
+
onBindTransform() {
|
|
6266
|
+
if (this.current && !this.renderState.dimensions) {
|
|
6267
|
+
frame.postRender(this.updateDimensions);
|
|
6268
|
+
}
|
|
6269
|
+
}
|
|
6070
6270
|
build(renderState, latestValues, props) {
|
|
6071
6271
|
buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate);
|
|
6072
6272
|
}
|
|
@@ -6152,18 +6352,6 @@ class FlatTree {
|
|
|
6152
6352
|
}
|
|
6153
6353
|
}
|
|
6154
6354
|
|
|
6155
|
-
/**
|
|
6156
|
-
* If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
|
|
6157
|
-
*
|
|
6158
|
-
* TODO: Remove and move to library
|
|
6159
|
-
*/
|
|
6160
|
-
function resolveMotionValue(value) {
|
|
6161
|
-
const unwrappedValue = isMotionValue(value) ? value.get() : value;
|
|
6162
|
-
return isCustomValue(unwrappedValue)
|
|
6163
|
-
? unwrappedValue.toValue()
|
|
6164
|
-
: unwrappedValue;
|
|
6165
|
-
}
|
|
6166
|
-
|
|
6167
6355
|
const borders = ["TopLeft", "TopRight", "BottomLeft", "BottomRight"];
|
|
6168
6356
|
const numBorders = borders.length;
|
|
6169
6357
|
const asNumber = (value) => typeof value === "string" ? parseFloat(value) : value;
|
|
@@ -7010,6 +7198,11 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
7010
7198
|
if (this.snapshot || !this.instance)
|
|
7011
7199
|
return;
|
|
7012
7200
|
this.snapshot = this.measure();
|
|
7201
|
+
if (this.snapshot &&
|
|
7202
|
+
!calcLength(this.snapshot.measuredBox.x) &&
|
|
7203
|
+
!calcLength(this.snapshot.measuredBox.y)) {
|
|
7204
|
+
this.snapshot = undefined;
|
|
7205
|
+
}
|
|
7013
7206
|
}
|
|
7014
7207
|
updateLayout() {
|
|
7015
7208
|
if (!this.instance)
|
|
@@ -8200,11 +8393,6 @@ const correctBoxShadow = {
|
|
|
8200
8393
|
},
|
|
8201
8394
|
};
|
|
8202
8395
|
|
|
8203
|
-
/**
|
|
8204
|
-
* @public
|
|
8205
|
-
*/
|
|
8206
|
-
const PresenceContext = react.createContext(null);
|
|
8207
|
-
|
|
8208
8396
|
/**
|
|
8209
8397
|
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
|
8210
8398
|
* to access information about whether it's still present in the React tree.
|
|
@@ -8615,8 +8803,6 @@ const MotionConfigContext = react.createContext({
|
|
|
8615
8803
|
reducedMotion: "never",
|
|
8616
8804
|
});
|
|
8617
8805
|
|
|
8618
|
-
const MotionContext = react.createContext({});
|
|
8619
|
-
|
|
8620
8806
|
function getCurrentTreeVariants(props, context) {
|
|
8621
8807
|
if (isControllingVariants(props)) {
|
|
8622
8808
|
const { initial, animate } = props;
|
|
@@ -8892,240 +9078,6 @@ function getProjectionFunctionality(props) {
|
|
|
8892
9078
|
};
|
|
8893
9079
|
}
|
|
8894
9080
|
|
|
8895
|
-
/**
|
|
8896
|
-
* We keep these listed separately as we use the lowercase tag names as part
|
|
8897
|
-
* of the runtime bundle to detect SVG components
|
|
8898
|
-
*/
|
|
8899
|
-
const lowercaseSVGElements = [
|
|
8900
|
-
"animate",
|
|
8901
|
-
"circle",
|
|
8902
|
-
"defs",
|
|
8903
|
-
"desc",
|
|
8904
|
-
"ellipse",
|
|
8905
|
-
"g",
|
|
8906
|
-
"image",
|
|
8907
|
-
"line",
|
|
8908
|
-
"filter",
|
|
8909
|
-
"marker",
|
|
8910
|
-
"mask",
|
|
8911
|
-
"metadata",
|
|
8912
|
-
"path",
|
|
8913
|
-
"pattern",
|
|
8914
|
-
"polygon",
|
|
8915
|
-
"polyline",
|
|
8916
|
-
"rect",
|
|
8917
|
-
"stop",
|
|
8918
|
-
"switch",
|
|
8919
|
-
"symbol",
|
|
8920
|
-
"svg",
|
|
8921
|
-
"text",
|
|
8922
|
-
"tspan",
|
|
8923
|
-
"use",
|
|
8924
|
-
"view",
|
|
8925
|
-
];
|
|
8926
|
-
|
|
8927
|
-
function isSVGComponent(Component) {
|
|
8928
|
-
if (
|
|
8929
|
-
/**
|
|
8930
|
-
* If it's not a string, it's a custom React component. Currently we only support
|
|
8931
|
-
* HTML custom React components.
|
|
8932
|
-
*/
|
|
8933
|
-
typeof Component !== "string" ||
|
|
8934
|
-
/**
|
|
8935
|
-
* If it contains a dash, the element is a custom HTML webcomponent.
|
|
8936
|
-
*/
|
|
8937
|
-
Component.includes("-")) {
|
|
8938
|
-
return false;
|
|
8939
|
-
}
|
|
8940
|
-
else if (
|
|
8941
|
-
/**
|
|
8942
|
-
* If it's in our list of lowercase SVG tags, it's an SVG component
|
|
8943
|
-
*/
|
|
8944
|
-
lowercaseSVGElements.indexOf(Component) > -1 ||
|
|
8945
|
-
/**
|
|
8946
|
-
* If it contains a capital letter, it's an SVG component
|
|
8947
|
-
*/
|
|
8948
|
-
/[A-Z]/u.test(Component)) {
|
|
8949
|
-
return true;
|
|
8950
|
-
}
|
|
8951
|
-
return false;
|
|
8952
|
-
}
|
|
8953
|
-
|
|
8954
|
-
/**
|
|
8955
|
-
* Creates a constant value over the lifecycle of a component.
|
|
8956
|
-
*
|
|
8957
|
-
* Even if `useMemo` is provided an empty array as its final argument, it doesn't offer
|
|
8958
|
-
* a guarantee that it won't re-run for performance reasons later on. By using `useConstant`
|
|
8959
|
-
* you can ensure that initialisers don't execute twice or more.
|
|
8960
|
-
*/
|
|
8961
|
-
function useConstant(init) {
|
|
8962
|
-
const ref = react.useRef(null);
|
|
8963
|
-
if (ref.current === null) {
|
|
8964
|
-
ref.current = init();
|
|
8965
|
-
}
|
|
8966
|
-
return ref.current;
|
|
8967
|
-
}
|
|
8968
|
-
|
|
8969
|
-
function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
|
|
8970
|
-
const state = {
|
|
8971
|
-
latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
|
|
8972
|
-
renderState: createRenderState(),
|
|
8973
|
-
};
|
|
8974
|
-
if (onUpdate) {
|
|
8975
|
-
/**
|
|
8976
|
-
* onMount works without the VisualElement because it could be
|
|
8977
|
-
* called before the VisualElement payload has been hydrated.
|
|
8978
|
-
* (e.g. if someone is using m components <m.circle />)
|
|
8979
|
-
*/
|
|
8980
|
-
state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
|
|
8981
|
-
state.onUpdate = (visualElement) => onUpdate(visualElement);
|
|
8982
|
-
}
|
|
8983
|
-
return state;
|
|
8984
|
-
}
|
|
8985
|
-
const makeUseVisualState = (config) => (props, isStatic) => {
|
|
8986
|
-
const context = react.useContext(MotionContext);
|
|
8987
|
-
const presenceContext = react.useContext(PresenceContext);
|
|
8988
|
-
const make = () => makeState(config, props, context, presenceContext);
|
|
8989
|
-
return isStatic ? make() : useConstant(make);
|
|
8990
|
-
};
|
|
8991
|
-
function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
|
8992
|
-
const values = {};
|
|
8993
|
-
const motionValues = scrapeMotionValues(props, {});
|
|
8994
|
-
for (const key in motionValues) {
|
|
8995
|
-
values[key] = resolveMotionValue(motionValues[key]);
|
|
8996
|
-
}
|
|
8997
|
-
let { initial, animate } = props;
|
|
8998
|
-
const isControllingVariants$1 = isControllingVariants(props);
|
|
8999
|
-
const isVariantNode$1 = isVariantNode(props);
|
|
9000
|
-
if (context &&
|
|
9001
|
-
isVariantNode$1 &&
|
|
9002
|
-
!isControllingVariants$1 &&
|
|
9003
|
-
props.inherit !== false) {
|
|
9004
|
-
if (initial === undefined)
|
|
9005
|
-
initial = context.initial;
|
|
9006
|
-
if (animate === undefined)
|
|
9007
|
-
animate = context.animate;
|
|
9008
|
-
}
|
|
9009
|
-
let isInitialAnimationBlocked = presenceContext
|
|
9010
|
-
? presenceContext.initial === false
|
|
9011
|
-
: false;
|
|
9012
|
-
isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
|
|
9013
|
-
const variantToSet = isInitialAnimationBlocked ? animate : initial;
|
|
9014
|
-
if (variantToSet &&
|
|
9015
|
-
typeof variantToSet !== "boolean" &&
|
|
9016
|
-
!isAnimationControls(variantToSet)) {
|
|
9017
|
-
const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
|
|
9018
|
-
for (let i = 0; i < list.length; i++) {
|
|
9019
|
-
const resolved = resolveVariantFromProps(props, list[i]);
|
|
9020
|
-
if (resolved) {
|
|
9021
|
-
const { transitionEnd, transition, ...target } = resolved;
|
|
9022
|
-
for (const key in target) {
|
|
9023
|
-
let valueTarget = target[key];
|
|
9024
|
-
if (Array.isArray(valueTarget)) {
|
|
9025
|
-
/**
|
|
9026
|
-
* Take final keyframe if the initial animation is blocked because
|
|
9027
|
-
* we want to initialise at the end of that blocked animation.
|
|
9028
|
-
*/
|
|
9029
|
-
const index = isInitialAnimationBlocked
|
|
9030
|
-
? valueTarget.length - 1
|
|
9031
|
-
: 0;
|
|
9032
|
-
valueTarget = valueTarget[index];
|
|
9033
|
-
}
|
|
9034
|
-
if (valueTarget !== null) {
|
|
9035
|
-
values[key] = valueTarget;
|
|
9036
|
-
}
|
|
9037
|
-
}
|
|
9038
|
-
for (const key in transitionEnd) {
|
|
9039
|
-
values[key] = transitionEnd[key];
|
|
9040
|
-
}
|
|
9041
|
-
}
|
|
9042
|
-
}
|
|
9043
|
-
}
|
|
9044
|
-
return values;
|
|
9045
|
-
}
|
|
9046
|
-
|
|
9047
|
-
const createHtmlRenderState = () => ({
|
|
9048
|
-
style: {},
|
|
9049
|
-
transform: {},
|
|
9050
|
-
transformOrigin: {},
|
|
9051
|
-
vars: {},
|
|
9052
|
-
});
|
|
9053
|
-
|
|
9054
|
-
const createSvgRenderState = () => ({
|
|
9055
|
-
...createHtmlRenderState(),
|
|
9056
|
-
attrs: {},
|
|
9057
|
-
});
|
|
9058
|
-
|
|
9059
|
-
function updateSVGDimensions(instance, renderState) {
|
|
9060
|
-
try {
|
|
9061
|
-
renderState.dimensions =
|
|
9062
|
-
typeof instance.getBBox === "function"
|
|
9063
|
-
? instance.getBBox()
|
|
9064
|
-
: instance.getBoundingClientRect();
|
|
9065
|
-
}
|
|
9066
|
-
catch (e) {
|
|
9067
|
-
// Most likely trying to measure an unrendered element under Firefox
|
|
9068
|
-
renderState.dimensions = {
|
|
9069
|
-
x: 0,
|
|
9070
|
-
y: 0,
|
|
9071
|
-
width: 0,
|
|
9072
|
-
height: 0,
|
|
9073
|
-
};
|
|
9074
|
-
}
|
|
9075
|
-
}
|
|
9076
|
-
const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
|
|
9077
|
-
const svgMotionConfig = {
|
|
9078
|
-
useVisualState: makeUseVisualState({
|
|
9079
|
-
scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
|
|
9080
|
-
createRenderState: createSvgRenderState,
|
|
9081
|
-
onUpdate: ({ props, prevProps, current, renderState, latestValues, }) => {
|
|
9082
|
-
if (!current)
|
|
9083
|
-
return;
|
|
9084
|
-
let hasTransform = !!props.drag;
|
|
9085
|
-
if (!hasTransform) {
|
|
9086
|
-
for (const key in latestValues) {
|
|
9087
|
-
if (transformProps.has(key)) {
|
|
9088
|
-
hasTransform = true;
|
|
9089
|
-
break;
|
|
9090
|
-
}
|
|
9091
|
-
}
|
|
9092
|
-
}
|
|
9093
|
-
if (!hasTransform)
|
|
9094
|
-
return;
|
|
9095
|
-
let needsMeasure = !prevProps;
|
|
9096
|
-
if (prevProps) {
|
|
9097
|
-
/**
|
|
9098
|
-
* Check the layout props for changes, if any are found we need to
|
|
9099
|
-
* measure the element again.
|
|
9100
|
-
*/
|
|
9101
|
-
for (let i = 0; i < layoutProps.length; i++) {
|
|
9102
|
-
const key = layoutProps[i];
|
|
9103
|
-
if (props[key] !==
|
|
9104
|
-
prevProps[key]) {
|
|
9105
|
-
needsMeasure = true;
|
|
9106
|
-
}
|
|
9107
|
-
}
|
|
9108
|
-
}
|
|
9109
|
-
if (!needsMeasure)
|
|
9110
|
-
return;
|
|
9111
|
-
frame.read(() => {
|
|
9112
|
-
updateSVGDimensions(current, renderState);
|
|
9113
|
-
frame.render(() => {
|
|
9114
|
-
buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
|
|
9115
|
-
renderSVG(current, renderState);
|
|
9116
|
-
});
|
|
9117
|
-
});
|
|
9118
|
-
},
|
|
9119
|
-
}),
|
|
9120
|
-
};
|
|
9121
|
-
|
|
9122
|
-
const htmlMotionConfig = {
|
|
9123
|
-
useVisualState: makeUseVisualState({
|
|
9124
|
-
scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
|
|
9125
|
-
createRenderState: createHtmlRenderState,
|
|
9126
|
-
}),
|
|
9127
|
-
};
|
|
9128
|
-
|
|
9129
9081
|
function copyRawValuesOnly(target, source, props) {
|
|
9130
9082
|
for (const key in source) {
|
|
9131
9083
|
if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
|
|
@@ -9288,6 +9240,65 @@ function filterProps(props, isDom, forwardMotionProps) {
|
|
|
9288
9240
|
return filteredProps;
|
|
9289
9241
|
}
|
|
9290
9242
|
|
|
9243
|
+
/**
|
|
9244
|
+
* We keep these listed separately as we use the lowercase tag names as part
|
|
9245
|
+
* of the runtime bundle to detect SVG components
|
|
9246
|
+
*/
|
|
9247
|
+
const lowercaseSVGElements = [
|
|
9248
|
+
"animate",
|
|
9249
|
+
"circle",
|
|
9250
|
+
"defs",
|
|
9251
|
+
"desc",
|
|
9252
|
+
"ellipse",
|
|
9253
|
+
"g",
|
|
9254
|
+
"image",
|
|
9255
|
+
"line",
|
|
9256
|
+
"filter",
|
|
9257
|
+
"marker",
|
|
9258
|
+
"mask",
|
|
9259
|
+
"metadata",
|
|
9260
|
+
"path",
|
|
9261
|
+
"pattern",
|
|
9262
|
+
"polygon",
|
|
9263
|
+
"polyline",
|
|
9264
|
+
"rect",
|
|
9265
|
+
"stop",
|
|
9266
|
+
"switch",
|
|
9267
|
+
"symbol",
|
|
9268
|
+
"svg",
|
|
9269
|
+
"text",
|
|
9270
|
+
"tspan",
|
|
9271
|
+
"use",
|
|
9272
|
+
"view",
|
|
9273
|
+
];
|
|
9274
|
+
|
|
9275
|
+
function isSVGComponent(Component) {
|
|
9276
|
+
if (
|
|
9277
|
+
/**
|
|
9278
|
+
* If it's not a string, it's a custom React component. Currently we only support
|
|
9279
|
+
* HTML custom React components.
|
|
9280
|
+
*/
|
|
9281
|
+
typeof Component !== "string" ||
|
|
9282
|
+
/**
|
|
9283
|
+
* If it contains a dash, the element is a custom HTML webcomponent.
|
|
9284
|
+
*/
|
|
9285
|
+
Component.includes("-")) {
|
|
9286
|
+
return false;
|
|
9287
|
+
}
|
|
9288
|
+
else if (
|
|
9289
|
+
/**
|
|
9290
|
+
* If it's in our list of lowercase SVG tags, it's an SVG component
|
|
9291
|
+
*/
|
|
9292
|
+
lowercaseSVGElements.indexOf(Component) > -1 ||
|
|
9293
|
+
/**
|
|
9294
|
+
* If it contains a capital letter, it's an SVG component
|
|
9295
|
+
*/
|
|
9296
|
+
/[A-Z]/u.test(Component)) {
|
|
9297
|
+
return true;
|
|
9298
|
+
}
|
|
9299
|
+
return false;
|
|
9300
|
+
}
|
|
9301
|
+
|
|
9291
9302
|
function useSVGProps(props, visualState, _isStatic, Component) {
|
|
9292
9303
|
const visualProps = react.useMemo(() => {
|
|
9293
9304
|
const state = createSvgRenderState();
|
|
@@ -9330,6 +9341,13 @@ function createUseRender(forwardMotionProps = false) {
|
|
|
9330
9341
|
return useRender;
|
|
9331
9342
|
}
|
|
9332
9343
|
|
|
9344
|
+
const htmlMotionConfig = {
|
|
9345
|
+
useVisualState: makeUseVisualState({
|
|
9346
|
+
scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
|
|
9347
|
+
createRenderState: createHtmlRenderState,
|
|
9348
|
+
}),
|
|
9349
|
+
};
|
|
9350
|
+
|
|
9333
9351
|
function createMotionComponentFactory(preloadedFeatures, createVisualElement) {
|
|
9334
9352
|
return function createMotionComponent(Component, { forwardMotionProps } = { forwardMotionProps: false }) {
|
|
9335
9353
|
const baseConfig = isSVGComponent(Component)
|