UNPKG

reblend-ui

Version:

Utilities for creating robust overlay components

140 lines (137 loc) 4.93 kB
"use strict"; exports.__esModule = true; exports.default = void 0; var _reblendjs = require("reblendjs"); var Reblend = _reblendjs; var _reblendHooks = require("reblend-hooks"); var _usePopper = require("./usePopper"); var _useRootClose = require("./useRootClose"); var _useWaitForDOMRef = require("./useWaitForDOMRef"); var _mergeOptionsWithPopperConfig = require("./mergeOptionsWithPopperConfig"); var _ImperativeTransition = require("./ImperativeTransition"); /** * Built on top of `Popper.js`, the overlay component is * great for custom tooltip overlays. */ const Overlay = class /* @Reblend: Transformed from function to class */ extends Reblend.Reblend { static ELEMENT_NAME = "Overlay"; constructor() { super(); } async initState() { const { flip, offset, placement, containerPadding, popperConfig = {}, transition: Transition, runTransition } = this.props; this.state.flip = flip; this.state.offset = offset; this.state.placement = placement; this.state.containerPadding = containerPadding; this.state.popperConfig = popperConfig; this.state.Transition = Transition; this.state.runTransition = runTransition; const [rootElement, attachRef] = _reblendHooks.useCallbackRef.bind(this)(); this.state.rootElement = rootElement; this.state.attachRef = attachRef; const [arrowElement, attachArrowRef] = _reblendHooks.useCallbackRef.bind(this)(); this.state.arrowElement = arrowElement; this.state.attachArrowRef = attachArrowRef; const mergedRef = _reblendHooks.useMergedRefs.bind(this)(this.state.attachRef, this.props.outerRef); this.state.mergedRef = mergedRef; const container = _useWaitForDOMRef.default.bind(this)(this.props.container); this.state.container = container; const target = _useWaitForDOMRef.default.bind(this)(this.props.target); this.state.target = target; const [exited, setExited] = _reblendjs.useState.bind(this)(!this.props.show, "exited"); this.state.exited = exited; this.state.setExited = setExited; const popper = _usePopper.default.bind(this)(this.state.target, this.state.rootElement, (0, _mergeOptionsWithPopperConfig.default)({ placement: this.state.placement, enableEvents: !!this.props.show, containerPadding: this.state.containerPadding || 5, flip: this.state.flip, offset: this.state.offset, arrowElement: this.state.arrowElement, popperConfig: this.state.popperConfig })); // TODO: I think this needs to be in an effect this.state.popper = popper; if (this.props.show && this.state.exited) { this.state.setExited(false); } const handleHidden = (...args) => { this.state.setExited(true); if (this.props.onExited) { this.props.onExited(...args); } }; // Don't un-render the overlay while it's transitioning out. this.state.handleHidden = handleHidden; const mountOverlay = this.props.show || !this.state.exited; this.state.mountOverlay = mountOverlay; _useRootClose.default.bind(this)(this.state.rootElement, this.props.onHide, { disabled: !this.props.rootClose || this.props.rootCloseDisabled, clickTrigger: this.props.rootCloseEvent }); if (!this.state.mountOverlay) { // Don't bother showing anything if we don't have to. return null; } const { onExit, onExiting, onEnter, onEntering, onEntered } = this.props; this.state.onExit = onExit; this.state.onExiting = onExiting; this.state.onEnter = onEnter; this.state.onEntering = onEntering; this.state.onEntered = onEntered; let child = this.props.children({ ...this.state.popper.attributes.popper, style: this.state.popper.styles.popper, ref: this.state.mergedRef }, { popper: this.state.popper, placement: this.state.placement, show: !!this.props.show, arrowProps: { ...this.state.popper.attributes.arrow, style: this.state.popper.styles.arrow, ref: this.state.attachArrowRef } }); this.state.child = child; this.state.child = (0, _ImperativeTransition.renderTransition)(this.state.Transition, this.state.runTransition, { in: !!this.props.show, appear: true, mountOnEnter: true, unmountOnExit: true, children: this.state.child, onExit: this.state.onExit, onExiting: this.state.onExiting, onExited: this.state.handleHidden, onEnter: this.state.onEnter, onEntering: this.state.onEntering, onEntered: this.state.onEntered }); } async initProps(props) { this.props = {}; this.props = props; } async html() { return this.state.container ? Reblend.createPortal(this.state.child, this.state.container) : null; } }; Overlay.displayName = 'Overlay'; var _default = exports.default = Overlay;