reshaped 2.7.0 → 2.7.2

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.
@@ -7,7 +7,8 @@ import Overlay from "../Overlay/index.js";
7
7
  import useElementId from "../../hooks/useElementId.js";
8
8
  import s from "./Modal.module.css";
9
9
  import getPaddingStyles from "../../styles/padding/index.js";
10
- const DRAG_THRESHOLD = 16;
10
+ const DRAG_THRESHOLD = 32;
11
+ const DRAG_OPPOSITE_THRESHOLD = 100;
11
12
  const DRAG_EDGE_BOUNDARY = 32;
12
13
  const Context = React.createContext({
13
14
  id: "",
@@ -43,7 +44,8 @@ const Modal = (props) => {
43
44
  const [subtitleMounted, setSubtitleMounted] = React.useState(false);
44
45
  const [dragging, setDragging] = React.useState(false);
45
46
  const rootRef = React.useRef(null);
46
- const dragClientCoordinatesRef = React.useRef(0);
47
+ const dragStartCoordinatesRef = React.useRef({ x: 0, y: 0 });
48
+ const dragLastCoordinateRef = React.useRef(0);
47
49
  const dragDistanceRef = React.useRef(0);
48
50
  const dragDirectionRef = React.useRef(0);
49
51
  const [dragDistance, setDragDistance] = React.useState(0);
@@ -57,10 +59,10 @@ const Modal = (props) => {
57
59
  id,
58
60
  }), [id, subtitleMounted, titleMounted]);
59
61
  const resetDragData = () => {
62
+ dragStartCoordinatesRef.current = { x: 0, y: 0 };
63
+ dragLastCoordinateRef.current = 0;
60
64
  dragDirectionRef.current = 0;
61
- dragClientCoordinatesRef.current = 0;
62
65
  setDragDistance(0);
63
- setHideProgress(0);
64
66
  };
65
67
  const handleDragStart = (e) => {
66
68
  const el = e.target;
@@ -92,9 +94,7 @@ const Modal = (props) => {
92
94
  setDragging(false);
93
95
  // Close only when dragging in the closing direction
94
96
  // Changing to a different direction will keep the modal opened
95
- const shouldClose = clientPosition && ["bottom", "end"].includes(clientPosition)
96
- ? dragDirectionRef.current > 0
97
- : dragDirectionRef.current < 0;
97
+ const shouldClose = clientPosition === "start" ? dragDirectionRef.current < 0 : dragDirectionRef.current > 0;
98
98
  if (Math.abs(dragDistanceRef.current) > DRAG_THRESHOLD && shouldClose) {
99
99
  onClose === null || onClose === void 0 ? void 0 : onClose();
100
100
  }
@@ -105,18 +105,29 @@ const Modal = (props) => {
105
105
  const handleDrag = (e) => {
106
106
  if (!dragging || clientPosition === "center")
107
107
  return;
108
- const prev = dragClientCoordinatesRef.current;
109
108
  const target = e.targetTouches[0];
110
- dragClientCoordinatesRef.current =
111
- clientPosition === "bottom" ? target.clientY : target.clientX;
112
- if (!prev)
109
+ const coordinate = { x: target.clientX, y: target.clientY };
110
+ const key = clientPosition === "bottom" ? "y" : "x";
111
+ const oppositeKey = clientPosition === "bottom" ? "x" : "y";
112
+ // Save the initial coordinates
113
+ if (!dragStartCoordinatesRef.current[key]) {
114
+ dragStartCoordinatesRef.current = coordinate;
115
+ dragLastCoordinateRef.current = coordinate[key];
116
+ }
117
+ const next = Math.abs(coordinate[key] - dragStartCoordinatesRef.current[key]);
118
+ const nextOpposite = Math.abs(coordinate[oppositeKey] - dragStartCoordinatesRef.current[oppositeKey]);
119
+ // For start/end drawers - ignore the swiping
120
+ // If user is scrolling vertically more than swiping
121
+ if (position !== "bottom" &&
122
+ (next < nextOpposite || nextOpposite > DRAG_OPPOSITE_THRESHOLD)) {
123
+ dragLastCoordinateRef.current = coordinate[key];
113
124
  return;
114
- const delta = dragClientCoordinatesRef.current - prev;
115
- dragDirectionRef.current = delta < 0 ? -1 : 1;
116
- setDragDistance((prev) => {
117
- const next = prev + delta;
118
- return clientPosition === "start" ? Math.min(0, next) : Math.max(0, next);
119
- });
125
+ }
126
+ dragDirectionRef.current = coordinate[key] - dragLastCoordinateRef.current;
127
+ dragLastCoordinateRef.current = coordinate[key];
128
+ setDragDistance((prev) => clientPosition === "start"
129
+ ? Math.min(0, prev + dragDirectionRef.current)
130
+ : Math.max(0, prev + dragDirectionRef.current));
120
131
  };
121
132
  document.addEventListener("touchmove", handleDrag);
122
133
  document.addEventListener("touchend", handleDragEnd);
@@ -134,15 +145,17 @@ const Modal = (props) => {
134
145
  const isInline = ["start", "end"].includes(clientPosition);
135
146
  const size = isInline ? rootEl.clientWidth : rootEl.clientHeight;
136
147
  const progress = Math.abs(dragDistance) / size;
137
- dragDistanceRef.current = dragDistance;
138
148
  setHideProgress(progress / 2);
149
+ dragDistanceRef.current = dragDistance;
139
150
  }, [dragDistance, clientPosition]);
140
- return (React.createElement(Overlay, { onClose: onClose, active: active, transparent: transparentOverlay || hideProgress }, ({ active }) => {
151
+ return (React.createElement(Overlay, { onClose: onClose, active: active, transparent: transparentOverlay || hideProgress, attributes: {
152
+ onTouchStart: handleDragStart,
153
+ } }, ({ active }) => {
141
154
  const rootClassNames = classNames(s.root, className, paddingStyles === null || paddingStyles === void 0 ? void 0 : paddingStyles.classNames, active && s["--active"], dragging && s["--dragging"], responsiveClassNames(s, "--position", position));
142
155
  return (React.createElement(Context.Provider, { value: value },
143
156
  React.createElement("div", Object.assign({}, attributes, { style: Object.assign(Object.assign(Object.assign({}, paddingStyles === null || paddingStyles === void 0 ? void 0 : paddingStyles.variables), responsiveVariables("--rs-modal-size", size)), { "--rs-modal-drag": Math.abs(dragDistance) < DRAG_THRESHOLD
144
157
  ? "0px"
145
- : `${dragDistance + DRAG_THRESHOLD * (clientPosition === "start" ? 1 : -1)}px` }), "aria-labelledby": titleMounted ? `${id}-title` : undefined, "aria-describedby": subtitleMounted ? `${id}-subtitle` : undefined, className: rootClassNames, "aria-modal": "true", role: "dialog", onTouchStart: handleDragStart, onTransitionEnd: handleTransitionEnd, ref: rootRef }), children)));
158
+ : `${dragDistance + DRAG_THRESHOLD * (clientPosition === "start" ? 1 : -1)}px` }), "aria-labelledby": titleMounted ? `${id}-title` : undefined, "aria-describedby": subtitleMounted ? `${id}-subtitle` : undefined, className: rootClassNames, "aria-modal": "true", role: "dialog", ref: rootRef, onTransitionEnd: handleTransitionEnd }), children)));
146
159
  }));
