UNPKG

gui-one-nutui-react-taro

Version:

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

271 lines (270 loc) 10.5 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; var _excluded = ["height", "acceptKey", "indexList", "isSticky", "spaceHeight", "titleHeight", "className", "onClickItem", "onClickIndex", "children"]; 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, { createContext, useRef, useState, useEffect } from 'react'; import Taro from '@tarojs/taro'; import { ScrollView } from '@tarojs/components'; import { c as cn } from './bem-893ad28d.js'; var elevatorContext = createContext({}); var defaultProps = { height: '200px', acceptKey: 'title', indexList: [], isSticky: false, spaceHeight: 23, titleHeight: 35, className: 'weapp-elevator' }; var Elevator = function Elevator(props) { var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props), height = _defaultProps$props.height, acceptKey = _defaultProps$props.acceptKey, indexList = _defaultProps$props.indexList, isSticky = _defaultProps$props.isSticky, spaceHeight = _defaultProps$props.spaceHeight, titleHeight = _defaultProps$props.titleHeight, className = _defaultProps$props.className, onClickItem = _defaultProps$props.onClickItem, onClickIndex = _defaultProps$props.onClickIndex, children = _defaultProps$props.children, rest = _objectWithoutProperties(_defaultProps$props, _excluded); var b = cn('elevator'); var listview = useRef(null); var initData = { anchorIndex: 0, listHeight: [], listGroup: [], scrollY: 0, diff: -1, fixedTop: 0 }; var touchState = useRef({ y1: 0, y2: 0 }); var _useState = useState(0), _useState2 = _slicedToArray(_useState, 2), scrollY = _useState2[0], setScrollY = _useState2[1]; var _useState3 = useState({}), _useState4 = _slicedToArray(_useState3, 2), currentData = _useState4[0], setCurrentData = _useState4[1]; var _useState5 = useState(''), _useState6 = _slicedToArray(_useState5, 2), currentKey = _useState6[0], setCurrentKey = _useState6[1]; var _useState7 = useState(0), _useState8 = _slicedToArray(_useState7, 2), currentIndex = _useState8[0], setCurrentIndex = _useState8[1]; var _useState9 = useState(0), _useState10 = _slicedToArray(_useState9, 2), codeIndex = _useState10[0], setCodeIndex = _useState10[1]; var _useState11 = useState(false), _useState12 = _slicedToArray(_useState11, 2), scrollStart = _useState12[0], setScrollStart = _useState12[1]; var state = useRef(initData); var _useState13 = useState(0), _useState14 = _slicedToArray(_useState13, 2), scrollTop = _useState14[0], setScrollTop = _useState14[1]; // 重置滚动参数 var resetScrollState = function resetScrollState() { setScrollStart(false); }; var clientHeight = function clientHeight() { return listview.current ? listview.current.clientHeight : 0; }; var getData = function getData(el) { if (!el.dataset.index) { return '0'; } return el.dataset.index; }; var calculateHeight = function calculateHeight() { var height = 0; state.current.listHeight.push(height); for (var i = 0; i < state.current.listGroup.length; i++) { var query = Taro.createSelectorQuery(); query.selectAll(".".concat(className, " .elevator__item__").concat(i)).boundingClientRect(); // eslint-disable-next-line no-loop-func query.exec(function (res) { if (res[0][0]) height += res[0][0].height; // console.log(res, res[0][0].height, height, 'res') state.current.listHeight.push(height); }); } }; var scrollTo = function scrollTo(index) { if (!index && index !== 0) { return; } if (!state.current.listHeight.length) { calculateHeight(); } var cacheIndex = index; if (index < 0) { cacheIndex = 0; } if (index > state.current.listHeight.length - 2) { cacheIndex = state.current.listHeight.length - 2; } setCodeIndex(cacheIndex); setScrollTop(state.current.listHeight[cacheIndex]); }; var touchMove = function touchMove(e) { var firstTouch = e.touches[0]; touchState.current.y2 = firstTouch.pageY; var delta = (touchState.current.y2 - touchState.current.y1) / spaceHeight || 0; var cacheIndex = state.current.anchorIndex + Math.floor(delta); setCodeIndex(cacheIndex); scrollTo(cacheIndex); }; var touchEnd = function touchEnd() { resetScrollState(); }; var touchStart = function touchStart(e) { setScrollStart(true); var index = Number(getData(e.target)); var firstTouch = e.touches[0]; touchState.current.y1 = firstTouch.pageY; state.current.anchorIndex = +index; setCodeIndex(function (codeIndex) { return codeIndex + index; }); scrollTo(index); }; var handleClickItem = function handleClickItem(key, item) { onClickItem && onClickItem(key, item); setCurrentData(item); setCurrentKey(key); }; var handleClickIndex = function handleClickIndex(key) { onClickIndex && onClickIndex(key); }; var setListGroup = function setListGroup() { if (listview.current) { Taro.createSelectorQuery().selectAll(".".concat(className, " .nut-elevator__list__item")).node(function (el) { state.current.listGroup = _toConsumableArray(Object.keys(el)); calculateHeight(); }).exec(); } }; var listViewScroll = function listViewScroll(e) { var listHeight = state.current.listHeight; if (!listHeight.length) { calculateHeight(); } var target = e.target; var scrollTop = target.scrollTop; state.current.scrollY = Math.floor(scrollTop); setScrollY(scrollTop); for (var i = 0; i < listHeight.length - 1; i++) { var height1 = listHeight[i]; var height2 = listHeight[i + 1]; if (state.current.scrollY >= height1 && state.current.scrollY < height2) { setCurrentIndex(i); state.current.diff = height2 - state.current.scrollY; return; } } setCurrentIndex(listHeight.length - 2); }; useEffect(function () { if (listview.current) { Taro.nextTick(function () { setListGroup(); }); } }, [listview]); useEffect(function () { var _state$current = state.current, listHeight = _state$current.listHeight, diff = _state$current.diff, scrollY = _state$current.scrollY; var fixedTop = diff > 0 && diff < titleHeight ? diff - titleHeight : 0; if (scrollY + clientHeight() === listHeight[listHeight.length - 1]) { if (fixedTop !== 0) { fixedTop = 0; } } if (state.current.fixedTop === fixedTop) return; state.current.fixedTop = fixedTop; }, [state.current.diff, titleHeight]); return React__default.createElement("div", _objectSpread({ className: "".concat(b(), " ").concat(className, " ") }, rest), isSticky && scrollY > 0 ? React__default.createElement("div", { className: b('list__fixed') }, React__default.createElement("span", { className: "fixed-title" }, indexList[currentIndex][acceptKey])) : null, React__default.createElement("div", { className: b('list'), style: { height: Number.isNaN(+height) ? height : "".concat(height, "px") } }, React__default.createElement(ScrollView, { scrollTop: scrollTop, scrollY: true, className: b('list__inner'), ref: listview, onScroll: listViewScroll }, indexList.map(function (item, idx) { return React__default.createElement("div", { className: "".concat(b('list__item'), " elevator__item__").concat(idx), key: idx }, React__default.createElement("div", { className: b('list__item__code') }, item[acceptKey]), React__default.createElement(React__default.Fragment, null, item.list.map(function (subitem) { return React__default.createElement("div", { className: b('list__item__name', { highcolor: currentData.id === subitem.id && currentKey === item[acceptKey] }), key: subitem.id, onClick: function onClick() { return handleClickItem(item[acceptKey], subitem); } }, children ? React__default.createElement(React__default.Fragment, null, React__default.createElement(elevatorContext.Provider, { value: subitem }, children)) : subitem.name); }))); }))), indexList.length && scrollStart ? React__default.createElement("div", { className: b('code--current', { current: true }) }, indexList[codeIndex][acceptKey]) : null, React__default.createElement("div", { className: b('bars') }, React__default.createElement("div", { className: b('bars__inner'), onTouchStart: function onTouchStart(event) { return touchStart(event); }, onTouchMove: function onTouchMove(event) { return touchMove(event); }, onTouchEnd: touchEnd, style: { touchAction: 'pan-y' } }, indexList.map(function (item, index) { return React__default.createElement("div", { className: "".concat(b('bars__inner__item', { active: item[acceptKey] === indexList[currentIndex][acceptKey] }), " "), "data-index": index, key: index, onClick: function onClick() { return handleClickIndex(item[acceptKey]); } }, item[acceptKey]); })))); }; Elevator.defaultProps = defaultProps; Elevator.displayName = 'NutElevator'; export { Elevator as E };