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

ContextMenu fixes & Overlay didClose #2399

Merged
merged 5 commits into from
Apr 18, 2018
Merged

ContextMenu fixes & Overlay didClose #2399

merged 5 commits into from
Apr 18, 2018

Conversation

giladgray
Copy link
Contributor

Fixes #2131, Fixes #803, Fixes #1188

Changes proposed in this pull request:

several intertwined changes here with some very tricky associated logic. i added unit tests!

@giladgray giladgray requested a review from jkillian April 17, 2018 21:58
@blueprint-bot
Copy link

fix Overlay outside click

Preview: documentation | landing | table

const onClose = spy();
ContextMenu.show(MENU, { left: 0, top: 0 }, onClose);
it("invokes onClose callback when menu closed", done => {
ContextMenu.show(MENU, { left: 0, top: 0 }, done);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels a little odd to me to do things this way w/o an assertion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a pattern i see frequently in other test suites: it essentially asserts that the callback is called at all. if it's not called then it will time out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 seems reasonable, I didn't know the exact timeout behavior

@@ -361,7 +368,7 @@ export class Overlay extends React.PureComponent<IOverlayProps, IOverlayState> {

const isClickInThisOverlayOrDescendant = openStack
.slice(stackIndex)
.some(({ containerElement }) => containerElement && containerElement.contains(eventTarget));
.some(({ containerElement: elem }) => elem && elem.contains(eventTarget) && !elem.isSameNode(eventTarget));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave a comment why we need the isSameNode check?

@@ -62,10 +61,10 @@ class ContextMenu extends AbstractPureComponent<{}, IContextMenuState> {
onInteraction={this.handlePopoverInteraction}
position={Position.RIGHT_TOP}
popoverClassName={popoverClassName}
popoverDidClose={this.props.didClose}
target={<div />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it better to make this "div" so as not to break shallow comparison of props for updates? though you'd also need to change backdropProps above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't understand the action item here. i could make it a static constant?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just make it "div", right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but either way, prop comparison will never be equal because of backdropProps above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"div" is quite different from <div /> here... one would appear as three letters in the DOM, the other is an empty element.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I see, you have to use targetElementTag for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

targetElementTag is actually the parent target prop, and a target is required so you can't just set that prop

};
const TRANSITION_DURATION = 100;

/* istanbul ignore next */
class ContextMenu extends AbstractPureComponent<{}, IContextMenuState> {
class ContextMenu extends AbstractPureComponent<{ didClose: () => void }, IContextMenuState> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe interface instead of inline? not sure what current BP standards are

@jkillian
Copy link
Contributor

👍 everything generally looks reasonable to me. Just as a caveat, it's been a little while since I've looked at complicated BP code like Overlay, and I didn't actually test things out, just looked over the code

@blueprint-bot
Copy link

ICMProps, comment

Preview: documentation | landing | table

@giladgray giladgray merged commit 979a8ed into develop Apr 18, 2018
@giladgray giladgray deleted the gg/context-menu branch April 18, 2018 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants