/*
 * Copyright 2021 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import classNames from "classnames";
import * as React from "react";
import { Manager, Popper, Reference, } from "react-popper";
import { AbstractPureComponent, Classes, DISPLAYNAME_PREFIX, mergeRefs, refHandler, Utils, } from "../../common";
import * as Errors from "../../common/errors";
import { Overlay2 } from "../overlay2/overlay2";
import { ResizeSensor } from "../resize-sensor/resizeSensor";
// eslint-disable-next-line import/no-cycle
import { Tooltip } from "../tooltip/tooltip";
import { matchReferenceWidthModifier } from "./customModifiers";
import { POPOVER_ARROW_SVG_SIZE, PopoverArrow } from "./popoverArrow";
import { positionToPlacement } from "./popoverPlacementUtils";
import { getBasePlacement, getTransformOrigin } from "./popperUtils";
export const PopoverInteractionKind = {
    CLICK: "click",
    CLICK_TARGET_ONLY: "click-target",
    HOVER: "hover",
    HOVER_TARGET_ONLY: "hover-target",
};
/**
 * Popover component, used to display a floating UI next to and tethered to a target element.
 *
 * @template T target element props interface. Consumers wishing to stay in sync with Blueprint's default target HTML
 * props interface should use the `DefaultPopoverTargetHTMLProps` type (although this is already the default type for
 * this type param).
 * @see https://blueprintjs.com/docs/#core/components/popover
 */
