UNPKG

gui-one-nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

272 lines (271 loc) 9.57 kB
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _regeneratorRuntime from "@babel/runtime/regenerator"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React__default, { forwardRef, useRef, useState, useMemo, useImperativeHandle, useEffect } from 'react'; import { c as cn } from './bem-893ad28d.js'; import { u as useTouch } from './useTouch-a2ea68c6.js'; import { g as getRectByTaro } from './useClientRect-bf69d7b3.js'; function preventDefault(event, isStopPropagation) { if (typeof event.cancelable !== 'boolean' || event.cancelable) { event.preventDefault(); } if (isStopPropagation) { event.stopPropagation(); } } var defaultProps = { name: '', leftWidth: 0, rightWidth: 0 }; var Swipe = forwardRef(function (props, instanceRef) { var swipeBem = cn('swipe'); var touch = useTouch(); var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props), children = _defaultProps$props.children, className = _defaultProps$props.className, style = _defaultProps$props.style; var root = useRef(); var opened = useRef(false); var lockClick = useRef(false); var startOffset = useRef(0); var _useState = useState({ offset: 0, dragging: false }), _useState2 = _slicedToArray(_useState, 2), state = _useState2[0], setState = _useState2[1]; var _useState3 = useState({ left: 0, right: 0 }), _useState4 = _slicedToArray(_useState3, 2), actionWidth = _useState4[0], setActionWidth = _useState4[1]; var wrapperStyle = { transform: "translate3d(".concat(state.offset, "px, 0, 0)"), transitionDuration: state.dragging ? '0s' : '.6s' }; var leftWidth = useMemo(function () { return props.leftWidth ? props.leftWidth : actionWidth.left; }, [props.leftWidth, actionWidth.left]); var rightWidth = useMemo(function () { return props.rightWidth ? props.rightWidth : actionWidth.right; }, [props.rightWidth, actionWidth.right]); var _onTouchStart = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(event) { var leftRect, rightRect; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!leftWrapper.current) { _context.next = 5; break; } _context.next = 3; return getRectByTaro(leftWrapper.current); case 3: leftRect = _context.sent; setActionWidth(function (v) { return _objectSpread(_objectSpread({}, v), {}, { left: leftRect.width }); }); case 5: if (!rightWrapper.current) { _context.next = 10; break; } _context.next = 8; return getRectByTaro(rightWrapper.current); case 8: rightRect = _context.sent; setActionWidth(function (v) { return _objectSpread(_objectSpread({}, v), {}, { right: rightRect.width }); }); case 10: if (!props.disabled) { startOffset.current = state.offset; touch.start(event); } case 11: case "end": return _context.stop(); } } }, _callee); })); return function onTouchStart(_x) { return _ref.apply(this, arguments); }; }(); var _onTouchMove = function onTouchMove(event) { if (props.disabled) { return; } touch.move(event); if (touch.isHorizontal()) { lockClick.current = true; var newState = _objectSpread(_objectSpread({}, state), {}, { dragging: true }); var isEdge = !opened || touch.deltaX * startOffset.current < 0; if (isEdge) { preventDefault(event, true); } newState.offset = rangeCalculation(touch.deltaX + startOffset.current, -rightWidth || 0, leftWidth || 0); setState(newState); } }; var onTouchEnd = function onTouchEnd() { if (state.dragging) { setState(function (v) { return _objectSpread(_objectSpread({}, v), {}, { dragging: false }); }); toggle(state.offset > 0 ? 'left' : 'right'); setTimeout(function () { lockClick.current = false; }, 0); } }; var toggle = function toggle(side) { var offset = Math.abs(state.offset); var base = 0.3; var baseNum = opened ? 1 - base : base; var width = side === 'left' ? leftWidth : rightWidth; if (width && offset > Number(width) * baseNum) { open(side); } else { _close(side); } }; var open = function open(side) { var _props$onOpen; opened.current = true; var offset = side === 'left' ? leftWidth : -rightWidth; var name = props.name; (_props$onOpen = props.onOpen) === null || _props$onOpen === void 0 ? void 0 : _props$onOpen.call(props, { name: name, position: side }); setState(function (v) { return _objectSpread(_objectSpread({}, v), {}, { offset: Number(offset) || 0 }); }); }; var _close = function close(position) { if (opened.current) { var _props$onClose; opened.current = false; (_props$onClose = props.onClose) === null || _props$onClose === void 0 ? void 0 : _props$onClose.call(props, { name: props.name, position: position || 'left' }); } setState(function (v) { return _objectSpread(_objectSpread({}, v), {}, { offset: 0 }); }); }; var rangeCalculation = function rangeCalculation(num, min, max) { return Math.min(Math.max(Number(num), Number(min)), Number(max)); }; // const getNodeWidth = (node: Element) => { // if (node) { // const ele: any = getRectByTaro(node) // return ele.width // } // return 0 // } // const leftRef = useCallback( // (node: Element | null) => { // if (node !== null) { // setActionWidth((v) => ({ ...v, left: getNodeWidth(node) })) // } // }, // [props.leftAction] // ) // const rightRef = useCallback( // (node: Element | null) => { // if (node !== null) { // setActionWidth((v) => ({ ...v, right: getNodeWidth(node) })) // } // }, // [props.rightAction] // ) var leftWrapper = useRef(null); var rightWrapper = useRef(null); var renderActionContent = function renderActionContent(side) { if (props["".concat(side, "Action")]) { return React__default.createElement("div", { ref: side === 'left' ? leftWrapper : rightWrapper, className: "".concat(swipeBem(side)), onClick: function onClick(e) { return handleOperate(e, side); } }, props["".concat(side, "Action")]); } return null; }; var handleOperate = function handleOperate(event, position) { event.stopPropagation(); if (props.beforeClose) { props.beforeClose(position); } else { props.onActionClick && props.onActionClick(event, position); } }; useImperativeHandle(instanceRef, function () { return { open: open, close: function close() { return _close(); } }; }); useEffect(function () { var handler = function handler(event) { var targets = [root]; if (targets.some(function (targetItem) { var targetElement = targetItem.current || targetItem; return !targetElement || (targetElement === null || targetElement === void 0 ? void 0 : targetElement.contains(event.target)); })) { return; } _close(); }; document.addEventListener('touchstart', handler); return function () { document.removeEventListener('touchstart', handler); }; }, []); return React__default.createElement("div", { ref: root, className: "".concat(swipeBem(), " ").concat(className), onTouchStart: function onTouchStart(e) { return _onTouchStart(e); }, onTouchMove: function onTouchMove(e) { return _onTouchMove(e); }, onTouchEnd: onTouchEnd, style: style }, React__default.createElement("div", { className: "".concat(swipeBem('wrapper')), style: wrapperStyle }, renderActionContent('left'), children, renderActionContent('right'))); }); Swipe.defaultProps = defaultProps; Swipe.displayName = 'NutSwipe'; export { Swipe as S };