UNPKG

@nutui/nutui-react-taro

Version:

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

263 lines (262 loc) 13.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return _default; } }); var _interop_require_default = require("@swc/helpers/_/_interop_require_default"); var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); var _async_to_generator = require("@swc/helpers/_/_async_to_generator"); var _define_property = require("@swc/helpers/_/_define_property"); var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array"); var _ts_generator = require("@swc/helpers/_/_ts_generator"); var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames")); var _components = require("@tarojs/components"); var _usetouch = require("../../hooks/use-touch"); var _supportspassive = require("../../utils/supports-passive"); var _platform = require("../../utils/taro/platform"); var _utils = require("../../utils"); var _utils1 = require("./utils"); var _useuuid = require("../../hooks/use-uuid"); var _getrect = require("../../utils/taro/get-rect"); var InternalPickerRoller = function InternalPickerRoller(props, ref) { var _props_keyIndex = props.keyIndex, keyIndex = _props_keyIndex === void 0 ? 0 : _props_keyIndex, _props_options = props.options, options = _props_options === void 0 ? [] : _props_options, _props_threeDimensional = props.threeDimensional, threeDimensional = _props_threeDimensional === void 0 ? true : _props_threeDimensional, _props_duration = props.duration, duration = _props_duration === void 0 ? 1000 : _props_duration, onSelect = props.onSelect, _props_renderLabel = props.renderLabel, renderLabel = _props_renderLabel === void 0 ? function renderLabel(item) { return item.label; } : _props_renderLabel; var classPrefix = 'nut-pickerview-roller'; var uuid = (0, _useuuid.useUuid)(); var DEFAULT_DURATION = 200; var INERTIA_TIME = 300; var INERTIA_DISTANCE = 15; var ROTATION = 20; var touch = (0, _usetouch.useTouch)(); var _useState = (0, _sliced_to_array._)((0, _react.useState)(0), 2), currentIndex = _useState[0], setCurrentIndex = _useState[1]; var lineSpacing = (0, _react.useRef)(36); var _useState1 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), touchTime = _useState1[0], setTouchTime = _useState1[1]; var _useState2 = (0, _sliced_to_array._)((0, _react.useState)('0deg'), 2), touchDeg = _useState2[0], setTouchDeg = _useState2[1]; var isMoving = (0, _react.useRef)(false); var rollerRef = (0, _react.useRef)(null); var pickerRollerRef = (0, _react.useRef)(null); var placeholderRef = (0, _react.useRef)(null); var _useState3 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), startTime = _useState3[0], setStartTime = _useState3[1]; var _useState4 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), startY = _useState4[0], setStartY = _useState4[1]; var transformY = (0, _react.useRef)(0); var _useState5 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), scrollDistance = _useState5[0], setScrollDistance = _useState5[1]; var _useState6 = (0, _sliced_to_array._)((0, _react.useState)((0, _platform.web)()), 2), isGetLineSpacing = _useState6[0], setGetStatus = _useState6[1]; var _useStyles = (0, _utils1.useStyles)(touchTime, touchDeg, scrollDistance, lineSpacing, ROTATION), touchRollerStyle = _useStyles.touchRollerStyle, touchTiledStyle = _useStyles.touchTiledStyle, rollerStyle = _useStyles.rollerStyle; var isItemHidden = function isItemHidden(index) { return index >= currentIndex + 8 || index <= currentIndex - 8; }; var applyTransform = function applyTransform(type, deg) { var time = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : DEFAULT_DURATION, translateY = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 0; setTouchTime(type !== 'end' ? 0 : time); setTouchDeg(deg); setScrollDistance(translateY); }; var handleMove = function handleMove(move, type, time) { var updatedMove = move + transformY.current; if (type === 'end') { updatedMove = Math.max(Math.min(updatedMove, 0), -(options.length - 1) * lineSpacing.current); // 滚动距离为lineSpacing.current的倍数值 var endMove = Math.round(updatedMove / lineSpacing.current) * lineSpacing.current; var deg = "".concat((Math.abs(Math.round(endMove / lineSpacing.current)) + 1) * ROTATION, "deg"); applyTransform(type, deg, time, endMove); setCurrentIndex(Math.abs(Math.round(endMove / lineSpacing.current)) + 1); } else { var currentDeg = (-updatedMove / lineSpacing.current + 1) * ROTATION; var deg1 = Math.min(Math.max(currentDeg, 0), (options.length + 1) * ROTATION); if (deg1 >= 0 && deg1 < (options.length + 1) * ROTATION) { applyTransform('', "".concat(deg1, "deg"), undefined, updatedMove); deg1 > 0 && setCurrentIndex(Math.abs(Math.round(updatedMove / lineSpacing.current)) + 1); } } }; var selectValue = function selectValue(move) { onSelect === null || onSelect === void 0 ? void 0 : onSelect(options === null || options === void 0 ? void 0 : options[Math.round(-move / lineSpacing.current)], keyIndex); }; var isScroll = (0, _react.useRef)(false); var handleTouchStart = function handleTouchStart(event) { isScroll.current = true; touch.start(event); setStartY(touch.deltaY.current); setStartTime(Date.now()); transformY.current = scrollDistance; }; var handleTouchMove = function handleTouchMove(event) { touch.move(event); if (touch.isVertical) { isMoving.current = true; (0, _utils.preventDefault)(event, true); } var move = touch.deltaY.current - startY; handleMove(move); }; var handleTouchEnd = function handleTouchEnd() { if (!isMoving.current) return; var move = touch.deltaY.current - startY; var moveTime = Date.now() - startTime; if (moveTime <= INERTIA_TIME && Math.abs(move) > INERTIA_DISTANCE) { var distance = (0, _utils1.momentum)(move, moveTime); handleMove(distance, 'end', +duration); } else { handleMove(move, 'end'); } isScroll.current = false; setTimeout(function() { touch.reset(); }, 0); }; var updateStatus = function updateStatus(shouldSelect, value) { var selectedValue = value || props.value; var index = options.findIndex(function(item) { return item.value === selectedValue; }); setCurrentIndex(index === -1 ? 0 : index + 1); var move = index * lineSpacing.current; shouldSelect && selectValue(-move); handleMove(-move); }; var stopMomentumScroll = function stopMomentumScroll() { isMoving.current = false; setTouchTime(0); selectValue(scrollDistance); }; var getReactHeight = function getReactHeight() { return (0, _async_to_generator._)(function() { var placeholder, placeholderHeight, error; return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: _state.trys.push([ 0, 2, , 3 ]); return [ 4, (0, _getrect.getRectInMultiPlatform)(placeholderRef.current) ]; case 1: placeholder = _state.sent(); placeholderHeight = placeholder.height || 36; return [ 2, placeholderHeight ]; case 2: error = _state.sent(); console.error('获取高度失败:', error); return [ 2, 36 ]; case 3: return [ 2 ]; } }); })(); }; // lineSpacing.current CSS variable (0, _react.useEffect)(function() { var element = pickerRollerRef.current; var currentLineSpacing; if (element && (0, _platform.web)()) { var computedStyle = getComputedStyle(element); currentLineSpacing = computedStyle.getPropertyValue('--nutui-picker-item-height'); if (currentLineSpacing) { lineSpacing.current = parseFloat(currentLineSpacing); } } else if (placeholderRef.current) { getReactHeight().then(function(height) { currentLineSpacing = height; if (currentLineSpacing) { lineSpacing.current = currentLineSpacing; setGetStatus(true); } }); } }, [ pickerRollerRef.current, placeholderRef.current ]); (0, _react.useEffect)(function() { isMoving.current = false; setScrollDistance(0); transformY.current = 0; updateStatus(false); }, [ options, props.value ]); (0, _react.useImperativeHandle)(ref, function() { return { stopMomentum: stopMomentumScroll, moving: isMoving.current }; }); (0, _react.useEffect)(function() { var _pickerRollerRef_current, _pickerRollerRef_current1, _pickerRollerRef_current2; var eventOptions = _supportspassive.passiveSupported ? { passive: false, once: true } : false; (_pickerRollerRef_current = pickerRollerRef.current) === null || _pickerRollerRef_current === void 0 ? void 0 : _pickerRollerRef_current.addEventListener('touchstart', handleTouchStart, eventOptions); (_pickerRollerRef_current1 = pickerRollerRef.current) === null || _pickerRollerRef_current1 === void 0 ? void 0 : _pickerRollerRef_current1.addEventListener('touchmove', handleTouchMove, eventOptions); (_pickerRollerRef_current2 = pickerRollerRef.current) === null || _pickerRollerRef_current2 === void 0 ? void 0 : _pickerRollerRef_current2.addEventListener('touchend', handleTouchEnd, eventOptions); return function() { var _pickerRollerRef_current, _pickerRollerRef_current1, _pickerRollerRef_current2; (_pickerRollerRef_current = pickerRollerRef.current) === null || _pickerRollerRef_current === void 0 ? void 0 : _pickerRollerRef_current.removeEventListener('touchstart', handleTouchStart, eventOptions); (_pickerRollerRef_current1 = pickerRollerRef.current) === null || _pickerRollerRef_current1 === void 0 ? void 0 : _pickerRollerRef_current1.removeEventListener('touchmove', handleTouchMove, eventOptions); (_pickerRollerRef_current2 = pickerRollerRef.current) === null || _pickerRollerRef_current2 === void 0 ? void 0 : _pickerRollerRef_current2.removeEventListener('touchend', handleTouchEnd, eventOptions); }; }, [ pickerRollerRef.current, handleTouchStart, handleTouchMove, handleTouchEnd ]); var onTransitionEnd = function onTransitionEnd() { if (!isScroll.current) { stopMomentumScroll(); } }; return /*#__PURE__*/ _react.default.createElement(_components.View, { className: "nut-pickerview-list", ref: pickerRollerRef }, /*#__PURE__*/ _react.default.createElement(_components.View, { className: "".concat(classPrefix, "-placeholder"), ref: placeholderRef, id: "".concat(classPrefix, "-placeholder-").concat(uuid) }), /*#__PURE__*/ _react.default.createElement(_components.View, { className: classPrefix, id: "".concat(classPrefix, "-").concat(uuid), ref: rollerRef, style: threeDimensional ? touchRollerStyle() : touchTiledStyle(), onTransitionEnd: onTransitionEnd }, threeDimensional && options.map(function(item, index) { var _item_value; var _obj; return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, { key: (_item_value = item.value) !== null && _item_value !== void 0 ? _item_value : index }, isGetLineSpacing ? /*#__PURE__*/ _react.default.createElement(_components.View, { className: (0, _classnames.default)("".concat(classPrefix, "-item"), (_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-item-hidden"), isItemHidden(index + 1)), (0, _define_property._)(_obj, "".concat(classPrefix, "-item-active"), index + 1 === currentIndex), _obj)), style: rollerStyle(index) }, renderLabel(item)) : null); }), !threeDimensional && options.map(function(item, index) { var _item_value; return /*#__PURE__*/ _react.default.createElement(_components.View, { className: (0, _classnames.default)("".concat(classPrefix, "-item-tiled"), (0, _define_property._)({}, "".concat(classPrefix, "-item-active"), index + 1 === currentIndex)), key: (_item_value = item.value) !== null && _item_value !== void 0 ? _item_value : index }, renderLabel(item)); }))); }; var PickerRoller = /*#__PURE__*/ _react.default.forwardRef(InternalPickerRoller); var _default = PickerRoller;