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.
@@ -916,7 +916,7 @@ class MotionValue {
916
916
  * This will be replaced by the build step with the latest version number.
917
917
  * When MotionValues are provided to motion components, warn if versions are mixed.
918
918
  */
919
- this.version = "12.0.5";
919
+ this.version = "12.0.8-alpha.0";
920
920
  /**
921
921
  * Tracks whether this value can output a velocity. Currently this is only true
922
922
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -6778,6 +6778,11 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
6778
6778
  if (this.snapshot || !this.instance)
6779
6779
  return;
6780
6780
  this.snapshot = this.measure();
6781
+ if (this.snapshot &&
6782
+ !calcLength(this.snapshot.measuredBox.x) &&
6783
+ !calcLength(this.snapshot.measuredBox.y)) {
6784
+ this.snapshot = undefined;
6785
+ }
6781
6786
  }
6782
6787
  updateLayout() {
6783
6788
  if (!this.instance)
@@ -8457,156 +8462,11 @@ function getProjectionFunctionality(props) {
8457
8462
  };
8458
8463
  }
8459
8464
 
8460
- /**
8461
- * We keep these listed separately as we use the lowercase tag names as part
8462
- * of the runtime bundle to detect SVG components
8463
- */
8464
- const lowercaseSVGElements = [
8465
- "animate",
8466
- "circle",
8467
- "defs",
8468
- "desc",
8469
- "ellipse",
8470
- "g",
8471
- "image",
8472
- "line",
8473
- "filter",
8474
- "marker",
8475
- "mask",
8476
- "metadata",
8477
- "path",
8478
- "pattern",
8479
- "polygon",
8480
- "polyline",
8481
- "rect",
8482
- "stop",
8483
- "switch",
8484
- "symbol",
8485
- "svg",
8486
- "text",
8487
- "tspan",
8488
- "use",
8489
- "view",
8490
- ];
8491
-
8492
- function isSVGComponent(Component) {
8493
- if (
8494
- /**
8495
- * If it's not a string, it's a custom React component. Currently we only support
8496
- * HTML custom React components.
8497
- */
8498
- typeof Component !== "string" ||
8499
- /**
8500
- * If it contains a dash, the element is a custom HTML webcomponent.
8501
- */
8502
- Component.includes("-")) {
8503
- return false;
8504
- }
8505
- else if (
8506
- /**
8507
- * If it's in our list of lowercase SVG tags, it's an SVG component
8508
- */
8509
- lowercaseSVGElements.indexOf(Component) > -1 ||
8510
- /**
8511
- * If it contains a capital letter, it's an SVG component
8512
- */
8513
- /[A-Z]/u.test(Component)) {
8514
- return true;
8515
- }
8516
- return false;
8517
- }
8518
-
8519
- /**
8520
- * Creates a constant value over the lifecycle of a component.
8521
- *
8522
- * Even if `useMemo` is provided an empty array as its final argument, it doesn't offer
8523
- * a guarantee that it won't re-run for performance reasons later on. By using `useConstant`
8524
- * you can ensure that initialisers don't execute twice or more.
8525
- */
8526
- function useConstant(init) {
8527
- const ref = react.useRef(null);
8528
- if (ref.current === null) {
8529
- ref.current = init();
8530
- }
8531
- return ref.current;
8532
- }
8533
-
8534
- function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
8535
- const state = {
8536
- latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
8537
- renderState: createRenderState(),
8538
- };
8539
- if (onUpdate) {
8540
- /**
8541
- * onMount works without the VisualElement because it could be
8542
- * called before the VisualElement payload has been hydrated.
8543
- * (e.g. if someone is using m components <m.circle />)
8544
- */
8545
- state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
8546
- state.onUpdate = (visualElement) => onUpdate(visualElement);
8547
- }
8548
- return state;
8549
- }
8550
- const makeUseVisualState = (config) => (props, isStatic) => {
8551
- const context = react.useContext(MotionContext);
8552
- const presenceContext = react.useContext(PresenceContext);
8553
- const make = () => makeState(config, props, context, presenceContext);
8554
- return isStatic ? make() : useConstant(make);
8555
- };
8556
- function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
8557
- const values = {};
8558
- const motionValues = scrapeMotionValues(props, {});
8559
- for (const key in motionValues) {
8560
- values[key] = resolveMotionValue(motionValues[key]);
8561
- }
8562
- let { initial, animate } = props;
8563
- const isControllingVariants$1 = isControllingVariants(props);
8564
- const isVariantNode$1 = isVariantNode(props);
8565
- if (context &&
8566
- isVariantNode$1 &&
8567
- !isControllingVariants$1 &&
8568
- props.inherit !== false) {
8569
- if (initial === undefined)
8570
- initial = context.initial;
8571
- if (animate === undefined)
8572
- animate = context.animate;
8573
- }
8574
- let isInitialAnimationBlocked = presenceContext
8575
- ? presenceContext.initial === false
8576
- : false;
8577
- isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
8578
- const variantToSet = isInitialAnimationBlocked ? animate : initial;
8579
- if (variantToSet &&
8580
- typeof variantToSet !== "boolean" &&
8581
- !isAnimationControls(variantToSet)) {
8582
- const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
8583
- for (let i = 0; i < list.length; i++) {
8584
- const resolved = resolveVariantFromProps(props, list[i]);
8585
- if (resolved) {
8586
- const { transitionEnd, transition, ...target } = resolved;
8587
- for (const key in target) {
8588
- let valueTarget = target[key];
8589
- if (Array.isArray(valueTarget)) {
8590
- /**
8591
- * Take final keyframe if the initial animation is blocked because
8592
- * we want to initialise at the end of that blocked animation.
8593
- */
8594
- const index = isInitialAnimationBlocked
8595
- ? valueTarget.length - 1
8596
- : 0;
8597
- valueTarget = valueTarget[index];
8598
- }
8599
- if (valueTarget !== null) {
8600
- values[key] = valueTarget;
8601
- }
8602
- }
8603
- for (const key in transitionEnd) {
8604
- values[key] = transitionEnd[key];
8605
- }
8606
- }
8607
- }
8608
- }
8609
- return values;
8465
+ function isForcedMotionValue(key, { layout, layoutId }) {
8466
+ return (transformProps.has(key) ||
8467
+ key.startsWith("origin") ||
8468
+ ((layout || layoutId !== undefined) &&
8469
+ (!!scaleCorrectors[key] || key === "opacity")));
8610
8470
  }
