UNPKG

@d8660091/react-popper

Version:

A React component for displaying popper based on popper.js

131 lines (124 loc) 3.68 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; import React from 'react'; import PropTypes from 'prop-types'; import Popper from 'popper.js'; import { compose, lifecycle, setDisplayName, setPropTypes, withHandlers, withStateHandlers } from 'recompose'; var enhance = compose(setDisplayName('Popper'), setPropTypes({ renderRef: PropTypes.any.isRequired, renderPop: PropTypes.func, children: PropTypes.any, options: PropTypes.object, defaultIsOpened: PropTypes.bool, canClickOutside: PropTypes.bool }), withStateHandlers({ reference: null }, { setReference: function setReference() { return function (reference) { if (reference) { return { reference: reference }; } }; } }), withStateHandlers({ pop: null, popper: null }, { setPop: function setPop(_ref, props) { var prevPopper = _ref.popper; return function (pop) { if (prevPopper) { prevPopper.destroy(); } var popper = pop ? new Popper(props.reference, pop, props.options) : null; return { pop: pop, popper: popper }; }; } }), withStateHandlers(function (_ref2) { var _ref2$defaultIsOpened = _ref2.defaultIsOpened, defaultIsOpened = _ref2$defaultIsOpened === undefined ? false : _ref2$defaultIsOpened; return { isOpened: defaultIsOpened }; }, { open: function open(_, props) { return function () { return { isOpened: true }; }; }, close: function close() { return function () { return { isOpened: false }; }; }, toggle: function toggle(_ref3, props) { var isOpened = _ref3.isOpened; return function () { return { isOpened: !isOpened }; }; } }), withHandlers({ onClick: function onClick(props) { return function (e) { if (props.reference && !props.canClickOutside && !e.canBeIgnoredByReactPopper) { var isInsidePop = props.pop && props.pop.contains(e.target); if (!props.reference.contains(e.target) && !isInsidePop) { // click outside props.close(); } } }; } }), lifecycle({ componentDidUpdate: function componentDidUpdate() { if (this.props.popper) { this.props.popper.scheduleUpdate(); } }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (this.props.options != nextProps.options && this.props.pop) { this.props.setPop(this.props.pop); } }, componentWillMount: function componentWillMount() { document.addEventListener('mousedown', this.props.onClick); }, componentWillUnmount: function componentWillUnmount() { document.removeEventListener('mousedown', this.props.onClick); if (this.props.popper) { this.props.popper.destroy(); } } })); export default enhance(function (props) { return React.createElement( React.Fragment, null, props.renderRef(_extends({}, props)), props.isOpened && (props.renderPop ? props.renderPop(_extends({}, props)) : React.createElement( 'div', { ref: props.setPop, style: props.style, className: props.className }, props.children )) ); }); export var ClickableArea = function ClickableArea(props) { return React.createElement( 'div', { ref: function ref(el) { return el && el.addEventListener('mousedown', ignoreEvent); } }, props.children ); }; function ignoreEvent(e) { e.canBeIgnoredByReactPopper = true; }