All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.
Note: Version bump only for package @react-md/portal
import type
when possible
(ba96bb6)eslint
(8111cd3)ConditionalPortal
supports ReactNode children
(c83d578)prop-types
package.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:style
className
component
lastChild
renderNode
(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
propThe intoId
prop is used when you want to render into a specific element on the
page by id.
const App = () => {
<div>
<div id="portal-div" />
<Portal intoId="portal-div">
<h3>This is a portaled h3 tag!</h3>
</Portal>
</div>;
};
into
propThe 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.
const 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
.
const 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.
const 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
into
prop can be strongly typed for Typescript users with thePortalInto
type.