base-ui icon indicating copy to clipboard operation
base-ui copied to clipboard

[portal] Add a Portal component

Open cpakken opened this issue 9 months ago • 9 comments

Feature request

Base-UI is internally using portals for components like <Popover />

Please expose the <Portal /> as its own component

Similar to https://www.radix-ui.com/primitives/docs/utilities/portal

Others:

  • https://mui.com/base-ui/react-portal/

cpakken avatar Mar 02 '25 20:03 cpakken

@cpakken Could you share some details about your use-case for using a portal directly?

As you said, all the components that could have a portal should already provide it

mj12albert avatar Mar 03 '25 03:03 mj12albert

I have a <ReaderView /> component that I want to maximize to the viewport by portaling out with fixed position. I can use React's native portal but I'd rather use BaseUI's underlying portal if I'm going to be using its other components. This way I don't need to create a separate portal dom node and just keep things consistent

cpakken avatar Mar 03 '25 04:03 cpakken

Actually the internal portals are just Floating UI's portal: https://github.com/mui/base-ui/blob/master/packages/react/src/select/portal/SelectPortal.tsx#L19

mj12albert avatar Mar 03 '25 07:03 mj12albert

@cpakken Do you need focus management for your use case? We have a lite Portal that we use internally that we could export, but it doesn't include focus management.

colmtuite avatar Mar 03 '25 11:03 colmtuite

@colmtuite that would be nice, there are some control buttons in the <ReaderView />

cpakken avatar Mar 03 '25 12:03 cpakken

@cpakken Can you provide much more detail on what you're trying to do? It would be a bit of work to export a Portal that works with focus management, as opposed to just exporting the lite Portal. I'd love to get a closer look at the problem you're having?

colmtuite avatar Mar 10 '25 12:03 colmtuite

@colmtuite I think this is overcomplicated my use case. I just wanted an equivalent to:

import { Portal } from 'radix-ui'

I have a custom element, <ReaderView /> that I would like to use portal and instead of making a separate element appended to

and then use React's portal I wanted to leverage what Base UI has already implemented.

cpakken avatar Mar 10 '25 22:03 cpakken

@cpakken the main issue with portals is that they need proper focus management to remain accessible to non-pointer users. Our existing components (like Dialog or Popover) handle portaling and focus management tightly coupled together, which can often be used for other related components. Can ReaderView be a Dialog?

If we export a Portal component, it would not handle any focus management and simply move the element outside of clipping containers—matching what Base UI does internally for things like the NumberField virtual cursor subcomponent. But a11y concerns need to be taken into consideration

atomiks avatar Mar 11 '25 03:03 atomiks

@atomiks Oh. I just realized I can use <Dialog /> and then set position: fixed with width and height set to screen dimensions. I think that will work

cpakken avatar Mar 11 '25 08:03 cpakken