export class Popover extends AbstractPureComponent {
    static displayName = `${DISPLAYNAME_PREFIX}.Popover`;
    static defaultProps = {
        boundary: "clippingParents",
        captureDismiss: false,
        defaultIsOpen: false,
        disabled: false,
        fill: false,
        hasBackdrop: false,
        hoverCloseDelay: 300,
        hoverOpenDelay: 150,
        inheritDarkTheme: true,
        interactionKind: PopoverInteractionKind.CLICK,
        matchTargetWidth: false,
        minimal: false,
        openOnTargetFocus: true,
        // N.B. we don't set a default for `placement` or `position` here because that would trigger
        // a warning in validateProps if the other prop is specified by a user of this component
        positioningStrategy: "absolute",
        renderTarget: undefined,
        shouldReturnFocusOnClose: false,
        targetTagName: "span",
        transitionDuration: 300,
        usePortal: true,
    };
    state = {
        hasDarkParent: false,
        isClosingViaEscapeKeypress: false,
        isOpen: this.getIsOpen(this.props),
    };
    /**
     * DOM element that contains the popover.
     * When `usePortal={true}`, this element will be portaled outside the usual DOM flow,
     * so this reference can be very useful for testing.
     *
     * @public for testing
     */
    popoverElement = null;
    /** Popover ref handler */
    popoverRef = refHandler(this, "popoverElement", this.props.popoverRef);
    /**
     * Target DOM element ref.
     *
     * N.B. this must be a ref object since we pass it to `<ResizeSensor>`, which needs to know about the target
     * DOM element in order to observe its dimensions.
     *
     * @public for testing
     */
    targetRef = React.createRef();
    /**
     * Overlay2 transition container element ref.
     */
    transitionContainerElement = React.createRef();
    cancelOpenTimeout;
    // a flag that lets us detect mouse movement between the target and popover,
    // now that mouseleave is triggered when you cross the gap between the two.
    isMouseInTargetOrPopover = false;
    // a flag that indicates whether the target previously lost focus to another
    // element on the same page.
    lostFocusOnSamePage = true;
    // Reference to the Poppper.scheduleUpdate() function, this changes every time the popper is mounted
    popperScheduleUpdate;
    isControlled = () => this.props.isOpen !== undefined;
    // arrow is disabled if minimal, or if the arrow modifier was explicitly disabled
    isArrowEnabled = () => !this.props.minimal && this.props.modifiers?.arrow?.enabled !== false;
    isHoverInteractionKind = () => {
        return (this.props.interactionKind === PopoverInteractionKind.HOVER ||
            this.props.interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY);
    };
    // popper innerRef gives us a handle on the transition container, since that's what we render as the overlay child,
    // so if we want to look at our actual popover element, we need to reach inside a bit
    getPopoverElement() {
        return this.popoverElement?.querySelector(`.${Classes.POPOVER}`);
    }
    getIsOpen(props) {
        // disabled popovers should never be allowed to open.
        if (props.disabled) {
            return false;
        }
        else {
            return props.isOpen ?? props.defaultIsOpen;
        }
    }
    render() {
        const { disabled, placement, position = "auto", positioningStrategy } = this.props;
        const { isOpen } = this.state;
        if (this.getIsContentEmpty()) {
            // need to do this check in render(), because `isOpen` is derived from
            // state, and state can't necessarily be accessed in validateProps.
            if (!disabled && isOpen !== false && !Utils.isNodeEnv("production")) {
                console.warn(Errors.POPOVER_WARN_EMPTY_CONTENT);
            }
            // just render the target without a content overlay if there is no content to display
            return this.renderTarget({ ref: noop });
        }
        // Important: do not use <Reference innerRef> since it has a bug when used in React 18 strict mode
        // see https://github.com/floating-ui/react-popper/pull/459
        return (React.createElement(Manager, null,
            React.createElement(Reference, null, this.renderTarget),
            React.createElement(Popper, { innerRef: this.popoverRef, placement: placement ?? positionToPlacement(position), strategy: positioningStrategy, modifiers: this.getPopperModifiers() }, this.renderPopover)));
    }
    componentDidMount() {
        this.updateDarkParent();
    }
    componentDidUpdate(props, state) {
        super.componentDidUpdate(props, state);
        this.updateDarkParent();
        const nextIsOpen = this.getIsOpen(this.props);
        if (this.props.isOpen != null && nextIsOpen !== this.state.isOpen) {
            this.setOpenState(nextIsOpen);
            // tricky: setOpenState calls setState only if this.props.isOpen is
            // not controlled, so we need to invoke setState manually here.
            this.setState({ isOpen: nextIsOpen });
        }
        else if (this.props.disabled && this.state.isOpen && this.props.isOpen == null) {
            // special case: close an uncontrolled popover when disabled is set to true
            this.setOpenState(false);
        }
    }
    validateProps(props) {
        if (props.isOpen == null && props.onInteraction != null) {
            console.warn(Errors.POPOVER_WARN_UNCONTROLLED_ONINTERACTION);
        }
        if (props.hasBackdrop && !props.usePortal) {
            console.warn(Errors.POPOVER_WARN_HAS_BACKDROP_INLINE);
        }
        if (props.hasBackdrop && props.interactionKind !== PopoverInteractionKind.CLICK) {
            console.warn(Errors.POPOVER_HAS_BACKDROP_INTERACTION);
        }
        if (props.placement !== undefined && props.position !== undefined) {
            console.warn(Errors.POPOVER_WARN_PLACEMENT_AND_POSITION_MUTEX);
        }
        const childrenCount = React.Children.count(props.children);
        const hasRenderTargetProp = props.renderTarget !== undefined;
        const hasTargetPropsProp = props.targetProps !== undefined;
        if (childrenCount === 0 && !hasRenderTargetProp) {
            console.warn(Errors.POPOVER_REQUIRES_TARGET);
        }
        if (childrenCount > 1) {
            console.warn(Errors.POPOVER_WARN_TOO_MANY_CHILDREN);
        }
        if (childrenCount > 0 && hasRenderTargetProp) {
            console.warn(Errors.POPOVER_WARN_DOUBLE_TARGET);
        }
        if (hasRenderTargetProp && hasTargetPropsProp) {
            console.warn(Errors.POPOVER_WARN_TARGET_PROPS_WITH_RENDER_TARGET);
        }
    }
    /**
     * Instance method to instruct the `Popover` to recompute its position.
     *
     * This method should only be used if you are updating the target in a way
     * that does not cause it to re-render, such as changing its _position_
     * without changing its _size_ (since `Popover` already repositions when it
     * detects a resize).
     */
    reposition = () => this.popperScheduleUpdate?.();
    renderTarget = ({ ref: popperChildRef }) => {
        const { children, className, disabled, fill, openOnTargetFocus, renderTarget } = this.props;
        const { isOpen } = this.state;
        const isControlled = this.isControlled();
        const isHoverInteractionKind = this.isHoverInteractionKind();
        let { targetTagName } = this.props;
        if (fill) {
            targetTagName = "div";
        }
        // N.B. react-popper has a wide type for this ref, but we can narrow it based on the source,
        // see https://github.com/floating-ui/react-popper/blob/beac280d61082852c4efc302be902911ce2d424c/src/Reference.js#L17
        const ref = mergeRefs(popperChildRef, this.targetRef);
        const targetEventHandlers = isHoverInteractionKind
            ? {
                // HOVER handlers
                onBlur: this.handleTargetBlur,
                onContextMenu: this.handleTargetContextMenu,
                onFocus: this.handleTargetFocus,
                onMouseEnter: this.handleMouseEnter,
                onMouseLeave: this.handleMouseLeave,
            }
            : {
                // CLICK needs only one handler
                onClick: this.handleTargetClick,
                // For keyboard accessibility, trigger the same behavior as a click event upon pressing ENTER/SPACE
                onKeyDown: this.handleKeyDown,
            };
        // Ensure target is focusable if relevant prop enabled
        const targetTabIndex = !this.getIsContentEmpty() && !disabled && openOnTargetFocus && isHoverInteractionKind ? 0 : undefined;
        const ownTargetProps = {
            // N.B. this.props.className is passed along to renderTarget even though the user would have access to it.
            // If, instead, renderTarget is undefined and the target is provided as a child, this.props.className is
            // applied to the generated target wrapper element.
            className: classNames(className, Classes.POPOVER_TARGET, {
                [Classes.POPOVER_OPEN]: isOpen,
                // this class is mainly useful for button targets
                [Classes.ACTIVE]: isOpen && !isControlled && !isHoverInteractionKind,
            }),
            ref,
            ...targetEventHandlers,
        };
        const childTargetProps = {
            "aria-expanded": isHoverInteractionKind ? undefined : isOpen,
            "aria-haspopup": this.props.interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY
                ? undefined
                : this.props.popupKind ?? "menu",
        };
        const targetModifierClasses = {
            // this class is mainly useful for Blueprint <Button> targets; we should only apply it for
            // uncontrolled popovers when they are opened by a user interaction
            [Classes.ACTIVE]: isOpen && !isControlled && !isHoverInteractionKind,
            // similarly, this class is mainly useful for targets like <Button>, <InputGroup>, etc.
            [Classes.FILL]: fill,
        };
        let target;
        if (renderTarget !== undefined) {
            target = renderTarget({
                ...ownTargetProps,
                ...childTargetProps,
                className: classNames(ownTargetProps.className, targetModifierClasses),
                // if the consumer renders a tooltip target, it's their responsibility to disable that tooltip
                // when *this* popover is open
                isOpen,
                tabIndex: targetTabIndex,
            });
        }
        else {
            const childTarget = Utils.ensureElement(React.Children.toArray(children)[0]);
            if (childTarget === undefined) {
                return null;
            }
            const clonedTarget = React.cloneElement(childTarget, {
                ...childTargetProps,
                className: classNames(childTarget.props.className, targetModifierClasses),
                // force disable single Tooltip child when popover is open
                disabled: isOpen && Utils.isElementOfType(childTarget, Tooltip) ? true : childTarget.props.disabled,
                tabIndex: childTarget.props.tabIndex ?? targetTabIndex,
            });
            const wrappedTarget = React.createElement(targetTagName, {
                ...ownTargetProps,
                ...this.props.targetProps,
            }, clonedTarget);
            target = wrappedTarget;
        }
        // No need to use the merged `ref` here, that only needs to be forwarded to the child node so that React can
        // notify both popper.js and our components about the mounted DOM element.
        return (React.createElement(ResizeSensor, { targetRef: this.targetRef, onResize: this.reposition }, target));
    };
    renderPopover = (popperProps) => {
        const { autoFocus, enforceFocus, backdropProps, canEscapeKeyClose, hasBackdrop, interactionKind, usePortal } = this.props;
        const { isClosingViaEscapeKeypress, isOpen } = this.state;
        // compute an appropriate transform origin so the scale animation points towards target
        const transformOrigin = getTransformOrigin(popperProps.placement, this.isArrowEnabled() ? popperProps.arrowProps.style : undefined);
        // need to update our reference to this function on every render as it will change.
        this.popperScheduleUpdate = popperProps.update;
        const popoverHandlers = {
            // always check popover clicks for dismiss class
            onClick: this.handlePopoverClick,
            // treat ENTER/SPACE keys the same as a click for accessibility
            onKeyDown: event => Utils.isKeyboardClick(event) && this.handlePopoverClick(event),
        };
        if (interactionKind === PopoverInteractionKind.HOVER ||
            (!usePortal && interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY)) {
            popoverHandlers.onMouseEnter = this.handleMouseEnter;
            popoverHandlers.onMouseLeave = this.handleMouseLeave;
        }
        const basePlacement = getBasePlacement(popperProps.placement);
        const popoverClasses = classNames(Classes.POPOVER, {
            [Classes.DARK]: this.props.inheritDarkTheme && this.state.hasDarkParent,
            [Classes.MINIMAL]: this.props.minimal,
            [Classes.POPOVER_CAPTURING_DISMISS]: this.props.captureDismiss,
            [Classes.POPOVER_MATCH_TARGET_WIDTH]: this.props.matchTargetWidth,
            [Classes.POPOVER_REFERENCE_HIDDEN]: popperProps.isReferenceHidden === true,
            [Classes.POPOVER_POPPER_ESCAPED]: popperProps.hasPopperEscaped === true,
        }, `${Classes.POPOVER_CONTENT_PLACEMENT}-${basePlacement}`, this.props.popoverClassName);
        const defaultAutoFocus = this.isHoverInteractionKind() ? false : undefined;
        // if hover interaction, it doesn't make sense to take over focus control
        const shouldReturnFocusOnClose = this.isHoverInteractionKind()
            ? false
            : isClosingViaEscapeKeypress
                ? true
                : this.props.shouldReturnFocusOnClose;
        return (React.createElement(Overlay2, { autoFocus: autoFocus ?? defaultAutoFocus, backdropClassName: Classes.POPOVER_BACKDROP, backdropProps: backdropProps, canEscapeKeyClose: canEscapeKeyClose, canOutsideClickClose: interactionKind === PopoverInteractionKind.CLICK, childRef: this.transitionContainerElement, enforceFocus: enforceFocus, hasBackdrop: hasBackdrop, isOpen: isOpen, lazy: this.props.lazy, onClose: this.handleOverlayClose, onClosed: this.props.onClosed, onClosing: this.props.onClosing, onOpened: this.props.onOpened, onOpening: this.props.onOpening, transitionDuration: this.props.transitionDuration, transitionName: Classes.POPOVER, usePortal: usePortal, portalClassName: this.props.portalClassName, portalContainer: this.props.portalContainer, 
            // eslint-disable-next-line @typescript-eslint/no-deprecated
            portalStopPropagationEvents: this.props.portalStopPropagationEvents, shouldReturnFocusOnClose: shouldReturnFocusOnClose },
            React.createElement("div", { className: Classes.POPOVER_TRANSITION_CONTAINER, 
                // We need to attach a ref that notifies both react-popper and our Popover component about the DOM
                // element inside the Overlay2. We cannot re-use `PopperChildrenProps.ref` because Overlay2 only
                // accepts a ref object (not a callback) due to a CSSTransition API limitation.
                // N.B. react-popper has a wide type for this ref, but we can narrow it based on the source,
                // see https://github.com/floating-ui/react-popper/blob/beac280d61082852c4efc302be902911ce2d424c/src/Popper.js#L94
                ref: mergeRefs(popperProps.ref, this.transitionContainerElement), style: popperProps.style },
                React.createElement(ResizeSensor, { onResize: this.reposition },
                    React.createElement("div", { className: popoverClasses, style: { transformOrigin }, ref: this.popoverRef, ...popoverHandlers },
                        this.isArrowEnabled() && (React.createElement(PopoverArrow, { arrowProps: popperProps.arrowProps, placement: popperProps.placement })),
                        React.createElement("div", { className: Classes.POPOVER_CONTENT }, this.props.content))))));
    };
    getPopperModifiers() {
        const { matchTargetWidth, modifiers, modifiersCustom } = this.props;
        const popperModifiers = [
            {
                enabled: this.isArrowEnabled(),
                name: "arrow",
                ...modifiers?.arrow,
            },
            {
                name: "computeStyles",
                ...modifiers?.computeStyles,
                options: {
                    adaptive: true,
                    // We disable the built-in gpuAcceleration so that
                    // Popper.js will return us easy to interpolate values
                    // (top, left instead of transform: translate3d)
                    // We'll then use these values to generate the needed
                    // css transform values blended with the react-spring values
                    gpuAcceleration: false,
                    ...modifiers?.computeStyles?.options,
                },
            },
            {
                enabled: this.isArrowEnabled(),
                name: "offset",
                ...modifiers?.offset,
                options: {
                    offset: [0, POPOVER_ARROW_SVG_SIZE / 2],
                    ...modifiers?.offset?.options,
                },
            },
            {
                name: "flip",
                ...modifiers?.flip,
                options: {
                    boundary: this.props.boundary,
                    rootBoundary: this.props.rootBoundary,
                    ...modifiers?.flip?.options,
                },
            },
            {
                name: "preventOverflow",
                ...modifiers?.preventOverflow,
                options: {
                    boundary: this.props.boundary,
                    rootBoundary: this.props.rootBoundary,
                    ...modifiers?.preventOverflow?.options,
                },
            },
        ];
        if (matchTargetWidth) {
            popperModifiers.push(matchReferenceWidthModifier);
        }
        if (modifiersCustom !== undefined) {
            popperModifiers.push(...modifiersCustom);
        }
        return popperModifiers;
    }
    handleTargetFocus = (e) => {
        if (this.props.openOnTargetFocus && this.isHoverInteractionKind()) {
            if (e.relatedTarget == null && !this.lostFocusOnSamePage) {
                // ignore this focus event -- the target was already focused but the page itself
                // lost focus (e.g. due to switching tabs).
                return;
            }
            this.handleMouseEnter(e);
        }
    };
    handleTargetBlur = (e) => {
        if (this.props.openOnTargetFocus && this.isHoverInteractionKind()) {
            if (e.relatedTarget != null) {
                // if the next element to receive focus is within the popover, we'll want to leave the
                // popover open.
                if (e.relatedTarget !== this.popoverElement &&
                    !this.isElementInPopover(e.relatedTarget)) {
                    this.handleMouseLeave(e);
                }
            }
            else {
                this.handleMouseLeave(e);
            }
        }
        this.lostFocusOnSamePage = e.relatedTarget != null;
    };
    handleTargetContextMenu = (e) => {
        // we assume that when someone prevents the default interaction on this event (a browser native context menu),
        // they are showing a custom context menu (as ContextMenu2 does); in this case, we should close this popover/tooltip
        if (e.defaultPrevented) {
            this.setOpenState(false, e);
        }
    };
    handleMouseEnter = (e) => {
        this.isMouseInTargetOrPopover = true;
        // if we're entering the popover, and the mode is set to be HOVER_TARGET_ONLY, we want to manually
        // trigger the mouse leave event, as hovering over the popover shouldn't count.
        if (!this.props.usePortal &&
            this.isElementInPopover(e.target) &&
            this.props.interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY &&
            !this.props.openOnTargetFocus) {
            this.handleMouseLeave(e);
        }
        else if (!this.props.disabled) {
            // only begin opening popover when it is enabled
            this.setOpenState(true, e, this.props.hoverOpenDelay);
        }
    };
    handleMouseLeave = (e) => {
        this.isMouseInTargetOrPopover = false;
        // Wait until the event queue is flushed, because we want to leave the
        // popover open if the mouse entered the popover immediately after
        // leaving the target (or vice versa). Make sure to persist the event since
        // we need to access `nativeEvent` in `this.setOpenState()`.
        e.persist();
        this.setTimeout(() => {
            if (this.isMouseInTargetOrPopover) {
                return;
            }
            // user-configurable closing delay is helpful when moving mouse from target to popover
            this.setOpenState(false, e, this.props.hoverCloseDelay);
        });
    };
    handlePopoverClick = (e) => {
        const eventTarget = e.target;
        const eventPopover = eventTarget.closest(`.${Classes.POPOVER}`);
        const eventPopoverV1 = eventTarget.closest(`.${Classes.POPOVER}`);
        const isEventFromSelf = (eventPopover ?? eventPopoverV1) === this.getPopoverElement();
        const isEventPopoverCapturing = eventPopover?.classList.contains(Classes.POPOVER_CAPTURING_DISMISS) ??
            eventPopoverV1?.classList.contains(Classes.POPOVER_CAPTURING_DISMISS) ??
            false;
        // an OVERRIDE inside a DISMISS does not dismiss, and a DISMISS inside an OVERRIDE will dismiss.
        const dismissElement = eventTarget.closest(`.${Classes.POPOVER_DISMISS}, .${Classes.POPOVER_DISMISS_OVERRIDE}`);
        const shouldDismiss = dismissElement?.classList.contains(Classes.POPOVER_DISMISS) ?? false;
        const isDisabled = eventTarget.closest(`:disabled, .${Classes.DISABLED}`) != null;
        if (shouldDismiss && !isDisabled && (!isEventPopoverCapturing || isEventFromSelf)) {
            this.setOpenState(false, e);
        }
    };
    handleOverlayClose = (e) => {
        if (this.targetRef.current == null || e === undefined) {
            return;
        }
        const event = (e.nativeEvent ?? e);
        const eventTarget = (event.composed ? event.composedPath()[0] : event.target);
        // if click was in target, target event listener will handle things, so don't close
        if (!Utils.elementIsOrContains(this.targetRef.current, eventTarget) || e.nativeEvent instanceof KeyboardEvent) {
            this.setOpenState(false, e);
        }
    };
    handleKeyDown = (e) => {
        const isKeyboardClick = Utils.isKeyboardClick(e);
        // For keyboard accessibility, trigger the same behavior as a click event upon pressing ENTER/SPACE
        if (isKeyboardClick) {
            this.handleTargetClick(e);
        }
    };
    handleTargetClick = (e) => {
        // Target element(s) may fire simulated click event upon pressing ENTER/SPACE, which we should ignore
        // see: https://github.com/palantir/blueprint/issues/5775
        const shouldIgnoreClick = this.state.isOpen && this.isSimulatedButtonClick(e);
        if (!shouldIgnoreClick) {
            // ensure click did not originate from within inline popover before closing
            if (!this.props.disabled && !this.isElementInPopover(e.target)) {
                if (this.props.isOpen == null) {
                    this.setState(prevState => ({ isOpen: !prevState.isOpen }));
                }
                else {
                    this.setOpenState(!this.props.isOpen, e);
                }
            }
        }
    };
    isSimulatedButtonClick = (e) => {
        return !e.isTrusted && e.target.matches(`.${Classes.BUTTON}`);
    };
    // a wrapper around setState({ isOpen }) that will call props.onInteraction instead when in controlled mode.
    // starts a timeout to delay changing the state if a non-zero duration is provided.
    setOpenState(isOpen, e, timeout) {
        // cancel any existing timeout because we have new state
        this.cancelOpenTimeout?.();
        if (timeout !== undefined && timeout > 0) {
            // Persist the react event since it will be used in a later macrotask.
            e?.persist();
            this.cancelOpenTimeout = this.setTimeout(() => {
                this.setOpenState(isOpen, e);
            }, timeout);
        }
        else {
            if (this.props.isOpen == null) {
                this.setState({ isOpen });
            }
            else {
                this.props.onInteraction?.(isOpen, e);
            }
            if (!isOpen) {
                // non-null assertion because the only time `e` is undefined is when in controlled mode
                // or the rare special case in uncontrolled mode when the `disabled` flag is toggled true
                this.props.onClose?.(e);
                this.setState({ isClosingViaEscapeKeypress: isEscapeKeypressEvent(e?.nativeEvent) });
            }
        }
    }
    updateDarkParent() {
        if (this.props.usePortal && this.state.isOpen) {
            const hasDarkParent = this.targetRef.current?.closest(`.${Classes.DARK}`) != null;
            this.setState({ hasDarkParent });
        }
    }
    isElementInPopover(element) {
        return this.getPopoverElement()?.contains(element) ?? false;
    }
    getIsContentEmpty() {
        const { content } = this.props;
        return content == null || Utils.isEmptyString(content);
    }
}
function isEscapeKeypressEvent(e) {
    return e instanceof KeyboardEvent && e.key === "Escape";
}
function noop() {
    // no-op
}
//# sourceMappingURL=popover.js.map