UNPKG

shineout

Version:

Shein 前端组件库

402 lines (322 loc) 14.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _reactDom = _interopRequireDefault(require("react-dom")); var _classnames = _interopRequireDefault(require("classnames")); var _component = require("../component"); var _popover = require("../utils/dom/popover"); var _is = require("../utils/is"); var _element = require("../utils/dom/element"); var _styles = require("./styles"); var _document = require("../utils/dom/document"); var _isDOMElement = _interopRequireDefault(require("../utils/dom/isDOMElement")); var _context = require("../Table/context"); var _context2 = require("./context"); var _uid = require("../utils/uid"); var _isInDocument = require("../utils/dom/isInDocument"); var _popContainer = _interopRequireDefault(require("../utils/dom/popContainer")); var _context3 = require("../Scroll/context"); var emptyEvent = function emptyEvent(e) { return e.stopPropagation(); }; var DefaultProps = { background: '', trigger: 'hover', mouseEnterDelay: 0, mouseLeaveDelay: 0, priorityDirection: 'vertical', showArrow: true }; var Panel = /*#__PURE__*/ function (_Component) { (0, _inheritsLoose2.default)(Panel, _Component); function Panel(props) { var _this; _this = _Component.call(this, props) || this; (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "isRendered", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "chain", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "id", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "element", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "parentElement", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "placeholder", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "container", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "delayTimeout", void 0); _this.state = { show: props.defaultVisible || false }; _this.isRendered = false; _this.chain = []; _this.id = "popover_" + (0, _uid.getUidStr)(); _this.placeholderRef = _this.placeholderRef.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.clickAway = _this.clickAway.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleShow = _this.handleShow.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleHide = _this.handleHide.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.setShow = _this.setShow.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.bindChain = _this.bindChain.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleCancel = _this.handleCancel.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.createContainer = _this.createContainer.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.element = document.createElement('div'); return _this; } var _proto = Panel.prototype; _proto.componentDidMount = function componentDidMount() { _Component.prototype.componentDidMount.call(this); var bindChain = this.props.bindChain; if (bindChain) bindChain(this.id); this.parentElement = this.placeholder.parentElement; this.bindEvents(); if (this.props.visible) { this.createContainer(); this.forceUpdate(); } }; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { if (this.props.visible === true || nextProps.visible === true) return true; if (this.state.show === true || nextState.show === true) return true; return false; }; _proto.componentDidUpdate = function componentDidUpdate(prevProps) { if (this.props.visible) { this.createContainer(); } if (this.props.trigger !== prevProps.trigger) { this.bindEvents(); } if (this.props.zIndex !== prevProps.zIndex && this.element) { this.element.style.zIndex = String(this.props.zIndex); } }; _proto.componentWillUnmount = function componentWillUnmount() { _Component.prototype.componentWillUnmount.call(this); this.parentElement.removeEventListener('mouseenter', this.handleShow); this.parentElement.removeEventListener('mouseleave', this.handleHide); this.parentElement.removeEventListener('click', this.handleShow); document.removeEventListener('click', this.clickAway); document.removeEventListener('mousedown', this.clickAway); if (!this.container) return; if (this.container === (0, _popContainer.default)()) { if (this.element && this.element.parentNode) { this.element.parentNode.removeChild(this.element); } } else if (this.container && this.container.parentNode) { this.container.parentNode.removeChild(this.container); } }; _proto.setShow = function setShow(show) { var _this2 = this; var _this$props = this.props, onVisibleChange = _this$props.onVisibleChange, mouseEnterDelay = _this$props.mouseEnterDelay, mouseLeaveDelay = _this$props.mouseLeaveDelay, trigger = _this$props.trigger; var delay = show ? mouseEnterDelay : mouseLeaveDelay; this.delayTimeout = setTimeout(function () { if (onVisibleChange) onVisibleChange(show); _this2.setState({ show: show }); if (show && _this2.props.onOpen) _this2.props.onOpen(); if (!show && _this2.props.onClose) _this2.props.onClose(); if (show) { _this2.bindScrollDismiss(true); document.addEventListener('mousedown', _this2.clickAway); } else { _this2.bindScrollDismiss(false); document.removeEventListener('mousedown', _this2.clickAway); } }, trigger === 'hover' ? delay : 0); }; _proto.getPositionStr = function getPositionStr() { var position = this.props.position; var priorityDirection = this.props.priorityDirection; if (position) return position; var rect = this.parentElement.getBoundingClientRect(); var horizontalPoint = rect.left + rect.width / 2; var verticalPoint = rect.top + rect.height / 2; var windowHeight = _document.docSize.height; var windowWidth = _document.docSize.width; var tempPriorityDirection = priorityDirection; if (priorityDirection === 'auto') { var maxX = Math.max(rect.left, windowWidth - rect.left - rect.width); var maxY = Math.max(rect.top, windowHeight - rect.top - rect.height); tempPriorityDirection = maxX > maxY ? 'horizontal' : 'vertical'; } if (tempPriorityDirection === 'horizontal') { if (horizontalPoint > windowWidth / 2) position = 'left';else position = 'right'; if (verticalPoint > windowHeight * 0.6) { position += '-bottom'; } else if (verticalPoint < windowHeight * 0.4) { position += '-top'; } } else { if (verticalPoint > windowHeight / 2) position = 'top';else position = 'bottom'; if (horizontalPoint > windowWidth * 0.6) { position += '-right'; } else if (horizontalPoint < windowWidth * 0.4) { position += '-left'; } } return position; }; _proto.getContainer = function getContainer() { var getPopupContainer = this.props.getPopupContainer; var container; if (getPopupContainer) container = getPopupContainer(); if (container && (0, _isDOMElement.default)(container)) { var child = document.createElement('div'); child.setAttribute('style', ' position: absolute; top: 0px; left: 0px; width: 100% '); return container.appendChild(child); } return (0, _popContainer.default)(); }; _proto.createContainer = function createContainer() { var zIndex = this.props.zIndex; if (!this.container || !(0, _isInDocument.isInDocument)(this.container)) { this.container = this.getContainer(); this.element.style.zIndex = String(zIndex); this.container.appendChild(this.element); } }; _proto.updatePosition = function updatePosition(position) { var _this3 = this; var pos = (0, _popover.getPosition)(position, this.parentElement, this.container); // eslint-disable-next-line Object.keys(pos).forEach(function (attr) { _this3.element.style[attr] = String(pos[attr]); }); }; _proto.bindEvents = function bindEvents() { var _this$props2 = this.props, trigger = _this$props2.trigger, clickToCancelDelay = _this$props2.clickToCancelDelay, _this$props2$mouseEnt = _this$props2.mouseEnterDelay, mouseEnterDelay = _this$props2$mouseEnt === void 0 ? DefaultProps.mouseEnterDelay : _this$props2$mouseEnt; if (trigger === 'hover') { this.parentElement.addEventListener('mouseenter', this.handleShow); this.parentElement.addEventListener('mouseleave', this.handleHide); this.element.addEventListener('mouseenter', this.handleShow); this.element.addEventListener('mouseleave', this.handleHide); this.parentElement.removeEventListener('click', this.handleShow); if (clickToCancelDelay && mouseEnterDelay > 0) { this.parentElement.addEventListener('click', this.handleCancel); } } else { this.parentElement.addEventListener('click', this.handleShow); this.parentElement.removeEventListener('click', this.handleCancel); this.parentElement.removeEventListener('mouseenter', this.handleShow); this.parentElement.removeEventListener('mouseleave', this.handleHide); this.element.removeEventListener('mouseenter', this.handleShow); this.element.removeEventListener('mouseleave', this.handleHide); } }; _proto.placeholderRef = function placeholderRef(el) { this.placeholder = el; }; _proto.clickAway = function clickAway(e) { var target = e.target; if (this.parentElement.contains(target)) return; if (this.element.contains(target)) return; if ((0, _element.getParent)(target, "." + (0, _styles.popoverClass)('_'))) return; this.handleHide(0); }; _proto.bindScrollDismiss = function bindScrollDismiss(show) { var scrollDismiss = this.props.scrollDismiss; if (!scrollDismiss) return; var target = document; if (typeof scrollDismiss === 'function') target = scrollDismiss() || document; var method = show ? target.addEventListener : target.removeEventListener; method.call(target, 'scroll', this.handleHide); }; _proto.bindChain = function bindChain(id) { this.chain.push(id); }; _proto.handleShow = function handleShow() { this.createContainer(); if (this.delayTimeout) clearTimeout(this.delayTimeout); if (this.state.show) return; this.setShow(true); }; _proto.isChildren = function isChildren(el) { for (var i = 0; i < this.chain.length; i++) { if ((0, _element.getParent)(el, "." + this.chain[i])) return true; } return false; }; _proto.handleCancel = function handleCancel() { if (this.delayTimeout) clearTimeout(this.delayTimeout); }; _proto.handleHide = function handleHide(e) { if (e && this.isChildren(e.relatedTarget)) return; if (this.delayTimeout) clearTimeout(this.delayTimeout); this.setShow(false); }; _proto.render = function render() { var _this$props3 = this.props, background = _this$props3.background, border = _this$props3.border, children = _this$props3.children, type = _this$props3.type, visible = _this$props3.visible, showArrow = _this$props3.showArrow, useTextStyle = _this$props3.useTextStyle, destroy = _this$props3.destroy; var show = typeof visible === 'boolean' ? visible : this.state.show; if ((!this.isRendered || destroy) && !show || !this.parentElement || !children) { return _react.default.createElement("noscript", { ref: this.placeholderRef }); } this.isRendered = true; var colorStyle = { background: background, borderColor: border }; var innerStyle = Object.assign({}, this.props.style, { background: background }); var position = this.getPositionStr(); // eslint-disable-next-line var style = this.element.style; if (show) { // 先隐藏再设置样式这样可以减少回流 style.display = 'none'; this.updatePosition(position); if (background) style.background = background; if (border) style.borderColor = border; style.display = 'block'; } else { style.display = 'none'; } this.element.className = (0, _classnames.default)((0, _styles.popoverClass)('_', position, type), this.props.className, this.id); var childrened = (0, _is.isFunc)(children) ? children(this.handleHide) : children; if (typeof childrened === 'string' || useTextStyle) childrened = _react.default.createElement("span", { className: (0, _styles.popoverClass)('text') }, childrened); return _reactDom.default.createPortal([showArrow && _react.default.createElement("div", { key: "arrow", className: (0, _styles.popoverClass)('arrow'), style: colorStyle }), _react.default.createElement("div", { key: "content", onClick: emptyEvent, className: (0, _styles.popoverClass)('content'), style: innerStyle }, _react.default.createElement(_context2.Provider, { value: this.bindChain }, _react.default.createElement(_context3.Provider, { value: { element: undefined } }, _react.default.createElement(_context.Provider, { value: false }, childrened))))], this.element); }; return Panel; }(_component.Component); (0, _defineProperty2.default)(Panel, "defaultProps", DefaultProps); var _default = (0, _context2.consumer)(Panel); exports.default = _default;