@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
275 lines (274 loc) • 12 kB
JavaScript
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
import { _ as _define_property } from "@swc/helpers/_/_define_property";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
import React, { useEffect, useRef, useState, createContext, useMemo } from "react";
import Taro, { nextTick, createSelectorQuery } from "@tarojs/taro";
import { ScrollView, View, Text } from "@tarojs/components";
import classNames from "classnames";
import { ComponentDefaults } from "../../utils/typings";
import { harmony } from "../../utils/taro/platform";
import { useUuid } from "../../hooks/use-uuid";
import raf from "../../utils/raf";
import { usePropsValue } from "../../hooks";
export var elevatorContext = /*#__PURE__*/ createContext({});
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
mode: 'horizontal',
height: '200px',
floorKey: 'title',
list: [],
sticky: false,
spaceHeight: 18,
showKeys: true,
defaultValue: undefined,
value: undefined
});
export var Elevator = function(props) {
var _ref = _object_spread({}, defaultProps, props), value = _ref.value, defaultValue = _ref.defaultValue, mode = _ref.mode, height = _ref.height, floorKey = _ref.floorKey, list = _ref.list, sticky = _ref.sticky, spaceHeight = _ref.spaceHeight, showKeys = _ref.showKeys, className = _ref.className, style = _ref.style, onItemClick = _ref.onItemClick, onIndexClick = _ref.onIndexClick, children = _ref.children, rest = _object_without_properties(_ref, [
"value",
"defaultValue",
"mode",
"height",
"floorKey",
"list",
"sticky",
"spaceHeight",
"showKeys",
"className",
"style",
"onItemClick",
"onIndexClick",
"children"
]);
var uuid = useUuid();
var classPrefix = 'nut-elevator';
var initData = {
anchorIndex: 0,
listHeight: [],
scrollY: 0
};
var touchState = useRef({
y1: 0,
y2: 0
});
var _usePropsValue = _sliced_to_array(usePropsValue({
value: value,
defaultValue: defaultValue || {}
}), 2), currentData = _usePropsValue[0], setCurrentData = _usePropsValue[1];
var _useState = _sliced_to_array(useState(0), 2), codeIndex = _useState[0], setCodeIndex = _useState[1];
var _useState1 = _sliced_to_array(useState(false), 2), scrollStart = _useState1[0], setScrollStart = _useState1[1];
var state = useRef(initData);
var scrolling = useRef(false);
var _useState2 = _sliced_to_array(useState(0), 2), scrollTop = _useState2[0], setScrollTop = _useState2[1];
var _useState3 = _sliced_to_array(useState(0), 2), scrollY = _useState3[0], setScrollY = _useState3[1];
var resetScrollState = function() {
setScrollStart(false);
};
var getData = function(el) {
if (!el.dataset.index) {
return '0';
}
return el.dataset.index;
};
var calculateHeight = function() {
state.current.listHeight = [
0
];
var query = createSelectorQuery();
query.selectAll("#".concat(classPrefix, "-").concat(uuid, " .").concat(classPrefix, "-list-item")).boundingClientRect().exec(function() {
var rect = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [];
if (rect[0] && rect[0].length) {
// rect[0] = rect[0].reverse()
state.current.listHeight = rect[0].reduce(function(acc, item, index) {
// 当前项的高度等于前面所有项的高度之和
var height = acc[index] + item.height;
acc.push(height);
return acc;
}, [
0
]);
}
});
};
var scrollTo = function(index) {
return _async_to_generator(function() {
var cacheIndex, scrollTop;
return _ts_generator(this, function(_state) {
switch(_state.label){
case 0:
if (!index && index !== 0) {
return [
2
];
}
if (!!state.current.listHeight.length) return [
3,
2
];
return [
4,
calculateHeight()
];
case 1:
_state.sent();
_state.label = 2;
case 2:
cacheIndex = index;
if (index < 0) {
cacheIndex = 0;
}
if (index > state.current.listHeight.length - 2) {
cacheIndex = Math.max(0, state.current.listHeight.length - 2);
}
setCodeIndex(cacheIndex);
scrollTop = state.current.listHeight[cacheIndex];
setScrollTop(scrollTop);
if (mode === 'vertical' && sticky) {
setScrollY(Math.floor(scrollTop) > 0 ? 1 : 0);
}
return [
2
];
}
});
})();
};
var touchMove = function(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.round(delta);
setCodeIndex(cacheIndex);
scrollTo(cacheIndex);
};
var touchEnd = function() {
resetScrollState();
};
var touchStart = function(e) {
var index = Number(getData(e.target));
var firstTouch = e.touches[0];
scrolling.current = true;
touchState.current.y1 = firstTouch.pageY;
state.current.anchorIndex = +index;
setScrollStart(true);
setCodeIndex(index);
scrollTo(index);
};
var handleClickItem = function(key, item) {
onItemClick && onItemClick(key, item);
setCurrentData(item);
};
var handleClickIndex = function(key) {
onIndexClick && onIndexClick(key);
};
var listViewScroll = function(e) {
raf(function() {
var listHeight = state.current.listHeight;
if (!listHeight.length) {
calculateHeight();
}
var target = e.target;
var scrollTop = target.scrollTop;
state.current.scrollY = Math.floor(scrollTop);
Taro.getEnv() === 'WEB' && setScrollTop(scrollTop);
if (mode === 'vertical' && sticky) {
setScrollY(Math.floor(scrollTop) > 0 ? 1 : 0);
}
if (scrolling.current) return;
var index = listHeight.findIndex(function(height, i) {
return state.current.scrollY >= height && state.current.scrollY < (listHeight[i + 1] || Infinity);
});
if (index !== -1 && index !== codeIndex) {
setCodeIndex(index);
}
});
};
var getWrapStyle = useMemo(function() {
var calcHeight = Number.isNaN(+height) ? height : "".concat(height, "px");
return {
height: harmony() ? Number(height) : calcHeight
};
}, [
height
]);
useEffect(function() {
nextTick(function() {
calculateHeight();
});
}, []);
var _obj;
return /*#__PURE__*/ React.createElement("div", _object_spread({
className: "".concat(classPrefix, " ").concat(className, " ").concat(classPrefix, "-").concat(mode, " "),
id: "".concat(classPrefix, "-").concat(uuid),
style: style
}, rest), /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-list"),
style: getWrapStyle
}, /*#__PURE__*/ React.createElement(ScrollView, {
scrollTop: scrollTop,
scrollY: true,
enhanced: true,
scrollWithAnimation: false,
scrollAnchoring: true,
className: "".concat(classPrefix, "-list-inner"),
onScroll: listViewScroll,
onTouchStart: function(e) {
scrolling.current = false;
}
}, list.map(function(item, idx) {
return /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-list-item nut-elevator-item-").concat(idx),
key: idx
}, /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-list-item-code")
}, item[floorKey]), /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-list-item-sublist")
}, item.list.map(function(subitem) {
var _obj;
return /*#__PURE__*/ React.createElement(View, {
className: classNames((_obj = {}, _define_property(_obj, "".concat(classPrefix, "-list-item-name"), true), _define_property(_obj, "".concat(classPrefix, "-list-item-name-highcolor"), currentData.id === subitem.id), _obj)),
key: subitem.id,
onClick: function() {
return handleClickItem(item[floorKey], subitem);
}
}, children ? /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(elevatorContext.Provider, {
value: subitem
}, children)) : subitem.name);
})));
}))), showKeys ? /*#__PURE__*/ React.createElement(React.Fragment, null, list.length && scrollStart ? /*#__PURE__*/ React.createElement(View, {
className: classNames((_obj = {}, _define_property(_obj, "".concat(classPrefix, "-code-current"), true), _define_property(_obj, "".concat(classPrefix, "-code-current-current"), true), _obj))
}, list[codeIndex] && String(list[codeIndex][floorKey])) : null, /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-bars")
}, /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-bars-inner")
}, list.map(function(item, index) {
var _obj;
return /*#__PURE__*/ React.createElement(View, {
className: classNames((_obj = {}, _define_property(_obj, "".concat(classPrefix, "-bars-inner-item"), true), _define_property(_obj, "".concat(classPrefix, "-bars-inner-item-active"), item[floorKey] === list[codeIndex][floorKey]), _obj)),
"data-index": index,
key: index,
onClick: function() {
return handleClickIndex(item[floorKey]);
},
onTouchStart: function(event) {
return touchStart(event);
},
onTouchMove: function(event) {
return touchMove(event);
},
onTouchEnd: touchEnd,
style: {
touchAction: 'pan-y'
}
}, String(item[floorKey]));
})))) : null, mode === 'vertical' && sticky && scrollY > 0 ? /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-list-fixed")
}, /*#__PURE__*/ React.createElement(Text, {
className: "".concat(classPrefix, "-list-fixed-title")
}, list[codeIndex] && String(list[codeIndex][floorKey]))) : null);
};
Elevator.displayName = 'NutElevator';
Elevator.Context = elevatorContext;