147
160
  };
148
161
  Modal.Title = ModalTitle;
@@ -61,7 +61,7 @@ const Overlay = (props) => {
61
61
  close();
62
62
  };
63
63
  const handleTransitionEnd = (e) => {
64
- if (e.propertyName !== "opacity" || !e.pseudoElement)
64
+ if (e.propertyName !== "transform" || !e.pseudoElement)
65
65
  return;
66
66
  setAnimated(false);
67
67
  if (visible)
@@ -84,7 +84,9 @@ const Overlay = (props) => {
84
84
  return;
85
85
  if (!clickThrough)
86
86
  lockScroll();
87
- onNextFrame(() => show());
87
+ onNextFrame(() => {
88
+ show();
89
+ });
88
90
  }, [rendered, show, lockScroll, clickThrough]);
89
91
  React.useEffect(() => {
90
92
  if (!rendered)
@@ -1 +1 @@
1
- .root{-webkit-overflow-scrolling:touch;color:var(--rs-color-white);overflow:auto;z-index:var(--rs-z-index-overlay)}.root,.root:after{inset:0;position:fixed}.root:after{background:var(--rs-color-black);content:"";opacity:0}.wrapper{display:table;height:100%;width:100%}.inner{display:table-cell;text-align:center}.content,.inner{vertical-align:middle}.content{display:inline-block;position:relative;text-align:initial;z-index:var(--rs-z-index-raised)}.root.--visible:after{opacity:var(--rs-overlay-opacity)}.root.--click-through{color:inherit;pointer-events:none}.root.--click-through .content,.root.--click-through>:not(.wrapper){pointer-events:all}.root.--animated:after{transition:opacity var(--rs-duration-medium) var(--rs-easing-standard)}
1
+ .root{-webkit-overflow-scrolling:touch;color:var(--rs-color-white);overflow:auto;z-index:var(--rs-z-index-overlay)}.root,.root:after{inset:0;position:fixed}.root:after{background:var(--rs-color-black);content:"";opacity:0;transform:scale(1.01)}.wrapper{display:table;height:100%;width:100%}.inner{display:table-cell;text-align:center}.content,.inner{vertical-align:middle}.content{display:inline-block;position:relative;text-align:initial;z-index:var(--rs-z-index-raised)}.root.--visible:after{opacity:var(--rs-overlay-opacity);transform:scale(1)}.root.--click-through{color:inherit;pointer-events:none}.root.--click-through .content,.root.--click-through>:not(.wrapper){pointer-events:all}.root.--animated:after{transition:var(--rs-duration-medium) var(--rs-easing-standard);transition-property:opacity,transform}
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": "2.7.0",
4
+ "version": "2.7.2",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",