Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[popover2] feat(ContextMenu2): support popoverProps.rootBoundary #5423

Merged
merged 8 commits into from
Aug 11, 2022
14 changes: 14 additions & 0 deletions packages/docs-app/src/examples/core-examples/drawerExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
H5,
HTMLSelect,
Label,
Menu,
MenuItem,
OptionProps,
Position,
Switch,
Expand All @@ -37,6 +39,7 @@ import {
handleValueChange,
IExampleProps,
} from "@blueprintjs/docs-theme";
import { ContextMenu2 } from "@blueprintjs/popover2";

import { IBlueprintExampleData } from "../../tags/types";

Expand Down Expand Up @@ -119,6 +122,17 @@ export class DrawerExample extends React.PureComponent<IExampleProps<IBlueprintE
can build upon. And the enterprise data foundation goes where the business drives it.
</p>
<p>Start the revolution. Unleash the power of data integration with Palantir Foundry.</p>
<ContextMenu2
content={
<Menu>
<MenuItem text="Menu Item 1" />
</Menu>
}
>
<Button onClick={this.handleClose}>
Right Click for a <Code>&lt;ContextMenu2 /&gt;</Code>
</Button>
</ContextMenu2>
</div>
</div>
<div className={Classes.DRAWER_FOOTER}>Footer</div>
Expand Down
4 changes: 2 additions & 2 deletions packages/popover2/src/contextMenu2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export interface ContextMenu2Props
* A limited subset of props to forward along to the popover generated by this component.
*/
popoverProps?: IOverlayLifecycleProps &
Pick<Popover2Props, "popoverClassName" | "transitionDuration" | "popoverRef">;
Pick<Popover2Props, "popoverClassName" | "transitionDuration" | "popoverRef" | "rootBoundary">;

/**
* HTML tag to use for container element. Only used if this component's children are specified as
Expand Down Expand Up @@ -204,7 +204,7 @@ export const ContextMenu2: React.FC<ContextMenu2Props> = React.forwardRef<any, C
})}
placement="right-start"
positioningStrategy="fixed"
rootBoundary="viewport"
rootBoundary={popoverProps?.rootBoundary ?? "viewport"}
renderTarget={renderTarget}
transitionDuration={popoverProps?.transitionDuration ?? 100}
/>
Expand Down
52 changes: 51 additions & 1 deletion packages/popover2/test/contextMenu2Tests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { mount, ReactWrapper } from "enzyme";
import * as React from "react";
import { spy } from "sinon";

import { Classes as CoreClasses, Menu, MenuItem } from "@blueprintjs/core";
import { Classes as CoreClasses, Drawer, Menu, MenuItem } from "@blueprintjs/core";

import {
Classes,
Expand Down Expand Up @@ -48,6 +48,16 @@ const COMMON_TOOLTIP_PROPS: Partial<Tooltip2Props> = {
};

describe("ContextMenu2", () => {
let containerElement: HTMLElement | undefined;

beforeEach(() => {
containerElement = document.createElement("div");
document.body.appendChild(containerElement);
});
afterEach(() => {
containerElement?.remove();
});

describe("basic usage", () => {
it("renders children and Popover2", () => {
const ctxMenu = mountTestMenu();
Expand Down Expand Up @@ -108,6 +118,7 @@ describe("ContextMenu2", () => {
<ContextMenu2 content={MENU} popoverProps={{ transitionDuration: 0 }} {...props}>
<div className={TARGET_CLASSNAME} />
</ContextMenu2>,
{ attachTo: containerElement },
);
}
});
Expand Down Expand Up @@ -158,6 +169,7 @@ describe("ContextMenu2", () => {
</div>
)}
</ContextMenu2>,
{ attachTo: containerElement },
);
}
});
Expand Down Expand Up @@ -430,6 +442,44 @@ describe("ContextMenu2", () => {
});
});

describe("with Drawer as parent content", () => {
it("positions correctly", () => {
const POPOVER_CLASSNAME = "test-positions-popover";
const wrapper = mount(
<Drawer isOpen={true} position="right" transitionDuration={0}>
<ContextMenu2
content={MENU}
className="test-ctx-menu"
popoverProps={{ transitionDuration: 0, popoverClassName: POPOVER_CLASSNAME }}
style={{ padding: 20, background: "red" }}
>
<div className={TARGET_CLASSNAME} style={{ width: 20, height: 20, background: "blue" }} />
</ContextMenu2>
</Drawer>,
{ attachTo: containerElement },
);
const target = wrapper.find(`.${TARGET_CLASSNAME}`).hostNodes();
assert.isTrue(target.exists(), "target should exist");
const nonExistentPopover = wrapper.find(`.${POPOVER_CLASSNAME}`).hostNodes();
assert.isFalse(
nonExistentPopover.exists(),
"ContextMenu2 popover should not be open before triggering contextmenu event",
);

const targetRect = target.getDOMNode().getBoundingClientRect();
// right click on the target
const simulateArgs = {
clientX: targetRect.left + targetRect.width / 2,
clientY: targetRect.top + targetRect.height / 2,
x: targetRect.left + targetRect.width / 2,
y: targetRect.top + targetRect.height / 2,
};
target.simulate("contextmenu", simulateArgs);
const popover = wrapper.find(`.${POPOVER_CLASSNAME}`).hostNodes();
assert.isTrue(popover.exists(), "ContextMenu2 popover should be open");
});
});

function openTooltip(wrapper: ReactWrapper, targetClassName = TARGET_CLASSNAME) {
const target = wrapper.find(`.${targetClassName}`);
if (!target.exists()) {
Expand Down