gui-one-nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
272 lines (271 loc) • 9.57 kB
JavaScript
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 };