OverlayTrigger on custom component not working
Asked Answered
B

2

10

I'm trying to show a Popover when a custom component (a button) is hovered:

class MyComponent extends React.PureComponent<MyComponentProperties>  {
    public render(): JSX.Element {
        const overlay: JSX.Element = (
            <Popover id={this.uuid}>
                <Popover.Content>
                    Hello world!
                </Popover.Content>
            </Popover>
        );

        return <OverlayTrigger trigger="hover" placement="auto" delay={{show : 700, hide : 0}} overlay={overlay}>
            <MyFancyButton ... />
        </OverlayTrigger >
    }
}
class MyFancyButton extends React.PureComponent<MyFancyButtonProperties> {
    public render(): JSX.Element {
        return <button ...>Hover me!</button>
    }
}

The Popover doesn't show. However, it works if I change the return of the render function of MyComponent to:

return <OverlayTrigger trigger="hover" placement="auto" delay={{show : 700, hide : 0}} overlay={overlay}>
    <button>Hover me!</button>
</OverlayTrigger >

I checked https://react-bootstrap.github.io/components/overlays/#overlay-trigger and it says:

Note that triggering components must be able to accept a ref since will attempt to add one. You can use forwardRef() for function components.

I'm not sure how to do this. I tried adding a ref property in MyFancyButtonProperties and forwarding it to button, but it doesn't work:

class MyFancyButton extends React.PureComponent<MyFancyButtonProperties> {
    public render(): JSX.Element {
        return <button ref={this.props.ref} ...>Hover me!</button>
    }
}

My versions:

  • React 16.8.6
  • React bootstrap 1.0.0-beta.14
Bans answered 26/2, 2020 at 14:24 Comment(1)
I asked a somewhat similar question to see why forwardRef does not seem to work correctly with bootstrap: #60875568Adames
B
22

I finally found a solution here: https://github.com/react-bootstrap/react-bootstrap/issues/2208#issuecomment-301737531

I wrapped the component, which should get a tooltip, with a <span> in the render function of MyComponent to

return <OverlayTrigger trigger="hover" placement="auto" delay={{show : 700, hide : 0}} overlay={overlay}>
    <span><MyFancyButton ... /></span>
</OverlayTrigger >

and now it works.

Bans answered 26/2, 2020 at 20:52 Comment(1)
This breaks placement location in my case.Dentation
D
3

Your custom component needs to pass the event handler props through.

const FancyButton = ({ children, ...props }) => (
  <Button {...props}>
    {children}
  </Button>
);

Source: https://github.com/react-bootstrap/react-bootstrap/issues/2208

Dentation answered 4/12, 2021 at 15:13 Comment(2)
This maintains control over the DOM without having to add an extra span.Rector
IMHO, this is the best solution.Perceval

© 2022 - 2024 — McMap. All rights reserved.