Stanko / react-animate-height

Lightweight React component for animating height using CSS transitions. Slide up/down the element, and animate it to any specific height.
https://muffinman.io/react-animate-height
MIT License
756 stars 53 forks source link

Provide a `disable` option to disable/reduce animation #124

Closed walopee closed 2 years ago

walopee commented 2 years ago

Expected behavior It would be nice to have the option to conditionally disable the animation for users who have their OS settings set to reduced or no animations

Your Environment

Additional context This would help fulfill an accessibility best practice by allowing users the option to avoid animations (https://www.w3.org/TR/WCAG21/#animation-from-interactions). I did just realize that this is also achievable by setting the duration to 0 when needed, though 😅

Stanko commented 2 years ago

Hey @walopee, that is a good point. I'll take a look this weekend.

For now you can add a simple workaround, by checking for (prefers-reduced-motion) using matchMedia:

Live demo: https://codesandbox.io/s/sleepy-panna-2ohhf1?file=/src/App.js

Code:

import { useState } from "react";
import AnimateHeight from "react-animate-height";

export default function App() {
  const [height, setHeight] = useState("auto");
  const reducedMotion = matchMedia("(prefers-reduced-motion)").matches;

  return (
    <div>
      <button onClick={() => setHeight(height === 0 ? "auto" : 0)}>
        Toggle
      </button>
      <AnimateHeight height={height} duration={reducedMotion ? 0 : 500}>
        <div
          style={{
            padding: "50px 20px",
            background: "#eee",
            border: "1px solid #ddd",
            marginTop: 20
          }}
        >
          Hello World
        </div>
      </AnimateHeight>
    </div>
  );
}
Stanko commented 2 years ago

Component now respects prefers-reduced-motion flag, published in 2.1.1:

https://github.com/Stanko/react-animate-height/commit/b7fd78d998f7c10c6786794a0a20df2b13e95aac#diff-af8ea84e12681096191e9bd85c5d016e492d25a9fd8baeedb117a0b6ee46f593

Cheers!

Bdragon93 commented 1 year ago

@Stanko is there any way to enable it? I'd like to force the application to keep the animation for all users even if they set reduce motion, would be great if there's an option as a prop to turn it on/off

Stanko commented 1 year ago

Hey @Bdragon93, You can just pass duration={0} and the animation will be disabled. If you want to control it, you can use a boolean parameter duration={ isDisabled ? 0 : 500 }

Cheers!

Bdragon93 commented 1 year ago

@Stanko unfortunately it doesn't work for me. even from your live demos and codesandbox example

Version used: 3.1.1 OS: MacOS 13.2.1, turning on "reduce motion" Browser: Chrome Browser Version: 112.0.5615.121

Stanko commented 1 year ago

Check this sandbox, it works for me: https://codesandbox.io/s/react-animate-height-v3-disable-animation-8ncjjv?file=%2Fsrc%2Findex.js

Bdragon93 commented 1 year ago

@Stanko I just tried on another Macbook and more browsers - safari/firefox, not work for all.

Bdragon93 commented 1 year ago

additionally, my devices use chip Apple M1, in case it's related

Stanko commented 1 year ago

If a user has "reduce motion" flag on, animation won't work, as that would breaks accessibility. I won't implement "force animation" prop.

It works as intended on Chrome, Firefox and Safari.

Here is video of Firefox and Chrome with the same sandbox I sent you earlier: https://codesandbox.io/s/react-animate-height-v3-disable-animation-8ncjjv?file=%2Fsrc%2Findex.js

https://user-images.githubusercontent.com/776788/232762505-822f7828-5ab8-4aa4-a4a1-8ebed0398d8e.mp4