UNPKG

@wix/design-system

Version:

@wix/design-system

368 lines (366 loc) 13 kB
"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