8611
8471
 
8612
8472
  /**
@@ -8733,97 +8593,6 @@ function buildHTMLStyles(state, latestValues, transformTemplate) {
8733
8593
  }
8734
8594
  }
8735
8595
 
8736
- const dashKeys = {
8737
- offset: "stroke-dashoffset",
8738
- array: "stroke-dasharray",
8739
- };
8740
- const camelKeys = {
8741
- offset: "strokeDashoffset",
8742
- array: "strokeDasharray",
8743
- };
8744
- /**
8745
- * Build SVG path properties. Uses the path's measured length to convert
8746
- * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
8747
- * and stroke-dasharray attributes.
8748
- *
8749
- * This function is mutative to reduce per-frame GC.
8750
- */
8751
- function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
8752
- // Normalise path length by setting SVG attribute pathLength to 1
8753
- attrs.pathLength = 1;
8754
- // We use dash case when setting attributes directly to the DOM node and camel case
8755
- // when defining props on a React component.
8756
- const keys = useDashCase ? dashKeys : camelKeys;
8757
- // Build the dash offset
8758
- attrs[keys.offset] = px.transform(-offset);
8759
- // Build the dash array
8760
- const pathLength = px.transform(length);
8761
- const pathSpacing = px.transform(spacing);
8762
- attrs[keys.array] = `${pathLength} ${pathSpacing}`;
8763
- }
8764
-
8765
- function calcOrigin(origin, offset, size) {
8766
- return typeof origin === "string"
8767
- ? origin
8768
- : px.transform(offset + size * origin);
8769
- }
8770
- /**
8771
- * The SVG transform origin defaults are different to CSS and is less intuitive,
8772
- * so we use the measured dimensions of the SVG to reconcile these.
8773
- */
8774
- function calcSVGTransformOrigin(dimensions, originX, originY) {
8775
- const pxOriginX = calcOrigin(originX, dimensions.x, dimensions.width);
8776
- const pxOriginY = calcOrigin(originY, dimensions.y, dimensions.height);
8777
- return `${pxOriginX} ${pxOriginY}`;
8778
- }
8779
-
8780
- /**
8781
- * Build SVG visual attrbutes, like cx and style.transform
8782
- */
8783
- function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
8784
- // This is object creation, which we try to avoid per-frame.
8785
- ...latest }, isSVGTag, transformTemplate) {
8786
- buildHTMLStyles(state, latest, transformTemplate);
8787
- /**
8788
- * For svg tags we just want to make sure viewBox is animatable and treat all the styles
8789
- * as normal HTML tags.
8790
- */
8791
- if (isSVGTag) {
8792
- if (state.style.viewBox) {
8793
- state.attrs.viewBox = state.style.viewBox;
8794
- }
8795
- return;
8796
- }
8797
- state.attrs = state.style;
8798
- state.style = {};
8799
- const { attrs, style, dimensions } = state;
8800
- /**
8801
- * However, we apply transforms as CSS transforms. So if we detect a transform we take it from attrs
8802
- * and copy it into style.
8803
- */
8804
- if (attrs.transform) {
8805
- if (dimensions)
8806
- style.transform = attrs.transform;
8807
- delete attrs.transform;
8808
- }
8809
- // Parse transformOrigin
8810
- if (dimensions &&
8811
- (originX !== undefined || originY !== undefined || style.transform)) {
8812
- style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== undefined ? originX : 0.5, originY !== undefined ? originY : 0.5);
8813
- }
8814
- // Render attrX/attrY/attrScale as attributes
8815
- if (attrX !== undefined)
8816
- attrs.x = attrX;
8817
- if (attrY !== undefined)
8818
- attrs.y = attrY;
8819
- if (attrScale !== undefined)
8820
- attrs.scale = attrScale;
8821
- // Build SVG path if one has been defined
8822
- if (pathLength !== undefined) {
8823
- buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
8824
- }
8825
- }
8826
-
8827
8596
  const createHtmlRenderState = () => ({
8828
8597
  style: {},
8829
8598
  transform: {},
@@ -8831,15 +8600,485 @@ const createHtmlRenderState = () => ({
8831
8600
  vars: {},
8832
8601
  });
8833
8602
 
8834
- const createSvgRenderState = () => ({
8835
- ...createHtmlRenderState(),
8836
- attrs: {},
8837
- });
8838
-
8839
- const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
8840
-
8841
- function renderHTML(element, { style, vars }, styleProp, projection) {
8842
- Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
8603
+ function copyRawValuesOnly(target, source, props) {
8604
+ for (const key in source) {
8605
+ if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
8606
+ target[key] = source[key];
8607
+ }
8608
+ }
8609
+ }
8610
+ function useInitialMotionValues({ transformTemplate }, visualState) {
8611
+ return react.useMemo(() => {
8612
+ const state = createHtmlRenderState();
8613
+ buildHTMLStyles(state, visualState, transformTemplate);
8614
+ return Object.assign({}, state.vars, state.style);
8615
+ }, [visualState]);
8616
+ }
8617
+ function useStyle(props, visualState) {
8618
+ const styleProp = props.style || {};
8619
+ const style = {};
8620
+ /**
8621
+ * Copy non-Motion Values straight into style
8622
+ */
8623
+ copyRawValuesOnly(style, styleProp, props);
8624
+ Object.assign(style, useInitialMotionValues(props, visualState));
8625
+ return style;
8626
+ }
8627
+ function useHTMLProps(props, visualState) {
8628
+ // The `any` isn't ideal but it is the type of createElement props argument
8629
+ const htmlProps = {};
8630
+ const style = useStyle(props, visualState);
8631
+ if (props.drag && props.dragListener !== false) {
8632
+ // Disable the ghost element when a user drags
8633
+ htmlProps.draggable = false;
8634
+ // Disable text selection
8635
+ style.userSelect =
8636
+ style.WebkitUserSelect =
8637
+ style.WebkitTouchCallout =
8638
+ "none";
8639
+ // Disable scrolling on the draggable direction
8640
+ style.touchAction =
8641
+ props.drag === true
8642
+ ? "none"
8643
+ : `pan-${props.drag === "x" ? "y" : "x"}`;
8644
+ }
8645
+ if (props.tabIndex === undefined &&
8646
+ (props.onTap || props.onTapStart || props.whileTap)) {
8647
+ htmlProps.tabIndex = 0;
8648
+ }
8649
+ htmlProps.style = style;
8650
+ return htmlProps;
8651
+ }
8652
+
8653
+ /**
8654
+ * A list of all valid MotionProps.
8655
+ *
8656
+ * @privateRemarks
8657
+ * This doesn't throw if a `MotionProp` name is missing - it should.
8658
+ */
8659
+ const validMotionProps = new Set([
8660
+ "animate",
8661
+ "exit",
8662
+ "variants",
8663
+ "initial",
8664
+ "style",
8665
+ "values",
8666
+ "variants",
8667
+ "transition",
8668
+ "transformTemplate",
8669
+ "custom",
8670
+ "inherit",
8671
+ "onBeforeLayoutMeasure",
8672
+ "onAnimationStart",
8673
+ "onAnimationComplete",
8674
+ "onUpdate",
8675
+ "onDragStart",
8676
+ "onDrag",
8677
+ "onDragEnd",
8678
+ "onMeasureDragConstraints",
8679
+ "onDirectionLock",
8680
+ "onDragTransitionEnd",
8681
+ "_dragX",
8682
+ "_dragY",
8683
+ "onHoverStart",
8684
+ "onHoverEnd",
8685
+ "onViewportEnter",
8686
+ "onViewportLeave",
8687
+ "globalTapTarget",
8688
+ "ignoreStrict",
8689
+ "viewport",
8690
+ ]);
8691
+ /**
8692
+ * Check whether a prop name is a valid `MotionProp` key.
8693
+ *
8694
+ * @param key - Name of the property to check
8695
+ * @returns `true` is key is a valid `MotionProp`.
8696
+ *
8697
+ * @public
8698
+ */
8699
+ function isValidMotionProp(key) {
8700
+ return (key.startsWith("while") ||
8701
+ (key.startsWith("drag") && key !== "draggable") ||
8702
+ key.startsWith("layout") ||
8703
+ key.startsWith("onTap") ||
8704
+ key.startsWith("onPan") ||
8705
+ key.startsWith("onLayout") ||
8706
+ validMotionProps.has(key));
8707
+ }
8708
+
8709
+ let shouldForward = (key) => !isValidMotionProp(key);
8710
+ function loadExternalIsValidProp(isValidProp) {
8711
+ if (!isValidProp)
8712
+ return;
8713
+ // Explicitly filter our events
8714
+ shouldForward = (key) => key.startsWith("on") ? !isValidMotionProp(key) : isValidProp(key);
8715
+ }
8716
+ /**
8717
+ * Emotion and Styled Components both allow users to pass through arbitrary props to their components
8718
+ * to dynamically generate CSS. They both use the `@emotion/is-prop-valid` package to determine which
8719
+ * of these should be passed to the underlying DOM node.
8720
+ *
8721
+ * However, when styling a Motion component `styled(motion.div)`, both packages pass through *all* props
8722
+ * as it's seen as an arbitrary component rather than a DOM node. Motion only allows arbitrary props
8723
+ * passed through the `custom` prop so it doesn't *need* the payload or computational overhead of
8724
+ * `@emotion/is-prop-valid`, however to fix this problem we need to use it.
8725
+ *
8726
+ * By making it an optionalDependency we can offer this functionality only in the situations where it's
8727
+ * actually required.
8728
+ */
8729
+ try {
8730
+ /**
8731
+ * We attempt to import this package but require won't be defined in esm environments, in that case
8732
+ * isPropValid will have to be provided via `MotionContext`. In a 6.0.0 this should probably be removed
8733
+ * in favour of explicit injection.
8734
+ */
8735
+ loadExternalIsValidProp(require("@emotion/is-prop-valid").default);
8736
+ }
8737
+ catch (_a) {
8738
+ // We don't need to actually do anything here - the fallback is the existing `isPropValid`.
8739
+ }
8740
+ function filterProps(props, isDom, forwardMotionProps) {
8741
+ const filteredProps = {};
8742
+ for (const key in props) {
8743
+ /**
8744
+ * values is considered a valid prop by Emotion, so if it's present
8745
+ * this will be rendered out to the DOM unless explicitly filtered.
8746
+ *
8747
+ * We check the type as it could be used with the `feColorMatrix`
8748
+ * element, which we support.
8749
+ */
8750
+ if (key === "values" && typeof props.values === "object")
8751
+ continue;
8752
+ if (shouldForward(key) ||
8753
+ (forwardMotionProps === true && isValidMotionProp(key)) ||
8754
+ (!isDom && !isValidMotionProp(key)) ||
8755
+ // If trying to use native HTML drag events, forward drag listeners
8756
+ (props["draggable"] &&
8757
+ key.startsWith("onDrag"))) {
8758
+ filteredProps[key] =
8759
+ props[key];
8760
+ }
8761
+ }
8762
+ return filteredProps;
8763
+ }
8764
+
8765
+ /**
8766
+ * We keep these listed separately as we use the lowercase tag names as part
8767
+ * of the runtime bundle to detect SVG components
8768
+ */
8769
+ const lowercaseSVGElements = [
8770
+ "animate",
8771
+ "circle",
8772
+ "defs",
8773
+ "desc",
8774
+ "ellipse",
8775
+ "g",
8776
+ "image",
8777
+ "line",
8778
+ "filter",
8779
+ "marker",
8780
+ "mask",
8781
+ "metadata",
8782
+ "path",
8783
+ "pattern",
8784
+ "polygon",
8785
+ "polyline",
8786
+ "rect",
8787
+ "stop",
8788
+ "switch",
8789
+ "symbol",
8790
+ "svg",
8791
+ "text",
8792
+ "tspan",
8793
+ "use",
8794
+ "view",
8795
+ ];
8796
+
8797
+ function isSVGComponent(Component) {
8798
+ if (
8799
+ /**
8800
+ * If it's not a string, it's a custom React component. Currently we only support
8801
+ * HTML custom React components.
8802
+ */
8803
+ typeof Component !== "string" ||
8804
+ /**
8805
+ * If it contains a dash, the element is a custom HTML webcomponent.
8806
+ */
8807
+ Component.includes("-")) {
8808
+ return false;
8809
+ }
8810
+ else if (
8811
+ /**
8812
+ * If it's in our list of lowercase SVG tags, it's an SVG component
8813
+ */
8814
+ lowercaseSVGElements.indexOf(Component) > -1 ||
8815
+ /**
8816
+ * If it contains a capital letter, it's an SVG component
8817
+ */
8818
+ /[A-Z]/u.test(Component)) {
8819
+ return true;
8820
+ }
8821
+ return false;
8822
+ }
8823
+
8824
+ const dashKeys = {
8825
+ offset: "stroke-dashoffset",
8826
+ array: "stroke-dasharray",
8827
+ };
8828
+ const camelKeys = {
8829
+ offset: "strokeDashoffset",
8830
+ array: "strokeDasharray",
8831
+ };
8832
+ /**
8833
+ * Build SVG path properties. Uses the path's measured length to convert
8834
+ * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
8835
+ * and stroke-dasharray attributes.
8836
+ *
8837
+ * This function is mutative to reduce per-frame GC.
8838
+ */
8839
+ function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
8840
+ // Normalise path length by setting SVG attribute pathLength to 1
8841
+ attrs.pathLength = 1;
8842
+ // We use dash case when setting attributes directly to the DOM node and camel case
8843
+ // when defining props on a React component.
8844
+ const keys = useDashCase ? dashKeys : camelKeys;
8845
+ // Build the dash offset
8846
+ attrs[keys.offset] = px.transform(-offset);
8847
+ // Build the dash array
8848
+ const pathLength = px.transform(length);
8849
+ const pathSpacing = px.transform(spacing);
8850
+ attrs[keys.array] = `${pathLength} ${pathSpacing}`;
8851
+ }
8852
+
8853
+ function calcOrigin(origin, offset, size) {
8854
+ return typeof origin === "string"
8855
+ ? origin
8856
+ : px.transform(offset + size * origin);
8857
+ }
8858
+ /**
8859
+ * The SVG transform origin defaults are different to CSS and is less intuitive,
8860
+ * so we use the measured dimensions of the SVG to reconcile these.
8861
+ */
8862
+ function calcSVGTransformOrigin(dimensions, originX, originY) {
8863
+ const pxOriginX = calcOrigin(originX, dimensions.x, dimensions.width);
8864
+ const pxOriginY = calcOrigin(originY, dimensions.y, dimensions.height);
8865
+ return `${pxOriginX} ${pxOriginY}`;
8866
+ }
8867
+
8868
+ /**
8869
+ * Build SVG visual attrbutes, like cx and style.transform
8870
+ */
8871
+ function buildSVGAttrs(state, { attrX, attrY, attrScale, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
8872
+ // This is object creation, which we try to avoid per-frame.
8873
+ ...latest }, isSVGTag, transformTemplate) {
8874
+ buildHTMLStyles(state, latest, transformTemplate);
8875
+ /**
8876
+ * For svg tags we just want to make sure viewBox is animatable and treat all the styles
8877
+ * as normal HTML tags.
8878
+ */
8879
+ if (isSVGTag) {
8880
+ if (state.style.viewBox) {
8881
+ state.attrs.viewBox = state.style.viewBox;
8882
+ }
8883
+ return;
8884
+ }
8885
+ state.attrs = state.style;
8886
+ state.style = {};
8887
+ const { attrs, style, dimensions } = state;
8888
+ /**
8889
+ * However, we apply transforms as CSS transforms. So if we detect a transform we take it from attrs
8890
+ * and copy it into style.
8891
+ */
8892
+ if (attrs.transform) {
8893
+ if (dimensions)
8894
+ style.transform = attrs.transform;
8895
+ delete attrs.transform;
8896
+ }
8897
+ // Parse transformOrigin
8898
+ if (dimensions &&
8899
+ (originX !== undefined || originY !== undefined || style.transform)) {
8900
+ style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== undefined ? originX : 0.5, originY !== undefined ? originY : 0.5);
8901
+ }
8902
+ // Render attrX/attrY/attrScale as attributes
8903
+ if (attrX !== undefined)
8904
+ attrs.x = attrX;
8905
+ if (attrY !== undefined)
8906
+ attrs.y = attrY;
8907
+ if (attrScale !== undefined)
8908
+ attrs.scale = attrScale;
8909
+ // Build SVG path if one has been defined
8910
+ if (pathLength !== undefined) {
8911
+ buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
8912
+ }
8913
+ }
8914
+
8915
+ const createSvgRenderState = () => ({
8916
+ ...createHtmlRenderState(),
8917
+ attrs: {},
8918
+ });
8919
+
8920
+ const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
8921
+
8922
+ function useSVGProps(props, visualState, _isStatic, Component) {
8923
+ const visualProps = react.useMemo(() => {
8924
+ const state = createSvgRenderState();
8925
+ buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate);
8926
+ return {
8927
+ ...state.attrs,
8928
+ style: { ...state.style },
8929
+ };
8930
+ }, [visualState]);
8931
+ if (props.style) {
8932
+ const rawStyles = {};
8933
+ copyRawValuesOnly(rawStyles, props.style, props);
8934
+ visualProps.style = { ...rawStyles, ...visualProps.style };
8935
+ }
8936
+ return visualProps;
8937
+ }
8938
+
8939
+ function createUseRender(forwardMotionProps = false) {
8940
+ const useRender = (Component, props, ref, { latestValues }, isStatic) => {
8941
+ const useVisualProps = isSVGComponent(Component)
8942
+ ? useSVGProps
8943
+ : useHTMLProps;
8944
+ const visualProps = useVisualProps(props, latestValues, isStatic, Component);
8945
+ const filteredProps = filterProps(props, typeof Component === "string", forwardMotionProps);
8946
+ const elementProps = Component !== react.Fragment
8947
+ ? { ...filteredProps, ...visualProps, ref }
8948
+ : {};
8949
+ /**
8950
+ * If component has been handed a motion value as its child,
8951
+ * memoise its initial value and render that. Subsequent updates
8952
+ * will be handled by the onChange handler
8953
+ */
8954
+ const { children } = props;
8955
+ const renderedChildren = react.useMemo(() => (isMotionValue(children) ? children.get() : children), [children]);
8956
+ return react.createElement(Component, {
8957
+ ...elementProps,
8958
+ children: renderedChildren,
8959
+ });
8960
+ };
8961
+ return useRender;
8962
+ }
8963
+
8964
+ /**
8965
+ * Creates a constant value over the lifecycle of a component.
8966
+ *
8967
+ * Even if `useMemo` is provided an empty array as its final argument, it doesn't offer
8968
+ * a guarantee that it won't re-run for performance reasons later on. By using `useConstant`
8969
+ * you can ensure that initialisers don't execute twice or more.
8970
+ */
8971
+ function useConstant(init) {
8972
+ const ref = react.useRef(null);
8973
+ if (ref.current === null) {
8974
+ ref.current = init();
8975
+ }
8976
+ return ref.current;
8977
+ }
8978
+
8979
+ function makeState({ scrapeMotionValuesFromProps, createRenderState, onUpdate, }, props, context, presenceContext) {
8980
+ const state = {
8981
+ latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
8982
+ renderState: createRenderState(),
8983
+ };
8984
+ if (onUpdate) {
8985
+ /**
8986
+ * onMount works without the VisualElement because it could be
8987
+ * called before the VisualElement payload has been hydrated.
8988
+ * (e.g. if someone is using m components <m.circle />)
8989
+ */
8990
+ state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
8991
+ state.onUpdate = (visualElement) => onUpdate(visualElement);
8992
+ }
8993
+ return state;
8994
+ }
8995
+ const makeUseVisualState = (config) => (props, isStatic) => {
8996
+ const context = react.useContext(MotionContext);
8997
+ const presenceContext = react.useContext(PresenceContext);
8998
+ const make = () => makeState(config, props, context, presenceContext);
8999
+ return isStatic ? make() : useConstant(make);
9000
+ };
9001
+ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
9002
+ const values = {};
9003
+ const motionValues = scrapeMotionValues(props, {});
9004
+ for (const key in motionValues) {
9005
+ values[key] = resolveMotionValue(motionValues[key]);
9006
+ }
9007
+ let { initial, animate } = props;
9008
+ const isControllingVariants$1 = isControllingVariants(props);
9009
+ const isVariantNode$1 = isVariantNode(props);
9010
+ if (context &&
9011
+ isVariantNode$1 &&
9012
+ !isControllingVariants$1 &&
9013
+ props.inherit !== false) {
9014
+ if (initial === undefined)
9015
+ initial = context.initial;
9016
+ if (animate === undefined)
9017
+ animate = context.animate;
9018
+ }
9019
+ let isInitialAnimationBlocked = presenceContext
9020
+ ? presenceContext.initial === false
9021
+ : false;
9022
+ isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
9023
+ const variantToSet = isInitialAnimationBlocked ? animate : initial;
9024
+ if (variantToSet &&
9025
+ typeof variantToSet !== "boolean" &&
9026
+ !isAnimationControls(variantToSet)) {
9027
+ const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
9028
+ for (let i = 0; i < list.length; i++) {
9029
+ const resolved = resolveVariantFromProps(props, list[i]);
9030
+ if (resolved) {
9031
+ const { transitionEnd, transition, ...target } = resolved;
9032
+ for (const key in target) {
9033
+ let valueTarget = target[key];
9034
+ if (Array.isArray(valueTarget)) {
9035
+ /**
9036
+ * Take final keyframe if the initial animation is blocked because
9037
+ * we want to initialise at the end of that blocked animation.
9038
+ */
9039
+ const index = isInitialAnimationBlocked
9040
+ ? valueTarget.length - 1
9041
+ : 0;
9042
+ valueTarget = valueTarget[index];
9043
+ }
9044
+ if (valueTarget !== null) {
9045
+ values[key] = valueTarget;
9046
+ }
9047
+ }
9048
+ for (const key in transitionEnd) {
9049
+ values[key] = transitionEnd[key];
9050
+ }
9051
+ }
9052
+ }
9053
+ }
9054
+ return values;
9055
+ }
9056
+
9057
+ function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
9058
+ var _a;
9059
+ const { style } = props;
9060
+ const newValues = {};
9061
+ for (const key in style) {
9062
+ if (isMotionValue(style[key]) ||
9063
+ (prevProps.style &&
9064
+ isMotionValue(prevProps.style[key])) ||
9065
+ isForcedMotionValue(key, props) ||
9066
+ ((_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.getValue(key)) === null || _a === void 0 ? void 0 : _a.liveStyle) !== undefined) {
9067
+ newValues[key] = style[key];
9068
+ }
9069
+ }
9070
+ return newValues;
9071
+ }
9072
+
9073
+ const htmlMotionConfig = {
9074
+ useVisualState: makeUseVisualState({
9075
+ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
9076
+ createRenderState: createHtmlRenderState,
9077
+ }),
9078
+ };
9079
+
9080
+ function renderHTML(element, { style, vars }, styleProp, projection) {
9081
+ Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
8843
9082
  // Loop over any CSS variables and assign those.
8844
9083
  for (const key in vars) {
8845
9084
  element.style.setProperty(key, vars[key]);
@@ -8882,29 +9121,6 @@ function renderSVG(element, renderState, _styleProp, projection) {
8882
9121
  }
8883
9122
  }
8884
9123
 
8885
- function isForcedMotionValue(key, { layout, layoutId }) {
8886
- return (transformProps.has(key) ||
8887
- key.startsWith("origin") ||
8888
- ((layout || layoutId !== undefined) &&
8889
- (!!scaleCorrectors[key] || key === "opacity")));
8890
- }
8891
-
8892
- function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
8893
- var _a;
8894
- const { style } = props;
8895
- const newValues = {};
8896
- for (const key in style) {
8897
- if (isMotionValue(style[key]) ||
8898
- (prevProps.style &&
8899
- isMotionValue(prevProps.style[key])) ||
8900
- isForcedMotionValue(key, props) ||
8901
- ((_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.getValue(key)) === null || _a === void 0 ? void 0 : _a.liveStyle) !== undefined) {
8902
- newValues[key] = style[key];
8903
- }
8904
- }
8905
- return newValues;
8906
- }
8907
-
8908
9124
  function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
