@wix/design-system
Version:
@wix/design-system
368 lines (366 loc) • 13 kB
JavaScript
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var Dialog = _interopRequireWildcard(require("@radix-ui/react-dialog"));
var _DrawerSt = require("./Drawer.st.css.js");
var _Drawer = require("./Drawer.constants");
var _ZIndex = require("../common/ZIndex");
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/Drawer/Drawer.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
var Drawer = _ref => {
var open = _ref.open,
_ref$backdrop = _ref.backdrop,
backdrop = _ref$backdrop === void 0 ? true : _ref$backdrop,
_ref$renderBackdrop = _ref.renderBackdrop,
renderBackdrop = _ref$renderBackdrop === void 0 ? true : _ref$renderBackdrop,
_ref$resizable = _ref.resizable,
resizable = _ref$resizable === void 0 ? true : _ref$resizable,
_ref$margin = _ref.margin,
margin = _ref$margin === void 0 ? true : _ref$margin,
onClose = _ref.onClose,
_ref$role = _ref.role,
role = _ref$role === void 0 ? 'dialog' : _ref$role,
ariaLabelledBy = _ref.ariaLabelledBy,
_ref$snapPoints = _ref.snapPoints,
snapPoints = _ref$snapPoints === void 0 ? [1] : _ref$snapPoints,
children = _ref.children,
_ref$dismissible = _ref.dismissible,
dismissible = _ref$dismissible === void 0 ? true : _ref$dismissible,
dataHook = _ref.dataHook,
_ref$zIndex = _ref.zIndex,
zIndex = _ref$zIndex === void 0 ? _ZIndex.ZIndex.popover : _ref$zIndex,
_ref$scrollable = _ref.scrollable,
scrollable = _ref$scrollable === void 0 ? true : _ref$scrollable,
_ref$repositionInputs = _ref.repositionInputs,
repositionInputs = _ref$repositionInputs === void 0 ? true : _ref$repositionInputs,
_ref$modal = _ref.modal,
modal = _ref$modal === void 0 ? true : _ref$modal;
var contentRef = (0, _react.useRef)(null);
var handleRef = (0, _react.useRef)(null);
var restingY = (0, _react.useRef)(0);
var dragState = (0, _react.useRef)({
isDragging: false,
startY: 0,
startTranslateY: 0,
currentDelta: 0
});
var contentGesture = (0, _react.useRef)({
active: false,
committed: false,
startX: 0,
startY: 0,
pointerId: -1
});
(0, _react.useEffect)(() => {
if (!open || !repositionInputs || typeof window === 'undefined' || !window.visualViewport) {
return;
}
var viewport = window.visualViewport;
var el = contentRef.current;
var onViewportResize = () => {
if (!el) return;
var keyboardHeight = Math.max(0, window.innerHeight - viewport.height - viewport.offsetTop);
el.style.bottom = keyboardHeight > 0 ? "".concat(keyboardHeight, "px") : '';
};
viewport.addEventListener('resize', onViewportResize);
return () => {
viewport.removeEventListener('resize', onViewportResize);
if (el) {
el.style.bottom = '';
}
};
}, [open, repositionInputs]);
(0, _react.useEffect)(() => {
var el = contentRef.current;
if (!open || !resizable || !el) return;
var onTouchMove = e => {
if (dragState.current.isDragging && e.cancelable) {
e.preventDefault();
}
};
el.addEventListener('touchmove', onTouchMove, {
passive: false
});
return () => el.removeEventListener('touchmove', onTouchMove);
}, [open, resizable]);
var resolveSnapPoint = snap => {
var value = typeof snap === 'string' ? parseFloat(snap.replace('px', '')) : snap;
if (value <= 1) {
var _contentRef$current$c, _contentRef$current;
return value * ((_contentRef$current$c = (_contentRef$current = contentRef.current) == null ? void 0 : _contentRef$current.clientHeight) !== null && _contentRef$current$c !== void 0 ? _contentRef$current$c : window.innerHeight);
}
return value;
};
var animateToY = (fromY, toY, onDone) => {
var el = contentRef.current;
if (!el) return;
el.style.animation = 'none';
// Check needed for JSDOM environment, since animation api isn't implemented
if (typeof el.animate !== 'function') {
el.style.transform = toY === 0 ? '' : "translateY(".concat(toY, "px)");
el.style.animation = '';
restingY.current = toY;
onDone == null || onDone();
return;
}
var anim = el.animate([{
transform: "translateY(".concat(fromY, "px)")
}, {
transform: "translateY(".concat(toY, "px)")
}], {
duration: 300,
easing: 'ease'
});
anim.onfinish = () => {
el.style.transform = toY === 0 ? '' : "translateY(".concat(toY, "px)");
if (onDone) {
onDone();
} else {
el.style.animation = '';
restingY.current = toY;
}
};
};
var beginDrag = startY => {
dragState.current = {
isDragging: true,
startY,
startTranslateY: restingY.current,
currentDelta: 0
};
if (contentRef.current) {
contentRef.current.style.animation = 'none';
contentRef.current.style.transition = 'none';
}
};
var onHandlePointerDown = e => {
e.currentTarget.setPointerCapture == null || e.currentTarget.setPointerCapture(e.pointerId);
beginDrag(e.clientY);
};
var onHandlePointerMove = e => {
if (!dragState.current.isDragging) return;
var delta = e.clientY - dragState.current.startY;
dragState.current.currentDelta = delta;
var newY = Math.max(0, dragState.current.startTranslateY + delta);
if (contentRef.current) {
contentRef.current.style.transform = "translateY(".concat(newY, "px)");
}
};
var onHandlePointerUp = () => {
if (!dragState.current.isDragging) return;
dragState.current.isDragging = false;
var el = contentRef.current;
if (!el) return;
var contentHeight = el.offsetHeight;
var currentY = Math.max(0, dragState.current.startTranslateY + dragState.current.currentDelta);
var resolvedSnaps = snapPoints.map(resolveSnapPoint).sort((a, b) => a - b);
var visibleHeight = contentHeight - currentY;
var lowestSnap = resolvedSnaps[0];
if (dismissible && visibleHeight < lowestSnap * 0.5) {
animateToY(currentY, contentHeight, () => onClose(false));
return;
}
var nearest = resolvedSnaps[0];
var minDist = Infinity;
for (var snap of resolvedSnaps) {
var dist = Math.abs(visibleHeight - snap);
if (dist < minDist) {
minDist = dist;
nearest = snap;
}
}
animateToY(currentY, Math.max(0, contentHeight - nearest));
};
var findScrolledAncestor = target => {
var el = target;
while (el) {
if (el.scrollTop > 0) return el;
if (el === contentRef.current) break;
el = el.parentElement;
}
return null;
};
var isAtLargestSnapPoint = () => {
var el = contentRef.current;
if (!el) return true;
var resolvedSnaps = snapPoints.map(resolveSnapPoint).sort((a, b) => a - b);
var largest = resolvedSnaps[resolvedSnaps.length - 1];
var visibleHeight = el.offsetHeight - restingY.current;
return visibleHeight >= largest - 1;
};
var onContentPointerDown = e => {
var _handleRef$current;
if (e.pointerType === 'mouse') return;
if ((_handleRef$current = handleRef.current) != null && _handleRef$current.contains(e.target)) return;
contentGesture.current = {
active: true,
committed: false,
startX: e.clientX,
startY: e.clientY,
pointerId: e.pointerId
};
};
var onContentPointerMove = e => {
var _contentRef$current2;
var gesture = contentGesture.current;
if (!gesture.active) return;
if (gesture.committed) {
onHandlePointerMove(e);
return;
}
var deltaY = e.clientY - gesture.startY;
var deltaX = e.clientX - gesture.startX;
if (Math.abs(deltaY) < _Drawer.CONTENT_DRAG_THRESHOLD_PX) return;
if (Math.abs(deltaY) <= Math.abs(deltaX)) {
gesture.active = false;
return;
}
var draggingDown = deltaY > 0;
var shouldDrag = draggingDown ? !findScrolledAncestor(e.target) : !isAtLargestSnapPoint();
if (!shouldDrag) {
gesture.active = false;
return;
}
gesture.committed = true;
(_contentRef$current2 = contentRef.current) == null || _contentRef$current2.setPointerCapture == null || _contentRef$current2.setPointerCapture(gesture.pointerId);
beginDrag(gesture.startY);
onHandlePointerMove(e);
};
var onContentPointerUp = () => {
var committed = contentGesture.current.committed;
contentGesture.current.active = false;
contentGesture.current.committed = false;
if (committed) {
onHandlePointerUp();
}
};
var handleDismiss = e => {
e.preventDefault();
if (!dismissible) return;
var el = contentRef.current;
if (!el) {
onClose(false);
return;
}
animateToY(restingY.current, el.offsetHeight, () => onClose(false));
};
var lastAnimatedElRef = (0, _react.useRef)(null);
var handleContentRef = (0, _react.useCallback)(el => {
if (el && el !== lastAnimatedElRef.current) {
contentRef.current = el;
lastAnimatedElRef.current = el;
if (!contentRef.current) return;
var snapPx = resolveSnapPoint(snapPoints[0]);
var targetY = Math.max(0, el.offsetHeight - snapPx);
animateToY(contentRef.current.clientHeight, targetY);
}
}, [snapPoints]);
return /*#__PURE__*/_react.default.createElement("div", {
"data-hook": dataHook,
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 312,
columnNumber: 5
}
}, /*#__PURE__*/_react.default.createElement(Dialog.Root, {
open: open,
onOpenChange: onClose,
modal: modal,
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 313,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement(Dialog.Portal, {
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 314,
columnNumber: 9
}
}, renderBackdrop && /*#__PURE__*/_react.default.createElement(Dialog.Overlay, {
"data-hook": _Drawer.DATA_HOOKS.OVERLAY,
className: (0, _DrawerSt.st)(_DrawerSt.classes.overlay, {
backdrop
}),
style: {
zIndex
},
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 316,
columnNumber: 13
}
}), /*#__PURE__*/_react.default.createElement(Dialog.Content, {
ref: handleContentRef,
"data-hook": _Drawer.DATA_HOOKS.CONTENT,
"aria-modal": "true",
"aria-labelledby": ariaLabelledBy,
role: role,
className: (0, _DrawerSt.st)(_DrawerSt.classes.content, {
margin,
resizable
}),
onInteractOutside: dismissible ? undefined : e => e.preventDefault(),
onEscapeKeyDown: handleDismiss,
onPointerDown: resizable ? onContentPointerDown : undefined,
onPointerMove: resizable ? onContentPointerMove : undefined,
onPointerUp: resizable ? onContentPointerUp : undefined,
style: {
zIndex
},
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 322,
columnNumber: 11
}
}, /*#__PURE__*/_react.default.createElement(Dialog.Title, {
className: _DrawerSt.classes.title,
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 341,
columnNumber: 13
}
}), resizable && /*#__PURE__*/_react.default.createElement("div", {
ref: handleRef,
className: _DrawerSt.classes.handle,
"data-hook": _Drawer.DATA_HOOKS.HANDLE,
onPointerDown: onHandlePointerDown,
onPointerMove: onHandlePointerMove,
onPointerUp: onHandlePointerUp,
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 343,
columnNumber: 15
}
}), /*#__PURE__*/_react.default.createElement("div", {
className: _DrawerSt.classes.contentInner,
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 352,
columnNumber: 13
}
}, scrollable ? /*#__PURE__*/_react.default.createElement("div", {
"data-hook": _Drawer.DATA_HOOKS.CONTENT_WRAPPER,
className: (0, _DrawerSt.st)(_DrawerSt.classes.contentWrapper, {
margin
}),
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 354,
columnNumber: 17
}
}, children) : children)))));
};
Drawer.displayName = 'Drawer';
var _default = exports.default = Drawer;
//# sourceMappingURL=Drawer.js.map