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

Uses new WindowEvent component for Flyout "close on ESC" #1127

Merged
merged 11 commits into from
Aug 22, 2018

Conversation

jasonrhodes
Copy link
Member

@jasonrhodes jasonrhodes commented Aug 20, 2018

The keyDown event listener for the Flyout component was attached to the Flyout node itself, so if you clicked anywhere outside of the Flyout and pressed "ESC", the Flyout would remain open. This PR does the following:

  • Defines a new EuiWindowEvent component to safely handle the adding and necessary unmount-removal of window events
  • Adds a few tests for the new component
  • Uses the new component to define a window listener for closing the flyout on ESC press

I built the code locally and ran in local Kibana and it works as described here. The local build fails on the webpack bundle step, which I'm looking more into now.

Update: local webpack error was a circular dependency because I was importing directly from components instead of from components/window_event ... all fixed now :)

@sorenlouv
Copy link
Member

sorenlouv commented Aug 20, 2018

Do we still need the event listener on the flyout?

onKeyDown={this.onKeyDown}

Won't onKeyDown be invoked twice now? Both by the listener on the div and EuiWindowEvent?

@jasonrhodes
Copy link
Member Author

@sqren good catch -- I'd removed that and then accidentally killed my changes in that file with git checkout -- . and forgot to re-remove it. Thanks!

@jasonrhodes
Copy link
Member Author

Note: this PR addresses a TODO item in elastic/kibana#21300

@sorenlouv
Copy link
Member

LGTM! You also need a 👍 from someone on the EUI before merging.

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

Thanks for jumping in here to add this.

A couple of things:

  1. Can you actually move this to the services folder instead of components as it doesn't actually render any dom elements but is just a helper?
  2. Can you also add a documentation page under the Utilities category with some more explanation of what it does and why one would need to use it.
  3. Don't forget to add an entry to the Changelog.

@@ -0,0 +1 @@
export { default as EuiWindowEvent } from './window_event';
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need the default as here as it's in the component file.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is how you "proxy export" a default component from another file, I think. Or I could make the export in window_event be named and drop default as here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah I think we just name everything so we ensure there are no conflicts or that we can add to them down the line without breaking changes.

@jasonrhodes
Copy link
Member Author

jasonrhodes commented Aug 20, 2018

Hey @cchaos, I just pushed some example/docs and changelog additions, but please let me know if I've done anything funky in there. I'll add a bit more explanation to what I've got in the docs stuff, and I'll move the component into services in a bit. Thanks for the feedback!

CHANGELOG.md Outdated
- Added a new `EuiWindowEvent` component for declarative, safe management of `window` event listeners
- Changed `Flyout` component to close on ESC keypress even if the flyout does not have focus

## [`master`](https://github.com/elastic/eui/tree/master)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a copied heading, you can just append your bullets after the EuiSuperSelect one.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed here: 73f0ed0

}],
text: (
<p>
Use an <EuiCode>EuiWindowEvent</EuiCode> to safely manage adding and auto-removing event listeners to <EuiCode>window</EuiCode>.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you also describe how?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure!

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed: e4d90d9

</p>
),
components: { EuiWindowEvent },
demo: <WindowEvent />,
Copy link
Contributor

Choose a reason for hiding this comment

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

Also add a props key here to populate a props tab with the props listed in a table like so:
props: { EuiWindowEvent }

@jasonrhodes
Copy link
Member Author

@cchaos I can't find the comment now due to GitHub magic, but re: your request for explaining "how" to use the component, that's addressed here: e4d90d9

@jasonrhodes
Copy link
Member Author

New component moved to services directory here: a348dbb

@cchaos
Copy link
Contributor

cchaos commented Aug 20, 2018

Here's an issue I saw using the example:

Is there any way to add scope or prevent something like this?

@jasonrhodes
Copy link
Member Author

@cchaos re: scope, I think the answer is that my example is a bad one (or at least bad for that particular problem). Normally you wouldn't be listening for such a common key-press. If you were instead listening for "esc", for example, and there was a typeahead that was directly also listening on "esc" to clear results, the typeahead would do e.stopPropagation() which would prevent the window from hearing the event.

In other words, window events will always fire unless a more targeted event stops the event propagation earlier, so they need to be less generic than "any backspace key press".

I can change that to "escape" in the example if you think that would help? And/or make a note to this effect in the example docs?

@cchaos
Copy link
Contributor

cchaos commented Aug 20, 2018

Yeah, I think I would err on the side of creating an example that is the proper use of the service. We see a lot of just copy and paste style usages and want to make sure that doing so doesn't introduce issues. But I also think adding another paragraph or even a callout, to describe this issue would be good as well.

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

These new examples are fantastic. I think it's a lot clearer when and why to use this helper. Thanks so much for adding it all.

Just had one more adjustment to add, but LGTM!

</div>
),
components: { EuiWindowEvent },
demo: <BasicWindowEvent />,
Copy link
Contributor

Choose a reason for hiding this comment

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

Add props: { EuiWindowEvent }

@jasonrhodes jasonrhodes merged commit 658d538 into elastic:master Aug 22, 2018
@jasonrhodes jasonrhodes deleted the flyout-esc-window branch August 22, 2018 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants