UNPKG

shineout

Version:

Shein 前端组件库

390 lines (330 loc) 12.5 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; import _createClass from "@babel/runtime/helpers/createClass"; import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectSpread from "@babel/runtime/helpers/objectSpread"; import React from 'react'; import { PureComponent } from '../component'; import { defaultProps } from '../utils/defaultProps'; import { getParent } from '../utils/dom/element'; import Button from '../Button'; import { dropdownClass } from './styles'; import List from '../AnimationList'; import Item from './Item'; import { docSize } from '../utils/dom/document'; import absoluteList from '../AnimationList/AbsoluteList'; import { getUidStr } from '../utils/uid'; import { isFunc } from '../utils/is'; import absoluteComsumer from '../Table/context'; import Caret from '../icons/Caret'; import { isRTL } from '../config'; import { getDirectionClass } from '../utils/classname'; import getDataset from '../utils/dom/getDataset'; var positionMap = { 'left-top': 'left-top', 'left-bottom': 'left-bottom', 'right-top': 'right-top', 'right-bottom': 'right-bottom', 'top-right': 'left-bottom', 'top-left': 'right-bottom', 'bottom-right': 'left-top', 'bottom-left': 'right-top', auto: '' }; var DefaultProps = _objectSpread({}, defaultProps, { data: [], animation: true, disabled: false, trigger: 'click', position: 'bottom-left' }); var Dropdown = /*#__PURE__*/ function (_PureComponent) { _inheritsLoose(Dropdown, _PureComponent); function Dropdown(props) { var _this; _this = _PureComponent.call(this, props) || this; _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "dropdownId", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleMouseEnter", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleMouseLeave", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "element", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "DropdownList", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "closeTimer", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "focus", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "lastFoucs", void 0); _this.state = { show: false }; // @ts-ignore if (props.hover !== undefined) { console.warn('The "hover" property is not recommend, use trigger="hover" instead.'); } _this.dropdownId = "dropdown_" + getUidStr(); _this.bindElement = _this.bindElement.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.clickAway = _this.clickAway.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleFocus = _this.handleFocus.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleHide = _this.handleHide.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleMouseEnter = _this.handleToggle.bind(_assertThisInitialized(_assertThisInitialized(_this)), true); _this.handleMouseLeave = _this.handleToggle.bind(_assertThisInitialized(_assertThisInitialized(_this)), false); _this.renderList = _this.renderList.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.bindList(); return _this; } var _proto = Dropdown.prototype; _proto.componentDidMount = function componentDidMount() { _PureComponent.prototype.componentDidMount.call(this); this.setOpenEvent(); }; _proto.componentDidUpdate = function componentDidUpdate() { this.setOpenEvent(); }; _proto.componentWillUnmount = function componentWillUnmount() { _PureComponent.prototype.componentWillUnmount.call(this); this.toggleDocumentEvent(false); }; _proto.setOpenEvent = function setOpenEvent() { if (this.lastFoucs !== this.show) if (this.show) { this.toggleDocumentEvent(true); } else if (this.lastFoucs !== undefined) { this.toggleDocumentEvent(false); } this.lastFoucs = this.show; }; _proto.getTrigger = function getTrigger() { // @ts-ignore if (this.props.hover === true) return 'hover'; return this.props.trigger; }; _proto.getPosition = function getPosition() { var position = this.props.position; if (position !== 'auto') return position; if (!this.element) return 'bottom-left'; var windowHeight = docSize.height; var windowWidth = docSize.width; var rect = this.element.getBoundingClientRect(); var prefix = rect.bottom > windowHeight / 2 ? 'top-' : 'bottom-'; var suffix = rect.right > windowWidth / 2 ? 'right' : 'left'; position = prefix + suffix; return position; }; _proto.bindElement = function bindElement(el) { this.element = el; }; _proto.bindList = function bindList() { var animation = this.props.animation; var FadeList = List('fade', animation ? 'fast' : 0); // @ts-ignore this.DropdownList = absoluteList(function (_ref) { var focus = _ref.focus, other = _objectWithoutPropertiesLoose(_ref, ["focus"]); return React.createElement(FadeList, _extends({ show: focus }, other)); }); }; _proto.toggleDocumentEvent = function toggleDocumentEvent(bind) { var method = bind ? 'addEventListener' : 'removeEventListener'; document[method]('mousedown', this.clickAway, true); }; _proto.clickAway = function clickAway(e) { var absolute = this.props.absolute; var el = getParent(e.target, 'a'); var onSelf = absolute ? getParent(e.target, "[data-id=" + this.dropdownId + "]") : el === this.element || this.element.contains(el); if (el && onSelf && el.getAttribute('data-role') === 'item') return; this.handleHide(0); }; _proto.handleFocus = function handleFocus() { var onCollapse = this.props.onCollapse; if (this.closeTimer) { clearTimeout(this.closeTimer); } if (this.show) return; if (onCollapse) onCollapse(true); this.setState({ show: true }); }; _proto.handleHide = function handleHide(delay) { var _this2 = this; if (delay === void 0) { delay = 200; } var onCollapse = this.props.onCollapse; this.closeTimer = setTimeout(function () { if (onCollapse) onCollapse(false); _this2.setState({ show: false }); }, delay); }; _proto.handleToggle = function handleToggle(show) { var disabled = this.props.disabled; if (disabled === true) return; if (this.getTrigger() === 'click') return; if (show) { this.handleFocus(); } else this.handleHide(); }; _proto.renderRTLButton = function renderRTLButton(placeholder, spanClassName, caret, buttonClassName) { var _this$props = this.props, isSub = _this$props.isSub, type = _this$props.type, outline = _this$props.outline, size = _this$props.size, disabled = _this$props.disabled; if (isSub) { return React.createElement("a", { key: "button", className: dropdownClass('button', 'item', this.show && 'active'), "data-role": "item", onClick: this.handleFocus }, React.createElement("span", { className: spanClassName }, placeholder), caret); } return React.createElement(Button, { disabled: disabled, onClick: this.handleFocus, outline: outline, className: buttonClassName, type: type, size: size, key: "button" }, React.createElement("span", { className: spanClassName }, placeholder), caret); }; _proto.renderButton = function renderButton(placeholder) { var _this$props2 = this.props, type = _this$props2.type, outline = _this$props2.outline, size = _this$props2.size, disabled = _this$props2.disabled, isSub = _this$props2.isSub, position = _this$props2.position; var rtl = isRTL(); var buttonClassName = dropdownClass('button', !placeholder && 'split-button', rtl && 'rtl'); var spanClassName = dropdownClass('button-content'); var caret = React.createElement("span", { key: "caret", className: dropdownClass('caret', rtl && 'rtl') }, React.createElement(Caret, null)); var childs = [React.createElement("span", { key: "text", className: spanClassName }, placeholder), caret]; if (['left-bottom', 'left-top'].includes(position)) { childs.reverse(); } if (isSub) { return React.createElement("a", { key: "button", className: dropdownClass('button', 'item', this.show && 'active'), "data-role": "item", onClick: this.handleFocus }, childs); } return React.createElement(Button, { disabled: disabled, onClick: this.handleFocus, outline: outline, className: buttonClassName, type: type, size: size, key: "button" }, childs); }; _proto.renderList = function renderList(data, placeholder, position) { var _this3 = this; var _this$props3 = this.props, width = _this$props3.width, onClick = _this$props3.onClick, columns = _this$props3.columns, renderItem = _this$props3.renderItem, absolute = _this$props3.absolute; if (!Array.isArray(data) || data.length === 0) return null; var DropdownList = this.DropdownList; return [React.createElement(DropdownList, { absolute: absolute, parentElement: this.element, position: position, className: dropdownClass(getDirectionClass('menu'), columns !== undefined && columns > 1 && 'box-list', isRTL() && 'rtl'), style: { width: width }, key: "list", focus: this.show, "data-id": this.dropdownId, fixed: "min" }, data.map(function (d, index) { var childPosition = positionMap[position]; var itemClassName = dropdownClass('item', !width && 'no-width', childPosition.indexOf('left') === 0 && 'item-left'); var renderPlaceholder; if (renderItem) { renderPlaceholder = isFunc(renderItem) ? renderItem(d) : d[renderItem]; } else { renderPlaceholder = d.content; } var children = d.children; return children ? React.createElement(Dropdown, { style: { width: '100%' }, data: children, disabled: !!d.disabled, placeholder: renderPlaceholder, type: "link", key: index, position: childPosition, onClick: onClick, renderItem: renderItem, trigger: _this3.getTrigger(), isSub: true }) : React.createElement(Item, { data: d, key: index, onClick: d.onClick || onClick, itemClassName: itemClassName, renderItem: renderItem, columns: columns, width: width }); })), this.renderButton(placeholder)]; }; _proto.render = function render() { var _this$props4 = this.props, data = _this$props4.data, className = _this$props4.className, style = _this$props4.style, placeholder = _this$props4.placeholder; // const { show } = this.state var position = this.getPosition(); var wrapClassName = dropdownClass('_', position, this.show && 'show', { 'split-dropdown': !placeholder, rtl: isRTL() }); if (className) wrapClassName += " " + className; return React.createElement("div", _extends({ ref: this.bindElement, className: wrapClassName, style: style, onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave }, getDataset(this.props)), this.renderList(data, placeholder, position)); }; _createClass(Dropdown, [{ key: "show", get: function get() { if ('open' in this.props) { return !!this.props.open; } return this.state.show; } }]); return Dropdown; }(PureComponent); _defineProperty(Dropdown, "defaultProps", DefaultProps); _defineProperty(Dropdown, "displayName", void 0); Dropdown.displayName = 'ShineoutDropdown'; var exports = absoluteComsumer(Dropdown); export default exports;