Skip to content

Commit ad3247a

Browse files
authored
Add optional node container target to Portal (#756)
* Add `containerRef` to Portal to target a specific DOM node * Add Portal prop 'type' to website documentation
1 parent 0ae8332 commit ad3247a

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

packages/portal/src/index.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ import { createPortal } from "react-dom";
2121
*
2222
* @see Docs https://reach.tech/portal#portal
2323
*/
24-
const Portal: React.FC<PortalProps> = ({ children, type = "reach-portal" }) => {
24+
const Portal: React.FC<PortalProps> = ({
25+
children,
26+
type = "reach-portal",
27+
containerRef,
28+
}) => {
2529
let mountNode = React.useRef<HTMLDivElement | null>(null);
2630
let portalNode = React.useRef<HTMLElement | null>(null);
2731
let forceUpdate = useForceUpdate();
@@ -33,11 +37,12 @@ const Portal: React.FC<PortalProps> = ({ children, type = "reach-portal" }) => {
3337
// In that case, it's important to append to the correct document element.
3438
const ownerDocument = mountNode.current!.ownerDocument;
3539
portalNode.current = ownerDocument?.createElement(type)!;
36-
ownerDocument!.body.appendChild(portalNode.current);
40+
const body = containerRef?.current || ownerDocument.body;
41+
body.appendChild(portalNode.current);
3742
forceUpdate();
3843
return () => {
39-
if (portalNode.current && portalNode.current.ownerDocument) {
40-
portalNode.current.ownerDocument.body.removeChild(portalNode.current);
44+
if (portalNode.current && body) {
45+
body.removeChild(portalNode.current);
4146
}
4247
};
4348
}, [type, forceUpdate]);
@@ -65,6 +70,12 @@ type PortalProps = {
6570
* @see Docs https://reach.tech/portal#portal-type
6671
*/
6772
type?: string;
73+
/**
74+
* Optional container ref to render the portal in.
75+
*
76+
* @see Docs https://reach.tech/portal#portal-containerRef
77+
*/
78+
containerRef?: React.RefObject<any>;
6879
};
6980

7081
if (__DEV__) {

website/src/pages/portal.mdx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ Renders content inside of a portal at the end of the DOM tree.
6262
6363
#### Portal Props
6464
65-
| Prop | Type | Required |
66-
| ----------------------- | ---- | -------- |
67-
| [`children`](#children) | node | true |
65+
| Prop | Type | Required |
66+
| ------------------------------- | ------ | -------- |
67+
| [`children`](#children) | node | true |
68+
| [`type`](#type) | string | false |
69+
| [`containerRef`](#containerRef) | ref | false |
6870
6971
##### Portal children
7072
@@ -83,3 +85,9 @@ Any content you want to render inside of the portal.
8385
_Type_: `string` default: `reach-portal`
8486
8587
The DOM element type to render.
88+
89+
##### Portal containerRef
90+
91+
_containerRef_: `ref` default: `document.body`
92+
93+
Ref to the container in where to render the portal. If not set the portal will be appended to the body of the document.

0 commit comments

Comments
 (0)