framer-motion 7.2.0 → 7.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +728 -624
- package/dist/es/animation/use-animated-state.mjs +3 -5
- package/dist/es/animation/utils/default-transitions.mjs +1 -1
- package/dist/es/animation/utils/transitions.mjs +28 -26
- package/dist/es/components/AnimatePresence/PopChild.mjs +3 -2
- package/dist/es/components/AnimatePresence/PresenceChild.mjs +5 -2
- package/dist/es/components/AnimatePresence/use-presence.mjs +1 -1
- package/dist/es/components/LayoutGroup/index.mjs +4 -5
- package/dist/es/components/LazyMotion/index.mjs +3 -5
- package/dist/es/components/MotionConfig/index.mjs +2 -4
- package/dist/es/components/Reorder/Group.mjs +2 -4
- package/dist/es/components/Reorder/Item.mjs +6 -8
- package/dist/es/context/MotionContext/utils.mjs +3 -2
- package/dist/es/gestures/PanSession.mjs +2 -2
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +16 -4
- package/dist/es/gestures/use-focus-gesture.mjs +3 -4
- package/dist/es/gestures/use-hover-gesture.mjs +4 -3
- package/dist/es/gestures/use-tap-gesture.mjs +9 -10
- package/dist/es/index.mjs +2 -1
- package/dist/es/motion/features/animations.mjs +8 -3
- package/dist/es/motion/features/definitions.mjs +1 -13
- package/dist/es/motion/features/layout/MeasureLayout.mjs +12 -6
- package/dist/es/motion/features/load-features.mjs +14 -0
- package/dist/es/motion/features/viewport/observers.mjs +4 -7
- package/dist/es/motion/features/viewport/use-viewport.mjs +8 -6
- package/dist/es/motion/index.mjs +23 -23
- package/dist/es/motion/utils/VisualElementHandler.mjs +2 -5
- package/dist/es/motion/utils/is-forced-motion-value.mjs +3 -3
- package/dist/es/motion/utils/use-motion-ref.mjs +1 -2
- package/dist/es/motion/utils/use-visual-element.mjs +14 -12
- package/dist/es/motion/utils/use-visual-state.mjs +19 -16
- package/dist/es/motion/utils/valid-prop.mjs +22 -17
- package/dist/es/projection/node/HTMLProjectionNode.mjs +1 -1
- package/dist/es/projection/node/create-projection-node.mjs +34 -16
- package/dist/es/projection/use-instant-layout-transition.mjs +2 -2
- package/dist/es/render/dom/features-animation.mjs +5 -1
- package/dist/es/render/dom/features-max.mjs +6 -1
- package/dist/es/render/dom/motion.mjs +6 -1
- package/dist/es/render/dom/use-render.mjs +5 -1
- package/dist/es/render/dom/utils/camel-to-dash.mjs +1 -3
- package/dist/es/render/dom/utils/create-config.mjs +7 -2
- package/dist/es/render/dom/utils/css-variables-conversion.mjs +5 -7
- package/dist/es/render/dom/utils/unit-conversion.mjs +4 -4
- package/dist/es/render/dom/value-types/defaults.mjs +15 -3
- package/dist/es/render/dom/value-types/type-int.mjs +4 -1
- package/dist/es/render/html/config-motion.mjs +1 -1
- package/dist/es/render/html/use-props.mjs +5 -9
- package/dist/es/render/html/utils/build-styles.mjs +17 -15
- package/dist/es/render/html/utils/build-transform.mjs +8 -18
- package/dist/es/render/html/utils/transform.mjs +20 -30
- package/dist/es/render/html/visual-element.mjs +8 -9
- package/dist/es/render/index.mjs +118 -40
- package/dist/es/render/svg/use-props.mjs +5 -2
- package/dist/es/render/svg/utils/build-attrs.mjs +3 -5
- package/dist/es/render/svg/utils/create-render-state.mjs +4 -1
- package/dist/es/render/svg/visual-element.mjs +8 -4
- package/dist/es/render/utils/animation-state.mjs +12 -9
- package/dist/es/render/utils/animation.mjs +14 -8
- package/dist/es/render/utils/is-controlling-variants.mjs +22 -0
- package/dist/es/render/utils/is-variant-label.mjs +8 -0
- package/dist/es/render/utils/motion-values.mjs +3 -3
- package/dist/es/render/utils/resolve-dynamic-variants.mjs +24 -0
- package/dist/es/render/utils/resolve-variants.mjs +26 -0
- package/dist/es/render/utils/setters.mjs +12 -9
- package/dist/es/utils/reduced-motion/index.mjs +19 -0
- package/dist/es/utils/reduced-motion/state.mjs +5 -0
- package/dist/es/utils/reduced-motion/use-reduced-motion-config.mjs +19 -0
- package/dist/es/utils/reduced-motion/use-reduced-motion.mjs +43 -0
- package/dist/es/utils/transform.mjs +4 -1
- package/dist/es/utils/use-in-view.mjs +1 -2
- package/dist/es/value/index.mjs +1 -1
- package/dist/es/value/use-scroll.mjs +6 -4
- package/dist/es/value/use-spring.mjs +7 -1
- package/dist/es/value/use-will-change/index.mjs +4 -4
- package/dist/es/value/utils/is-motion-value.mjs +1 -3
- package/dist/framer-motion.dev.js +769 -664
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +55 -52
- package/dist/projection.dev.js +368 -210
- package/dist/size-rollup-dom-animation-assets.js +1 -0
- package/dist/size-rollup-dom-animation-m.js +1 -0
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -0
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-rollup-motion.js +1 -0
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/dist/size-webpack-m.js +1 -1
- package/dist/three-entry.d.ts +36 -20
- package/package.json +12 -8
- package/dist/es/motion/features/use-features.mjs +0 -40
- package/dist/es/motion/features/use-projection.mjs +0 -33
- package/dist/es/render/utils/variants.mjs +0 -73
- package/dist/es/utils/use-reduced-motion.mjs +0 -73
package/dist/three-entry.d.ts
CHANGED
|
@@ -2256,6 +2256,10 @@ declare class FlatTree {
|
|
|
2256
2256
|
forEach(callback: (child: WithDepth) => void): void;
|
|
2257
2257
|
}
|
|
2258
2258
|
|
|
2259
|
+
interface SwitchLayoutGroup {
|
|
2260
|
+
register?: (member: IProjectionNode) => void;
|
|
2261
|
+
deregister?: (member: IProjectionNode) => void;
|
|
2262
|
+
}
|
|
2259
2263
|
declare type InitialPromotionConfig = {
|
|
2260
2264
|
/**
|
|
2261
2265
|
* The initial transition to use when the elements in this group mount (and automatically promoted).
|
|
@@ -2267,6 +2271,11 @@ declare type InitialPromotionConfig = {
|
|
|
2267
2271
|
*/
|
|
2268
2272
|
shouldPreserveFollowOpacity?: (member: IProjectionNode) => boolean;
|
|
2269
2273
|
};
|
|
2274
|
+
declare type SwitchLayoutGroupContext = SwitchLayoutGroup & InitialPromotionConfig;
|
|
2275
|
+
/**
|
|
2276
|
+
* Internal, exported only for usage in Framer
|
|
2277
|
+
*/
|
|
2278
|
+
declare const SwitchLayoutGroupContext: React.Context<SwitchLayoutGroupContext>;
|
|
2270
2279
|
|
|
2271
2280
|
interface Snapshot {
|
|
2272
2281
|
measured: Box;
|
|
@@ -2382,8 +2391,33 @@ interface ProjectionNodeOptions {
|
|
|
2382
2391
|
initialPromotionConfig?: InitialPromotionConfig;
|
|
2383
2392
|
}
|
|
2384
2393
|
|
|
2394
|
+
declare type ReducedMotionConfig = "always" | "never" | "user";
|
|
2395
|
+
|
|
2385
2396
|
declare function filterProps(props: MotionProps, isDom: boolean, forwardMotionProps: boolean): {};
|
|
2386
2397
|
|
|
2398
|
+
/**
|
|
2399
|
+
* @public
|
|
2400
|
+
*/
|
|
2401
|
+
interface FeatureProps extends MotionProps {
|
|
2402
|
+
visualElement: VisualElement;
|
|
2403
|
+
}
|
|
2404
|
+
declare type FeatureComponent = React.ComponentType<React.PropsWithChildren<FeatureProps>>;
|
|
2405
|
+
interface FeatureComponents {
|
|
2406
|
+
animation?: FeatureComponent;
|
|
2407
|
+
exit?: FeatureComponent;
|
|
2408
|
+
drag?: FeatureComponent;
|
|
2409
|
+
tap?: FeatureComponent;
|
|
2410
|
+
focus?: FeatureComponent;
|
|
2411
|
+
hover?: FeatureComponent;
|
|
2412
|
+
pan?: FeatureComponent;
|
|
2413
|
+
inView?: FeatureComponent;
|
|
2414
|
+
measureLayout?: FeatureComponent;
|
|
2415
|
+
}
|
|
2416
|
+
interface FeatureBundle extends FeatureComponents {
|
|
2417
|
+
renderer: CreateVisualElement<any>;
|
|
2418
|
+
projectionNodeConstructor?: any;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2387
2421
|
interface VisualElement<Instance = any, RenderState = any> extends LifecycleManager {
|
|
2388
2422
|
treeType: string;
|
|
2389
2423
|
depth: number;
|
|
@@ -2405,6 +2439,7 @@ interface VisualElement<Instance = any, RenderState = any> extends LifecycleMana
|
|
|
2405
2439
|
getClosestVariantNode(): VisualElement | undefined;
|
|
2406
2440
|
shouldReduceMotion?: boolean | null;
|
|
2407
2441
|
animateMotionValue?: typeof startAnimation;
|
|
2442
|
+
loadFeatures(props: MotionProps, isStrict?: boolean, preloadedFeatures?: FeatureBundle, projectionId?: number, ProjectionNodeConstructor?: any, initialPromotionConfig?: SwitchLayoutGroupContext): JSX.Element[];
|
|
2408
2443
|
projection?: IProjectionNode;
|
|
2409
2444
|
/**
|
|
2410
2445
|
* Visibility
|
|
@@ -2458,7 +2493,7 @@ declare type VisualElementOptions<Instance, RenderState = any> = {
|
|
|
2458
2493
|
presenceId?: string | undefined;
|
|
2459
2494
|
props: MotionProps;
|
|
2460
2495
|
blockInitialAnimation?: boolean;
|
|
2461
|
-
|
|
2496
|
+
reducedMotionConfig?: ReducedMotionConfig;
|
|
2462
2497
|
};
|
|
2463
2498
|
declare type CreateVisualElement<Instance> = (Component: string | React.ComponentType<React.PropsWithChildren<unknown>>, options: VisualElementOptions<Instance>) => VisualElement<Instance>;
|
|
2464
2499
|
/**
|
|
@@ -2468,25 +2503,6 @@ interface ResolvedValues {
|
|
|
2468
2503
|
[key: string]: string | number;
|
|
2469
2504
|
}
|
|
2470
2505
|
|
|
2471
|
-
/**
|
|
2472
|
-
* @public
|
|
2473
|
-
*/
|
|
2474
|
-
interface FeatureProps extends MotionProps {
|
|
2475
|
-
visualElement: VisualElement;
|
|
2476
|
-
}
|
|
2477
|
-
declare type FeatureComponent = React.ComponentType<React.PropsWithChildren<FeatureProps>>;
|
|
2478
|
-
interface FeatureComponents {
|
|
2479
|
-
animation?: FeatureComponent;
|
|
2480
|
-
exit?: FeatureComponent;
|
|
2481
|
-
drag?: FeatureComponent;
|
|
2482
|
-
tap?: FeatureComponent;
|
|
2483
|
-
focus?: FeatureComponent;
|
|
2484
|
-
hover?: FeatureComponent;
|
|
2485
|
-
pan?: FeatureComponent;
|
|
2486
|
-
inView?: FeatureComponent;
|
|
2487
|
-
measureLayout?: FeatureComponent;
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2490
2506
|
declare const animations: FeatureComponents;
|
|
2491
2507
|
|
|
2492
2508
|
declare function useVisualElementContext(): VisualElement<any, any> | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "framer-motion",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.1",
|
|
4
4
|
"description": "A simple and powerful React animation library",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/es/index.mjs",
|
|
@@ -71,30 +71,34 @@
|
|
|
71
71
|
"@emotion/is-prop-valid": "^0.8.2"
|
|
72
72
|
},
|
|
73
73
|
"bundlesize": [
|
|
74
|
+
{
|
|
75
|
+
"path": "./dist/size-rollup-motion.js",
|
|
76
|
+
"maxSize": "29.1 kB"
|
|
77
|
+
},
|
|
74
78
|
{
|
|
75
79
|
"path": "./dist/size-rollup-m.js",
|
|
76
|
-
"maxSize": "
|
|
80
|
+
"maxSize": "4.67 kB"
|
|
77
81
|
},
|
|
78
82
|
{
|
|
79
83
|
"path": "./dist/size-rollup-dom-animation.js",
|
|
80
|
-
"maxSize": "16.
|
|
84
|
+
"maxSize": "16.75 kB"
|
|
81
85
|
},
|
|
82
86
|
{
|
|
83
87
|
"path": "./dist/size-rollup-dom-max.js",
|
|
84
|
-
"maxSize": "27.
|
|
88
|
+
"maxSize": "27.2 kB"
|
|
85
89
|
},
|
|
86
90
|
{
|
|
87
91
|
"path": "./dist/size-webpack-m.js",
|
|
88
|
-
"maxSize": "
|
|
92
|
+
"maxSize": "4.9 kB"
|
|
89
93
|
},
|
|
90
94
|
{
|
|
91
95
|
"path": "./dist/size-webpack-dom-animation.js",
|
|
92
|
-
"maxSize": "19 kB"
|
|
96
|
+
"maxSize": "19.1 kB"
|
|
93
97
|
},
|
|
94
98
|
{
|
|
95
99
|
"path": "./dist/size-webpack-dom-max.js",
|
|
96
|
-
"maxSize": "30.
|
|
100
|
+
"maxSize": "30.15kB"
|
|
97
101
|
}
|
|
98
102
|
],
|
|
99
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "b5133f553afef699972b7838cad64763f0006989"
|
|
100
104
|
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useContext } from 'react';
|
|
3
|
-
import { env } from '../../utils/process.mjs';
|
|
4
|
-
import { featureDefinitions } from './definitions.mjs';
|
|
5
|
-
import { invariant } from 'hey-listen';
|
|
6
|
-
import { LazyContext } from '../../context/LazyContext.mjs';
|
|
7
|
-
|
|
8
|
-
const featureNames = Object.keys(featureDefinitions);
|
|
9
|
-
const numFeatures = featureNames.length;
|
|
10
|
-
/**
|
|
11
|
-
* Load features via renderless components based on the provided MotionProps.
|
|
12
|
-
*/
|
|
13
|
-
function useFeatures(props, visualElement, preloadedFeatures) {
|
|
14
|
-
const features = [];
|
|
15
|
-
const lazyContext = useContext(LazyContext);
|
|
16
|
-
if (!visualElement)
|
|
17
|
-
return null;
|
|
18
|
-
/**
|
|
19
|
-
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
20
|
-
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
21
|
-
*/
|
|
22
|
-
if (env !== "production" && preloadedFeatures && lazyContext.strict) {
|
|
23
|
-
invariant(false, "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.");
|
|
24
|
-
}
|
|
25
|
-
for (let i = 0; i < numFeatures; i++) {
|
|
26
|
-
const name = featureNames[i];
|
|
27
|
-
const { isEnabled, Component } = featureDefinitions[name];
|
|
28
|
-
/**
|
|
29
|
-
* It might be possible in the future to use this moment to
|
|
30
|
-
* dynamically request functionality. In initial tests this
|
|
31
|
-
* was producing a lot of duplication amongst bundles.
|
|
32
|
-
*/
|
|
33
|
-
if (isEnabled(props) && Component) {
|
|
34
|
-
features.push(React.createElement(Component, Object.assign({ key: name }, props, { visualElement: visualElement })));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return features;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export { useFeatures };
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { isRefObject } from '../../utils/is-ref-object.mjs';
|
|
2
|
-
import { useContext } from 'react';
|
|
3
|
-
import { SwitchLayoutGroupContext } from '../../context/SwitchLayoutGroupContext.mjs';
|
|
4
|
-
|
|
5
|
-
function useProjection(projectionId, { layoutId, layout, drag, dragConstraints, layoutScroll }, visualElement, ProjectionNodeConstructor) {
|
|
6
|
-
var _a;
|
|
7
|
-
const initialPromotionConfig = useContext(SwitchLayoutGroupContext);
|
|
8
|
-
if (!ProjectionNodeConstructor ||
|
|
9
|
-
!visualElement ||
|
|
10
|
-
(visualElement === null || visualElement === void 0 ? void 0 : visualElement.projection)) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
visualElement.projection = new ProjectionNodeConstructor(projectionId, visualElement.getLatestValues(), (_a = visualElement.parent) === null || _a === void 0 ? void 0 : _a.projection);
|
|
14
|
-
visualElement.projection.setOptions({
|
|
15
|
-
layoutId,
|
|
16
|
-
layout,
|
|
17
|
-
alwaysMeasureLayout: Boolean(drag) || (dragConstraints && isRefObject(dragConstraints)),
|
|
18
|
-
visualElement,
|
|
19
|
-
scheduleRender: () => visualElement.scheduleRender(),
|
|
20
|
-
/**
|
|
21
|
-
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
22
|
-
* to update by the time layout animations run.
|
|
23
|
-
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
24
|
-
* ensuring it gets called if there's no potential layout animations.
|
|
25
|
-
*
|
|
26
|
-
*/
|
|
27
|
-
animationType: typeof layout === "string" ? layout : "both",
|
|
28
|
-
initialPromotionConfig,
|
|
29
|
-
layoutScroll,
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export { useProjection };
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Decides if the supplied variable is an array of variant labels
|
|
3
|
-
*/
|
|
4
|
-
function isVariantLabels(v) {
|
|
5
|
-
return Array.isArray(v);
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Decides if the supplied variable is variant label
|
|
9
|
-
*/
|
|
10
|
-
function isVariantLabel(v) {
|
|
11
|
-
return typeof v === "string" || isVariantLabels(v);
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Creates an object containing the latest state of every MotionValue on a VisualElement
|
|
15
|
-
*/
|
|
16
|
-
function getCurrent(visualElement) {
|
|
17
|
-
const current = {};
|
|
18
|
-
visualElement.forEachValue((value, key) => (current[key] = value.get()));
|
|
19
|
-
return current;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Creates an object containing the latest velocity of every MotionValue on a VisualElement
|
|
23
|
-
*/
|
|
24
|
-
function getVelocity(visualElement) {
|
|
25
|
-
const velocity = {};
|
|
26
|
-
visualElement.forEachValue((value, key) => (velocity[key] = value.getVelocity()));
|
|
27
|
-
return velocity;
|
|
28
|
-
}
|
|
29
|
-
function resolveVariantFromProps(props, definition, custom, currentValues = {}, currentVelocity = {}) {
|
|
30
|
-
var _a;
|
|
31
|
-
/**
|
|
32
|
-
* If the variant definition is a function, resolve.
|
|
33
|
-
*/
|
|
34
|
-
if (typeof definition === "function") {
|
|
35
|
-
definition = definition(custom !== null && custom !== void 0 ? custom : props.custom, currentValues, currentVelocity);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* If the variant definition is a variant label, or
|
|
39
|
-
* the function returned a variant label, resolve.
|
|
40
|
-
*/
|
|
41
|
-
if (typeof definition === "string") {
|
|
42
|
-
definition = (_a = props.variants) === null || _a === void 0 ? void 0 : _a[definition];
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* At this point we've resolved both functions and variant labels,
|
|
46
|
-
* but the resolved variant label might itself have been a function.
|
|
47
|
-
* If so, resolve. This can only have returned a valid target object.
|
|
48
|
-
*/
|
|
49
|
-
if (typeof definition === "function") {
|
|
50
|
-
definition = definition(custom !== null && custom !== void 0 ? custom : props.custom, currentValues, currentVelocity);
|
|
51
|
-
}
|
|
52
|
-
return definition;
|
|
53
|
-
}
|
|
54
|
-
function resolveVariant(visualElement, definition, custom) {
|
|
55
|
-
const props = visualElement.getProps();
|
|
56
|
-
return resolveVariantFromProps(props, definition, custom !== null && custom !== void 0 ? custom : props.custom, getCurrent(visualElement), getVelocity(visualElement));
|
|
57
|
-
}
|
|
58
|
-
function checkIfControllingVariants(props) {
|
|
59
|
-
var _a;
|
|
60
|
-
return (typeof ((_a = props.animate) === null || _a === void 0 ? void 0 : _a.start) === "function" ||
|
|
61
|
-
isVariantLabel(props.initial) ||
|
|
62
|
-
isVariantLabel(props.animate) ||
|
|
63
|
-
isVariantLabel(props.whileHover) ||
|
|
64
|
-
isVariantLabel(props.whileDrag) ||
|
|
65
|
-
isVariantLabel(props.whileTap) ||
|
|
66
|
-
isVariantLabel(props.whileFocus) ||
|
|
67
|
-
isVariantLabel(props.exit));
|
|
68
|
-
}
|
|
69
|
-
function checkIfVariantNode(props) {
|
|
70
|
-
return Boolean(checkIfControllingVariants(props) || props.variants);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export { checkIfControllingVariants, checkIfVariantNode, isVariantLabel, isVariantLabels, resolveVariant, resolveVariantFromProps };
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { useState, useContext } from 'react';
|
|
2
|
-
import { MotionConfigContext } from '../context/MotionConfigContext.mjs';
|
|
3
|
-
import { isBrowser } from './is-browser.mjs';
|
|
4
|
-
|
|
5
|
-
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
6
|
-
const prefersReducedMotion = { current: null };
|
|
7
|
-
let hasDetected = false;
|
|
8
|
-
function initPrefersReducedMotion() {
|
|
9
|
-
hasDetected = true;
|
|
10
|
-
if (!isBrowser)
|
|
11
|
-
return;
|
|
12
|
-
if (window.matchMedia) {
|
|
13
|
-
const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
|
|
14
|
-
const setReducedMotionPreferences = () => (prefersReducedMotion.current = motionMediaQuery.matches);
|
|
15
|
-
motionMediaQuery.addListener(setReducedMotionPreferences);
|
|
16
|
-
setReducedMotionPreferences();
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
prefersReducedMotion.current = false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* A hook that returns `true` if we should be using reduced motion based on the current device's Reduced Motion setting.
|
|
24
|
-
*
|
|
25
|
-
* This can be used to implement changes to your UI based on Reduced Motion. For instance, replacing motion-sickness inducing
|
|
26
|
-
* `x`/`y` animations with `opacity`, disabling the autoplay of background videos, or turning off parallax motion.
|
|
27
|
-
*
|
|
28
|
-
* It will actively respond to changes and re-render your components with the latest setting.
|
|
29
|
-
*
|
|
30
|
-
* ```jsx
|
|
31
|
-
* export function Sidebar({ isOpen }) {
|
|
32
|
-
* const shouldReduceMotion = useReducedMotion()
|
|
33
|
-
* const closedX = shouldReduceMotion ? 0 : "-100%"
|
|
34
|
-
*
|
|
35
|
-
* return (
|
|
36
|
-
* <motion.div animate={{
|
|
37
|
-
* opacity: isOpen ? 1 : 0,
|
|
38
|
-
* x: isOpen ? 0 : closedX
|
|
39
|
-
* }} />
|
|
40
|
-
* )
|
|
41
|
-
* }
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @return boolean
|
|
45
|
-
*
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
function useReducedMotion() {
|
|
49
|
-
/**
|
|
50
|
-
* Lazy initialisation of prefersReducedMotion
|
|
51
|
-
*/
|
|
52
|
-
!hasDetected && initPrefersReducedMotion();
|
|
53
|
-
const [shouldReduceMotion] = useState(prefersReducedMotion.current);
|
|
54
|
-
/**
|
|
55
|
-
* TODO See if people miss automatically updating shouldReduceMotion setting
|
|
56
|
-
*/
|
|
57
|
-
return shouldReduceMotion;
|
|
58
|
-
}
|
|
59
|
-
function useReducedMotionConfig() {
|
|
60
|
-
const reducedMotionPreference = useReducedMotion();
|
|
61
|
-
const { reducedMotion } = useContext(MotionConfigContext);
|
|
62
|
-
if (reducedMotion === "never") {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
else if (reducedMotion === "always") {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
return reducedMotionPreference;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export { useReducedMotion, useReducedMotionConfig };
|