raster-foundry / blasterjs

React UI library designed and built by Azavea
https://raster-foundry-blaster.netlify.com
Other
6 stars 3 forks source link

Difficult to use button elements inside tooltip #249

Open jfrankl opened 4 years ago

jfrankl commented 4 years ago

I want to use a tooltip as though it is a dropdown. This seemed appropriate because Blaster does not have a dropdown component and effectively all of the functionality is the same.

Where I'm running into an issue is with including button elements in the tooltip. Because the tooltip needs to be nested in the element inside the component that triggers it, I end up with something that looks like this:

<Button>
  Open menu
  <Tooltip bg="white" trigger="click" placement="bottom-end" closeOnClickOutside>
    <Button appearance={Appearance.MINIMAL}>RCT Hub</Button>
    <Button appearance={Appearance.MINIMAL}>Logout</Button>
  </Tooltip>
</Button>

The resulting DOM is fine—the inner buttons are actually rendered outside of the outer buttons. But this code results in React warnings about nested buttons.

index.js:1446 Warning: validateDOMNesting(...): <button> cannot appear as a descendant of <button>.

It would be valuable if there were a different way to connect a tooltip to the trigger element. Or, if there were a dedicated dropdown component. Having a basic dropdown with buttons comes up on most of our applications (for example, needing to make a flyout/overflow menu with some actions inside).

designmatty commented 4 years ago

A dropdown component is planned https://github.com/raster-foundry/blasterjs/issues/29

If I remember correctly, the tooltip component currently renders within the HTML element in the DOM for which it's attached to. If you were to render your Button as a different HTML element other than a <button>, the warning would go away. You could achieve this with the as prop. https://styled-components.com/docs/api#as-polymorphic-prop

<Button as="div">
  Open menu
  <Tooltip bg="white" trigger="click" placement="bottom-end" closeOnClickOutside>
    <Button appearance={Appearance.MINIMAL}>RCT Hub</Button>
    <Button appearance={Appearance.MINIMAL}>Logout</Button>
  </Tooltip>
</Button>

Note this may require some additional aria attributes. But I'm not sure. You'd have to test.