@fluentui/react-portal 9.4.29 → 9.4.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -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,24 @@
|
|
1
1
|
# Change Log - @fluentui/react-portal
|
2
2
|
|
3
|
-
This log was last generated on Mon,
|
3
|
+
This log was last generated on Mon, 15 Jul 2024 17:20:23 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.4.30](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.30)
|
8
|
+
|
9
|
+
Mon, 15 Jul 2024 17:20:23 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.29..@fluentui/react-portal_v9.4.30)
|
11
|
+
|
12
|
+
### Patches
|
13
|
+
|
14
|
+
- fix: revert incorectly set npm versions in all packages ([PR #31937](https://github.com/microsoft/fluentui/pull/31937) by martinhochel@microsoft.com)
|
15
|
+
- Bump @fluentui/react-shared-contexts to v9.19.1 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
16
|
+
- Bump @fluentui/react-tabster to v9.22.2 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
17
|
+
- Bump @fluentui/react-utilities to v9.18.12 ([PR #31998](https://github.com/microsoft/fluentui/pull/31998) by beachball)
|
18
|
+
|
7
19
|
## [9.4.29](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.29)
|
8
20
|
|
9
|
-
Mon, 01 Jul 2024 20:
|
21
|
+
Mon, 01 Jul 2024 20:30:26 GMT
|
10
22
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.28..@fluentui/react-portal_v9.4.29)
|
11
23
|
|
12
24
|
### 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.30",
|
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.19.
|
36
|
-
"@fluentui/react-tabster": "^9.22.
|
37
|
-
"@fluentui/react-utilities": "^9.18.
|
35
|
+
"@fluentui/react-shared-contexts": "^9.19.1",
|
36
|
+
"@fluentui/react-tabster": "^9.22.2",
|
37
|
+
"@fluentui/react-utilities": "^9.18.12",
|
38
38
|
"@griffel/react": "^1.5.22",
|
39
39
|
"@swc/helpers": "^0.5.1",
|
40
40
|
"use-disposable": "^1.0.1"
|