# @fluentui/react-portal
**React Portal components for [Fluent UI React](https://react.fluentui.dev)**
This package contains the `Portal` component, which allow consumers to render [React portals](https://reactjs.org/docs/portals.html) with Fluent styling and RTL awareness.
## Usage
### Portal
`Portal` can be used as standalone with any part of a Fluent app. The component should be under a `FluentProvider` in the tree to make sure that proper theming and RTL handling is available.
By default `Portal` will render content to `document body`
```tsx
Content rendered by default to Fluent's document.body
```
The mount location of the portal can be customized
```tsx
const node = document.getElementById('customNode');
Render to a custom node in DOM;
```
### Styling
`Portal` renders React children directly to the default/configured DOM node. Therefore styling should be applied to the `children` by users directly.
### Virtual parents
Out of order DOM elements can be problematic when using 'click outside' event listeners since you cannot rely on `element.contains(event.target)` because the `Portal` elements are out of DOM order.
```tsx
const outerButtonRef = React.useRef();
const innerButtonRef = React.useRef();
// DOM output
// Let's add an event listener to 'dismss' the outer portal when clicked outside
// ⚠⚠⚠ This will always be called when clicking on the inner button
document.addEventListener((event) => {
if (outerButtonRef.current.contains(event.target)) {
dismissOuterPortal();
}
})
```
When the above case is not required, using `element.contains` is perfectly fine. But nested cases should still be handled appropriately. We do this using the concept of `virtual parents`
`Portal` will make public 2 utilities that will only be used in cases where the user needs to know if an out of order DOM element will need to be used or not.
- `setVirtualParent` - sets virtual parent. Portal uses this already internally.
- `elementContains` - similar to `element.contains` but uses the virtual hierarchy as reference
Below shows what a virtual parent is
```tsx
// Setting a virtual parent
const parent = document.getElementById('parent');
const child = document.getElementById('child');
child._virtual.parent = parent;
```
`Portals` will render a hidden span that will be the virtual parent, by nesting portals virtual parens will also be nested so that `elementContains` will work predictably.
```tsx
```
DOM output:
```tsx
{/* Virtual parent for portal*/}
{/* Virtual parent for portal*/}