From a41ae2928ea9301a6bda8ca5dbce835519777b99 Mon Sep 17 00:00:00 2001 From: Goutham Ponnada Date: Fri, 8 Nov 2024 11:24:52 -0800 Subject: [PATCH] feat(carousel): respect reduced-motion during autoplay (#2319) --- .changeset/plenty-tips-perform.md | 5 +++++ src/common/dom/index.ts | 14 ++++++++++++++ src/components/ebay-carousel/README.md | 4 ++++ src/components/ebay-carousel/component.ts | 6 ++++++ .../ebay-progress-bar-expressive/component.ts | 5 +---- .../ebay-progress-bar-expressive/index.marko | 2 +- 6 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 .changeset/plenty-tips-perform.md diff --git a/.changeset/plenty-tips-perform.md b/.changeset/plenty-tips-perform.md new file mode 100644 index 000000000..e3482bcad --- /dev/null +++ b/.changeset/plenty-tips-perform.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": minor +--- + +feat(carousel): respect reduced-motion during autoplay diff --git a/src/common/dom/index.ts b/src/common/dom/index.ts index 2e8b60709..a45ac11f0 100644 --- a/src/common/dom/index.ts +++ b/src/common/dom/index.ts @@ -14,3 +14,17 @@ export function getMaxWidth(el: HTMLElement) { el.style.width = width; return result; } + +/** + * Determines if the user has requested reduced motion in their system preferences. + * + * This function checks the `prefers-reduced-motion` media query to see if the user + * has indicated that they prefer reduced motion. This can be useful for improving + * accessibility by disabling animations or transitions for users who may be sensitive + * to motion. + * + * @returns {boolean} `true` if the user prefers reduced motion, `false` otherwise. + */ +export const useReducedMotion = + typeof window !== "undefined" && + window.matchMedia("(prefers-reduced-motion: reduce)").matches; diff --git a/src/components/ebay-carousel/README.md b/src/components/ebay-carousel/README.md index 1c7960a4e..063fb76c2 100644 --- a/src/components/ebay-carousel/README.md +++ b/src/components/ebay-carousel/README.md @@ -19,3 +19,7 @@ Descrete or Continuious carousel component. Can show items as a slide or various When scrolling items, focusable elements that are not visible in the carousel should not be tabbable by default. When the carousel scrolls, it then removes the tabindex to allow the item to be focusable. In order to preserve the tabindex on an item, pass `data-carousel-tabindex="-1"` attribute to a given focusable element in order to default to that tabindex instead of removing the tabindex when the item is visible. + +## Reduced motion + +The carousel doesnot autoplay by respecting the `prefers-reduced-motion` media query. Toggle your reduced motion settings to view autoplay example with the default behavior and reduced motion behavior. diff --git a/src/components/ebay-carousel/component.ts b/src/components/ebay-carousel/component.ts index 7a47c62ea..34073a561 100644 --- a/src/components/ebay-carousel/component.ts +++ b/src/components/ebay-carousel/component.ts @@ -6,6 +6,7 @@ import { processHtmlAttributes } from "../../common/html-attributes"; import { onScrollDebounced as onScroll } from "./utils/on-scroll-debounced"; import { scrollTransition } from "./utils/scroll-transition"; import type { WithNormalizedProps } from "../../global"; +import { useReducedMotion } from "../../common/dom"; type Direction = typeof LEFT | typeof RIGHT; // Used for carousel slide direction. @@ -517,6 +518,11 @@ class Carousel extends Marko.Component { }); this.skipScrolling = false; + // If user had reduced motion turned on in OS settings, pause autoplay. + if(useReducedMotion) { + this.state.paused = true; + } + if (isNativeScrolling(this.listEl)) { config.nativeScrolling = true; this.once( diff --git a/src/components/ebay-progress-bar-expressive/component.ts b/src/components/ebay-progress-bar-expressive/component.ts index 128a2dcaa..fa073c0ab 100644 --- a/src/components/ebay-progress-bar-expressive/component.ts +++ b/src/components/ebay-progress-bar-expressive/component.ts @@ -1,9 +1,6 @@ import { AttrString } from "marko/tags-html"; import type { WithNormalizedProps } from "../../global"; - -export const useReducedMotion = - typeof window !== "undefined" && - window.matchMedia("(prefers-reduced-motion: reduce)").matches; +import { useReducedMotion } from "../../common/dom"; export const messageDurationStandard = 1500; export const messageDurationReducedMotionMultiplier = 1.5; diff --git a/src/components/ebay-progress-bar-expressive/index.marko b/src/components/ebay-progress-bar-expressive/index.marko index 302533eb0..dfa68f7ea 100644 --- a/src/components/ebay-progress-bar-expressive/index.marko +++ b/src/components/ebay-progress-bar-expressive/index.marko @@ -1,5 +1,5 @@ import { processHtmlAttributes } from "../../common/html-attributes"; -import { useReducedMotion } from "./component"; +import { useReducedMotion } from "../../common/dom"; $ const { a11yText = "Loading...", class: inputClass,