All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.
yarn format to include new files
(48d3d7f)Note: Version bump only for package @react-md/portal
typedoc
(cf54c35)Note: Version bump only for package @react-md/portal
Note: Version bump only for package @react-md/portal
Note: Version bump only for package @react-md/portal
Note: Version bump only for package @react-md/portal
Note: Version bump only for package @react-md/portal
sideEffects field to package.json
(31820b9)sideEffects formatting
(78a7b6b)No changes.
This was a re-write of the Portal component that created a "more usable" API
as well as removing temporary workarounds before the createPortal API was
added into React.
There is also now another new component: ConditionalPortal that can be used to
conditionally render children wrapped in the Portal component only when
portal props have been enabled. This will most likely be used internally between
packages though, but it is still exported and documented for external use.
react@15 and only uses the new createPortal API from
react@16+. This major change removed all need for the following props since
they have no DOM node to create/apply them to:styleclassNamecomponentlastChildrenderNode (see API changes below)visible, onOpen, and onClose props since you'll
normally want to handle enter/exit transitions with the
@react-md/transition package insteadWith the switch to using the createPortal API from React, you can create
portals by using the into or intoId props instead of using the renderNode
/ lastChild props.
If both the into and intoId props are undefined, a portal will be created
into the main document.body which is kind of how the API worked before when
you did not specify a renderNode. If the into or intoId props result in
the container being null, the Portal's children will not be rendered.
The portal's container element will be evaluated once the component mounts as
well as each time the into or intoId props are no longer shallow equal. This
means that if you use an arrow function for the into prop, you might want to
use the useCallback hook from react instead otherwise it'll re-evaluate each
time this component renders.
intoId prop
The intoId prop is used when you want to render into a specific element on the
page by id.
12345678const App = () => {
<div>
<div id="portal-div" />
<Portal intoId="portal-div">
<h3>This is a portaled h3 tag!</h3>
</Portal>
</div>;
};into prop
The into prop can either be a string, function, an HTMLElement, or
null. If the into prop is a string, the portal will be created into the
result of document.querySelector so you can do some fancy element selecting if
you need.
1234567891011121314const App = () => (
<div>
<ul id="some-list">
<li class="custom-class">Item 1</li>
<li class="custom-class">Item 2</li>
<li class="custom-class">Item 3</li>
<li class="custom-class">Item 4</li>
<li class="custom-class">Item 5</li>
</ul>
<Portal into="#some-list .custom-class:nth-child(3)">
<h3>This is a portaled h3 tag!</h3>
</Portal>
</div>
);If the into prop is a function, it should return an HTMLElement or null.
12345678910111213141516const App = () => {
// Note: this function will be called each time the Portal (and App) component
// is rendered, so if this function is expensive to compute, you should
// instead use `useCallback`:
// const into = useCallback(() => { /* expensive calculation here */ }, []);
const into = () => document.getElementById("portal-div");
return (
<div>
<div id="portal-div" />
<Portal into={into}>
<h3>This is a portaled h3 tag!</h3>
</Portal>
</div>
);
};Finally, if the into prop is an HTMLElement, this will behave just like the
renderNode prop did before and just render into that element. This is really
just useful if you would like to use React refs or cache the portal's node
yourself in your lifecycle methods or some other way.
123456789101112const App = () => {
const ref = useRef<HTMLDivElement | null>(null);
return (
<>
<div ref={ref} />
<Portal into={this.ref.current}>
<h3>This is a portalled h3 tag!</h3>
</Portal>
</>
);
};Note: The
intoprop can be strongly typed for Typescript users with thePortalIntotype.