carbon-design-system / carbon-addons-cloud

[DEPRECATED] Carbon Design System add-on for IBM Cloud
http://cloud-styles.carbondesignsystem.com
Apache License 2.0
15 stars 23 forks source link

CloudHeader menus do not closed when clicked outside #30

Open ajdaniel opened 6 years ago

ajdaniel commented 6 years ago

CloudHeader menus (e.g. user menu) does not close when you click away

Detailed description

In the CloudHeader, it would be good for the user to be able to click outside of the cloudheader menu for the menu to close. At the moment, the only way to do such a thing is to click the button that triggers them to toggle the internal state.

What browser are you working in?

Chrome

What version of the Carbon Design System are you using?

1.1.3

What offering/product do you work on? Any pressing ship or release dates we should be aware of?

IBM Watson Conversation.

Suggested fix

While looking around for a solution, I found that there is a library to create a HOC to assist with clicking outside which can be found here: https://github.com/Pomax/react-onclickoutside. Perhaps either use this library, or implement something manually like in this StackOverflow question https://stackoverflow.com/questions/32553158/detect-click-outside-react-component

tw15egan commented 6 years ago

This seems like a good enhancement to the current component. @asudoh / @joshblack do we currently have a way in place to hook in to clicks outside a component?

joshblack commented 6 years ago

Since teams can customize the menus themselves, this could get a little weird. We have a ClickListener and InnerClickListener component that we can use here over from carbon-components-react https://github.com/carbon-design-system/carbon-components-react/blob/master/src/internal/ClickListener.js

Seems like we have a couple of options:

  1. In the render* method for a menu in the header, we provide an onClickOutside argument that consumers can invoke when a click happens outside their node. This could look like:
<CloudHeader
  renderMenu={({ onClickOutside }) => (
    <ClickListener onClickOutside={onClickOutside}>
      <MyCustomMenu />
    </ClickListener>
  )}
/>
  1. We can use InnerClickListener in CloudHeader and pass the refKey through as props for someone to register.
<CloudHeader
  renderMenu={({ refKey }) => (
    <MyCustomMenu ref={refKey} />
  )}
/>

It seems like Option 1 would be the most intuitive, and has a clear analog to if we bring in the "standard" menu into this library as then someone could just do:

<CloudHeader
  renderMenu={props => <CloudHeader.Menu {...props} menuItems={[/* ... */]} />}
/>
tw15egan commented 6 years ago

I'm leaning towards option 1 as well