Skip to main content
react-md
react-md - Portal - Changelog

Change Log

All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.

3.1.0 (2021-09-10)

Other Internal Changes

  • 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)

Other Internal Changes

  • install: slighly reduce install size by excluding tests in publish (9d01a44)

2.8.3 (2021-05-18)

Documentation

  • react-md.dev: updated tsdoc to work with typedoc (cf54c35)

2.8.0 (2021-04-22)

Other Internal Changes

  • tsconfig: separate tsconfig by package instead of a single root (b278230)

2.7.0 (2021-02-28)

Documentation

  • tsdoc: fixed some tsdoc annotations and styling (0449b86)

Other Internal Changes

  • 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)

Features

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)

Bug Fixes

  • LICENSE: Removed the time range from license since it was incorrect (50c9021)
  • Added sideEffects field to package.json (31820b9)
  • sideEffects formatting (78a7b6b)

v2.0.1

No changes.

v2.0.0

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.

Breaking Changes

  • No longer supports 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)
  • no longer supports visible, onOpen, and onClose props since you'll normally want to handle enter/exit transitions with the @react-md/transition package instead

New API and Props

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.

Using the 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>;
};
Using the 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 into prop can be strongly typed for Typescript users with the PortalInto type.