All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.
5.1.0 (2022-03-18)
- run lint-scripts --fix for consistent-type-imports (42d839d)
5.0.0 (2022-01-31)
Note: Version bump only for package @react-md/portal
4.0.3 (2021-12-31)
4.0.1 (2021-11-27)
- Updated imports to use
import type
when possible (ba96bb6)
4.0.0 (2021-11-24)
- Update to use new JSX Transform and latest
eslint
(8111cd3) - @react-md/portal:
ConditionalPortal
supports ReactNode children (c83d578)
- Minimum React version is now 16.14 instead of 16.8
- react-md: There will no longer be run-time prop validation with
the
prop-types
package.
3.1.0 (2021-09-10)
- ran
yarn format
to include new files (48d3d7f)
3.0.0 (2021-08-13)
Note: Version bump only for package @react-md/portal
2.9.1 (2021-07-27)
- install: slighly reduce install size by excluding tests in publish (9d01a44)
2.8.3 (2021-05-18)
- react-md.dev: updated tsdoc to work with
typedoc
(cf54c35)
2.8.0 (2021-04-22)
- tsconfig: separate tsconfig by package instead of a single root (b278230)
2.7.0 (2021-02-28)
- tsdoc: fixed some tsdoc annotations and styling (0449b86)
- updated test coverage to not include conditional component PropTypes (24e5df1)
2.5.0 (2020-12-15)
Note: Version bump only for package @react-md/portal
2.4.2 (2020-10-23)
Note: Version bump only for package @react-md/portal
2.4.1 (2020-10-17)
Note: Version bump only for package @react-md/portal
2.4.0 (2020-10-17)
- @react-md/theme: Better Contrast Colors by Default and dev-utils refactor (#955) (519b128)
2.2.2 (2020-09-02)
Note: Version bump only for package @react-md/portal
2.2.1 (2020-09-02)
Note: Version bump only for package @react-md/portal
2.0.2 (2020-06-30)
- LICENSE: Removed the time range from license since it was incorrect (50c9021)
- Added
sideEffects
field topackage.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.
- No longer supports
react@15
and only uses the newcreatePortal
API fromreact@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)
- no longer supports
visible
,onOpen
, andonClose
props since you'll normally want to handle enter/exit transitions with the @react-md/transition package instead
With 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.
The 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>;
};
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.
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.