From 40da80327705b265d0bb9e2051eab7eaeee4682b Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Sat, 26 Aug 2023 01:34:20 +0200 Subject: [PATCH 1/2] feat: create useReducedMotion and apply to useMotion to skip all motion calculations (cherry picked from commit d2dca9db66d6a9ce0a3916e0ff6fb86474e2e874) --- .../react-motion-preview/package.json | 1 + .../src/hooks/useMotion.ts | 4 ++- .../src/hooks/useReducedMotion.ts | 36 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 packages/react-components/react-motion-preview/src/hooks/useReducedMotion.ts diff --git a/packages/react-components/react-motion-preview/package.json b/packages/react-components/react-motion-preview/package.json index f3c2b26c334041..9bc8fb3e5c8df1 100644 --- a/packages/react-components/react-motion-preview/package.json +++ b/packages/react-components/react-motion-preview/package.json @@ -31,6 +31,7 @@ }, "dependencies": { "@fluentui/react-jsx-runtime": "^9.0.3", + "@fluentui/react-shared-contexts": "^9.7.2", "@fluentui/react-theme": "^9.1.11", "@fluentui/react-utilities": "^9.13.0", "@griffel/react": "^1.5.14", diff --git a/packages/react-components/react-motion-preview/src/hooks/useMotion.ts b/packages/react-components/react-motion-preview/src/hooks/useMotion.ts index 49237bfa9f9ac9..4dc082f7a2a373 100644 --- a/packages/react-components/react-motion-preview/src/hooks/useMotion.ts +++ b/packages/react-components/react-motion-preview/src/hooks/useMotion.ts @@ -1,6 +1,7 @@ import * as React from 'react'; import { useAnimationFrame, useTimeout, usePrevious, useFirstMount } from '@fluentui/react-utilities'; +import { useReducedMotion } from './useReducedMotion'; import { getMotionDuration } from '../utils/dom-style'; import type { HTMLElementWithStyledMap } from '../utils/dom-style'; @@ -92,10 +93,11 @@ function useMotionPresence( const [currentElement, setCurrentElement] = React.useState | null>(null); + const isReducedMotion = useReducedMotion(); const isFirstReactRender = useFirstMount(); const isFirstDOMRender = useFirstMountCondition(!!currentElement); const isInitiallyPresent = React.useRef(presence).current; - const disableAnimation = isFirstDOMRender && isInitiallyPresent && !animateOnFirstMount; + const disableAnimation = isReducedMotion || (isFirstDOMRender && isInitiallyPresent && !animateOnFirstMount); const ref: React.RefCallback> = React.useCallback(node => { if (!node) { diff --git a/packages/react-components/react-motion-preview/src/hooks/useReducedMotion.ts b/packages/react-components/react-motion-preview/src/hooks/useReducedMotion.ts new file mode 100644 index 00000000000000..b192dc51291a8a --- /dev/null +++ b/packages/react-components/react-motion-preview/src/hooks/useReducedMotion.ts @@ -0,0 +1,36 @@ +import * as React from 'react'; +import { canUseDOM, useIsomorphicLayoutEffect } from '@fluentui/react-utilities'; +import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; + +/** + * @internal + * + * Returns whether the user has requested reduced motion based on the current media query. + */ +export const useReducedMotion = (): boolean => { + const fluent = useFluent(); + const reducedMotion = React.useRef(false); + const targetWindow = canUseDOM() && fluent.targetDocument?.defaultView; + + const onMediaQueryChange = React.useCallback((e: MediaQueryListEvent) => { + reducedMotion.current = e.matches; + }, []); + + useIsomorphicLayoutEffect(() => { + if (!targetWindow || !targetWindow.matchMedia) { + return; + } + + const match = targetWindow.matchMedia('screen and (prefers-reduced-motion: reduce)'); + + if (match.matches) { + reducedMotion.current = true; + } + + match.addEventListener('change', onMediaQueryChange); + + return () => match.removeEventListener('change', onMediaQueryChange); + }, [onMediaQueryChange, targetWindow]); + + return reducedMotion.current; +}; From 1539d03c127fdd83d98a31510226d9d6925b4f14 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Tue, 29 Aug 2023 15:42:19 +0200 Subject: [PATCH 2/2] fix: add missing changefiles --- ...otion-preview-636e24db-8a0b-4116-99d1-001f7103748d.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-motion-preview-636e24db-8a0b-4116-99d1-001f7103748d.json diff --git a/change/@fluentui-react-motion-preview-636e24db-8a0b-4116-99d1-001f7103748d.json b/change/@fluentui-react-motion-preview-636e24db-8a0b-4116-99d1-001f7103748d.json new file mode 100644 index 00000000000000..f4e4cae8eb0fac --- /dev/null +++ b/change/@fluentui-react-motion-preview-636e24db-8a0b-4116-99d1-001f7103748d.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: create useReducedMotion and apply to useMotion to skip all motion calculations", + "packageName": "@fluentui/react-motion-preview", + "email": "marcosvmmoura@gmail.com", + "dependentChangeType": "patch" +}