Socket
Socket
Sign inDemoInstall

@chakra-ui/portal

Package Overview
Dependencies
Maintainers
4
Versions
320
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@chakra-ui/portal - npm Package Compare versions

Comparing version 1.0.6 to 1.1.0

31

CHANGELOG.md
# Change Log
## 1.1.0
### Minor Changes
- [`e41e6b81b`](https://github.com/chakra-ui/chakra-ui/commit/e41e6b81bf6943fef9b34e5ddd31ee57b416a426)
[#3210](https://github.com/chakra-ui/chakra-ui/pull/3210) Thanks
[@segunadebayo](https://github.com/segunadebayo)! - - Add support for changing
the container that portal is appended to. You can now pass `containerRef` to
portal.
- Update portal `README.md` and tests.
- Add support for `appendToParentPortal={false}` to opt out of nested portals.
- Fix issue with portal `zIndex` container where it renders elements outside
of view.
- Renamed `getContainer` prop to `containerRef` to make it possible to pass
the `ref` directly. This affects the `Modal` component primarily
```jsx live=false
// Before
<Portal getContainer={() => ref.current}>{/** Content */}</Portal>
// After
<Portal containerRef={ref}>{/** Content */}</Portal>
```
### Patch Changes
- Updated dependencies
[[`b572bceed`](https://github.com/chakra-ui/chakra-ui/commit/b572bceedd9fb0c41c65118f0d9ba672791932ca)]:
- @chakra-ui/hooks@1.1.3
## 1.0.6

@@ -4,0 +35,0 @@

120

dist/cjs/portal.js

@@ -20,2 +20,6 @@ "use strict";

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
var _createContext = (0, _utils.createContext)({

@@ -28,52 +32,43 @@ strict: false,

var PORTAL_CLASSNAME = "chakra-portal";
var PORTAL_SELECTOR = ".chakra-portal";
var Container = function Container(props) {
var children = props.children,
zIndex = props.zIndex;
return /*#__PURE__*/React.createElement("div", {
className: "chakra-portal-zIndex",
style: {
position: "relative",
zIndex: zIndex
position: "absolute",
zIndex: props.zIndex,
top: 0,
left: 0,
right: 0 // NB: Don't add `bottom: 0`, it makes the entire app unusable
// @see https://github.com/chakra-ui/chakra-ui/issues/3201
}
}, children);
}, props.children);
};
/**
* Portal
*
* Declarative component used to render children into a DOM node
* that exists outside the DOM hierarchy of the parent component.
*
* @see Docs https://chakra-ui.com/docs/overlay/portal
* Portal that uses `document.body` as container
*/
function Portal(props) {
var DefaultPortal = function DefaultPortal(props) {
var appendToParentPortal = props.appendToParentPortal,
children = props.children;
var tempNode = React.useRef(null);
var portal = React.useRef(null);
var forceUpdate = (0, _hooks.useForceUpdate)();
var getContainer = (0, _hooks.useCallbackRef)(props.getContainer);
var onMount = (0, _hooks.useCallbackRef)(props.onMount);
var onUnmount = (0, _hooks.useCallbackRef)(props.onUnmount);
var parentPortal = usePortalContext();
var manager = (0, _portalManager.usePortalManager)();
(0, _hooks.useSafeLayoutEffect)(function () {
var _ref, _getContainer;
if (!tempNode.current) return;
var doc = tempNode.current.ownerDocument;
var host = (_ref = (_getContainer = getContainer()) != null ? _getContainer : parentPortal) != null ? _ref : doc.body;
/**
* host may be `null` when a hot-loader
* replaces components on the page
*/
var host = appendToParentPortal ? parentPortal != null ? parentPortal : doc.body : doc.body;
if (!host) return;
portal.current = doc.createElement("div");
portal.current.className = Portal.className;
portal.current.className = PORTAL_CLASSNAME;
host.appendChild(portal.current);
forceUpdate();
onMount();
var portalNode = portal.current;
return function () {
onUnmount();
if (host.contains(portalNode)) {

@@ -84,14 +79,71 @@ host.removeChild(portalNode);

}, []);
var childrenToRender = manager != null && manager.zIndex ? /*#__PURE__*/React.createElement(Container, {
zIndex: manager.zIndex
}, props.children) : props.children;
var _children = manager != null && manager.zIndex ? /*#__PURE__*/React.createElement(Container, {
zIndex: manager == null ? void 0 : manager.zIndex
}, children) : children;
return portal.current ? /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/React.createElement(PortalContextProvider, {
value: portal.current
}, childrenToRender), portal.current) : /*#__PURE__*/React.createElement("span", {
}, _children), portal.current) : /*#__PURE__*/React.createElement("span", {
ref: tempNode
});
};
/**
* Portal that uses a custom container
*/
var ContainerPortal = function ContainerPortal(props) {
var children = props.children,
containerRef = props.containerRef,
appendToParentPortal = props.appendToParentPortal;
var containerEl = containerRef.current;
var host = containerEl != null ? containerEl : _utils.isBrowser ? document.body : undefined;
var portal = React.useMemo(function () {
var node = containerEl == null ? void 0 : containerEl.ownerDocument.createElement("div");
if (node) node.className = PORTAL_CLASSNAME;
return node;
}, [containerEl]);
var forceUpdate = (0, _hooks.useForceUpdate)();
(0, _hooks.useSafeLayoutEffect)(function () {
forceUpdate();
}, []);
(0, _hooks.useSafeLayoutEffect)(function () {
if (!portal || !host) return;
host.appendChild(portal);
return function () {
host.removeChild(portal);
};
}, [portal, host]);
if (host && portal) {
return /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/React.createElement(PortalContextProvider, {
value: appendToParentPortal ? portal : null
}, children), portal);
}
return null;
};
/**
* Portal
*
* Declarative component used to render children into a DOM node
* that exists outside the DOM hierarchy of the parent component.
*
* @see Docs https://chakra-ui.com/docs/components/portal
*/
function Portal(props) {
var containerRef = props.containerRef,
rest = _objectWithoutPropertiesLoose(props, ["containerRef"]);
return containerRef ? /*#__PURE__*/React.createElement(ContainerPortal, _extends({
containerRef: containerRef
}, rest)) : /*#__PURE__*/React.createElement(DefaultPortal, rest);
}
Portal.className = "chakra-portal";
Portal.selector = "." + Portal.className;
Portal.defaultProps = {
appendToParentPortal: true
};
Portal.className = PORTAL_CLASSNAME;
Portal.selector = PORTAL_SELECTOR;

@@ -98,0 +150,0 @@ if (_utils.__DEV__) {

@@ -1,3 +0,7 @@

import { useCallbackRef, useForceUpdate, useSafeLayoutEffect } from "@chakra-ui/hooks";
import { createContext, __DEV__ } from "@chakra-ui/utils";
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import { useForceUpdate, useSafeLayoutEffect } from "@chakra-ui/hooks";
import { createContext, isBrowser, __DEV__ } from "@chakra-ui/utils";
import * as React from "react";

@@ -10,55 +14,43 @@ import { createPortal } from "react-dom";

});
var PORTAL_CLASSNAME = "chakra-portal";
var PORTAL_SELECTOR = ".chakra-portal";
var Container = props => {
var {
children,
zIndex
} = props;
return /*#__PURE__*/React.createElement("div", {
className: "chakra-portal-zIndex",
style: {
position: "relative",
zIndex
}
}, children);
};
var Container = props => /*#__PURE__*/React.createElement("div", {
className: "chakra-portal-zIndex",
style: {
position: "absolute",
zIndex: props.zIndex,
top: 0,
left: 0,
right: 0 // NB: Don't add `bottom: 0`, it makes the entire app unusable
// @see https://github.com/chakra-ui/chakra-ui/issues/3201
}
}, props.children);
/**
* Portal
*
* Declarative component used to render children into a DOM node
* that exists outside the DOM hierarchy of the parent component.
*
* @see Docs https://chakra-ui.com/docs/overlay/portal
* Portal that uses `document.body` as container
*/
export function Portal(props) {
var DefaultPortal = props => {
var {
appendToParentPortal,
children
} = props;
var tempNode = React.useRef(null);
var portal = React.useRef(null);
var forceUpdate = useForceUpdate();
var getContainer = useCallbackRef(props.getContainer);
var onMount = useCallbackRef(props.onMount);
var onUnmount = useCallbackRef(props.onUnmount);
var parentPortal = usePortalContext();
var manager = usePortalManager();
useSafeLayoutEffect(() => {
var _ref, _getContainer;
if (!tempNode.current) return;
var doc = tempNode.current.ownerDocument;
var host = (_ref = (_getContainer = getContainer()) != null ? _getContainer : parentPortal) != null ? _ref : doc.body;
/**
* host may be `null` when a hot-loader
* replaces components on the page
*/
var host = appendToParentPortal ? parentPortal != null ? parentPortal : doc.body : doc.body;
if (!host) return;
portal.current = doc.createElement("div");
portal.current.className = Portal.className;
portal.current.className = PORTAL_CLASSNAME;
host.appendChild(portal.current);
forceUpdate();
onMount();
var portalNode = portal.current;
return () => {
onUnmount();
if (host.contains(portalNode)) {

@@ -69,13 +61,74 @@ host.removeChild(portalNode);

}, []);
var childrenToRender = manager != null && manager.zIndex ? /*#__PURE__*/React.createElement(Container, {
zIndex: manager.zIndex
}, props.children) : props.children;
var _children = manager != null && manager.zIndex ? /*#__PURE__*/React.createElement(Container, {
zIndex: manager == null ? void 0 : manager.zIndex
}, children) : children;
return portal.current ? /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(PortalContextProvider, {
value: portal.current
}, childrenToRender), portal.current) : /*#__PURE__*/React.createElement("span", {
}, _children), portal.current) : /*#__PURE__*/React.createElement("span", {
ref: tempNode
});
};
/**
* Portal that uses a custom container
*/
var ContainerPortal = props => {
var {
children,
containerRef,
appendToParentPortal
} = props;
var containerEl = containerRef.current;
var host = containerEl != null ? containerEl : isBrowser ? document.body : undefined;
var portal = React.useMemo(() => {
var node = containerEl == null ? void 0 : containerEl.ownerDocument.createElement("div");
if (node) node.className = PORTAL_CLASSNAME;
return node;
}, [containerEl]);
var forceUpdate = useForceUpdate();
useSafeLayoutEffect(() => {
forceUpdate();
}, []);
useSafeLayoutEffect(() => {
if (!portal || !host) return;
host.appendChild(portal);
return () => {
host.removeChild(portal);
};
}, [portal, host]);
if (host && portal) {
return /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(PortalContextProvider, {
value: appendToParentPortal ? portal : null
}, children), portal);
}
return null;
};
/**
* Portal
*
* Declarative component used to render children into a DOM node
* that exists outside the DOM hierarchy of the parent component.
*
* @see Docs https://chakra-ui.com/docs/components/portal
*/
export function Portal(props) {
var {
containerRef
} = props,
rest = _objectWithoutPropertiesLoose(props, ["containerRef"]);
return containerRef ? /*#__PURE__*/React.createElement(ContainerPortal, _extends({
containerRef: containerRef
}, rest)) : /*#__PURE__*/React.createElement(DefaultPortal, rest);
}
Portal.className = "chakra-portal";
Portal.selector = "." + Portal.className;
Portal.defaultProps = {
appendToParentPortal: true
};
Portal.className = PORTAL_CLASSNAME;
Portal.selector = PORTAL_SELECTOR;

@@ -82,0 +135,0 @@ if (__DEV__) {

import * as React from "react";
export interface PortalProps {
/**
* Function called when the portal mounts
* The `ref` to the component where the portal will be attached to.
*/
onMount?(): void;
containerRef?: React.RefObject<HTMLElement | null>;
/**
* Function called when the portal unmounts
* The content or node you'll like to portal
*/
onUnmount?(): void;
children: React.ReactNode;
/**
* Function that will be called to get the parent element
* that the portal will be attached to.
* If `true`, the portal will check if it is within a parent portal
* and append itself to the parent's portal node.
* This provides nesting for portals.
*
* If `false`, the portal will always append to `document.body`
* regardless of nesting. It is used to opt out of portal nesting.
*/
getContainer?: () => HTMLElement | null;
/**
* The content or node you'll like to portal
*/
children: React.ReactNode;
appendToParentPortal?: boolean;
}

@@ -27,6 +27,9 @@ /**

*
* @see Docs https://chakra-ui.com/docs/overlay/portal
* @see Docs https://chakra-ui.com/docs/components/portal
*/
export declare function Portal(props: PortalProps): JSX.Element;
export declare namespace Portal {
var defaultProps: {
appendToParentPortal: boolean;
};
var className: string;

@@ -33,0 +36,0 @@ var selector: string;

{
"name": "@chakra-ui/portal",
"version": "1.0.6",
"version": "1.1.0",
"description": "React component used to render children outside the DOM hierarchy of the parent component",

@@ -55,3 +55,3 @@ "keywords": [

"dependencies": {
"@chakra-ui/hooks": "1.1.2",
"@chakra-ui/hooks": "1.1.3",
"@chakra-ui/utils": "1.1.0"

@@ -58,0 +58,0 @@ },

# @chakra-ui/portal
A wrapper for rendering components in React Portals, with support for nested
portals and stacking. No need to use `z-index` at all with this portal, that's
right!
portals and stacking.

@@ -41,4 +40,2 @@ ## Installation

> It'll only render into `document.body` if you don't include `PortalManager`.
```jsx

@@ -65,12 +62,12 @@ <div>

You can also portal elements into a custom containers. Simply pass a `container`
prop that points to the `node` of that element.
You can also portal elements into a custom containers. Simply pass a
`containerRef` prop that points to the `node` of that element.
```jsx
<>
<div data-testid="container" ref={ref} />
<Portal container={() => ref.current}>
<h1 data-testid="heading">Hello world</h1>
<div ref={ref} />
<Portal containerRef={ref}>
<h1>Hello world</h1>
</Portal>
</>
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc