@fluentui/react-portal 9.4.29 → 9.4.31
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +25 -2
- package/lib/Portal.js.map +1 -1
- package/lib/components/Portal/Portal.js.map +1 -1
- package/lib/components/Portal/Portal.types.js.map +1 -1
- package/lib/components/Portal/index.js.map +1 -1
- package/lib/components/Portal/renderPortal.js.map +1 -1
- package/lib/components/Portal/usePortal.js.map +1 -1
- package/lib/components/Portal/usePortalMountNode.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/utils/toMountNodeProps.js.map +1 -1
- package/lib-commonjs/Portal.js.map +1 -1
- package/lib-commonjs/components/Portal/Portal.js.map +1 -1
- package/lib-commonjs/components/Portal/Portal.types.js.map +1 -1
- package/lib-commonjs/components/Portal/index.js.map +1 -1
- package/lib-commonjs/components/Portal/renderPortal.js.map +1 -1
- package/lib-commonjs/components/Portal/usePortal.js.map +1 -1
- package/lib-commonjs/components/Portal/usePortalMountNode.js.map +1 -1
- package/lib-commonjs/components/Portal/usePortalMountNodeStyles.styles.js.map +1 -1
- package/lib-commonjs/index.js +8 -8
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/utils/toMountNodeProps.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
@@ -1,12 +1,35 @@
|
|
1
1
|
# Change Log - @fluentui/react-portal
|
2
2
|
|
3
|
-
This log was last generated on
|
3
|
+
This log was last generated on Tue, 23 Jul 2024 20:09:20 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.4.31](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.31)
|
8
|
+
|
9
|
+
Tue, 23 Jul 2024 20:09:20 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.30..@fluentui/react-portal_v9.4.31)
|
11
|
+
|
12
|
+
### Patches
|
13
|
+
|
14
|
+
- Bump @fluentui/react-shared-contexts to v9.20.0 ([PR #32067](https://github.com/microsoft/fluentui/pull/32067) by beachball)
|
15
|
+
- Bump @fluentui/react-tabster to v9.22.3 ([PR #32067](https://github.com/microsoft/fluentui/pull/32067) by beachball)
|
16
|
+
- Bump @fluentui/react-utilities to v9.18.13 ([PR #32067](https://github.com/microsoft/fluentui/pull/32067) by beachball)
|
17
|
+
|
18
|
+
## [9.4.30](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.30)
|
19
|
+
|
20
|
+
Mon, 15 Jul 2024 17:25:39 GMT
|
21
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.29..@fluentui/react-portal_v9.4.30)
|
22
|
+
|
23
|
+
### Patches
|
24
|
+
|
25
|
+
- fix: revert incorectly set npm versions in all packages ([PR #31937](https://github.com/microsoft/fluentui/pull/31937) by martinhochel@microsoft.com)
|
26
|
+
- Bump @fluentui/react-shared-contexts to v9.19.1 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
27
|
+
- Bump @fluentui/react-tabster to v9.22.2 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
28
|
+
- Bump @fluentui/react-utilities to v9.18.12 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
29
|
+
|
7
30
|
## [9.4.29](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.29)
|
8
31
|
|
9
|
-
Mon, 01 Jul 2024 20:
|
32
|
+
Mon, 01 Jul 2024 20:30:26 GMT
|
10
33
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.28..@fluentui/react-portal_v9.4.29)
|
11
34
|
|
12
35
|
### Patches
|
package/lib/Portal.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Portal.ts"],"sourcesContent":["export * from './components/Portal/index';\n"],"names":[],"mappings":"AAAA,cAAc,4BAA4B"}
|
1
|
+
{"version":3,"sources":["Portal.ts"],"sourcesContent":["export * from './components/Portal/index';\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,4BAA4B"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Portal.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { usePortal_unstable } from './usePortal';\nimport { renderPortal_unstable } from './renderPortal';\nimport type { PortalProps } from './Portal.types';\n\n/**\n * A portal provides a way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal: React.FC<PortalProps> = props => {\n const state = usePortal_unstable(props);\n\n return renderPortal_unstable(state);\n};\n\nPortal.displayName = 'Portal';\n"],"names":["React","usePortal_unstable","renderPortal_unstable","Portal","props","state","displayName"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,kBAAkB,QAAQ,cAAc;AACjD,SAASC,qBAAqB,QAAQ,iBAAiB;AAGvD;;;CAGC,GACD,OAAO,MAAMC,SAAgCC,CAAAA;IAC3C,MAAMC,QAAQJ,mBAAmBG;IAEjC,OAAOF,sBAAsBG;AAC/B,EAAE;AAEFF,OAAOG,WAAW,GAAG"}
|
1
|
+
{"version":3,"sources":["Portal.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { usePortal_unstable } from './usePortal';\nimport { renderPortal_unstable } from './renderPortal';\nimport type { PortalProps } from './Portal.types';\n\n/**\n * A portal provides a way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal: React.FC<PortalProps> = props => {\n const state = usePortal_unstable(props);\n\n return renderPortal_unstable(state);\n};\n\nPortal.displayName = 'Portal';\n"],"names":["React","usePortal_unstable","renderPortal_unstable","Portal","props","state","displayName"],"rangeMappings":";;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,kBAAkB,QAAQ,cAAc;AACjD,SAASC,qBAAqB,QAAQ,iBAAiB;AAGvD;;;CAGC,GACD,OAAO,MAAMC,SAAgCC,CAAAA;IAC3C,MAAMC,QAAQJ,mBAAmBG;IAEjC,OAAOF,sBAAsBG;AAC/B,EAAE;AAEFF,OAAOG,WAAW,GAAG"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Portal.types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type PortalProps = {\n /**\n * React children\n */\n children?: React.ReactNode;\n\n /**\n * Where the portal children are mounted on DOM\n *\n * @default a new element on document.body without any styling\n */\n mountNode?: HTMLElement | null | { element?: HTMLElement | null; className?: string };\n};\n\nexport type PortalState = Pick<PortalProps, 'children'> & {\n mountNode: HTMLElement | null | undefined;\n\n /**\n * Ref to the root span element as virtual parent\n */\n virtualParentRootRef: React.MutableRefObject<HTMLSpanElement | null>;\n};\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}
|
1
|
+
{"version":3,"sources":["Portal.types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type PortalProps = {\n /**\n * React children\n */\n children?: React.ReactNode;\n\n /**\n * Where the portal children are mounted on DOM\n *\n * @default a new element on document.body without any styling\n */\n mountNode?: HTMLElement | null | { element?: HTMLElement | null; className?: string };\n};\n\nexport type PortalState = Pick<PortalProps, 'children'> & {\n mountNode: HTMLElement | null | undefined;\n\n /**\n * Ref to the root span element as virtual parent\n */\n virtualParentRootRef: React.MutableRefObject<HTMLSpanElement | null>;\n};\n"],"names":["React"],"rangeMappings":"","mappings":"AAAA,YAAYA,WAAW,QAAQ"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './Portal';\nexport * from './Portal.types';\nexport * from './renderPortal';\nexport * from './usePortal';\n"],"names":[],"mappings":"AAAA,cAAc,WAAW;AACzB,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;AAC/B,cAAc,cAAc"}
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './Portal';\nexport * from './Portal.types';\nexport * from './renderPortal';\nexport * from './usePortal';\n"],"names":[],"rangeMappings":";;;","mappings":"AAAA,cAAc,WAAW;AACzB,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;AAC/B,cAAc,cAAc"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["renderPortal.tsx"],"sourcesContent":["import * as ReactDOM from 'react-dom';\nimport * as React from 'react';\nimport type { PortalState } from './Portal.types';\n\n/**\n * Render the final JSX of Portal\n */\nexport const renderPortal_unstable = (state: PortalState): React.ReactElement => {\n return (\n <span hidden ref={state.virtualParentRootRef}>\n {state.mountNode && ReactDOM.createPortal(state.children, state.mountNode)}\n </span>\n );\n};\n"],"names":["ReactDOM","React","renderPortal_unstable","state","span","hidden","ref","virtualParentRootRef","mountNode","createPortal","children"],"mappings":"AAAA,YAAYA,cAAc,YAAY;AACtC,YAAYC,WAAW,QAAQ;AAG/B;;CAEC,GACD,OAAO,MAAMC,wBAAwB,CAACC;IACpC,qBACE,oBAACC;QAAKC,QAAAA;QAAOC,KAAKH,MAAMI,oBAAoB;OACzCJ,MAAMK,SAAS,kBAAIR,SAASS,YAAY,CAACN,MAAMO,QAAQ,EAAEP,MAAMK,SAAS;AAG/E,EAAE"}
|
1
|
+
{"version":3,"sources":["renderPortal.tsx"],"sourcesContent":["import * as ReactDOM from 'react-dom';\nimport * as React from 'react';\nimport type { PortalState } from './Portal.types';\n\n/**\n * Render the final JSX of Portal\n */\nexport const renderPortal_unstable = (state: PortalState): React.ReactElement => {\n return (\n <span hidden ref={state.virtualParentRootRef}>\n {state.mountNode && ReactDOM.createPortal(state.children, state.mountNode)}\n </span>\n );\n};\n"],"names":["ReactDOM","React","renderPortal_unstable","state","span","hidden","ref","virtualParentRootRef","mountNode","createPortal","children"],"rangeMappings":";;;;;;;;;","mappings":"AAAA,YAAYA,cAAc,YAAY;AACtC,YAAYC,WAAW,QAAQ;AAG/B;;CAEC,GACD,OAAO,MAAMC,wBAAwB,CAACC;IACpC,qBACE,oBAACC;QAAKC,QAAAA;QAAOC,KAAKH,MAAMI,oBAAoB;OACzCJ,MAAMK,SAAS,kBAAIR,SAASS,YAAY,CAACN,MAAMO,QAAQ,EAAEP,MAAMK,SAAS;AAG/E,EAAE"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["usePortal.ts"],"sourcesContent":["import { setVirtualParent } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { toMountNodeProps } from '../../utils/toMountNodeProps';\nimport { usePortalMountNode } from './usePortalMountNode';\nimport type { PortalProps, PortalState } from './Portal.types';\n\n/**\n * Create the state required to render Portal.\n *\n * The returned state can be modified with hooks such as usePortalStyles, before being passed to renderPortal_unstable.\n *\n * @param props - props from this instance of Portal\n */\nexport const usePortal_unstable = (props: PortalProps): PortalState => {\n const { element, className } = toMountNodeProps(props.mountNode);\n\n const virtualParentRootRef = React.useRef<HTMLSpanElement>(null);\n const fallbackElement = usePortalMountNode({ disabled: !!element, className });\n\n const mountNode = element ?? fallbackElement;\n const state: PortalState = {\n children: props.children,\n mountNode,\n virtualParentRootRef,\n };\n\n React.useEffect(() => {\n if (!mountNode) {\n return;\n }\n\n const virtualParent = virtualParentRootRef.current;\n\n // By default, we create a mount node for portal on `document.body` (see usePortalMountNode()) and have following structure:\n //\n // <body>\n // <!-- ⚛️ application root -->\n // <div id=\"root\">\n // <!-- ⬇️ portal node rendered in a tree to anchor (virtual parent node) -->\n // <span aria-hidden=\"true\"></span>\n // </div>\n // <div id=\"portal-mount-node\">\n // <!-- 🧩portal content -->\n // </div>\n // </body>\n //\n // To make sure that `.elementContains()` works correctly, we link a virtual parent to a portal node (a virtual parent node becomes a parent of mount node):\n // virtual.contains(mountNode) === false\n // (while we need ⬇️⬇️⬇️)\n // elementsContains(virtualParent, mountNode) === true\n // elementsContains(mountNode, virtualParent) === false\n //\n // For more details, check docs for virtual parent utils.\n //\n // However, if a user provides a custom mount node (via `props`) the structure could be different:\n //\n // <body>\n // <!-- application root -->\n // <div id=\"root\">\n // <div id=\"portal-mount-node\">\n // <!-- 🧩portal content -->\n //\n // <span aria-hidden=\"true\"></span>\n // </div>\n // </div>\n // </body>\n //\n // A mount node in this case contains portal's content and a virtual parent node. In this case nodes linking is redundant and the check below avoids it.\n //\n // Otherwise, there is a circular reference - both elements are parents of each other:\n // elementsContains(mountNode, virtualParent) === true\n // elementsContains(virtualParent, mountNode) === true\n const isVirtualParentInsideChild = mountNode.contains(virtualParent);\n\n if (virtualParent && !isVirtualParentInsideChild) {\n setVirtualParent(mountNode, virtualParent);\n\n return () => {\n setVirtualParent(mountNode, undefined);\n };\n }\n }, [virtualParentRootRef, mountNode]);\n\n return state;\n};\n"],"names":["setVirtualParent","React","toMountNodeProps","usePortalMountNode","usePortal_unstable","props","element","className","mountNode","virtualParentRootRef","useRef","fallbackElement","disabled","state","children","useEffect","virtualParent","current","isVirtualParentInsideChild","contains","undefined"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,4BAA4B;AAC7D,YAAYC,WAAW,QAAQ;AAE/B,SAASC,gBAAgB,QAAQ,+BAA+B;AAChE,SAASC,kBAAkB,QAAQ,uBAAuB;AAG1D;;;;;;CAMC,GACD,OAAO,MAAMC,qBAAqB,CAACC;IACjC,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAGL,iBAAiBG,MAAMG,SAAS;IAE/D,MAAMC,uBAAuBR,MAAMS,MAAM,CAAkB;IAC3D,MAAMC,kBAAkBR,mBAAmB;QAAES,UAAU,CAAC,CAACN;QAASC;IAAU;IAE5E,MAAMC,YAAYF,oBAAAA,qBAAAA,UAAWK;IAC7B,MAAME,QAAqB;QACzBC,UAAUT,MAAMS,QAAQ;QACxBN;QACAC;IACF;IAEAR,MAAMc,SAAS,CAAC;QACd,IAAI,CAACP,WAAW;YACd;QACF;QAEA,MAAMQ,gBAAgBP,qBAAqBQ,OAAO;QAElD,4HAA4H;QAC5H,EAAE;QACF,SAAS;QACT,iCAAiC;QACjC,oBAAoB;QACpB,iFAAiF;QACjF,uCAAuC;QACvC,WAAW;QACX,iCAAiC;QACjC,gCAAgC;QAChC,WAAW;QACX,UAAU;QACV,EAAE;QACF,4JAA4J;QAC5J,0CAA0C;QAC1C,2BAA2B;QAC3B,wDAAwD;QACxD,yDAAyD;QACzD,EAAE;QACF,yDAAyD;QACzD,EAAE;QACF,kGAAkG;QAClG,EAAE;QACF,SAAS;QACT,8BAA8B;QAC9B,oBAAoB;QACpB,mCAAmC;QACnC,kCAAkC;QAClC,EAAE;QACF,yCAAyC;QACzC,aAAa;QACb,WAAW;QACX,UAAU;QACV,EAAE;QACF,wJAAwJ;QACxJ,EAAE;QACF,sFAAsF;QACtF,wDAAwD;QACxD,wDAAwD;QACxD,MAAMC,6BAA6BV,UAAUW,QAAQ,CAACH;QAEtD,IAAIA,iBAAiB,CAACE,4BAA4B;YAChDlB,iBAAiBQ,WAAWQ;YAE5B,OAAO;gBACLhB,iBAAiBQ,WAAWY;YAC9B;QACF;IACF,GAAG;QAACX;QAAsBD;KAAU;IAEpC,OAAOK;AACT,EAAE"}
|
1
|
+
{"version":3,"sources":["usePortal.ts"],"sourcesContent":["import { setVirtualParent } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { toMountNodeProps } from '../../utils/toMountNodeProps';\nimport { usePortalMountNode } from './usePortalMountNode';\nimport type { PortalProps, PortalState } from './Portal.types';\n\n/**\n * Create the state required to render Portal.\n *\n * The returned state can be modified with hooks such as usePortalStyles, before being passed to renderPortal_unstable.\n *\n * @param props - props from this instance of Portal\n */\nexport const usePortal_unstable = (props: PortalProps): PortalState => {\n const { element, className } = toMountNodeProps(props.mountNode);\n\n const virtualParentRootRef = React.useRef<HTMLSpanElement>(null);\n const fallbackElement = usePortalMountNode({ disabled: !!element, className });\n\n const mountNode = element ?? fallbackElement;\n const state: PortalState = {\n children: props.children,\n mountNode,\n virtualParentRootRef,\n };\n\n React.useEffect(() => {\n if (!mountNode) {\n return;\n }\n\n const virtualParent = virtualParentRootRef.current;\n\n // By default, we create a mount node for portal on `document.body` (see usePortalMountNode()) and have following structure:\n //\n // <body>\n // <!-- ⚛️ application root -->\n // <div id=\"root\">\n // <!-- ⬇️ portal node rendered in a tree to anchor (virtual parent node) -->\n // <span aria-hidden=\"true\"></span>\n // </div>\n // <div id=\"portal-mount-node\">\n // <!-- 🧩portal content -->\n // </div>\n // </body>\n //\n // To make sure that `.elementContains()` works correctly, we link a virtual parent to a portal node (a virtual parent node becomes a parent of mount node):\n // virtual.contains(mountNode) === false\n // (while we need ⬇️⬇️⬇️)\n // elementsContains(virtualParent, mountNode) === true\n // elementsContains(mountNode, virtualParent) === false\n //\n // For more details, check docs for virtual parent utils.\n //\n // However, if a user provides a custom mount node (via `props`) the structure could be different:\n //\n // <body>\n // <!-- application root -->\n // <div id=\"root\">\n // <div id=\"portal-mount-node\">\n // <!-- 🧩portal content -->\n //\n // <span aria-hidden=\"true\"></span>\n // </div>\n // </div>\n // </body>\n //\n // A mount node in this case contains portal's content and a virtual parent node. In this case nodes linking is redundant and the check below avoids it.\n //\n // Otherwise, there is a circular reference - both elements are parents of each other:\n // elementsContains(mountNode, virtualParent) === true\n // elementsContains(virtualParent, mountNode) === true\n const isVirtualParentInsideChild = mountNode.contains(virtualParent);\n\n if (virtualParent && !isVirtualParentInsideChild) {\n setVirtualParent(mountNode, virtualParent);\n\n return () => {\n setVirtualParent(mountNode, undefined);\n };\n }\n }, [virtualParentRootRef, mountNode]);\n\n return state;\n};\n"],"names":["setVirtualParent","React","toMountNodeProps","usePortalMountNode","usePortal_unstable","props","element","className","mountNode","virtualParentRootRef","useRef","fallbackElement","disabled","state","children","useEffect","virtualParent","current","isVirtualParentInsideChild","contains","undefined"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,gBAAgB,QAAQ,4BAA4B;AAC7D,YAAYC,WAAW,QAAQ;AAE/B,SAASC,gBAAgB,QAAQ,+BAA+B;AAChE,SAASC,kBAAkB,QAAQ,uBAAuB;AAG1D;;;;;;CAMC,GACD,OAAO,MAAMC,qBAAqB,CAACC;IACjC,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAGL,iBAAiBG,MAAMG,SAAS;IAE/D,MAAMC,uBAAuBR,MAAMS,MAAM,CAAkB;IAC3D,MAAMC,kBAAkBR,mBAAmB;QAAES,UAAU,CAAC,CAACN;QAASC;IAAU;IAE5E,MAAMC,YAAYF,oBAAAA,qBAAAA,UAAWK;IAC7B,MAAME,QAAqB;QACzBC,UAAUT,MAAMS,QAAQ;QACxBN;QACAC;IACF;IAEAR,MAAMc,SAAS,CAAC;QACd,IAAI,CAACP,WAAW;YACd;QACF;QAEA,MAAMQ,gBAAgBP,qBAAqBQ,OAAO;QAElD,4HAA4H;QAC5H,EAAE;QACF,SAAS;QACT,iCAAiC;QACjC,oBAAoB;QACpB,iFAAiF;QACjF,uCAAuC;QACvC,WAAW;QACX,iCAAiC;QACjC,gCAAgC;QAChC,WAAW;QACX,UAAU;QACV,EAAE;QACF,4JAA4J;QAC5J,0CAA0C;QAC1C,2BAA2B;QAC3B,wDAAwD;QACxD,yDAAyD;QACzD,EAAE;QACF,yDAAyD;QACzD,EAAE;QACF,kGAAkG;QAClG,EAAE;QACF,SAAS;QACT,8BAA8B;QAC9B,oBAAoB;QACpB,mCAAmC;QACnC,kCAAkC;QAClC,EAAE;QACF,yCAAyC;QACzC,aAAa;QACb,WAAW;QACX,UAAU;QACV,EAAE;QACF,wJAAwJ;QACxJ,EAAE;QACF,sFAAsF;QACtF,wDAAwD;QACxD,wDAAwD;QACxD,MAAMC,6BAA6BV,UAAUW,QAAQ,CAACH;QAEtD,IAAIA,iBAAiB,CAACE,4BAA4B;YAChDlB,iBAAiBQ,WAAWQ;YAE5B,OAAO;gBACLhB,iBAAiBQ,WAAWY;YAC9B;QACF;IACF,GAAG;QAACX;QAAsBD;KAAU;IAEpC,OAAOK;AACT,EAAE"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["usePortalMountNode.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n usePortalMountNode as usePortalMountNodeContext,\n} from '@fluentui/react-shared-contexts';\nimport { mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\nimport { useDisposable } from 'use-disposable';\n\nimport { usePortalMountNodeStylesStyles } from './usePortalMountNodeStyles.styles';\n\nconst useInsertionEffect = (React as never)['useInsertion' + 'Effect'] as typeof React.useLayoutEffect | undefined;\n\nexport type UsePortalMountNodeOptions = {\n /**\n * Since hooks cannot be called conditionally use this flag to disable creating the node\n */\n disabled?: boolean;\n\n className?: string;\n};\n\n/**\n * Creates a new element on a \"document.body\" to mount portals.\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n 'use no memo';\n\n const { targetDocument, dir } = useFluent();\n const mountNode = usePortalMountNodeContext();\n\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n const classes = usePortalMountNodeStylesStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root, options.className);\n const targetNode: HTMLElement | ShadowRoot | undefined = mountNode ?? targetDocument?.body;\n\n const element = useDisposable(() => {\n if (targetNode === undefined || options.disabled) {\n return [null, () => null];\n }\n\n const newElement = targetNode.ownerDocument.createElement('div');\n targetNode.appendChild(newElement);\n return [newElement, () => newElement.remove()];\n }, [targetNode]);\n\n if (useInsertionEffect) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useInsertionEffect(() => {\n if (!element) {\n return;\n }\n\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n element.setAttribute('data-portal-node', 'true');\n\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }, [className, dir, element, focusVisibleRef]);\n } else {\n // This useMemo call is intentional for React 17\n // We don't want to re-create the portal element when its attributes change.\n // This also should not be done in an effect because, changing the value of css variables\n // after initial mount can trigger interesting CSS side effects like transitions.\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useMemo(() => {\n if (!element) {\n return;\n }\n\n // Force replace all classes\n element.className = className;\n element.setAttribute('dir', dir);\n element.setAttribute('data-portal-node', 'true');\n\n focusVisibleRef.current = element;\n }, [className, dir, element, focusVisibleRef]);\n }\n\n return element;\n};\n"],"names":["React","useThemeClassName_unstable","useThemeClassName","useFluent_unstable","useFluent","usePortalMountNode","usePortalMountNodeContext","mergeClasses","useFocusVisible","useDisposable","usePortalMountNodeStylesStyles","useInsertionEffect","options","targetDocument","dir","mountNode","focusVisibleRef","classes","themeClassName","className","root","targetNode","body","element","undefined","disabled","newElement","ownerDocument","createElement","appendChild","remove","classesToApply","split","filter","Boolean","classList","add","setAttribute","current","removeAttribute","useMemo"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SACEC,8BAA8BC,iBAAiB,EAC/CC,sBAAsBC,SAAS,EAC/BC,sBAAsBC,yBAAyB,QAC1C,kCAAkC;AACzC,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,aAAa,QAAQ,iBAAiB;AAE/C,SAASC,8BAA8B,QAAQ,oCAAoC;AAEnF,MAAMC,qBAAqB,AAACX,KAAe,CAAC,iBAAiB,SAAS;AAWtE;;CAEC,GACD,OAAO,MAAMK,qBAAqB,CAACO;IACjC;IAEA,MAAM,EAAEC,cAAc,EAAEC,GAAG,EAAE,GAAGV;IAChC,MAAMW,YAAYT;IAElB,MAAMU,kBAAkBR;IACxB,MAAMS,UAAUP;IAChB,MAAMQ,iBAAiBhB;IAEvB,MAAMiB,YAAYZ,aAAaW,gBAAgBD,QAAQG,IAAI,EAAER,QAAQO,SAAS;IAC9E,MAAME,aAAmDN,sBAAAA,uBAAAA,YAAaF,2BAAAA,qCAAAA,eAAgBS,IAAI;IAE1F,MAAMC,UAAUd,cAAc;QAC5B,IAAIY,eAAeG,aAAaZ,QAAQa,QAAQ,EAAE;YAChD,OAAO;gBAAC;gBAAM,IAAM;aAAK;QAC3B;QAEA,MAAMC,aAAaL,WAAWM,aAAa,CAACC,aAAa,CAAC;QAC1DP,WAAWQ,WAAW,CAACH;QACvB,OAAO;YAACA;YAAY,IAAMA,WAAWI,MAAM;SAAG;IAChD,GAAG;QAACT;KAAW;IAEf,IAAIV,oBAAoB;QACtB,sDAAsD;QACtDA,mBAAmB;YACjB,IAAI,CAACY,SAAS;gBACZ;YACF;YAEA,MAAMQ,iBAAiBZ,UAAUa,KAAK,CAAC,KAAKC,MAAM,CAACC;YAEnDX,QAAQY,SAAS,CAACC,GAAG,IAAIL;YACzBR,QAAQc,YAAY,CAAC,OAAOvB;YAC5BS,QAAQc,YAAY,CAAC,oBAAoB;YAEzCrB,gBAAgBsB,OAAO,GAAGf;YAE1B,OAAO;gBACLA,QAAQY,SAAS,CAACL,MAAM,IAAIC;gBAC5BR,QAAQgB,eAAe,CAAC;YAC1B;QACF,GAAG;YAACpB;YAAWL;YAAKS;YAASP;SAAgB;IAC/C,OAAO;QACL,gDAAgD;QAChD,4EAA4E;QAC5E,yFAAyF;QACzF,iFAAiF;QACjF,sDAAsD;QACtDhB,MAAMwC,OAAO,CAAC;YACZ,IAAI,CAACjB,SAAS;gBACZ;YACF;YAEA,4BAA4B;YAC5BA,QAAQJ,SAAS,GAAGA;YACpBI,QAAQc,YAAY,CAAC,OAAOvB;YAC5BS,QAAQc,YAAY,CAAC,oBAAoB;YAEzCrB,gBAAgBsB,OAAO,GAAGf;QAC5B,GAAG;YAACJ;YAAWL;YAAKS;YAASP;SAAgB;IAC/C;IAEA,OAAOO;AACT,EAAE"}
|
1
|
+
{"version":3,"sources":["usePortalMountNode.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n usePortalMountNode as usePortalMountNodeContext,\n} from '@fluentui/react-shared-contexts';\nimport { mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\nimport { useDisposable } from 'use-disposable';\n\nimport { usePortalMountNodeStylesStyles } from './usePortalMountNodeStyles.styles';\n\nconst useInsertionEffect = (React as never)['useInsertion' + 'Effect'] as typeof React.useLayoutEffect | undefined;\n\nexport type UsePortalMountNodeOptions = {\n /**\n * Since hooks cannot be called conditionally use this flag to disable creating the node\n */\n disabled?: boolean;\n\n className?: string;\n};\n\n/**\n * Creates a new element on a \"document.body\" to mount portals.\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n 'use no memo';\n\n const { targetDocument, dir } = useFluent();\n const mountNode = usePortalMountNodeContext();\n\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n const classes = usePortalMountNodeStylesStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root, options.className);\n const targetNode: HTMLElement | ShadowRoot | undefined = mountNode ?? targetDocument?.body;\n\n const element = useDisposable(() => {\n if (targetNode === undefined || options.disabled) {\n return [null, () => null];\n }\n\n const newElement = targetNode.ownerDocument.createElement('div');\n targetNode.appendChild(newElement);\n return [newElement, () => newElement.remove()];\n }, [targetNode]);\n\n if (useInsertionEffect) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useInsertionEffect(() => {\n if (!element) {\n return;\n }\n\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n element.setAttribute('data-portal-node', 'true');\n\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }, [className, dir, element, focusVisibleRef]);\n } else {\n // This useMemo call is intentional for React 17\n // We don't want to re-create the portal element when its attributes change.\n // This also should not be done in an effect because, changing the value of css variables\n // after initial mount can trigger interesting CSS side effects like transitions.\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useMemo(() => {\n if (!element) {\n return;\n }\n\n // Force replace all classes\n element.className = className;\n element.setAttribute('dir', dir);\n element.setAttribute('data-portal-node', 'true');\n\n focusVisibleRef.current = element;\n }, [className, dir, element, focusVisibleRef]);\n }\n\n return element;\n};\n"],"names":["React","useThemeClassName_unstable","useThemeClassName","useFluent_unstable","useFluent","usePortalMountNode","usePortalMountNodeContext","mergeClasses","useFocusVisible","useDisposable","usePortalMountNodeStylesStyles","useInsertionEffect","options","targetDocument","dir","mountNode","focusVisibleRef","classes","themeClassName","className","root","targetNode","body","element","undefined","disabled","newElement","ownerDocument","createElement","appendChild","remove","classesToApply","split","filter","Boolean","classList","add","setAttribute","current","removeAttribute","useMemo"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SACEC,8BAA8BC,iBAAiB,EAC/CC,sBAAsBC,SAAS,EAC/BC,sBAAsBC,yBAAyB,QAC1C,kCAAkC;AACzC,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,aAAa,QAAQ,iBAAiB;AAE/C,SAASC,8BAA8B,QAAQ,oCAAoC;AAEnF,MAAMC,qBAAqB,AAACX,KAAe,CAAC,iBAAiB,SAAS;AAWtE;;CAEC,GACD,OAAO,MAAMK,qBAAqB,CAACO;IACjC;IAEA,MAAM,EAAEC,cAAc,EAAEC,GAAG,EAAE,GAAGV;IAChC,MAAMW,YAAYT;IAElB,MAAMU,kBAAkBR;IACxB,MAAMS,UAAUP;IAChB,MAAMQ,iBAAiBhB;IAEvB,MAAMiB,YAAYZ,aAAaW,gBAAgBD,QAAQG,IAAI,EAAER,QAAQO,SAAS;IAC9E,MAAME,aAAmDN,sBAAAA,uBAAAA,YAAaF,2BAAAA,qCAAAA,eAAgBS,IAAI;IAE1F,MAAMC,UAAUd,cAAc;QAC5B,IAAIY,eAAeG,aAAaZ,QAAQa,QAAQ,EAAE;YAChD,OAAO;gBAAC;gBAAM,IAAM;aAAK;QAC3B;QAEA,MAAMC,aAAaL,WAAWM,aAAa,CAACC,aAAa,CAAC;QAC1DP,WAAWQ,WAAW,CAACH;QACvB,OAAO;YAACA;YAAY,IAAMA,WAAWI,MAAM;SAAG;IAChD,GAAG;QAACT;KAAW;IAEf,IAAIV,oBAAoB;QACtB,sDAAsD;QACtDA,mBAAmB;YACjB,IAAI,CAACY,SAAS;gBACZ;YACF;YAEA,MAAMQ,iBAAiBZ,UAAUa,KAAK,CAAC,KAAKC,MAAM,CAACC;YAEnDX,QAAQY,SAAS,CAACC,GAAG,IAAIL;YACzBR,QAAQc,YAAY,CAAC,OAAOvB;YAC5BS,QAAQc,YAAY,CAAC,oBAAoB;YAEzCrB,gBAAgBsB,OAAO,GAAGf;YAE1B,OAAO;gBACLA,QAAQY,SAAS,CAACL,MAAM,IAAIC;gBAC5BR,QAAQgB,eAAe,CAAC;YAC1B;QACF,GAAG;YAACpB;YAAWL;YAAKS;YAASP;SAAgB;IAC/C,OAAO;QACL,gDAAgD;QAChD,4EAA4E;QAC5E,yFAAyF;QACzF,iFAAiF;QACjF,sDAAsD;QACtDhB,MAAMwC,OAAO,CAAC;YACZ,IAAI,CAACjB,SAAS;gBACZ;YACF;YAEA,4BAA4B;YAC5BA,QAAQJ,SAAS,GAAGA;YACpBI,QAAQc,YAAY,CAAC,OAAOvB;YAC5BS,QAAQc,YAAY,CAAC,oBAAoB;YAEzCrB,gBAAgBsB,OAAO,GAAGf;QAC5B,GAAG;YAACJ;YAAWL;YAAKS;YAASP;SAAgB;IAC/C;IAEA,OAAOO;AACT,EAAE"}
|
package/lib/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export { elementContains, setVirtualParent } from '@fluentui/react-utilities';\nexport { Portal, renderPortal_unstable, usePortal_unstable } from './components/Portal/index';\nexport type { PortalProps, PortalState } from './components/Portal/index';\n\nexport { toMountNodeProps } from './utils/toMountNodeProps';\n"],"names":["elementContains","setVirtualParent","Portal","renderPortal_unstable","usePortal_unstable","toMountNodeProps"],"mappings":"AAAA,SAASA,eAAe,EAAEC,gBAAgB,QAAQ,4BAA4B;AAC9E,SAASC,MAAM,EAAEC,qBAAqB,EAAEC,kBAAkB,QAAQ,4BAA4B;AAG9F,SAASC,gBAAgB,QAAQ,2BAA2B"}
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export { elementContains, setVirtualParent } from '@fluentui/react-utilities';\nexport { Portal, renderPortal_unstable, usePortal_unstable } from './components/Portal/index';\nexport type { PortalProps, PortalState } from './components/Portal/index';\n\nexport { toMountNodeProps } from './utils/toMountNodeProps';\n"],"names":["elementContains","setVirtualParent","Portal","renderPortal_unstable","usePortal_unstable","toMountNodeProps"],"rangeMappings":";;","mappings":"AAAA,SAASA,eAAe,EAAEC,gBAAgB,QAAQ,4BAA4B;AAC9E,SAASC,MAAM,EAAEC,qBAAqB,EAAEC,kBAAkB,QAAQ,4BAA4B;AAG9F,SAASC,gBAAgB,QAAQ,2BAA2B"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["toMountNodeProps.ts"],"sourcesContent":["import { isHTMLElement } from '@fluentui/react-utilities';\nimport type { PortalProps } from '../Portal';\n\n/**\n * The function that normalizes the `mountNode` prop into an object with element and className props.\n *\n * @param mountNode - an HTML element or an object with props\n */\nexport function toMountNodeProps(mountNode: PortalProps['mountNode']): {\n element?: HTMLElement | null;\n className?: string;\n} {\n if (isHTMLElement(mountNode)) {\n return { element: mountNode };\n }\n\n if (typeof mountNode === 'object') {\n if (mountNode === null) {\n return { element: null };\n }\n\n return mountNode;\n }\n\n return {};\n}\n"],"names":["isHTMLElement","toMountNodeProps","mountNode","element"],"mappings":"AAAA,SAASA,aAAa,QAAQ,4BAA4B;AAG1D;;;;CAIC,GACD,OAAO,SAASC,iBAAiBC,SAAmC;IAIlE,IAAIF,cAAcE,YAAY;QAC5B,OAAO;YAAEC,SAASD;QAAU;IAC9B;IAEA,IAAI,OAAOA,cAAc,UAAU;QACjC,IAAIA,cAAc,MAAM;YACtB,OAAO;gBAAEC,SAAS;YAAK;QACzB;QAEA,OAAOD;IACT;IAEA,OAAO,CAAC;AACV"}
|
1
|
+
{"version":3,"sources":["toMountNodeProps.ts"],"sourcesContent":["import { isHTMLElement } from '@fluentui/react-utilities';\nimport type { PortalProps } from '../Portal';\n\n/**\n * The function that normalizes the `mountNode` prop into an object with element and className props.\n *\n * @param mountNode - an HTML element or an object with props\n */\nexport function toMountNodeProps(mountNode: PortalProps['mountNode']): {\n element?: HTMLElement | null;\n className?: string;\n} {\n if (isHTMLElement(mountNode)) {\n return { element: mountNode };\n }\n\n if (typeof mountNode === 'object') {\n if (mountNode === null) {\n return { element: null };\n }\n\n return mountNode;\n }\n\n return {};\n}\n"],"names":["isHTMLElement","toMountNodeProps","mountNode","element"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,aAAa,QAAQ,4BAA4B;AAG1D;;;;CAIC,GACD,OAAO,SAASC,iBAAiBC,SAAmC;IAIlE,IAAIF,cAAcE,YAAY;QAC5B,OAAO;YAAEC,SAASD;QAAU;IAC9B;IAEA,IAAI,OAAOA,cAAc,UAAU;QACjC,IAAIA,cAAc,MAAM;YACtB,OAAO;gBAAEC,SAAS;YAAK;QACzB;QAEA,OAAOD;IACT;IAEA,OAAO,CAAC;AACV"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Portal.
|
1
|
+
{"version":3,"sources":["Portal.ts"],"sourcesContent":["export * from './components/Portal/index';\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;uBAAc"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Portal.
|
1
|
+
{"version":3,"sources":["Portal.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { usePortal_unstable } from './usePortal';\nimport { renderPortal_unstable } from './renderPortal';\nimport type { PortalProps } from './Portal.types';\n\n/**\n * A portal provides a way to render children into a DOM node\n * that exists outside the DOM hierarchy of the parent component.\n */\nexport const Portal: React.FC<PortalProps> = props => {\n const state = usePortal_unstable(props);\n\n return renderPortal_unstable(state);\n};\n\nPortal.displayName = 'Portal';\n"],"names":["Portal","props","state","usePortal_unstable","renderPortal_unstable","displayName"],"rangeMappings":";;;;;;;;;;;;;;;;;;","mappings":";;;;+BAUaA;;;eAAAA;;;;iEAVU;2BAEY;8BACG;AAO/B,MAAMA,SAAgCC,CAAAA;IAC3C,MAAMC,QAAQC,IAAAA,6BAAAA,EAAmBF;IAEjC,OAAOG,IAAAA,mCAAAA,EAAsBF;AAC/B;AAEAF,OAAOK,WAAW,GAAG"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Portal.types.
|
1
|
+
{"version":3,"sources":["Portal.types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type PortalProps = {\n /**\n * React children\n */\n children?: React.ReactNode;\n\n /**\n * Where the portal children are mounted on DOM\n *\n * @default a new element on document.body without any styling\n */\n mountNode?: HTMLElement | null | { element?: HTMLElement | null; className?: string };\n};\n\nexport type PortalState = Pick<PortalProps, 'children'> & {\n mountNode: HTMLElement | null | undefined;\n\n /**\n * Ref to the root span element as virtual parent\n */\n virtualParentRootRef: React.MutableRefObject<HTMLSpanElement | null>;\n};\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;iEAAuB"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './Portal';\nexport * from './Portal.types';\nexport * from './renderPortal';\nexport * from './usePortal';\n"],"names":[],"rangeMappings":";;;;;;;;","mappings":";;;;;uBAAc;uBACA;uBACA;uBACA"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["renderPortal.
|
1
|
+
{"version":3,"sources":["renderPortal.tsx"],"sourcesContent":["import * as ReactDOM from 'react-dom';\nimport * as React from 'react';\nimport type { PortalState } from './Portal.types';\n\n/**\n * Render the final JSX of Portal\n */\nexport const renderPortal_unstable = (state: PortalState): React.ReactElement => {\n return (\n <span hidden ref={state.virtualParentRootRef}>\n {state.mountNode && ReactDOM.createPortal(state.children, state.mountNode)}\n </span>\n );\n};\n"],"names":["renderPortal_unstable","state","React","createElement","span","hidden","ref","virtualParentRootRef","mountNode","ReactDOM","createPortal","children"],"rangeMappings":";;;;;;;;;;;;;;;;;;","mappings":";;;;+BAOaA;;;eAAAA;;;;oEAPa;iEACH;AAMhB,MAAMA,wBAAwB,CAACC;IACpC,OAAA,WAAA,GACEC,OAAAC,aAAA,CAACC,QAAAA;QAAKC,QAAAA;QAAOC,KAAKL,MAAMM,oBAAoB;OACzCN,MAAMO,SAAS,IAAA,WAAA,GAAIC,UAASC,YAAY,CAACT,MAAMU,QAAQ,EAAEV,MAAMO,SAAS;AAG/E"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["usePortal.
|
1
|
+
{"version":3,"sources":["usePortal.ts"],"sourcesContent":["import { setVirtualParent } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nimport { toMountNodeProps } from '../../utils/toMountNodeProps';\nimport { usePortalMountNode } from './usePortalMountNode';\nimport type { PortalProps, PortalState } from './Portal.types';\n\n/**\n * Create the state required to render Portal.\n *\n * The returned state can be modified with hooks such as usePortalStyles, before being passed to renderPortal_unstable.\n *\n * @param props - props from this instance of Portal\n */\nexport const usePortal_unstable = (props: PortalProps): PortalState => {\n const { element, className } = toMountNodeProps(props.mountNode);\n\n const virtualParentRootRef = React.useRef<HTMLSpanElement>(null);\n const fallbackElement = usePortalMountNode({ disabled: !!element, className });\n\n const mountNode = element ?? fallbackElement;\n const state: PortalState = {\n children: props.children,\n mountNode,\n virtualParentRootRef,\n };\n\n React.useEffect(() => {\n if (!mountNode) {\n return;\n }\n\n const virtualParent = virtualParentRootRef.current;\n\n // By default, we create a mount node for portal on `document.body` (see usePortalMountNode()) and have following structure:\n //\n // <body>\n // <!-- ⚛️ application root -->\n // <div id=\"root\">\n // <!-- ⬇️ portal node rendered in a tree to anchor (virtual parent node) -->\n // <span aria-hidden=\"true\"></span>\n // </div>\n // <div id=\"portal-mount-node\">\n // <!-- 🧩portal content -->\n // </div>\n // </body>\n //\n // To make sure that `.elementContains()` works correctly, we link a virtual parent to a portal node (a virtual parent node becomes a parent of mount node):\n // virtual.contains(mountNode) === false\n // (while we need ⬇️⬇️⬇️)\n // elementsContains(virtualParent, mountNode) === true\n // elementsContains(mountNode, virtualParent) === false\n //\n // For more details, check docs for virtual parent utils.\n //\n // However, if a user provides a custom mount node (via `props`) the structure could be different:\n //\n // <body>\n // <!-- application root -->\n // <div id=\"root\">\n // <div id=\"portal-mount-node\">\n // <!-- 🧩portal content -->\n //\n // <span aria-hidden=\"true\"></span>\n // </div>\n // </div>\n // </body>\n //\n // A mount node in this case contains portal's content and a virtual parent node. In this case nodes linking is redundant and the check below avoids it.\n //\n // Otherwise, there is a circular reference - both elements are parents of each other:\n // elementsContains(mountNode, virtualParent) === true\n // elementsContains(virtualParent, mountNode) === true\n const isVirtualParentInsideChild = mountNode.contains(virtualParent);\n\n if (virtualParent && !isVirtualParentInsideChild) {\n setVirtualParent(mountNode, virtualParent);\n\n return () => {\n setVirtualParent(mountNode, undefined);\n };\n }\n }, [virtualParentRootRef, mountNode]);\n\n return state;\n};\n"],"names":["usePortal_unstable","props","element","className","toMountNodeProps","mountNode","virtualParentRootRef","React","useRef","fallbackElement","usePortalMountNode","disabled","state","children","useEffect","virtualParent","current","isVirtualParentInsideChild","contains","setVirtualParent","undefined"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAcaA;;;eAAAA;;;;gCAdoB;iEACV;kCAEU;oCACE;AAU5B,MAAMA,qBAAqB,CAACC;IACjC,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAGC,IAAAA,kCAAAA,EAAiBH,MAAMI,SAAS;IAE/D,MAAMC,uBAAuBC,OAAMC,MAAM,CAAkB;IAC3D,MAAMC,kBAAkBC,IAAAA,sCAAAA,EAAmB;QAAEC,UAAU,CAAC,CAACT;QAASC;IAAU;IAE5E,MAAME,YAAYH,YAAAA,QAAAA,YAAAA,KAAAA,IAAAA,UAAWO;IAC7B,MAAMG,QAAqB;QACzBC,UAAUZ,MAAMY,QAAQ;QACxBR;QACAC;IACF;IAEAC,OAAMO,SAAS,CAAC;QACd,IAAI,CAACT,WAAW;YACd;QACF;QAEA,MAAMU,gBAAgBT,qBAAqBU,OAAO;QAElD,4HAA4H;QAC5H,EAAE;QACF,SAAS;QACT,iCAAiC;QACjC,oBAAoB;QACpB,iFAAiF;QACjF,uCAAuC;QACvC,WAAW;QACX,iCAAiC;QACjC,gCAAgC;QAChC,WAAW;QACX,UAAU;QACV,EAAE;QACF,4JAA4J;QAC5J,0CAA0C;QAC1C,2BAA2B;QAC3B,wDAAwD;QACxD,yDAAyD;QACzD,EAAE;QACF,yDAAyD;QACzD,EAAE;QACF,kGAAkG;QAClG,EAAE;QACF,SAAS;QACT,8BAA8B;QAC9B,oBAAoB;QACpB,mCAAmC;QACnC,kCAAkC;QAClC,EAAE;QACF,yCAAyC;QACzC,aAAa;QACb,WAAW;QACX,UAAU;QACV,EAAE;QACF,wJAAwJ;QACxJ,EAAE;QACF,sFAAsF;QACtF,wDAAwD;QACxD,wDAAwD;QACxD,MAAMC,6BAA6BZ,UAAUa,QAAQ,CAACH;QAEtD,IAAIA,iBAAiB,CAACE,4BAA4B;YAChDE,IAAAA,gCAAAA,EAAiBd,WAAWU;YAE5B,OAAO;gBACLI,IAAAA,gCAAAA,EAAiBd,WAAWe;YAC9B;QACF;IACF,GAAG;QAACd;QAAsBD;KAAU;IAEpC,OAAOO;AACT"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["usePortalMountNode.
|
1
|
+
{"version":3,"sources":["usePortalMountNode.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n usePortalMountNode as usePortalMountNodeContext,\n} from '@fluentui/react-shared-contexts';\nimport { mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\nimport { useDisposable } from 'use-disposable';\n\nimport { usePortalMountNodeStylesStyles } from './usePortalMountNodeStyles.styles';\n\nconst useInsertionEffect = (React as never)['useInsertion' + 'Effect'] as typeof React.useLayoutEffect | undefined;\n\nexport type UsePortalMountNodeOptions = {\n /**\n * Since hooks cannot be called conditionally use this flag to disable creating the node\n */\n disabled?: boolean;\n\n className?: string;\n};\n\n/**\n * Creates a new element on a \"document.body\" to mount portals.\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n 'use no memo';\n\n const { targetDocument, dir } = useFluent();\n const mountNode = usePortalMountNodeContext();\n\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n const classes = usePortalMountNodeStylesStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root, options.className);\n const targetNode: HTMLElement | ShadowRoot | undefined = mountNode ?? targetDocument?.body;\n\n const element = useDisposable(() => {\n if (targetNode === undefined || options.disabled) {\n return [null, () => null];\n }\n\n const newElement = targetNode.ownerDocument.createElement('div');\n targetNode.appendChild(newElement);\n return [newElement, () => newElement.remove()];\n }, [targetNode]);\n\n if (useInsertionEffect) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useInsertionEffect(() => {\n if (!element) {\n return;\n }\n\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n element.setAttribute('data-portal-node', 'true');\n\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }, [className, dir, element, focusVisibleRef]);\n } else {\n // This useMemo call is intentional for React 17\n // We don't want to re-create the portal element when its attributes change.\n // This also should not be done in an effect because, changing the value of css variables\n // after initial mount can trigger interesting CSS side effects like transitions.\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useMemo(() => {\n if (!element) {\n return;\n }\n\n // Force replace all classes\n element.className = className;\n element.setAttribute('dir', dir);\n element.setAttribute('data-portal-node', 'true');\n\n focusVisibleRef.current = element;\n }, [className, dir, element, focusVisibleRef]);\n }\n\n return element;\n};\n"],"names":["usePortalMountNode","useInsertionEffect","React","options","targetDocument","dir","useFluent","mountNode","usePortalMountNodeContext","focusVisibleRef","useFocusVisible","classes","usePortalMountNodeStylesStyles","themeClassName","useThemeClassName","className","mergeClasses","root","targetNode","body","element","useDisposable","undefined","disabled","newElement","ownerDocument","createElement","appendChild","remove","classesToApply","split","filter","Boolean","classList","add","setAttribute","current","removeAttribute","useMemo"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BA0BaA;;;eAAAA;;;;iEA1BU;qCAKhB;wBACsB;8BACG;+BACF;gDAEiB;AAE/C,MAAMC,qBAAqBC,MAAgB,CAAC,iBAAiB,SAAS;AAc/D,MAAMF,qBAAqB,CAACG;IACjC;IAEA,MAAM,EAAEC,cAAc,EAAEC,GAAG,EAAE,GAAGC,IAAAA,uCAAAA;IAChC,MAAMC,YAAYC,IAAAA,uCAAAA;IAElB,MAAMC,kBAAkBC,IAAAA,6BAAAA;IACxB,MAAMC,UAAUC,IAAAA,8DAAAA;IAChB,MAAMC,iBAAiBC,IAAAA,+CAAAA;IAEvB,MAAMC,YAAYC,IAAAA,oBAAAA,EAAaH,gBAAgBF,QAAQM,IAAI,EAAEd,QAAQY,SAAS;IAC9E,MAAMG,aAAmDX,cAAAA,QAAAA,cAAAA,KAAAA,IAAAA,YAAaH,mBAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAgBe,IAAI;IAE1F,MAAMC,UAAUC,IAAAA,4BAAAA,EAAc;QAC5B,IAAIH,eAAeI,aAAanB,QAAQoB,QAAQ,EAAE;YAChD,OAAO;gBAAC;gBAAM,IAAM;aAAK;QAC3B;QAEA,MAAMC,aAAaN,WAAWO,aAAa,CAACC,aAAa,CAAC;QAC1DR,WAAWS,WAAW,CAACH;QACvB,OAAO;YAACA;YAAY,IAAMA,WAAWI,MAAM;SAAG;IAChD,GAAG;QAACV;KAAW;IAEf,IAAIjB,oBAAoB;QACtB,sDAAsD;QACtDA,mBAAmB;YACjB,IAAI,CAACmB,SAAS;gBACZ;YACF;YAEA,MAAMS,iBAAiBd,UAAUe,KAAK,CAAC,KAAKC,MAAM,CAACC;YAEnDZ,QAAQa,SAAS,CAACC,GAAG,IAAIL;YACzBT,QAAQe,YAAY,CAAC,OAAO9B;YAC5Be,QAAQe,YAAY,CAAC,oBAAoB;YAEzC1B,gBAAgB2B,OAAO,GAAGhB;YAE1B,OAAO;gBACLA,QAAQa,SAAS,CAACL,MAAM,IAAIC;gBAC5BT,QAAQiB,eAAe,CAAC;YAC1B;QACF,GAAG;YAACtB;YAAWV;YAAKe;YAASX;SAAgB;IAC/C,OAAO;QACL,gDAAgD;QAChD,4EAA4E;QAC5E,yFAAyF;QACzF,iFAAiF;QACjF,sDAAsD;QACtDP,OAAMoC,OAAO,CAAC;YACZ,IAAI,CAAClB,SAAS;gBACZ;YACF;YAEA,4BAA4B;YAC5BA,QAAQL,SAAS,GAAGA;YACpBK,QAAQe,YAAY,CAAC,OAAO9B;YAC5Be,QAAQe,YAAY,CAAC,oBAAoB;YAEzC1B,gBAAgB2B,OAAO,GAAGhB;QAC5B,GAAG;YAACL;YAAWV;YAAKe;YAASX;SAAgB;IAC/C;IAEA,OAAOW;AACT"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["usePortalMountNodeStyles.styles.js"],"sourcesContent":["import {
|
1
|
+
{"version":3,"sources":["usePortalMountNodeStyles.styles.js"],"sourcesContent":["import { makeStyles } from '@griffel/react';\nexport const usePortalMountNodeStylesStyles = makeStyles({\n root: {\n // Creates new stacking context to prevent z-index issues\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context\n //\n // Also keeps a portal on top of a page to prevent scrollbars from appearing\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n zIndex: 1000000\n }\n});\n"],"names":["usePortalMountNodeStylesStyles","__styles","root","qhf8xq","Bhzewxz","oyh7mz","j35jbq","Bj3rh1h","d"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BACaA;;;eAAAA;;;uBADc;AACpB,MAAMA,iCAA8B,WAAA,GAAGC,IAAAA,eAAA,EAAA;IAAAC,MAAA;QAAAC,QAAA;QAAAC,SAAA;QAAAC,QAAA;YAAA;YAAA;SAAA;QAAAC,QAAA;YAAA;YAAA;SAAA;QAAAC,SAAA;IAAA;AAAA,GAAA;IAAAC,GAAA;QAAA;QAAA;QAAA;QAAA;QAAA;KAAA;AAAA"}
|
package/lib-commonjs/index.js
CHANGED
@@ -9,23 +9,23 @@ function _export(target, all) {
|
|
9
9
|
});
|
10
10
|
}
|
11
11
|
_export(exports, {
|
12
|
-
elementContains: function() {
|
13
|
-
return _reactutilities.elementContains;
|
14
|
-
},
|
15
|
-
setVirtualParent: function() {
|
16
|
-
return _reactutilities.setVirtualParent;
|
17
|
-
},
|
18
12
|
Portal: function() {
|
19
13
|
return _index.Portal;
|
20
14
|
},
|
15
|
+
elementContains: function() {
|
16
|
+
return _reactutilities.elementContains;
|
17
|
+
},
|
21
18
|
renderPortal_unstable: function() {
|
22
19
|
return _index.renderPortal_unstable;
|
23
20
|
},
|
24
|
-
|
25
|
-
return
|
21
|
+
setVirtualParent: function() {
|
22
|
+
return _reactutilities.setVirtualParent;
|
26
23
|
},
|
27
24
|
toMountNodeProps: function() {
|
28
25
|
return _toMountNodeProps.toMountNodeProps;
|
26
|
+
},
|
27
|
+
usePortal_unstable: function() {
|
28
|
+
return _index.usePortal_unstable;
|
29
29
|
}
|
30
30
|
});
|
31
31
|
const _reactutilities = require("@fluentui/react-utilities");
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export { elementContains, setVirtualParent } from '@fluentui/react-utilities';\nexport { Portal, renderPortal_unstable, usePortal_unstable } from './components/Portal/index';\nexport type { PortalProps, PortalState } from './components/Portal/index';\n\nexport { toMountNodeProps } from './utils/toMountNodeProps';\n"],"names":["Portal","elementContains","renderPortal_unstable","setVirtualParent","toMountNodeProps","usePortal_unstable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IACSA,MAAM;eAANA,aAAM;;IADNC,eAAe;eAAfA,+BAAe;;IACPC,qBAAqB;eAArBA,4BAAqB;;IADZC,gBAAgB;eAAhBA,gCAAgB;;IAIjCC,gBAAgB;eAAhBA,kCAAgB;;IAHeC,kBAAkB;eAAlBA,yBAAkB;;;gCADR;uBACgB;kCAGjC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["toMountNodeProps.
|
1
|
+
{"version":3,"sources":["toMountNodeProps.ts"],"sourcesContent":["import { isHTMLElement } from '@fluentui/react-utilities';\nimport type { PortalProps } from '../Portal';\n\n/**\n * The function that normalizes the `mountNode` prop into an object with element and className props.\n *\n * @param mountNode - an HTML element or an object with props\n */\nexport function toMountNodeProps(mountNode: PortalProps['mountNode']): {\n element?: HTMLElement | null;\n className?: string;\n} {\n if (isHTMLElement(mountNode)) {\n return { element: mountNode };\n }\n\n if (typeof mountNode === 'object') {\n if (mountNode === null) {\n return { element: null };\n }\n\n return mountNode;\n }\n\n return {};\n}\n"],"names":["toMountNodeProps","mountNode","isHTMLElement","element"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAQgBA;;;eAAAA;;;gCARc;AAQvB,SAASA,iBAAiBC,SAAmC;IAIlE,IAAIC,IAAAA,6BAAAA,EAAcD,YAAY;QAC5B,OAAO;YAAEE,SAASF;QAAU;IAC9B;IAEA,IAAI,OAAOA,cAAc,UAAU;QACjC,IAAIA,cAAc,MAAM;YACtB,OAAO;gBAAEE,SAAS;YAAK;QACzB;QAEA,OAAOF;IACT;IAEA,OAAO,CAAC;AACV"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fluentui/react-portal",
|
3
|
-
"version": "9.4.
|
3
|
+
"version": "9.4.31",
|
4
4
|
"description": "A utility component that creates portals compatible with Fluent UI",
|
5
5
|
"main": "lib-commonjs/index.js",
|
6
6
|
"module": "lib/index.js",
|
@@ -32,9 +32,9 @@
|
|
32
32
|
"@fluentui/scripts-tasks": "*"
|
33
33
|
},
|
34
34
|
"dependencies": {
|
35
|
-
"@fluentui/react-shared-contexts": "^9.
|
36
|
-
"@fluentui/react-tabster": "^9.22.
|
37
|
-
"@fluentui/react-utilities": "^9.18.
|
35
|
+
"@fluentui/react-shared-contexts": "^9.20.0",
|
36
|
+
"@fluentui/react-tabster": "^9.22.3",
|
37
|
+
"@fluentui/react-utilities": "^9.18.13",
|
38
38
|
"@griffel/react": "^1.5.22",
|
39
39
|
"@swc/helpers": "^0.5.1",
|
40
40
|
"use-disposable": "^1.0.1"
|