@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
290 lines (289 loc) • 11.2 kB
JavaScript
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import { View } from "@tarojs/components";
import { nextTick, useReady } from "@tarojs/taro";
import { useTouch } from "../../hooks/use-touch";
import { getRectInMultiPlatform } from "../../utils/taro/get-rect";
import { ComponentDefaults } from "../../utils/typings";
import { useRefState } from "../../hooks/use-ref-state";
import { useUuid } from "../../hooks/use-uuid";
function preventDefault(event, isStopPropagation) {
if (typeof event.cancelable !== 'boolean' || event.cancelable) {
event.preventDefault();
}
if (isStopPropagation) {
event.stopPropagation();
}
}
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
name: ''
});
export var Swipe = /*#__PURE__*/ forwardRef(function(props, instanceRef) {
var classPrefix = 'nut-swipe';
var touch = useTouch();
var uid = useUuid();
var leftId = "swipe-left-".concat(uid);
var rightId = "swipe-right-".concat(uid);
var getWidth = function() {
return _async_to_generator(function() {
var leftRect, rightRect;
return _ts_generator(this, function(_state) {
switch(_state.label){
case 0:
if (!leftWrapper.current) return [
3,
2
];
return [
4,
getRectInMultiPlatform(leftWrapper.current, leftId)
];
case 1:
leftRect = _state.sent();
leftRect && setActionWidth(function(v) {
return _object_spread_props(_object_spread({}, v), {
left: leftRect.width
});
});
_state.label = 2;
case 2:
if (!rightWrapper.current) return [
3,
4
];
return [
4,
getRectInMultiPlatform(rightWrapper.current, rightId)
];
case 3:
rightRect = _state.sent();
rightRect && setActionWidth(function(v) {
return _object_spread_props(_object_spread({}, v), {
right: rightRect.width
});
});
_state.label = 4;
case 4:
return [
2
];
}
});
})();
};
// 获取元素的时候要在页面 onReady 后,需要参考小程序的事件周期
useReady(function() {
nextTick(function() {
return getWidth();
});
});
var _$_object_spread = _object_spread({}, defaultProps, props), children = _$_object_spread.children, className = _$_object_spread.className, style = _$_object_spread.style;
var root = useRef();
var opened = useRef(false);
var lockClick = useRef(false);
var startOffset = useRef(0);
var _useState = _sliced_to_array(useState({
offset: 0,
dragging: false
}), 2), state = _useState[0], setState = _useState[1];
var _useRefState = _sliced_to_array(useRefState({
left: 0,
right: 0
}), 2), actionWidth = _useRefState[0], updateState = _useRefState[1];
var setActionWidth = function(fn) {
var res = fn();
if (res.left !== undefined) {
updateState(_object_spread_props(_object_spread({}, actionWidth.current), {
left: res.left
}));
}
if (res.right !== undefined) {
updateState(_object_spread_props(_object_spread({}, actionWidth.current), {
right: res.right
}));
}
};
var wrapperStyle = useMemo(function() {
return {
transform: "translate(".concat(state.offset, "px, 0)"),
transitionDuration: state.dragging ? '0.01s' : '.6s'
};
}, [
state.offset,
state.dragging
]);
var onTouchStart = function(event) {
return _async_to_generator(function() {
var _props_onTouchStart;
return _ts_generator(this, function(_state) {
if (!props.disabled) {
;
getWidth();
startOffset.current = state.offset;
touch.start(event);
(_props_onTouchStart = props.onTouchStart) === null || _props_onTouchStart === void 0 ? void 0 : _props_onTouchStart.call(props, event);
}
return [
2
];
});
})();
};
var onTouchMove = function(event) {
var _props_onTouchMove;
if (props.disabled) return;
touch.move(event);
(_props_onTouchMove = props.onTouchMove) === null || _props_onTouchMove === void 0 ? void 0 : _props_onTouchMove.call(props, event);
if (touch.isHorizontal()) {
lockClick.current = true;
var isEdge = !opened || touch.deltaX.current * startOffset.current < 0;
if (isEdge) {
preventDefault(event, true);
}
var offset = rangeCalculation(touch.deltaX.current + startOffset.current, -actionWidth.current.right || 0, actionWidth.current.left || 0);
setState(function(prevState) {
return _object_spread_props(_object_spread({}, prevState), {
dragging: true,
offset: Number(offset) || 0
});
});
}
};
var onTouchEnd = function(event) {
if (state.dragging) {
var _props_onTouchEnd;
setState(function(prevState) {
return _object_spread_props(_object_spread({}, prevState), {
dragging: false
});
});
toggle(state.offset > 0 ? 'left' : 'right');
setTimeout(function() {
lockClick.current = false;
}, 0);
(_props_onTouchEnd = props.onTouchEnd) === null || _props_onTouchEnd === void 0 ? void 0 : _props_onTouchEnd.call(props, event);
}
};
var toggle = function(side) {
var offset = Math.abs(state.offset);
var base = 0.3;
var baseNum = opened ? 1 - base : base;
var width = side === 'left' ? actionWidth.current.left : actionWidth.current.right;
if (width && offset > Number(width) * baseNum) {
open(side);
} else {
close(side);
}
};
var open = function(side) {
var _props_onOpen;
opened.current = true;
var offset = side === 'left' ? actionWidth.current.left : -actionWidth.current.right;
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(prevState) {
return _object_spread_props(_object_spread({}, prevState), {
offset: Number(offset) || 0
});
});
};
var close = useCallback(function(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(prevState) {
return _object_spread_props(_object_spread({}, prevState), {
offset: 0
});
});
}, [
props
]);
var rangeCalculation = function(num, min, max) {
return Math.min(Math.max(Number(num), Number(min)), Number(max));
};
var leftWrapper = useRef(null);
var rightWrapper = useRef(null);
var renderActionContent = function(side) {
if (props["".concat(side, "Action")]) {
return /*#__PURE__*/ React.createElement(View, {
ref: side === 'left' ? leftWrapper : rightWrapper,
className: "".concat(classPrefix, "-").concat(side),
id: side === 'left' ? leftId : rightId,
onClick: function(e) {
return handleOperate(e, side);
}
}, props["".concat(side, "Action")]);
}
return null;
};
var handleOperate = function(event, position) {
event.stopPropagation();
if (props.beforeClose) {
props.beforeClose(position);
} else {
var _props_onActionClick;
(_props_onActionClick = props.onActionClick) === null || _props_onActionClick === void 0 ? void 0 : _props_onActionClick.call(props, event, position);
}
};
useImperativeHandle(instanceRef, function() {
return {
open: open,
close: function() {
return close();
}
};
});
useEffect(function() {
// 并没有生效
var handler = function(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);
};
}, [
close
]);
return /*#__PURE__*/ React.createElement(View, {
ref: root,
className: classNames(classPrefix, className),
onTouchStart: function(e) {
return onTouchStart(e);
},
onTouchMove: function(e) {
return onTouchMove(e);
},
onTouchEnd: function(e) {
return onTouchEnd(e);
},
style: style
}, /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-wrapper"),
style: wrapperStyle
}, renderActionContent('left'), children, renderActionContent('right')));
});
Swipe.displayName = 'NutSwipe';