Skip to content

Commit

Permalink
Merge pull request #24 from swup/feature/reduce-motion
Browse files Browse the repository at this point in the history
Feature: respect reduced-motion user preference
  • Loading branch information
daun authored Aug 20, 2023
2 parents 4145727 + c6f6893 commit 12b197c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ All options with their default values:
contentSelector: 'main',
headingSelector: 'h1, h2, [role=heading]',
announcementTemplate: 'Navigated to: {title}',
urlTemplate: 'New page at {url}'
urlTemplate: 'New page at {url}',
respectReducedMotion: false
}
```

Expand All @@ -107,3 +108,11 @@ How to announce the new page title.
How to announce the new page url.

Only used as fallback if neither a title tag nor a heading were found.

### respectReducedMotion

Whether to respects users' preference for reduced motion.

Disable animated page transitions and animated scrolling if a user has enabled a
setting on their device to minimize the amount of non-essential motion. Learn more about
[prefers-reduced-motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).
30 changes: 29 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Plugin from '@swup/plugin';
import OnDemandLiveRegion from 'on-demand-live-region';

import 'focus-options-polyfill';
import { Visit } from 'swup';

type Options = {
/** The selector for matching the main content area of the page. */
Expand All @@ -12,6 +13,8 @@ type Options = {
announcementTemplate: string;
/** How to announce the new page url. Used as fallback if no heading was found. */
urlTemplate: string;
/** Whether to skip animations for users that prefer reduced motion. */
respectReducedMotion: boolean;
};

export default class SwupA11yPlugin extends Plugin {
Expand All @@ -23,7 +26,8 @@ export default class SwupA11yPlugin extends Plugin {
contentSelector: 'main',
headingSelector: 'h1, h2, [role=heading]',
announcementTemplate: 'Navigated to: {title}',
urlTemplate: 'New page at {url}'
urlTemplate: 'New page at {url}',
respectReducedMotion: false
};

options: Options;
Expand All @@ -37,9 +41,20 @@ export default class SwupA11yPlugin extends Plugin {
}

mount() {
// Mark page as busy during transitions
this.on('visit:start', this.markAsBusy);
this.on('visit:end', this.unmarkAsBusy);

// Announce new page after content is replaced
this.on('content:replace', this.announceVisit);

// Disable transition and scroll animations if user prefers reduced motion
if (this.options.respectReducedMotion) {
this.before('visit:start', this.disableTransitionAnimations);
this.before('visit:start', this.disableScrollAnimations);
this.before('link:self', this.disableScrollAnimations);
this.before('link:anchor', this.disableScrollAnimations);
}
}

markAsBusy() {
Expand Down Expand Up @@ -90,4 +105,17 @@ export default class SwupA11yPlugin extends Plugin {
content.focus({ preventScroll: true });
}
}

disableTransitionAnimations(visit: Visit) {
visit.animation.animate = this.shouldAnimate();
}

disableScrollAnimations(visit: Visit) {
// @ts-ignore: animate property is not defined unless Scroll Plugin installed
visit.scroll.animate = this.shouldAnimate();
}

shouldAnimate(): boolean {
return !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}
}

0 comments on commit 12b197c

Please sign in to comment.