Skip to content

Commit d8783f0

Browse files
authored
[chore] Move Popover props to separate module and eliminate circular imports (#7572)
1 parent 19af594 commit d8783f0

File tree

9 files changed

+100
-86
lines changed

9 files changed

+100
-86
lines changed

packages/core/src/common/alignment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ export const TextAlignment = {
3535
END: "end" as const,
3636
START: "start" as const,
3737
};
38-
// eslint-disable-next-line @typescript-eslint/no-redeclare
38+
3939
export type TextAlignment = (typeof TextAlignment)[keyof typeof TextAlignment];

packages/core/src/components/breadcrumbs/breadcrumbs.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import { AbstractPureComponent, Boundary, Classes, type Props, removeNonHTMLProp
2020
import { Menu } from "../menu/menu";
2121
import { MenuItem } from "../menu/menuItem";
2222
import { OverflowList, type OverflowListProps } from "../overflow-list/overflowList";
23-
import { Popover, type PopoverProps } from "../popover/popover";
23+
import { Popover } from "../popover/popover";
24+
import type { PopoverProps } from "../popover/popoverProps";
2425

2526
import { Breadcrumb, type BreadcrumbProps } from "./breadcrumb";
2627

packages/core/src/components/context-menu/contextMenuShared.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import type { OverlayLifecycleProps } from "../overlay/overlayProps";
18-
import type { PopoverProps } from "../popover/popover";
18+
import type { PopoverProps } from "../popover/popoverProps";
1919

2020
export type Offset = {
2121
left: number;

packages/core/src/components/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ export type { OverlayInstance } from "./overlay2/overlayInstance";
7777
export { Text, type TextProps } from "./text/text";
7878
export { PanelStack, type PanelStackProps, PanelStack2, type PanelStack2Props } from "./panel-stack/panelStack";
7979
export type { Panel, PanelProps } from "./panel-stack/panelTypes";
80-
export { type PopoverProps, Popover, PopoverInteractionKind } from "./popover/popover";
80+
export { Popover } from "./popover/popover";
81+
export { PopoverInteractionKind, type PopoverProps } from "./popover/popoverProps";
8182
export { PopoverPosition } from "./popover/popoverPosition";
8283
export type {
8384
DefaultPopoverTargetHTMLProps,

packages/core/src/components/menu/menuItem.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import { Classes } from "../../common";
2323
import { type ActionProps, DISPLAYNAME_PREFIX, removeNonHTMLProps } from "../../common/props";
2424
import { clickElementOnKeyPress } from "../../common/utils";
2525
import { Icon } from "../icon/icon";
26-
import { Popover, type PopoverProps } from "../popover/popover";
26+
import { Popover } from "../popover/popover";
27+
import type { PopoverProps } from "../popover/popoverProps";
2728
import { Text } from "../text/text";
2829

2930
import { Menu, type MenuProps } from "./menu";

packages/core/src/components/popover/popover.tsx

Lines changed: 7 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import type { State as PopperState, PositioningStrategy } from "@popperjs/core";
17+
import type { State as PopperState } from "@popperjs/core";
1818
import classNames from "classnames";
1919
import { Children, cloneElement, createElement, createRef } from "react";
2020
import {
@@ -38,92 +38,17 @@ import {
3838
import * as Errors from "../../common/errors";
3939
import { Overlay2 } from "../overlay2/overlay2";
4040
import { ResizeSensor } from "../resize-sensor/resizeSensor";
41-
// eslint-disable-next-line import/no-cycle
42-
import { Tooltip } from "../tooltip/tooltip";
4341

4442
import { matchReferenceWidthModifier } from "./customModifiers";
4543
import { POPOVER_ARROW_SVG_SIZE, PopoverArrow } from "./popoverArrow";
4644
import { positionToPlacement } from "./popoverPlacementUtils";
45+
import { PopoverInteractionKind, type PopoverProps } from "./popoverProps";
4746
import type {
4847
DefaultPopoverTargetHTMLProps,
4948
PopoverClickTargetHandlers,
5049
PopoverHoverTargetHandlers,
51-
PopoverSharedProps,
5250
} from "./popoverSharedProps";
5351
import { getBasePlacement, getTransformOrigin } from "./popperUtils";
54-
import type { PopupKind } from "./popupKind";
55-
56-
export const PopoverInteractionKind = {
57-
CLICK: "click" as const,
58-
CLICK_TARGET_ONLY: "click-target" as const,
59-
HOVER: "hover" as const,
60-
HOVER_TARGET_ONLY: "hover-target" as const,
61-
};
62-
export type PopoverInteractionKind = (typeof PopoverInteractionKind)[keyof typeof PopoverInteractionKind];
63-
64-
export interface PopoverProps<TProps extends DefaultPopoverTargetHTMLProps = DefaultPopoverTargetHTMLProps>
65-
extends PopoverSharedProps<TProps> {
66-
/**
67-
* Whether the popover/tooltip should acquire application focus when it first opens.
68-
*
69-
* @default true for click interactions, false for hover interactions
70-
*/
71-
autoFocus?: boolean;
72-
73-
/** HTML props for the backdrop element. Can be combined with `backdropClassName`. */
74-
backdropProps?: React.HTMLProps<HTMLDivElement>;
75-
76-
/**
77-
* The kind of interaction that triggers the display of the popover.
78-
*
79-
* @default "click"
80-
*/
81-
interactionKind?: PopoverInteractionKind;
82-
83-
/**
84-
* The kind of popup displayed by the popover. Gets directly applied to the
85-
* `aria-haspopup` attribute of the target element. This property is
86-
* ignored if `interactionKind` is {@link PopoverInteractionKind.HOVER_TARGET_ONLY}.
87-
*
88-
* @default "menu" or undefined
89-
*/
90-
popupKind?: PopupKind;
91-
92-
/**
93-
* Enables an invisible overlay beneath the popover that captures clicks and
94-
* prevents interaction with the rest of the document until the popover is
95-
* closed. This prop is only available when `interactionKind` is
96-
* `PopoverInteractionKind.CLICK`. When popovers with backdrop are opened,
97-
* they become focused.
98-
*
99-
* @default false
100-
*/
101-
hasBackdrop?: boolean;
102-
103-
/**
104-
* Whether the application should return focus to the last active element in the
105-
* document after this popover closes.
106-
*
107-
* This is automatically set (overridden) to:
108-
* - `false` for hover interaction popovers
109-
* - `true` when a popover closes due to an ESC keypress
110-
*
111-
* If you are attaching a popover _and_ a tooltip to the same target, you must take
112-
* care to either disable this prop for the popover _or_ disable the tooltip's
113-
* `openOnTargetFocus` prop.
114-
*
115-
* @default false
116-
*/
117-
shouldReturnFocusOnClose?: boolean;
118-
119-
/**
120-
* Popper.js positioning strategy.
121-
*
122-
* @see https://popper.js.org/docs/v2/constructors/#strategy
123-
* @default "absolute"
124-
*/
125-
positioningStrategy?: PositioningStrategy;
126-
}
12752

12853
export interface PopoverState {
12954
hasDarkParent: boolean;
@@ -421,7 +346,7 @@ export class Popover<
421346
...childTargetProps,
422347
className: classNames(childTarget.props.className, targetModifierClasses),
423348
// force disable single Tooltip child when popover is open
424-
disabled: isOpen && Utils.isElementOfType(childTarget, Tooltip) ? true : childTarget.props.disabled,
349+
disabled: isOpen && isElementTooltip(childTarget) ? true : childTarget.props.disabled,
425350
tabIndex: childTarget.props.tabIndex ?? targetTabIndex,
426351
});
427352
const wrappedTarget = createElement(
@@ -789,6 +714,10 @@ export class Popover<
789714
}
790715
}
791716

717+
function isElementTooltip(element: any): boolean {
718+
return element?.type?.displayName === `${DISPLAYNAME_PREFIX}.Tooltip`;
719+
}
720+
792721
function isEscapeKeypressEvent(e?: Event) {
793722
return e instanceof KeyboardEvent && e.key === "Escape";
794723
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* !
2+
* (c) Copyright 2025 Palantir Technologies Inc. All rights reserved.
3+
*/
4+
5+
import type { PositioningStrategy } from "@popperjs/core";
6+
import type * as React from "react";
7+
8+
import type { DefaultPopoverTargetHTMLProps, PopoverSharedProps } from "./popoverSharedProps";
9+
import type { PopupKind } from "./popupKind";
10+
11+
export const PopoverInteractionKind = {
12+
CLICK: "click" as const,
13+
CLICK_TARGET_ONLY: "click-target" as const,
14+
HOVER: "hover" as const,
15+
HOVER_TARGET_ONLY: "hover-target" as const,
16+
};
17+
export type PopoverInteractionKind = (typeof PopoverInteractionKind)[keyof typeof PopoverInteractionKind];
18+
19+
export interface PopoverProps<TProps extends DefaultPopoverTargetHTMLProps = DefaultPopoverTargetHTMLProps>
20+
extends PopoverSharedProps<TProps> {
21+
/**
22+
* Whether the popover/tooltip should acquire application focus when it first opens.
23+
*
24+
* @default true for click interactions, false for hover interactions
25+
*/
26+
autoFocus?: boolean;
27+
28+
/** HTML props for the backdrop element. Can be combined with `backdropClassName`. */
29+
backdropProps?: React.HTMLProps<HTMLDivElement>;
30+
31+
/**
32+
* The kind of interaction that triggers the display of the popover.
33+
*
34+
* @default "click"
35+
*/
36+
interactionKind?: PopoverInteractionKind;
37+
38+
/**
39+
* The kind of popup displayed by the popover. Gets directly applied to the
40+
* `aria-haspopup` attribute of the target element. This property is
41+
* ignored if `interactionKind` is {@link PopoverInteractionKind.HOVER_TARGET_ONLY}.
42+
*
43+
* @default "menu" or undefined
44+
*/
45+
popupKind?: PopupKind;
46+
47+
/**
48+
* Enables an invisible overlay beneath the popover that captures clicks and
49+
* prevents interaction with the rest of the document until the popover is
50+
* closed. This prop is only available when `interactionKind` is
51+
* `PopoverInteractionKind.CLICK`. When popovers with backdrop are opened,
52+
* they become focused.
53+
*
54+
* @default false
55+
*/
56+
hasBackdrop?: boolean;
57+
58+
/**
59+
* Whether the application should return focus to the last active element in the
60+
* document after this popover closes.
61+
*
62+
* This is automatically set (overridden) to:
63+
* - `false` for hover interaction popovers
64+
* - `true` when a popover closes due to an ESC keypress
65+
*
66+
* If you are attaching a popover _and_ a tooltip to the same target, you must take
67+
* care to either disable this prop for the popover _or_ disable the tooltip's
68+
* `openOnTargetFocus` prop.
69+
*
70+
* @default false
71+
*/
72+
shouldReturnFocusOnClose?: boolean;
73+
74+
/**
75+
* Popper.js positioning strategy.
76+
*
77+
* @see https://popper.js.org/docs/v2/constructors/#strategy
78+
* @default "absolute"
79+
*/
80+
positioningStrategy?: PositioningStrategy;
81+
}

packages/core/src/components/tooltip/tooltip.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import { createRef } from "react";
1919

2020
import { AbstractPureComponent, DISPLAYNAME_PREFIX, type IntentProps } from "../../common";
2121
import * as Classes from "../../common/classes";
22-
// eslint-disable-next-line import/no-cycle
23-
import { Popover, type PopoverInteractionKind } from "../popover/popover";
22+
import { Popover } from "../popover/popover";
2423
import { TOOLTIP_ARROW_SVG_SIZE } from "../popover/popoverArrow";
24+
import type { PopoverInteractionKind } from "../popover/popoverProps";
2525
import type { DefaultPopoverTargetHTMLProps, PopoverSharedProps } from "../popover/popoverSharedProps";
2626
import { TooltipContext, type TooltipContextState, TooltipProvider } from "../popover/tooltipContext";
2727

packages/core/test/popover/popoverTests.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import sinon from "sinon";
2222
import { Classes } from "../../src";
2323
import * as Errors from "../../src/common/errors";
2424
import { Button, PopupKind, Tooltip } from "../../src/components";
25-
import { Popover, type PopoverInteractionKind } from "../../src/components/popover/popover";
25+
import { Popover } from "../../src/components/popover/popover";
26+
import { type PopoverInteractionKind } from "../../src/components/popover/popoverProps";
2627
import { hasClass } from "../utils";
2728

2829
describe("<Popover>", () => {

0 commit comments

Comments
 (0)