@wix/design-system
Version:
@wix/design-system
83 lines • 3.09 kB
JavaScript
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