@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
JavaScript
/**
* 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 };