reshaped 3.10.2 → 3.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,13 +5,14 @@ import { classNames } from "@reshaped/headless";
5
5
  import React from "react";
6
6
  import Portal from "../_private/Portal/index.js";
7
7
  import useIsDismissible from "../../hooks/_private/useIsDismissible.js";
8
- import { onNextFrame } from "../../utilities/animation.js";
8
+ import { checkTransitions, onNextFrame } from "../../utilities/animation.js";
9
9
  import s from "./Overlay.module.css";
10
10
  const Overlay = (props) => {
11
11
  const { active, children, transparent, blurred, overflow, onClose, onOpen, onAfterClose, onAfterOpen, disableCloseOnClick, containerRef, contained, className, attributes, } = props;
12
12
  // Selectors wrapped with refs to simplify working with useEffect dependency array
13
13
  const onCloseRef = useHandlerRef(onClose);
14
14
  const onOpenRef = useHandlerRef(onOpen);
15
+ const onAfterCloseRef = useHandlerRef(onAfterClose);
15
16
  const isTransparent = transparent === true;
16
17
  const opacity = isTransparent ? 0 : (1 - (transparent || 0)) * 0.7;
17
18
  const [mounted, setMounted] = React.useState(false);
@@ -74,21 +75,28 @@ const Overlay = (props) => {
74
75
  Escape: () => close({ reason: "escape-key" }),
75
76
  }, [close]);
76
77
  React.useEffect(() => {
77
- setAnimated(true);
78
+ const hasTransitions = checkTransitions();
79
+ if (hasTransitions)
80
+ setAnimated(true);
78
81
  if (active && !rendered)
79
82
  render();
80
- if (!active && rendered)
83
+ if (!active && rendered) {
84
+ if (!hasTransitions) {
85
+ unlockScroll();
86
+ remove();
87
+ onAfterCloseRef.current?.();
88
+ return;
89
+ }
81
90
  hide();
82
- }, [active, render, hide, rendered]);
91
+ }
92
+ }, [active, render, hide, rendered, remove, unlockScroll, onAfterCloseRef]);
83
93
  // Show overlay after it was rendered
84
94
  React.useEffect(() => {
85
95
  if (!rendered)
86
96
  return;
87
97
  if (!isTransparent)
88
98
  lockScroll();
89
- onNextFrame(() => {
90
- show();
91
- });
99
+ onNextFrame(() => show());
92
100
  }, [rendered, show, lockScroll, isTransparent]);
93
101
  React.useEffect(() => {
94
102
  if (!rendered || !contentRef.current)
@@ -7,6 +7,7 @@ import Icon from "../Icon/index.js";
7
7
  import useFadeSide from "../../hooks/_private/useFadeSide.js";
8
8
  import IconChevronLeft from "../../icons/ChevronLeft.js";
9
9
  import IconChevronRight from "../../icons/ChevronRight.js";
10
+ import { checkTransitions } from "../../utilities/animation.js";
10
11
  import s from "./Tabs.module.css";
11
12
  import { useTabs } from "./TabsContext.js";
12
13
  import TabsItem from "./TabsItem.js";
@@ -88,7 +89,7 @@ const TabsList = (props) => {
88
89
  const selectionStyle = getElementSelectionStyle(elActiveRef.current);
89
90
  if (!selectionStyle)
90
91
  return;
91
- setSelection({ ...selectionStyle, status: "animated" });
92
+ setSelection({ ...selectionStyle, status: checkTransitions() ? "animated" : "idle" });
92
93
  }, [selection]);
93
94
  return (_jsxs("div", { ...attributes, className: rootClassNames, children: [_jsx("div", { className: s.inner, ref: elScrollableRef, children: _jsxs("div", { className: s.list, role: "tablist", children: [React.Children.map(children, (child, index) => {
94
95
  if (!React.isValidElement(child))
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { TrapFocus, classNames } from "@reshaped/headless";
4
4
  import { checkKeyboardMode } from "@reshaped/headless/internal";
5
5
  import React from "react";
6
- import { onNextFrame } from "../../utilities/animation.js";
6
+ import { checkTransitions, onNextFrame } from "../../utilities/animation.js";
7
7
  import Toast from "./Toast.js";
8
8
  import { timeouts } from "./Toast.constants.js";
9
9
  import ToastContext from "./Toast.context.js";
@@ -29,9 +29,13 @@ const ToastContainer = (props) => {
29
29
  if (timeout === 0)
30
30
  return;
31
31
  timeoutRef.current = setTimeout(() => {
32
+ if (!checkTransitions()) {
33
+ remove(id);
34
+ return;
35
+ }
32
36
  hide(id);
33
37
  }, timeoutValue ?? timeouts.short);
34
- }, [hide, id, timeout, stopTimer]);
38
+ }, [hide, id, remove, timeout, stopTimer]);
35
39
  const handleTransitionEnd = (e) => {
36
40
  if (e.propertyName !== "height")
37
41
  return;
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useIsomorphicLayoutEffect } from "@reshaped/headless";
4
4
  import { classNames } from "@reshaped/headless";
5
5
  import React from "react";
6
- import { onNextFrame } from "../../../utilities/animation.js";
6
+ import { checkTransitions, onNextFrame } from "../../../utilities/animation.js";
7
7
  import s from "./Expandable.module.css";
8
8
  const Expandable = (props) => {
9
9
  const { children, active, attributes } = props;
@@ -27,6 +27,10 @@ const Expandable = (props) => {
27
27
  const rootEl = rootRef.current;
28
28
  if (!rootEl || !mountedRef.current)
29
29
  return;
30
+ if (!checkTransitions()) {
31
+ setAnimatedHeight(active ? "auto" : null);
32
+ return;
33
+ }
30
34
  if (active) {
31
35
  rootEl.style.height = "auto";
32
36
  requestAnimationFrame(() => {
@@ -4,6 +4,7 @@ export const onNextFrame = (cb) => {
4
4
  });
5
5
  };
6
6
  const transitionAttribute = "data-rs-no-transition";
7
+ const reducedMotionMediaQuery = "(prefers-reduced-motion: reduce)";
7
8
  export const disableTransitions = () => {
8
9
  document.documentElement.setAttribute(transitionAttribute, "true");
9
10
  };
@@ -13,7 +14,7 @@ export const enableTransitions = () => {
13
14
  export const checkTransitions = () => {
14
15
  if (document.documentElement.hasAttribute(transitionAttribute))
15
16
  return false;
16
- if (window.matchMedia("(prefers-reduced-motion: reduce)").matches)
17
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function")
17
18
  return false;
18
- return true;
19
+ return !window.matchMedia(reducedMotionMediaQuery).matches;
19
20
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reshaped",
3
3
  "description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
4
- "version": "3.10.2",
4
+ "version": "3.10.3",
5
5
  "license": "MIT",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",
@@ -92,7 +92,7 @@
92
92
  "csstype": "3.2.3",
93
93
  "culori": "4.0.2",
94
94
  "postcss-custom-media": "12.0.1",
95
- "@reshaped/headless": "3.10.2"
95
+ "@reshaped/headless": "3.10.3"
96
96
  },
97
97
  "scripts": {
98
98
  "clean": "bash ./bin/clean.sh",