UNPKG

@wix/design-system

Version:

@wix/design-system

83 lines 3.09 kB
import React, { PureComponent } from 'react'; import PopoverNext from '../../PopoverNext'; import { Mode } from './constants'; const controlledErrorMsg = method => `ClosablePopover.${method}() can not be called when component is Controlled. (opened prop should be undefined)`; /** * Closable Popover * Either a normal Controlled Popover, or a Popover that is initially opened and can be the closed by * calling a closeAction. */ class ClosablePopover extends PureComponent { constructor() { super(...arguments); this.state = { open: this.props.initiallyOpened, mode: this.props.initiallyOpened ? Mode.ClickToClose : Mode.Hover, }; this.open = () => this._doOpen(Mode.ClickToClose); this._doOpen = nextMode => { !this.state.open && this.setState({ open: true, mode: nextMode, }, () => { this.props.onOpen && this.props.onOpen(); }); }; this.close = () => { if (this._isControlled()) { throw new Error(controlledErrorMsg('close')); } this.state.open && this.setState({ open: false, mode: Mode.Hover, }, () => { this.props.onClose && this.props.onClose(); }); }; this._handleMouseEnter = () => { if (this.state.mode === Mode.Hover) { this._doOpen(Mode.Hover); } }; this._handleMouseLeave = () => { if (this.state.mode === Mode.Hover && this.props.closeOnMouseLeave) { this.close(); } }; this.actions = { close: this.close, }; } _isControlled() { return typeof this.props.opened === 'boolean'; } render() { const { content, skin, target, children, onClose, onOpen, initiallyOpened, closeOnMouseLeave, hideDelay, moveBy, ...rest } = this.props; const open = this._isControlled() ? this.props.opened : this.state.open; const popoverProps = { appendTo: 'parent', ...rest, skin, animate: true, open, onMouseEnter: this._handleMouseEnter, onMouseLeave: this._handleMouseLeave, }; return (React.createElement(PopoverNext, { ...popoverProps, onOpenChange: () => { }, moveBy: { y: (moveBy?.y ?? 0) + 3, x: moveBy?.x ?? 0, }, focusManagerEnabled: false, autoUpdateOptions: { animationFrame: true } }, React.createElement(PopoverNext.Trigger, null, React.createElement("span", null, target)), React.createElement(PopoverNext.Content, null, content(this.actions)))); } } ClosablePopover.defaultProps = { hideDelay: 0, initiallyOpened: true, closeOnMouseLeave: true, }; export default ClosablePopover; //# sourceMappingURL=ClosablePopover.js.map