From 205c45f43956088a1e73bba104ea7f576872eba5 Mon Sep 17 00:00:00 2001 From: Rami Yushuvaev Date: Sun, 23 Nov 2025 18:46:55 +0200 Subject: [PATCH] feat(a11y): respect reduced-motion preferences --- examples/demo-react/src/App.css | 20 +++++ packages/docsearch-css/src/button.css | 12 +-- packages/docsearch-css/src/modal.css | 82 +++++++++++++------ packages/website/src/components/ui/button.jsx | 4 +- packages/website/src/components/ui/logos.jsx | 2 +- packages/website/src/css/custom.css | 18 ++++ 6 files changed, 104 insertions(+), 34 deletions(-) diff --git a/examples/demo-react/src/App.css b/examples/demo-react/src/App.css index 3a4e05522..19c10f03a 100644 --- a/examples/demo-react/src/App.css +++ b/examples/demo-react/src/App.css @@ -125,6 +125,12 @@ main { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05) !important; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-Button { + transition-duration: 0; + } +} + .DocSearch-Button:hover { border-color: #667eea !important; box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15) !important; @@ -148,6 +154,20 @@ main { animation-delay: 0.2s; } +@media (prefers-reduced-motion: reduce) { + .demo-section { + animation-duration: 0; + } + + .demo-section:nth-child(2) { + animation-delay: 0; + } + + .demo-section:nth-child(3) { + animation-delay: 0; + } +} + @keyframes fadeInUp { from { opacity: 0; diff --git a/packages/docsearch-css/src/button.css b/packages/docsearch-css/src/button.css index 186dd9ed7..6c041735f 100644 --- a/packages/docsearch-css/src/button.css +++ b/packages/docsearch-css/src/button.css @@ -67,6 +67,12 @@ border-radius: 4px; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-Button-Key { + transition-duration: 0; + } +} + .DocSearch-Button-Key--ctrl { width: 33px; } @@ -75,12 +81,6 @@ margin-inline-end: 0.4em; } -@media (prefers-reduced-motion) { - .DocSearch-Button-Key { - transition: none; - } -} - .DocSearch-Button-Key--pressed { transform: translateY(1px); box-shadow: var(--docsearch-key-pressed-shadow) !important; diff --git a/packages/docsearch-css/src/modal.css b/packages/docsearch-css/src/modal.css index 8b0bf53cc..46e564d78 100644 --- a/packages/docsearch-css/src/modal.css +++ b/packages/docsearch-css/src/modal.css @@ -165,20 +165,6 @@ justify-content: center; } -@media screen and (prefers-reduced-motion: reduce) { - .DocSearch-Action { - animation: none; - appearance: none; - background: none; - border: 0; - border-radius: 50%; - color: var(--docsearch-icon-color); - cursor: pointer; - inset-inline-end: 0; - stroke-width: var(--docsearch-icon-stroke-width); - } -} - .DocSearch-Action, .DocSearch-AskAi-Return { animation: fade-in 0.1s ease-in forwards; @@ -193,6 +179,13 @@ stroke-width: var(--docsearch-icon-stroke-width); } +@media (prefers-reduced-motion: reduce) { + .DocSearch-Action, + .DocSearch-AskAi-Return { + animation-duration: 0; + } +} + .DocSearch-Close[hidden], .DocSearch-StreamingIndicator[hidden], .DocSearch-AskAi-Return[hidden], @@ -463,11 +456,10 @@ svg.DocSearch-Hit-Select-Icon { display: block; } -@media screen and (prefers-reduced-motion: reduce) { +@media (prefers-reduced-motion: reduce) { .DocSearch-Hit-action-button:hover, .DocSearch-Hit-action-button:focus { - background: rgba(0, 0, 0, 0.2); - transition: none; + transition-duration: 0; } } @@ -519,14 +511,6 @@ svg.DocSearch-Hit-Select-Icon { color: var(--docsearch-highlight-color); } -@media screen and (prefers-reduced-motion: reduce) { - .DocSearch-Hit-action-button:hover, - .DocSearch-Hit-action-button:focus { - background: rgba(0, 0, 0, 0.2); - transition: none; - } -} - /* No Results - Start Screen - Error Screen */ .DocSearch-NoResults, @@ -855,6 +839,12 @@ assistive tech users */ border-radius: 4px; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-AskAiScreen-ActionButton { + transition-duration: 0; + } +} + .DocSearch-AskAiScreen-ActionButton:hover { background: var(--docsearch-hit-highlight-color); } @@ -917,6 +907,12 @@ assistive tech users */ animation: fade-in 0.3s ease-in forwards; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-AskAiScreen-FeedbackText--visible { + animation-duration: 0; + } +} + .DocSearch-AskAiScreen-RelatedSources { display: flex; flex-direction: column; @@ -968,6 +964,12 @@ assistive tech users */ transition: background-color 0.2s ease; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-AskAiScreen-RelatedSources-Item-Link { + transition-duration: 0; + } +} + .DocSearch-AskAiScreen-RelatedSources-Item-Link svg { flex-shrink: 0; color: var(--docsearch-icon-color); @@ -1005,6 +1007,12 @@ assistive tech users */ animation: fade-in 0.3s ease-in-out both; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-Markdown-Content--streaming { + animation-duration: 0; + } +} + .DocSearch-Markdown-Content p { margin: 1em 0; } @@ -1127,6 +1135,12 @@ assistive tech users */ transition: all 0.2s ease; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-Markdown-Content a { + transition-duration: 0; + } +} + .DocSearch-Markdown-Content a:hover { text-decoration: underline; opacity: 0.9; @@ -1199,6 +1213,12 @@ assistive tech users */ transition: box-shadow 0.2s ease; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-AskAiScreen-MessageContent-Tool-Query { + transition-duration: 0; + } +} + .DocSearch-AskAiScreen-MessageContent-Tool-Query svg { color: var(--docsearch-muted-color); } @@ -1236,6 +1256,12 @@ assistive tech users */ pointer-events: none; } +@media (prefers-reduced-motion: reduce) { + .shimmer { + animation-duration: 0; + } +} + @keyframes shimmerText { 0% { background-position: 200% 0; @@ -1362,6 +1388,12 @@ assistive tech users */ align-items: center; } +@media (prefers-reduced-motion: reduce) { + .DocSearch-CodeSnippet-CopyButton { + transition-duration: 0; + } +} + .DocSearch-CodeSnippet-CopyButton:hover { opacity: 0.8; } diff --git a/packages/website/src/components/ui/button.jsx b/packages/website/src/components/ui/button.jsx index 568c6e8c1..f1ffee96e 100644 --- a/packages/website/src/components/ui/button.jsx +++ b/packages/website/src/components/ui/button.jsx @@ -7,7 +7,7 @@ export const Button = ({ children, href, className = '', ...props }) => { {children} @@ -21,7 +21,7 @@ export const PrimaryButton = ({ children, href, className = '', ...props }) => { {children} diff --git a/packages/website/src/components/ui/logos.jsx b/packages/website/src/components/ui/logos.jsx index c9f718317..554843ba1 100644 --- a/packages/website/src/components/ui/logos.jsx +++ b/packages/website/src/components/ui/logos.jsx @@ -49,7 +49,7 @@ export const Logos = () => { href={href} target="_blank" rel="noopener noreferrer" - className="bg-gray-400/7 dark:bg-xenon-900 p-6 sm:p-10 flex flex-col items-center justify-center transition-all duration-200 cursor-pointer inset-shadow-none hover:inset-shadow-sm hover:bg-blue-400/40 !no-underline" + className="bg-gray-400/7 dark:bg-xenon-900 p-6 sm:p-10 flex flex-col items-center justify-center transition-all duration-200 motion-reduce:duration-0 cursor-pointer inset-shadow-none hover:inset-shadow-sm hover:bg-blue-400/40 !no-underline" > {alt} {alt} diff --git a/packages/website/src/css/custom.css b/packages/website/src/css/custom.css index 1c836b7b3..804ecb9d4 100644 --- a/packages/website/src/css/custom.css +++ b/packages/website/src/css/custom.css @@ -313,6 +313,12 @@ html[data-theme='dark'] .docusaurus-highlight-code-line { transition: all 0.2s ease-in-out; } +@media (prefers-reduced-motion: reduce) { + .theme-announcement-bar a { + transition-duration: 0; + } +} + .theme-announcement-bar a:hover { background-color: var(--ifm-color-primary); color: #fff; @@ -590,6 +596,12 @@ html[data-theme='dark'] .header-github-link::before { transition: translate 0.12s ease-out; } +@media (prefers-reduced-motion: reduce) { + .key__content { + transition-duration: 0; + } +} + .key__text { font-family: 'Inter', sans-serif; -webkit-font-smoothing: antialiased; @@ -707,6 +719,12 @@ html[data-theme='dark'] .shimmer-effect { animation: shimmer 2s infinite linear; } +@media (prefers-reduced-motion: reduce) { + .shimmer-effect { + animation-duration: 0; + } +} + @keyframes shimmer { 0% { background-position: 200% 0;