From f5ebdda126d237f2b8fd4c12659aa9c981dfeccc Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 12 May 2023 12:03:22 +0200 Subject: [PATCH] fix collapsible sidebar behavior when prefers-reduced-motion --- .../src/theme/DocRoot/Layout/Sidebar/index.tsx | 7 ++++++- .../src/components/Collapsible/index.tsx | 7 ++----- packages/docusaurus-theme-common/src/index.ts | 2 ++ .../src/utils/accessibilityUtils.ts | 10 ++++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 packages/docusaurus-theme-common/src/utils/accessibilityUtils.ts diff --git a/packages/docusaurus-theme-classic/src/theme/DocRoot/Layout/Sidebar/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocRoot/Layout/Sidebar/index.tsx index 573235f42e1e..36a50a58d92b 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocRoot/Layout/Sidebar/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocRoot/Layout/Sidebar/index.tsx @@ -7,7 +7,7 @@ import React, {type ReactNode, useState, useCallback} from 'react'; import clsx from 'clsx'; -import {ThemeClassNames} from '@docusaurus/theme-common'; +import {prefersReducedMotion, ThemeClassNames} from '@docusaurus/theme-common'; import {useDocsSidebar} from '@docusaurus/theme-common/internal'; import {useLocation} from '@docusaurus/router'; import DocSidebar from '@theme/DocSidebar'; @@ -40,6 +40,11 @@ export default function DocRootLayoutSidebar({ if (hiddenSidebar) { setHiddenSidebar(false); } + // onTransitionEnd won't fire when sidebar animation is disabled + // fixes https://github.com/facebook/docusaurus/issues/8918 + if (!hiddenSidebar && prefersReducedMotion()) { + setHiddenSidebar(true); + } setHiddenSidebarContainer((value) => !value); }, [setHiddenSidebarContainer, hiddenSidebar]); diff --git a/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx b/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx index 31c4f679e46b..4d5ee798c1e6 100644 --- a/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx +++ b/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx @@ -17,6 +17,7 @@ import React, { type ReactNode, } from 'react'; import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; +import {prefersReducedMotion} from '../../utils/accessibilityUtils'; const DefaultAnimationEasing = 'ease-in-out'; @@ -65,10 +66,6 @@ function applyCollapsedStyle(el: HTMLElement, collapsed: boolean) { el.style.height = collapsedStyles.height; } -function userPrefersReducedMotion(): boolean { - return window.matchMedia('(prefers-reduced-motion: reduce)').matches; -} - /* Lex111: Dynamic transition duration is used in Material design, this technique is good for a large number of items. @@ -76,7 +73,7 @@ https://material.io/archive/guidelines/motion/duration-easing.html#duration-easi https://github.com/mui-org/material-ui/blob/e724d98eba018e55e1a684236a2037e24bcf050c/packages/material-ui/src/styles/createTransitions.js#L40-L43 */ function getAutoHeightDuration(height: number) { - if (userPrefersReducedMotion()) { + if (prefersReducedMotion()) { // Not using 0 because it prevents onTransitionEnd to fire and bubble up :/ // See https://github.com/facebook/docusaurus/pull/8906 return 1; diff --git a/packages/docusaurus-theme-common/src/index.ts b/packages/docusaurus-theme-common/src/index.ts index 0d69d161aeaf..cf3a66c03aa6 100644 --- a/packages/docusaurus-theme-common/src/index.ts +++ b/packages/docusaurus-theme-common/src/index.ts @@ -45,6 +45,8 @@ export {useCollapsible, Collapsible} from './components/Collapsible'; export {ThemeClassNames} from './utils/ThemeClassNames'; +export {prefersReducedMotion} from './utils/accessibilityUtils'; + export { useIsomorphicLayoutEffect, useEvent, diff --git a/packages/docusaurus-theme-common/src/utils/accessibilityUtils.ts b/packages/docusaurus-theme-common/src/utils/accessibilityUtils.ts new file mode 100644 index 000000000000..f1cc1f54842b --- /dev/null +++ b/packages/docusaurus-theme-common/src/utils/accessibilityUtils.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export function prefersReducedMotion(): boolean { + return window.matchMedia('(prefers-reduced-motion: reduce)').matches; +}