UNPKG

30.1 kBJavaScriptView Raw
1/*
2 * Copyright 2021 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { __assign, __extends } from "tslib";
17import classNames from "classnames";
18import * as React from "react";
19import { Manager, Popper, Reference } from "react-popper";
20import { AbstractPureComponent, Classes, DISPLAYNAME_PREFIX, refHandler, Utils } from "../../common";
21import * as Errors from "../../common/errors";
22import { Overlay } from "../overlay/overlay";
23import { ResizeSensor } from "../resize-sensor/resizeSensor";
24// eslint-disable-next-line import/no-cycle
25import { Tooltip } from "../tooltip/tooltip";
26import { matchReferenceWidthModifier } from "./customModifiers";
27import { POPOVER_ARROW_SVG_SIZE, PopoverArrow } from "./popoverArrow";
28import { positionToPlacement } from "./popoverPlacementUtils";
29import { getBasePlacement, getTransformOrigin } from "./popperUtils";
30export var PopoverInteractionKind = {
31 CLICK: "click",
32 CLICK_TARGET_ONLY: "click-target",
33 HOVER: "hover",
34 HOVER_TARGET_ONLY: "hover-target",
35};
36/**
37 * Popover component, used to display a floating UI next to and tethered to a target element.
38 *
39 * @template T target element props interface. Consumers wishing to stay in sync with Blueprint's default target HTML
40 * props interface should use the `DefaultPopoverTargetHTMLProps` type (although this is already the default type for
41 * this type param).
42 * @see https://blueprintjs.com/docs/#core/components/popover
43 */
44var Popover = /** @class */ (function (_super) {
45 __extends(Popover, _super);
46 function Popover() {
47 var _this = _super !== null && _super.apply(this, arguments) || this;
48 _this.state = {
49 hasDarkParent: false,
50 isOpen: _this.getIsOpen(_this.props),
51 };
52 /**
53 * DOM element that contains the popover.
54 * When `usePortal={true}`, this element will be portaled outside the usual DOM flow,
55 * so this reference can be very useful for testing.
56 *
57 * @public for testing
58 */
59 _this.popoverElement = null;
60 /** Popover ref handler */
61 _this.popoverRef = refHandler(_this, "popoverElement", _this.props.popoverRef);
62 /**
63 * Target DOM element ref.
64 *
65 * @public for testing
66 */
67 _this.targetRef = React.createRef();
68 // a flag that lets us detect mouse movement between the target and popover,
69 // now that mouseleave is triggered when you cross the gap between the two.
70 _this.isMouseInTargetOrPopover = false;
71 // a flag that indicates whether the target previously lost focus to another
72 // element on the same page.
73 _this.lostFocusOnSamePage = true;
74 _this.isControlled = function () { return _this.props.isOpen !== undefined; };
75 // arrow is disabled if minimal, or if the arrow modifier was explicitly disabled
76 _this.isArrowEnabled = function () { var _a, _b; return !_this.props.minimal && ((_b = (_a = _this.props.modifiers) === null || _a === void 0 ? void 0 : _a.arrow) === null || _b === void 0 ? void 0 : _b.enabled) !== false; };
77 _this.isHoverInteractionKind = function () {
78 return (_this.props.interactionKind === PopoverInteractionKind.HOVER ||
79 _this.props.interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY);
80 };
81 /**
82 * Instance method to instruct the `Popover` to recompute its position.
83 *
84 * This method should only be used if you are updating the target in a way
85 * that does not cause it to re-render, such as changing its _position_
86 * without changing its _size_ (since `Popover` already repositions when it
87 * detects a resize).
88 */
89 _this.reposition = function () { var _a; return (_a = _this.popperScheduleUpdate) === null || _a === void 0 ? void 0 : _a.call(_this); };
90 _this.renderTarget = function (_a) {
91 var _b, _c;
92 var _d, _e;
93 var ref = _a.ref;
94 var _f = _this.props, children = _f.children, className = _f.className, fill = _f.fill, openOnTargetFocus = _f.openOnTargetFocus, renderTarget = _f.renderTarget;
95 var isOpen = _this.state.isOpen;
96 var isControlled = _this.isControlled();
97 var isHoverInteractionKind = _this.isHoverInteractionKind();
98 var targetTagName = _this.props.targetTagName;
99 if (fill) {
100 targetTagName = "div";
101 }
102 var targetEventHandlers = isHoverInteractionKind
103 ? {
104 // HOVER handlers
105 onBlur: _this.handleTargetBlur,
106 onContextMenu: _this.handleTargetContextMenu,
107 onFocus: _this.handleTargetFocus,
108 onMouseEnter: _this.handleMouseEnter,
109 onMouseLeave: _this.handleMouseLeave,
110 }
111 : {
112 // CLICK needs only one handler
113 onClick: _this.handleTargetClick,
114 // For keyboard accessibility, trigger the same behavior as a click event upon pressing ENTER/SPACE
115 onKeyDown: _this.handleKeyDown,
116 };
117 // Ensure target is focusable if relevant prop enabled
118 var targetTabIndex = openOnTargetFocus && isHoverInteractionKind ? 0 : undefined;
119 var ownTargetProps = __assign({ "aria-haspopup": (_d = _this.props.popupKind) !== null && _d !== void 0 ? _d : (_this.props.interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY
120 ? undefined
121 : "true"),
122 // N.B. this.props.className is passed along to renderTarget even though the user would have access to it.
123 // If, instead, renderTarget is undefined and the target is provided as a child, this.props.className is
124 // applied to the generated target wrapper element.
125 className: classNames(className, Classes.POPOVER_TARGET, (_b = {},
126 _b[Classes.POPOVER_OPEN] = isOpen,
127 // this class is mainly useful for button targets
128 _b[Classes.ACTIVE] = isOpen && !isControlled && !isHoverInteractionKind,
129 _b)), ref: ref }, targetEventHandlers);
130 var targetModifierClasses = (_c = {},
131 // this class is mainly useful for Blueprint <Button> targets; we should only apply it for
132 // uncontrolled popovers when they are opened by a user interaction
133 _c[Classes.ACTIVE] = isOpen && !isControlled && !isHoverInteractionKind,
134 // similarly, this class is mainly useful for targets like <Button>, <InputGroup>, etc.
135 _c[Classes.FILL] = fill,
136 _c);
137 var target;
138 if (renderTarget !== undefined) {
139 target = renderTarget(__assign(__assign({}, ownTargetProps), { className: classNames(ownTargetProps.className, targetModifierClasses),
140 // if the consumer renders a tooltip target, it's their responsibility to disable that tooltip
141 // when *this* popover is open
142 isOpen: isOpen, tabIndex: targetTabIndex }));
143 }
144 else {
145 var childTarget = Utils.ensureElement(React.Children.toArray(children)[0]);
146 if (childTarget === undefined) {
147 return null;
148 }
149 var clonedTarget = React.cloneElement(childTarget, {
150 className: classNames(childTarget.props.className, targetModifierClasses),
151 // force disable single Tooltip child when popover is open
152 disabled: isOpen && Utils.isElementOfType(childTarget, Tooltip) ? true : childTarget.props.disabled,
153 tabIndex: (_e = childTarget.props.tabIndex) !== null && _e !== void 0 ? _e : targetTabIndex,
154 });
155 var wrappedTarget = React.createElement(targetTagName, __assign(__assign({}, ownTargetProps), _this.props.targetProps), clonedTarget);
156 target = wrappedTarget;
157 }
158 // N.B. we must attach the ref ('wrapped' with react-popper functionality) to the DOM element here and
159 // let ResizeSensor know about it
160 return (React.createElement(ResizeSensor, { targetRef: _this.targetRef, onResize: _this.reposition }, target));
161 };
162 _this.renderPopover = function (popperProps) {
163 var _a;
164 var _b;
165 var _c = _this.props, interactionKind = _c.interactionKind, shouldReturnFocusOnClose = _c.shouldReturnFocusOnClose, usePortal = _c.usePortal;
166 var isOpen = _this.state.isOpen;
167 // compute an appropriate transform origin so the scale animation points towards target
168 var transformOrigin = getTransformOrigin(popperProps.placement, _this.isArrowEnabled() ? popperProps.arrowProps.style : undefined);
169 // need to update our reference to this function on every render as it will change.
170 _this.popperScheduleUpdate = popperProps.update;
171 var popoverHandlers = {
172 // always check popover clicks for dismiss class
173 onClick: _this.handlePopoverClick,
174 // treat ENTER/SPACE keys the same as a click for accessibility
175 onKeyDown: function (event) { return Utils.isKeyboardClick(event) && _this.handlePopoverClick(event); },
176 };
177 if (interactionKind === PopoverInteractionKind.HOVER ||
178 (!usePortal && interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY)) {
179 popoverHandlers.onMouseEnter = _this.handleMouseEnter;
180 popoverHandlers.onMouseLeave = _this.handleMouseLeave;
181 }
182 var basePlacement = getBasePlacement(popperProps.placement);
183 var popoverClasses = classNames(Classes.POPOVER, (_a = {},
184 _a[Classes.DARK] = _this.props.inheritDarkTheme && _this.state.hasDarkParent,
185 _a[Classes.MINIMAL] = _this.props.minimal,
186 _a[Classes.POPOVER_CAPTURING_DISMISS] = _this.props.captureDismiss,
187 _a[Classes.POPOVER_MATCH_TARGET_WIDTH] = _this.props.matchTargetWidth,
188 _a[Classes.POPOVER_REFERENCE_HIDDEN] = popperProps.isReferenceHidden === true,
189 _a[Classes.POPOVER_POPPER_ESCAPED] = popperProps.hasPopperEscaped === true,
190 _a), "".concat(Classes.POPOVER_CONTENT_PLACEMENT, "-").concat(basePlacement), _this.props.popoverClassName);
191 var defaultAutoFocus = _this.isHoverInteractionKind() ? false : undefined;
192 return (React.createElement(Overlay, { autoFocus: (_b = _this.props.autoFocus) !== null && _b !== void 0 ? _b : defaultAutoFocus, backdropClassName: Classes.POPOVER_BACKDROP, backdropProps: _this.props.backdropProps, canEscapeKeyClose: _this.props.canEscapeKeyClose, canOutsideClickClose: _this.props.interactionKind === PopoverInteractionKind.CLICK, enforceFocus: _this.props.enforceFocus, hasBackdrop: _this.props.hasBackdrop, isOpen: isOpen, 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: _this.props.usePortal, portalClassName: _this.props.portalClassName, portalContainer: _this.props.portalContainer, portalStopPropagationEvents: _this.props.portalStopPropagationEvents,
193 // if hover interaction, it doesn't make sense to take over focus control
194 shouldReturnFocusOnClose: _this.isHoverInteractionKind() ? false : shouldReturnFocusOnClose },
195 React.createElement("div", { className: Classes.POPOVER_TRANSITION_CONTAINER, ref: popperProps.ref, style: popperProps.style },
196 React.createElement(ResizeSensor, { onResize: _this.reposition },
197 React.createElement("div", __assign({ className: popoverClasses, style: { transformOrigin: transformOrigin }, ref: _this.popoverRef }, popoverHandlers),
198 _this.isArrowEnabled() && (React.createElement(PopoverArrow, { arrowProps: popperProps.arrowProps, placement: popperProps.placement })),
199 React.createElement("div", { className: Classes.POPOVER_CONTENT }, _this.props.content))))));
200 };
201 _this.handleTargetFocus = function (e) {
202 if (_this.props.openOnTargetFocus && _this.isHoverInteractionKind()) {
203 if (e.relatedTarget == null && !_this.lostFocusOnSamePage) {
204 // ignore this focus event -- the target was already focused but the page itself
205 // lost focus (e.g. due to switching tabs).
206 return;
207 }
208 _this.handleMouseEnter(e);
209 }
210 };
211 _this.handleTargetBlur = function (e) {
212 if (_this.props.openOnTargetFocus && _this.isHoverInteractionKind()) {
213 if (e.relatedTarget != null) {
214 // if the next element to receive focus is within the popover, we'll want to leave the
215 // popover open.
216 if (e.relatedTarget !== _this.popoverElement &&
217 !_this.isElementInPopover(e.relatedTarget)) {
218 _this.handleMouseLeave(e);
219 }
220 }
221 else {
222 _this.handleMouseLeave(e);
223 }
224 }
225 _this.lostFocusOnSamePage = e.relatedTarget != null;
226 };
227 _this.handleTargetContextMenu = function (e) {
228 // we assume that when someone prevents the default interaction on this event (a browser native context menu),
229 // they are showing a custom context menu (as ContextMenu2 does); in this case, we should close this popover/tooltip
230 if (e.defaultPrevented) {
231 _this.setOpenState(false, e);
232 }
233 };
234 _this.handleMouseEnter = function (e) {
235 _this.isMouseInTargetOrPopover = true;
236 // if we're entering the popover, and the mode is set to be HOVER_TARGET_ONLY, we want to manually
237 // trigger the mouse leave event, as hovering over the popover shouldn't count.
238 if (!_this.props.usePortal &&
239 _this.isElementInPopover(e.target) &&
240 _this.props.interactionKind === PopoverInteractionKind.HOVER_TARGET_ONLY &&
241 !_this.props.openOnTargetFocus) {
242 _this.handleMouseLeave(e);
243 }
244 else if (!_this.props.disabled) {
245 // only begin opening popover when it is enabled
246 _this.setOpenState(true, e, _this.props.hoverOpenDelay);
247 }
248 };
249 _this.handleMouseLeave = function (e) {
250 _this.isMouseInTargetOrPopover = false;
251 // wait until the event queue is flushed, because we want to leave the
252 // popover open if the mouse entered the popover immediately after
253 // leaving the target (or vice versa).
254 _this.setTimeout(function () {
255 if (_this.isMouseInTargetOrPopover) {
256 return;
257 }
258 // user-configurable closing delay is helpful when moving mouse from target to popover
259 _this.setOpenState(false, e, _this.props.hoverCloseDelay);
260 });
261 };
262 _this.handlePopoverClick = function (e) {
263 var _a, _b, _c, _d;
264 var eventTarget = e.target;
265 var eventPopover = eventTarget.closest(".".concat(Classes.POPOVER));
266 var eventPopoverV1 = eventTarget.closest(".".concat(Classes.POPOVER));
267 var isEventFromSelf = (eventPopover !== null && eventPopover !== void 0 ? eventPopover : eventPopoverV1) === _this.getPopoverElement();
268 var isEventPopoverCapturing = (_b = (_a = eventPopover === null || eventPopover === void 0 ? void 0 : eventPopover.classList.contains(Classes.POPOVER_CAPTURING_DISMISS)) !== null && _a !== void 0 ? _a : eventPopoverV1 === null || eventPopoverV1 === void 0 ? void 0 : eventPopoverV1.classList.contains(Classes.POPOVER_CAPTURING_DISMISS)) !== null && _b !== void 0 ? _b : false;
269 // an OVERRIDE inside a DISMISS does not dismiss, and a DISMISS inside an OVERRIDE will dismiss.
270 var dismissElement = eventTarget.closest(".".concat(Classes.POPOVER_DISMISS, ", .").concat(Classes.POPOVER_DISMISS_OVERRIDE));
271 // dismiss selectors from the "V1" version of Popover in the core package
272 // we expect these to be rendered by MenuItem, which at this point has no knowledge of Popover
273 // this can be removed once Popover is merged into core in v5.0
274 var dismissElementV1 = eventTarget.closest(".".concat(Classes.POPOVER_DISMISS, ", .").concat(Classes.POPOVER_DISMISS_OVERRIDE));
275 var shouldDismiss = (_d = (_c = dismissElement === null || dismissElement === void 0 ? void 0 : dismissElement.classList.contains(Classes.POPOVER_DISMISS)) !== null && _c !== void 0 ? _c : dismissElementV1 === null || dismissElementV1 === void 0 ? void 0 : dismissElementV1.classList.contains(Classes.POPOVER_DISMISS)) !== null && _d !== void 0 ? _d : false;
276 var isDisabled = eventTarget.closest(":disabled, .".concat(Classes.DISABLED)) != null;
277 if (shouldDismiss && !isDisabled && (!isEventPopoverCapturing || isEventFromSelf)) {
278 _this.setOpenState(false, e);
279 }
280 };
281 _this.handleOverlayClose = function (e) {
282 var _a;
283 if (_this.targetRef.current == null || e === undefined) {
284 return;
285 }
286 var event = ((_a = e.nativeEvent) !== null && _a !== void 0 ? _a : e);
287 var eventTarget = (event.composed ? event.composedPath()[0] : event.target);
288 // if click was in target, target event listener will handle things, so don't close
289 if (!Utils.elementIsOrContains(_this.targetRef.current, eventTarget) || e.nativeEvent instanceof KeyboardEvent) {
290 _this.setOpenState(false, e);
291 }
292 };
293 _this.handleKeyDown = function (e) {
294 var isKeyboardClick = Utils.isKeyboardClick(e);
295 // For keyboard accessibility, trigger the same behavior as a click event upon pressing ENTER/SPACE
296 if (isKeyboardClick) {
297 _this.handleTargetClick(e);
298 }
299 };
300 _this.handleTargetClick = function (e) {
301 // Target element(s) may fire simulated click event upon pressing ENTER/SPACE, which we should ignore
302 // see: https://github.com/palantir/blueprint/issues/5775
303 var shouldIgnoreClick = _this.state.isOpen && _this.isSimulatedButtonClick(e);
304 if (!shouldIgnoreClick) {
305 // ensure click did not originate from within inline popover before closing
306 if (!_this.props.disabled && !_this.isElementInPopover(e.target)) {
307 if (_this.props.isOpen == null) {
308 _this.setState(function (prevState) { return ({ isOpen: !prevState.isOpen }); });
309 }
310 else {
311 _this.setOpenState(!_this.props.isOpen, e);
312 }
313 }
314 }
315 };
316 _this.isSimulatedButtonClick = function (e) {
317 return !e.isTrusted && e.target.matches(".".concat(Classes.BUTTON));
318 };
319 return _this;
320 }
321 // popper innerRef gives us a handle on the transition container, since that's what we render as the overlay child,
322 // so if we want to look at our actual popover element, we need to reach inside a bit
323 Popover.prototype.getPopoverElement = function () {
324 var _a;
325 return (_a = this.popoverElement) === null || _a === void 0 ? void 0 : _a.querySelector(".".concat(Classes.POPOVER));
326 };
327 Popover.prototype.getIsOpen = function (props) {
328 var _a;
329 // disabled popovers should never be allowed to open.
330 if (props.disabled) {
331 return false;
332 }
333 else {
334 return (_a = props.isOpen) !== null && _a !== void 0 ? _a : props.defaultIsOpen;
335 }
336 };
337 Popover.prototype.render = function () {
338 var _a = this.props, disabled = _a.disabled, content = _a.content, placement = _a.placement, _b = _a.position, position = _b === void 0 ? "auto" : _b, positioningStrategy = _a.positioningStrategy;
339 var isOpen = this.state.isOpen;
340 var isContentEmpty = content == null || (typeof content === "string" && content.trim() === "");
341 if (isContentEmpty) {
342 // need to do this check in render(), because `isOpen` is derived from
343 // state, and state can't necessarily be accessed in validateProps.
344 if (!disabled && isOpen !== false && !Utils.isNodeEnv("production")) {
345 console.warn(Errors.POPOVER_WARN_EMPTY_CONTENT);
346 }
347 // just render the target without a content overlay if there is no content to display
348 return this.renderTarget({ ref: noop });
349 }
350 return (React.createElement(Manager, null,
351 React.createElement(Reference, { innerRef: this.targetRef }, this.renderTarget),
352 React.createElement(Popper, { innerRef: this.popoverRef, placement: placement !== null && placement !== void 0 ? placement : positionToPlacement(position), strategy: positioningStrategy, modifiers: this.getPopperModifiers() }, this.renderPopover)));
353 };
354 Popover.prototype.componentDidMount = function () {
355 this.updateDarkParent();
356 };
357 Popover.prototype.componentDidUpdate = function (props, state) {
358 _super.prototype.componentDidUpdate.call(this, props, state);
359 this.updateDarkParent();
360 var nextIsOpen = this.getIsOpen(this.props);
361 if (this.props.isOpen != null && nextIsOpen !== this.state.isOpen) {
362 this.setOpenState(nextIsOpen);
363 // tricky: setOpenState calls setState only if this.props.isOpen is
364 // not controlled, so we need to invoke setState manually here.
365 this.setState({ isOpen: nextIsOpen });
366 }
367 else if (this.props.disabled && this.state.isOpen && this.props.isOpen == null) {
368 // special case: close an uncontrolled popover when disabled is set to true
369 this.setOpenState(false);
370 }
371 };
372 Popover.prototype.validateProps = function (props) {
373 if (props.isOpen == null && props.onInteraction != null) {
374 console.warn(Errors.POPOVER_WARN_UNCONTROLLED_ONINTERACTION);
375 }
376 if (props.hasBackdrop && !props.usePortal) {
377 console.warn(Errors.POPOVER_WARN_HAS_BACKDROP_INLINE);
378 }
379 if (props.hasBackdrop && props.interactionKind !== PopoverInteractionKind.CLICK) {
380 console.warn(Errors.POPOVER_HAS_BACKDROP_INTERACTION);
381 }
382 if (props.placement !== undefined && props.position !== undefined) {
383 console.warn(Errors.POPOVER_WARN_PLACEMENT_AND_POSITION_MUTEX);
384 }
385 var childrenCount = React.Children.count(props.children);
386 var hasRenderTargetProp = props.renderTarget !== undefined;
387 var hasTargetPropsProp = props.targetProps !== undefined;
388 if (childrenCount === 0 && !hasRenderTargetProp) {
389 console.warn(Errors.POPOVER_REQUIRES_TARGET);
390 }
391 if (childrenCount > 1) {
392 console.warn(Errors.POPOVER_WARN_TOO_MANY_CHILDREN);
393 }
394 if (childrenCount > 0 && hasRenderTargetProp) {
395 console.warn(Errors.POPOVER_WARN_DOUBLE_TARGET);
396 }
397 if (hasRenderTargetProp && hasTargetPropsProp) {
398 console.warn(Errors.POPOVER_WARN_TARGET_PROPS_WITH_RENDER_TARGET);
399 }
400 };
401 Popover.prototype.getPopperModifiers = function () {
402 var _a, _b, _c, _d;
403 var _e = this.props, matchTargetWidth = _e.matchTargetWidth, modifiers = _e.modifiers, modifiersCustom = _e.modifiersCustom;
404 var popperModifiers = [
405 __assign({ enabled: this.isArrowEnabled(), name: "arrow" }, modifiers === null || modifiers === void 0 ? void 0 : modifiers.arrow),
406 __assign(__assign({ name: "computeStyles" }, modifiers === null || modifiers === void 0 ? void 0 : modifiers.computeStyles), { options: __assign({ adaptive: true,
407 // We disable the built-in gpuAcceleration so that
408 // Popper.js will return us easy to interpolate values
409 // (top, left instead of transform: translate3d)
410 // We'll then use these values to generate the needed
411 // css transform values blended with the react-spring values
412 gpuAcceleration: false }, (_a = modifiers === null || modifiers === void 0 ? void 0 : modifiers.computeStyles) === null || _a === void 0 ? void 0 : _a.options) }),
413 __assign(__assign({ enabled: this.isArrowEnabled(), name: "offset" }, modifiers === null || modifiers === void 0 ? void 0 : modifiers.offset), { options: __assign({ offset: [0, POPOVER_ARROW_SVG_SIZE / 2] }, (_b = modifiers === null || modifiers === void 0 ? void 0 : modifiers.offset) === null || _b === void 0 ? void 0 : _b.options) }),
414 __assign(__assign({ name: "flip" }, modifiers === null || modifiers === void 0 ? void 0 : modifiers.flip), { options: __assign({ boundary: this.props.boundary, rootBoundary: this.props.rootBoundary }, (_c = modifiers === null || modifiers === void 0 ? void 0 : modifiers.flip) === null || _c === void 0 ? void 0 : _c.options) }),
415 __assign(__assign({ name: "preventOverflow" }, modifiers === null || modifiers === void 0 ? void 0 : modifiers.preventOverflow), { options: __assign({ boundary: this.props.boundary, rootBoundary: this.props.rootBoundary }, (_d = modifiers === null || modifiers === void 0 ? void 0 : modifiers.preventOverflow) === null || _d === void 0 ? void 0 : _d.options) }),
416 ];
417 if (matchTargetWidth) {
418 popperModifiers.push(matchReferenceWidthModifier);
419 }
420 if (modifiersCustom !== undefined) {
421 popperModifiers.push.apply(popperModifiers, modifiersCustom);
422 }
423 return popperModifiers;
424 };
425 // a wrapper around setState({ isOpen }) that will call props.onInteraction instead when in controlled mode.
426 // starts a timeout to delay changing the state if a non-zero duration is provided.
427 Popover.prototype.setOpenState = function (isOpen, e, timeout) {
428 var _this = this;
429 var _a, _b, _c, _d, _e;
430 // cancel any existing timeout because we have new state
431 (_a = this.cancelOpenTimeout) === null || _a === void 0 ? void 0 : _a.call(this);
432 if (timeout !== undefined && timeout > 0) {
433 this.cancelOpenTimeout = this.setTimeout(function () { return _this.setOpenState(isOpen, e); }, timeout);
434 }
435 else {
436 if (this.props.isOpen == null) {
437 this.setState({ isOpen: isOpen });
438 }
439 else {
440 (_c = (_b = this.props).onInteraction) === null || _c === void 0 ? void 0 : _c.call(_b, isOpen, e);
441 }
442 if (!isOpen) {
443 // non-null assertion because the only time `e` is undefined is when in controlled mode
444 // or the rare special case in uncontrolled mode when the `disabled` flag is toggled true
445 (_e = (_d = this.props).onClose) === null || _e === void 0 ? void 0 : _e.call(_d, e);
446 }
447 }
448 };
449 Popover.prototype.updateDarkParent = function () {
450 if (this.props.usePortal && this.state.isOpen) {
451 var hasDarkParent = this.targetRef.current != null && this.targetRef.current.closest(".".concat(Classes.DARK)) != null;
452 this.setState({ hasDarkParent: hasDarkParent });
453 }
454 };
455 Popover.prototype.isElementInPopover = function (element) {
456 var _a, _b;
457 return (_b = (_a = this.getPopoverElement()) === null || _a === void 0 ? void 0 : _a.contains(element)) !== null && _b !== void 0 ? _b : false;
458 };
459 Popover.displayName = "".concat(DISPLAYNAME_PREFIX, ".Popover");
460 Popover.defaultProps = {
461 boundary: "clippingParents",
462 captureDismiss: false,
463 defaultIsOpen: false,
464 disabled: false,
465 fill: false,
466 hasBackdrop: false,
467 hoverCloseDelay: 300,
468 hoverOpenDelay: 150,
469 inheritDarkTheme: true,
470 interactionKind: PopoverInteractionKind.CLICK,
471 matchTargetWidth: false,
472 minimal: false,
473 openOnTargetFocus: true,
474 // N.B. we don't set a default for `placement` or `position` here because that would trigger
475 // a warning in validateProps if the other prop is specified by a user of this component
476 positioningStrategy: "absolute",
477 renderTarget: undefined,
478 shouldReturnFocusOnClose: false,
479 targetTagName: "span",
480 transitionDuration: 300,
481 usePortal: true,
482 };
483 return Popover;
484}(AbstractPureComponent));
485export { Popover };
486function noop() {
487 // no-op
488}
489//# sourceMappingURL=popover.js.map
\No newline at end of file