reach/reach-ui

Add Portal Provider to be able to configure `containerRef`

konstantinkreft opened this issue ยท 0 comments

๐Ÿš€ Feature request

Current Behavior

Currently, for most components (e.g. MenuButton, Dialog, ...) it is impossible to configure the containerRef of the underlying Portal if the user wants to portal that component. See #900

As a result, you can't portal most of the reach-ui components if you are using reach-ui in a Web Component.

Desired Behavior

A clear and concise way to be able to set the containerRef of a Portal in components that use the reach-ui Portal.

Suggested Solution

The smallest impact to the components APIs would be to add a PortalContainerContext:

const defaultBodyRef = useRef(document.body);
const PortalContainerContext = React.createContext(defaultBodyRef);

Which would be consumed by the Portal component and used if no containerRef is set directly on the Portal component.

And the default value could be overridden like:

return (
  <PortalContainerContext.Provider value={customContainerRef}>
    <Dialog>
      <p>Some Content</p>
      <PortalContainerContext.Provider value={anotherCustomContainerRef}>
        <MenuButton>...</MenuButton>
      </PortalContainerContext.Provider>
    </Dialog>
  </PortalContainerContext.Provider>
);

Who does this impact? Who is this for?

It serves as an opt-in for everyone who wants full control over the containerRef of the underlying Portal. Especially people who use reach-ui inside Web Components.

Describe alternatives you've considered

The alternative would be to expose the containerRef property on each component that may use a Portal underneath. That could be quite messy and PRs with that solution were closed without merging in the past (e.g. #901).

Additional context

I would be happy to contribute :)