Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
clvarley committed Dec 23, 2022
2 parents 7e89469 + 4757d2d commit 27381bb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,21 @@ expose more in the future.

| Property | Type | Purpose | Default |
| :------- | :--- | :------ | :------ |
| `duration` | [`number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) | Time (in milliseconds) the scroll animation should take | 0 |
| `duration` | [`number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) | Time (in milliseconds) the scroll animation should take<sup>[*](#caveats)</sup> | 0 |
| `padding` | [`number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) | Padding (in pixels) to be left above the element | 0 |
| `focus` | [`boolean`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) | Whether or not to focus the element after scroll | `false` |
| `timing` | [`function`](#timing) | Function used to control how the animation will be timed | [TIMING_EASE_IN_OUT](#ease-in-out) |

## Caveats

As standard `simpleScroll` respects the [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion)
setting. On systems where this flag has been enabled the `duration` and
`timing` options are silently ignored, with control instead being handled by the
default browser scrolling behaviour.

If you find your scroll animations aren't respecting the `duration` option this
may be why.

## Timing

By default, `simpleScroll` uses a [cubic ease-in-out](https://easings.net/#easeInOutCubic)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@clvarley/simple-scroll",
"version": "1.0.1",
"version": "1.1.0",
"description": "Simple utility to make scrolling elements into view easier.",
"type": "module",
"keywords": [
Expand Down
10 changes: 10 additions & 0 deletions src/a11y.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Determine whether or not the user has requested reduced motion
*
* @return {boolean} Reduced motion requested?
*/
const reducedMotion = () => {
return window.matchMedia("(prefers-reduced-motion)").matches;
};

export { reducedMotion };
25 changes: 23 additions & 2 deletions src/scroll.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { getDocumentYOffset } from "./position";
import { reducedMotion } from "./a11y";
import { TIMING_EASE_IN_OUT } from "./timing";

/**
* Wrapper to provide `scrollTo` fallback for older browsers
* Wrapper to allow use of the `behavior: smooth` option on supporting browsers
*
* @internal
* @param {ScrollToOptions} options Scroll options
Expand All @@ -15,12 +16,27 @@ const tryScroll = (options) => {
}
};

/**
* Wrapper to allow use of the `preventScroll` option on supporting browsers
*
* @internal
* @param {HTMLElement} element Target element
*/
const tryFocus = (element) => {
try {
element.focus({ preventScroll: true });
} catch (e) {
element.focus();
}
};

/**
* Available options used to control softScroll behaviour
*
* @typedef {Object} Options
* @property {?number} padding Buffer above element (in pixels)
* @property {?number} duration Scroll duration (in milliseconds)
* @property {?boolean} focus Move focus to element after scroll
* @property {?easingFunction} timing Easing function
*/

Expand Down Expand Up @@ -63,14 +79,19 @@ const animateScroll = (target, duration, timing) => {
const simpleScroll = (target, options) => {
const padding = (options && options.padding) || 0;
const duration = (options && options.duration) || 0;
const focus = (options && options.focus);
const timing = (options && options.timing) || TIMING_EASE_IN_OUT;
const target_y = getDocumentYOffset(target) - padding;

if (!duration) {
if (!duration || reducedMotion()) {
tryScroll({ top: target_y, left: 0, behavior: "smooth" });
} else {
animateScroll(target_y, duration, timing);
}

if (focus) {
tryFocus(target);
}
};

export { simpleScroll };

0 comments on commit 27381bb

Please sign in to comment.