8909
9125
  const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
8910
9126
  for (const key in props) {
@@ -8982,217 +9198,6 @@ const svgMotionConfig = {
8982
9198
  }),
8983
9199
  };
8984
9200
 
8985
- const htmlMotionConfig = {
8986
- useVisualState: makeUseVisualState({
8987
- scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
8988
- createRenderState: createHtmlRenderState,
8989
- }),
8990
- };
8991
-
8992
- function copyRawValuesOnly(target, source, props) {
8993
- for (const key in source) {
8994
- if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
8995
- target[key] = source[key];
8996
- }
8997
- }
8998
- }
8999
- function useInitialMotionValues({ transformTemplate }, visualState) {
9000
- return react.useMemo(() => {
9001
- const state = createHtmlRenderState();
9002
- buildHTMLStyles(state, visualState, transformTemplate);
9003
- return Object.assign({}, state.vars, state.style);
9004
- }, [visualState]);
9005
- }
9006
- function useStyle(props, visualState) {
9007
- const styleProp = props.style || {};
9008
- const style = {};
9009
- /**
9010
- * Copy non-Motion Values straight into style
9011
- */
9012
- copyRawValuesOnly(style, styleProp, props);
9013
- Object.assign(style, useInitialMotionValues(props, visualState));
9014
- return style;
9015
- }
9016
- function useHTMLProps(props, visualState) {
9017
- // The `any` isn't ideal but it is the type of createElement props argument
9018
- const htmlProps = {};
9019
- const style = useStyle(props, visualState);
9020
- if (props.drag && props.dragListener !== false) {
9021
- // Disable the ghost element when a user drags
9022
- htmlProps.draggable = false;
9023
- // Disable text selection
9024
- style.userSelect =
9025
- style.WebkitUserSelect =
9026
- style.WebkitTouchCallout =
9027
- "none";
9028
- // Disable scrolling on the draggable direction
9029
- style.touchAction =
9030
- props.drag === true
9031
- ? "none"
9032
- : `pan-${props.drag === "x" ? "y" : "x"}`;
9033
- }
9034
- if (props.tabIndex === undefined &&
9035
- (props.onTap || props.onTapStart || props.whileTap)) {
9036
- htmlProps.tabIndex = 0;
9037
- }
9038
- htmlProps.style = style;
9039
- return htmlProps;
9040
- }
9041
-
9042
- /**
9043
- * A list of all valid MotionProps.
9044
- *
9045
- * @privateRemarks
9046
- * This doesn't throw if a `MotionProp` name is missing - it should.
9047
- */
9048
- const validMotionProps = new Set([
9049
- "animate",
9050
- "exit",
9051
- "variants",
9052
- "initial",
9053
- "style",
9054
- "values",
9055
- "variants",
9056
- "transition",
9057
- "transformTemplate",
9058
- "custom",
9059
- "inherit",
9060
- "onBeforeLayoutMeasure",
9061
- "onAnimationStart",
9062
- "onAnimationComplete",
9063
- "onUpdate",
9064
- "onDragStart",
9065
- "onDrag",
9066
- "onDragEnd",
9067
- "onMeasureDragConstraints",
9068
- "onDirectionLock",
9069
- "onDragTransitionEnd",
9070
- "_dragX",
9071
- "_dragY",
9072
- "onHoverStart",
9073
- "onHoverEnd",
9074
- "onViewportEnter",
9075
- "onViewportLeave",
9076
- "globalTapTarget",
9077
- "ignoreStrict",
9078
- "viewport",
9079
- ]);
9080
- /**
9081
- * Check whether a prop name is a valid `MotionProp` key.
9082
- *
9083
- * @param key - Name of the property to check
9084
- * @returns `true` is key is a valid `MotionProp`.
9085
- *
9086
- * @public
9087
- */
9088
- function isValidMotionProp(key) {
9089
- return (key.startsWith("while") ||
9090
- (key.startsWith("drag") && key !== "draggable") ||
9091
- key.startsWith("layout") ||
9092
- key.startsWith("onTap") ||
9093
- key.startsWith("onPan") ||
9094
- key.startsWith("onLayout") ||
9095
- validMotionProps.has(key));
9096
- }
9097
-
9098
- let shouldForward = (key) => !isValidMotionProp(key);
9099
- function loadExternalIsValidProp(isValidProp) {
9100
- if (!isValidProp)
9101
- return;
9102
- // Explicitly filter our events
9103
- shouldForward = (key) => key.startsWith("on") ? !isValidMotionProp(key) : isValidProp(key);
9104
- }
9105
- /**
9106
- * Emotion and Styled Components both allow users to pass through arbitrary props to their components
9107
- * to dynamically generate CSS. They both use the `@emotion/is-prop-valid` package to determine which
9108
- * of these should be passed to the underlying DOM node.
9109
- *
9110
- * However, when styling a Motion component `styled(motion.div)`, both packages pass through *all* props
9111
- * as it's seen as an arbitrary component rather than a DOM node. Motion only allows arbitrary props
9112
- * passed through the `custom` prop so it doesn't *need* the payload or computational overhead of
9113
- * `@emotion/is-prop-valid`, however to fix this problem we need to use it.
9114
- *
9115
- * By making it an optionalDependency we can offer this functionality only in the situations where it's
9116
- * actually required.
9117
- */
9118
- try {
9119
- /**
9120
- * We attempt to import this package but require won't be defined in esm environments, in that case
9121
- * isPropValid will have to be provided via `MotionContext`. In a 6.0.0 this should probably be removed
9122
- * in favour of explicit injection.
9123
- */
9124
- loadExternalIsValidProp(require("@emotion/is-prop-valid").default);
9125
- }
9126
- catch (_a) {
9127
- // We don't need to actually do anything here - the fallback is the existing `isPropValid`.
9128
- }
9129
- function filterProps(props, isDom, forwardMotionProps) {
9130
- const filteredProps = {};
9131
- for (const key in props) {
9132
- /**
9133
- * values is considered a valid prop by Emotion, so if it's present
9134
- * this will be rendered out to the DOM unless explicitly filtered.
9135
- *
9136
- * We check the type as it could be used with the `feColorMatrix`
9137
- * element, which we support.
9138
- */
9139
- if (key === "values" && typeof props.values === "object")
9140
- continue;
9141
- if (shouldForward(key) ||
9142
- (forwardMotionProps === true && isValidMotionProp(key)) ||
9143
- (!isDom && !isValidMotionProp(key)) ||
9144
- // If trying to use native HTML drag events, forward drag listeners
9145
- (props["draggable"] &&
9146
- key.startsWith("onDrag"))) {
9147
- filteredProps[key] =
9148
- props[key];
9149
- }
9150
- }
9151
- return filteredProps;
9152
- }
9153
-
9154
- function useSVGProps(props, visualState, _isStatic, Component) {
9155
- const visualProps = react.useMemo(() => {
9156
- const state = createSvgRenderState();
9157
- buildSVGAttrs(state, visualState, isSVGTag(Component), props.transformTemplate);
9158
- return {
9159
- ...state.attrs,
9160
- style: { ...state.style },
9161
- };
9162
- }, [visualState]);
9163
- if (props.style) {
9164
- const rawStyles = {};
9165
- copyRawValuesOnly(rawStyles, props.style, props);
9166
- visualProps.style = { ...rawStyles, ...visualProps.style };
9167
- }
9168
- return visualProps;
9169
- }
9170
-
9171
- function createUseRender(forwardMotionProps = false) {
9172
- const useRender = (Component, props, ref, { latestValues }, isStatic) => {
9173
- const useVisualProps = isSVGComponent(Component)
9174
- ? useSVGProps
9175
- : useHTMLProps;
9176
- const visualProps = useVisualProps(props, latestValues, isStatic, Component);
9177
- const filteredProps = filterProps(props, typeof Component === "string", forwardMotionProps);
9178
- const elementProps = Component !== react.Fragment
9179
- ? { ...filteredProps, ...visualProps, ref }
9180
- : {};
9181
- /**
9182
- * If component has been handed a motion value as its child,
9183
- * memoise its initial value and render that. Subsequent updates
9184
- * will be handled by the onChange handler
9185
- */
9186
- const { children } = props;
9187
- const renderedChildren = react.useMemo(() => (isMotionValue(children) ? children.get() : children), [children]);
9188
- return react.createElement(Component, {
9189
- ...elementProps,
9190
- children: renderedChildren,
9191
- });
9192
- };
9193
- return useRender;
9194
- }
9195
-
9196
9201
  function createMotionComponentFactory(preloadedFeatures, createVisualElement) {
9197
9202
  return function createMotionComponent(Component, { forwardMotionProps } = { forwardMotionProps: false }) {
9198
9203
  const baseConfig = isSVGComponent(Component)
@@ -9254,7 +9259,7 @@ function updateMotionValuesFromProps(element, next, prev) {
9254
9259
  * and warn against mismatches.
9255
9260
  */
9256
9261
  if (process.env.NODE_ENV === "development") {
9257
- warnOnce(nextValue.version === "12.0.5", `Attempting to mix Motion versions ${nextValue.version} with 12.0.5 may not work as expected.`);
9262
+ 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.`);
9258
9263
  }
9259
9264
  }
9260
9265
  else if (isMotionValue(prevValue)) {
@@ -9476,6 +9481,9 @@ class VisualElement {
9476
9481
  this.valueSubscriptions.get(key)();
9477
9482
  }
9478
9483
  const valueIsTransform = transformProps.has(key);
9484
+ if (valueIsTransform && this.onBindTransform) {
9485
+ this.onBindTransform();
9486
+ }
9479
9487
  const removeOnChange = value.on("change", (latestValue) => {
9480
9488
  this.latestValues[key] = latestValue;
9481
9489
  this.props.onUpdate && frame.preRender(this.notifyUpdate);
@@ -9826,6 +9834,11 @@ class SVGVisualElement extends DOMVisualElement {
9826
9834
  this.type = "svg";
9827
9835
  this.isSVGTag = false;
9828
9836
  this.measureInstanceViewportBox = createBox;
9837
+ this.updateDimensions = () => {
9838
+ if (this.current && !this.renderState.dimensions) {
9839
+ updateSVGDimensions(this.current, this.renderState);
9840
+ }
9841
+ };
9829
9842
  }
9830
9843
  getBaseTargetFromProps(props, key) {
9831
9844
  return props[key];
@@ -9841,6 +9854,11 @@ class SVGVisualElement extends DOMVisualElement {
9841
9854
  scrapeMotionValuesFromProps(props, prevProps, visualElement) {
9842
9855
  return scrapeMotionValuesFromProps(props, prevProps, visualElement);
9843
9856
  }
9857
+ onBindTransform() {
9858
+ if (this.current && !this.renderState.dimensions) {
9859
+ frame.postRender(this.updateDimensions);
9860
+ }
9861
+ }
9844
9862
  build(renderState, latestValues, props) {
9845
9863
  buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate);
9846
9864
  }