UNPKG

shineout

Version:

Shein 前端组件库

288 lines (254 loc) 10.2 kB
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import React, { Component } from 'react'; import classnames from 'classnames'; import { getKey } from '../utils/uid'; import { setTranslate } from '../utils/dom/translate'; import List from '../AnimationList'; import Scroll from '../Scroll'; import Spin from '../Spin'; import { getLocale } from '../locale'; import { selectClass } from './styles'; import Option from './Option'; import { getDirectionClass } from '../utils/classname'; import { getCustomList } from './utils'; var ScaleList = List(['fade', 'scale-y'], 'fast'); var OptionList = /*#__PURE__*/ function (_Component) { _inheritsLoose(OptionList, _Component); function OptionList(props) { var _this; _this = _Component.call(this, props) || this; _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "optionInner", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "lastScrollTop", void 0); _this.state = { currentIndex: 0, hoverIndex: props.hideCreateOption ? -1 : 0, scrollTop: 0 }; _this.hoverMove = _this.hoverMove.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleHover = _this.handleHover.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleScroll = _this.handleScroll.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleMouseMove = _this.handleMouseMove.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.renderList = _this.renderList.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.lastScrollTop = 0; props.bindOptionFunc('handleHover', _this.handleHover); props.bindOptionFunc('hoverMove', _this.hoverMove); props.bindOptionFunc('getIndex', function () { return _this.state.hoverIndex; }); return _this; } var _proto = OptionList.prototype; _proto.componentDidUpdate = function componentDidUpdate(prevProps) { var _this2 = this; var data = this.props.data; if (data !== prevProps.data && data.length !== prevProps.data.length) { this.lastScrollTop = 0; // eslint-disable-next-line this.setState({ currentIndex: 0, scrollTop: 0 }, function () { if (_this2.optionInner) { setTranslate(_this2.optionInner, '0px', '0px'); _this2.optionInner.style.marginTop = '0px'; } }); } }; _proto.getText = function getText(key) { return this.props.text && this.props.text[key] || getLocale(key); }; _proto.hoverMove = function hoverMove(step) { var max = this.props.data.length; var _this$props = this.props, lineHeight = _this$props.lineHeight, height = _this$props.height, groupKey = _this$props.groupKey; var _this$state = this.state, hoverIndex = _this$state.hoverIndex, currentIndex = _this$state.currentIndex; if (hoverIndex === undefined) hoverIndex = currentIndex;else hoverIndex += step; if (hoverIndex >= max) { hoverIndex = 0; this.lastScrollTop = 0; } // jump the group, the group would't be the last, so do't need to fixed the last var data = this.props.data[hoverIndex]; if (data && data[groupKey]) { if (step > 0) hoverIndex += 1;else hoverIndex -= 1; } if (hoverIndex < 0) hoverIndex = max - 1; var scrollTop = hoverIndex / max; var offset = scrollTop * height; var emptyHeight = hoverIndex * lineHeight + offset; if (emptyHeight < this.lastScrollTop + offset) { // absolute at top this.optionInner.style.marginTop = offset + "px"; setTranslate(this.optionInner, '0px', "-" + emptyHeight + "px"); this.lastScrollTop = emptyHeight - offset; currentIndex = hoverIndex - 1; if (currentIndex < 0) currentIndex = max; this.setState({ currentIndex: currentIndex, scrollTop: emptyHeight / (lineHeight * max) }); } else if (emptyHeight + lineHeight > this.lastScrollTop + offset + height) { // absolute at bottom this.optionInner.style.marginTop = offset + "px"; var scrollHeight = emptyHeight + lineHeight - height; setTranslate(this.optionInner, '0px', "-" + scrollHeight + "px"); this.lastScrollTop = scrollHeight - offset; currentIndex = hoverIndex - Math.ceil(height / lineHeight); if (currentIndex < 0) currentIndex = 0; this.setState({ currentIndex: currentIndex, scrollTop: scrollHeight / (lineHeight * max) }); } else if (hoverIndex === 0 && emptyHeight === 0) { // reset to top this.optionInner.style.marginTop = '0px'; setTranslate(this.optionInner, '0px', '0px'); this.setState({ currentIndex: 0, scrollTop: 0 }); } this.setState({ hoverIndex: hoverIndex }); }; _proto.handleScroll = function handleScroll(_x, y, _max, _bar, _v, h, _pixelX, pixelY) { if (!this.optionInner) return; var _this$props2 = this.props, data = _this$props2.data, itemsInView = _this$props2.itemsInView, lineHeight = _this$props2.lineHeight, autoAdapt = _this$props2.autoAdapt, resetPosition = _this$props2.resetPosition; var fullHeight = itemsInView * lineHeight; var contentHeight = data.length * lineHeight - h; var scrollTop = h > fullHeight ? 0 : y; this.optionInner.style.marginTop = scrollTop * h + "px"; if (pixelY === undefined || pixelY === 0) { this.lastScrollTop = scrollTop * contentHeight; } else { this.lastScrollTop += pixelY; if (this.lastScrollTop < 0) this.lastScrollTop = 0; // scroll over bottom if (this.lastScrollTop > contentHeight) this.lastScrollTop = contentHeight; scrollTop = this.lastScrollTop / contentHeight; this.optionInner.style.marginTop = scrollTop * h + "px"; } var index = Math.floor(this.lastScrollTop / lineHeight) - 1; if (data.length - itemsInView < index) index = data.length - itemsInView; if (index < 0) index = 0; setTranslate(this.optionInner, '0px', "-" + (this.lastScrollTop + scrollTop * h) + "px"); this.setState({ scrollTop: scrollTop, currentIndex: index }); if (autoAdapt && resetPosition) { resetPosition(true); } }; _proto.handleHover = function handleHover(index, force) { if ((this.props.control === 'mouse' || force) && this.state.hoverIndex !== index) { this.setState({ hoverIndex: index }); } }; _proto.handleMouseMove = function handleMouseMove() { this.props.onControlChange('mouse'); }; _proto.renderList = function renderList() { var _this3 = this; var _this$props3 = this.props, loading = _this$props3.loading, data = _this$props3.data, renderPending = _this$props3.renderPending, height = _this$props3.height, lineHeight = _this$props3.lineHeight, itemsInView = _this$props3.itemsInView, datum = _this$props3.datum, keygen = _this$props3.keygen, multiple = _this$props3.multiple, onChange = _this$props3.onChange, renderItem = _this$props3.renderItem, groupKey = _this$props3.groupKey, filterText = _this$props3.filterText, emptyText = _this$props3.emptyText; var _this$state2 = this.state, hoverIndex = _this$state2.hoverIndex, currentIndex = _this$state2.currentIndex; var scroll = ''; var scrollHeight = lineHeight * data.length; if (height < scrollHeight) { scroll = 'y'; } if (loading) return React.createElement("span", { className: selectClass(getDirectionClass('option')) }, typeof loading === 'boolean' ? React.createElement(Spin, { size: 20 }) : loading); if (data.length === 0 || renderPending) return React.createElement("span", { className: selectClass(getDirectionClass('option')) }, emptyText || this.getText('noData')); return React.createElement(Scroll, { scroll: scroll, style: { height: scroll ? height : undefined }, onScroll: this.handleScroll, scrollHeight: data.length * lineHeight, scrollTop: this.state.scrollTop }, React.createElement("div", { ref: function ref(el) { _this3.optionInner = el; } }, React.createElement("div", { style: { height: currentIndex * lineHeight } }), data.slice(currentIndex, currentIndex + itemsInView).map(function (d, i) { return React.createElement(Option, { isActive: datum.check(d), disabled: datum.disabled(d), isHover: hoverIndex === currentIndex + i, key: d && d[groupKey] ? "__" + d[groupKey] + "__" : getKey(d, keygen, i), index: currentIndex + i, data: d, multiple: multiple, onClick: onChange, renderItem: renderItem, onHover: _this3.handleHover, groupKey: groupKey, filterText: filterText }); }))); }; _proto.render = function render() { var _this$props4 = this.props, control = _this$props4.control, focus = _this$props4.focus, style = _this$props4.style, selectId = _this$props4.selectId, autoClass = _this$props4.autoClass, getRef = _this$props4.getRef, customHeader = _this$props4.customHeader, renderOptionList = _this$props4.renderOptionList, loading = _this$props4.loading; var result = React.createElement(React.Fragment, null, customHeader, this.renderList()); return React.createElement(ScaleList, { show: focus, onMouseMove: this.handleMouseMove, style: style, "data-id": selectId, className: classnames(selectClass('options', "control-" + control), autoClass), getRef: getRef }, getCustomList(result, renderOptionList, loading)); }; return OptionList; }(Component); export default OptionList;