UNPKG

@livelybone/react-popper

Version:

A wrap of react-popper, achieved visible controlling via click/hover event or ref.show/ref.hide/ref.toggle

404 lines (353 loc) 12.9 kB
/** * Bundle of @livelybone/react-popper * Generated: 2020-03-29 * Version: 1.8.2 * License: MIT * Author: 2631541504@qq.com */ import React, { Component } from 'react'; import { Popper } from 'react-popper'; import PopperJs from 'popper.js'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); } function _typeof(obj) { if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") { _typeof = function _typeof(obj) { return _typeof2(obj); }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj); }; } return _typeof(obj); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function arrowModifier(arrowPosition, arrowOffset) { for (var _len = arguments.length, _ref = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { _ref[_key - 2] = arguments[_key]; } var dataObject = _ref[0], options = _ref[1]; // @ts-ignore var data = PopperJs.Defaults.modifiers.arrow.fn(dataObject, options); var posTypeNeedSet = /^(bottom|top)/.test(data.placement) ? 'left' : 'top'; data.offsets.arrow[posTypeNeedSet] = convertPos(data, posTypeNeedSet, arrowPosition, arrowOffset); return data; } function convertPos(data, type) { var arrowPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'middle'; var arrowOffset = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 15; var _data$offsets = data.offsets, _data$offsets$arrow = _data$offsets.arrow, left = _data$offsets$arrow.left, top = _data$offsets$arrow.top, reference = _data$offsets.reference, popper = _data$offsets.popper, arrowElement = data.arrowElement; var pos = type === 'left' ? left : top; var pos1 = 0; var altSide = type === 'left' ? 'left' : 'top'; var len = type === 'left' ? 'width' : 'height'; var offsetSize = type === 'left' ? 'offsetWidth' : 'offsetHeight'; var clientSize = type === 'left' ? 'clientWidth' : 'clientHeight'; var size = arrowElement[offsetSize] || arrowElement[clientSize]; if (arrowPosition === 'start') { pos1 = arrowOffset + Math.max(0, -(popper[altSide] - reference[altSide])); } else if (arrowPosition === 'end') { pos1 = Math.min(reference[len], popper[len]) - Math.min(0, popper[altSide] - reference[altSide]) - arrowOffset - size; } else if (pos < arrowOffset) { pos1 = arrowOffset; } else if (pos > popper[len] - size - arrowOffset) { pos1 = popper[len] - size - arrowOffset; } else { pos1 = pos; } return pos1; } var TriggerType; (function (TriggerType) { TriggerType[TriggerType["click"] = 0] = "click"; TriggerType[TriggerType["hover"] = 1] = "hover"; })(TriggerType || (TriggerType = {})); function containsOrEqual(parent, target) { if (!target || !(parent instanceof HTMLElement)) return false; return parent && parent.contains(target); } function getReferenceEl(popperRef, referenceRef) { var ref = typeof referenceRef === 'function' ? referenceRef() : referenceRef; return ref || popperRef && popperRef.parentElement || undefined; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var ReactPopper = /*#__PURE__*/ function (_Component) { _inherits(ReactPopper, _Component); /** * scheduleUpdate of popper * */ function ReactPopper(props) { var _this; _classCallCheck(this, ReactPopper); _this = _possibleConstructorReturn(this, _getPrototypeOf(ReactPopper).call(this, props)); _this.scheduleUpdate = void 0; _this.popperRef = void 0; _this.arrowRef = void 0; _this.timer = { type: '', id: null }; _this.show = function (ev) { if (_this.shouldToggle(true, _assertThisInitialized(_this), ev) && (!_this.delayShow && !_this.state.visible || _this.timer.type !== 'show')) { clearTimeout(_this.timer.id); var fn = function fn() { if (_this.popperRef) { var visible = _this.visible; _this.setState({ visible: true }, function () { _this.afterToggle(visible); _this.scheduleUpdate(); }); } }; if (_this.delayShow) _this.timer.id = setTimeout(fn, _this.delayShow);else fn(); _this.timer.type = 'show'; } }; _this.hide = function (ev) { if (_this.shouldToggle(false, _assertThisInitialized(_this), ev) && (!_this.delayHide && _this.state.visible || _this.timer.type !== 'hide')) { clearTimeout(_this.timer.id); var fn = function fn() { if (_this.popperRef) { _this.setState({ visible: false }, _this.afterToggle.bind(null, _this.visible)); } }; if (_this.delayHide) _this.timer.id = setTimeout(fn, _this.delayHide);else fn(); _this.timer.type = 'hide'; } }; _this.toggle = function (ev) { if (_this.state.visible) _this.hide(ev);else _this.show(ev); }; _this.eventHandler = function (ev) { if (!containsOrEqual(_this.popperRef, ev.target)) { if (!containsOrEqual(_this.referenceEl, ev.target)) _this.hide(ev);else if (_this.isHover) _this.show(ev);else _this.toggle(ev); } else _this.show(ev); }; _this.afterToggle = function (prevVisible) { if (_this.props.afterToggle && prevVisible !== _this.visible) _this.props.afterToggle(_this.visible, _assertThisInitialized(_this)); }; _this.state = { visible: false, isMounted: false }; return _this; } _createClass(ReactPopper, [{ key: "componentDidMount", value: function componentDidMount() { this.setState({ isMounted: true }); window.addEventListener(this.eventName, this.eventHandler, true); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { window.removeEventListener(this.eventName, this.eventHandler, true); } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, placement = _this$props.placement, className = _this$props.className, forceShow = _this$props.forceShow, children = _this$props.children, _this$props$positionF = _this$props.positionFixed, positionFixed = _this$props$positionF === void 0 ? true : _this$props$positionF; var _this$state = this.state, visible = _this$state.visible, isMounted = _this$state.isMounted; return React.createElement(Popper, { positionFixed: positionFixed, placement: placement || 'bottom-start', referenceElement: this.referenceEl, modifiers: this.modifiers }, function (props) { var _ref = props.ref, style = props.style, $placement = props.placement, arrowProps = props.arrowProps, scheduleUpdate = props.scheduleUpdate; _this2.scheduleUpdate = scheduleUpdate; return React.createElement("div", { ref: function ref(el) { _ref(el); _this2.popperRef = el; }, className: "react-popper ".concat(className || '', " ").concat(forceShow ? 'force-show' : '', " ").concat(!isMounted || !visible ? 'hide' : 'show').replace(/\s+(?=(\s|$))/g, ''), style: style, "data-placement": $placement }, React.createElement("div", { className: "arrow", "data-placement": $placement, "data-x-arrow": true, ref: function ref(arrowEl) { arrowProps.ref(arrowEl); _this2.arrowRef = arrowEl; }, style: arrowProps.style }), typeof children === 'function' ? children(_objectSpread({}, props, { popperRef: _this2 })) : children); }); } }, { key: "referenceEl", get: function get() { return getReferenceEl(this.popperRef, this.props.referenceRef); } }, { key: "isHover", get: function get() { return this.props.trigger === TriggerType.hover; } }, { key: "eventName", get: function get() { return this.isHover ? 'mouseover' : 'click'; } }, { key: "modifiers", get: function get() { var _this$props2 = this.props, modifiers = _this$props2.modifiers, arrowOffset = _this$props2.arrowOffset, arrowPosition = _this$props2.arrowPosition; return _objectSpread({}, modifiers, { arrow: _objectSpread({}, modifiers, { element: this.arrowRef, fn: arrowModifier.bind(null, arrowPosition, arrowOffset) }) }); } }, { key: "visible", get: function get() { return this.props.forceShow || this.state.visible; } }, { key: "delayShow", get: function get() { return this.props.delayShow || 0; } }, { key: "delayHide", get: function get() { return this.props.delayHide || (this.isHover ? 200 : 0); } }, { key: "shouldToggle", get: function get() { return this.props.shouldToggle || function () { return true; }; } /** * Show the popper * * Use it outside the component: * * <ReactPopper ref={compInstance => ref = compInstance}></ReactPopper> * ref.show() * */ }]); return ReactPopper; }(Component); export default ReactPopper; export { TriggerType, arrowModifier, containsOrEqual, convertPos, getReferenceEl };