@fluentui/react-portal 9.4.3 → 9.4.4
Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md
CHANGED
@@ -1,17 +1,29 @@
|
|
1
1
|
# Change Log - @fluentui/react-portal
|
2
2
|
|
3
|
-
This log was last generated on Thu,
|
3
|
+
This log was last generated on Thu, 14 Dec 2023 09:51:35 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.4.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.4)
|
8
|
+
|
9
|
+
Thu, 14 Dec 2023 09:51:35 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.3..@fluentui/react-portal_v9.4.4)
|
11
|
+
|
12
|
+
### Patches
|
13
|
+
|
14
|
+
- fix: Virtual parent cannot be the DOM child of mount node ([PR #29990](https://github.com/microsoft/fluentui/pull/29990) by lingfangao@hotmail.com)
|
15
|
+
- Bump @fluentui/react-shared-contexts to v9.13.1 ([commit](https://github.com/microsoft/fluentui/commit/80a1b02be2fbbdde916ac87fbf760e442a2295c4) by beachball)
|
16
|
+
- Bump @fluentui/react-tabster to v9.15.1 ([commit](https://github.com/microsoft/fluentui/commit/80a1b02be2fbbdde916ac87fbf760e442a2295c4) by beachball)
|
17
|
+
- Bump @fluentui/react-utilities to v9.15.3 ([commit](https://github.com/microsoft/fluentui/commit/80a1b02be2fbbdde916ac87fbf760e442a2295c4) by beachball)
|
18
|
+
|
7
19
|
## [9.4.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.3)
|
8
20
|
|
9
|
-
Thu, 30 Nov 2023 13:
|
21
|
+
Thu, 30 Nov 2023 13:42:06 GMT
|
10
22
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.4.2..@fluentui/react-portal_v9.4.3)
|
11
23
|
|
12
24
|
### Patches
|
13
25
|
|
14
|
-
- Bump @fluentui/react-tabster to v9.15.0 ([PR #
|
26
|
+
- Bump @fluentui/react-tabster to v9.15.0 ([PR #29929](https://github.com/microsoft/fluentui/pull/29929) by beachball)
|
15
27
|
|
16
28
|
## [9.4.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.4.2)
|
17
29
|
|
@@ -15,23 +15,66 @@ import { usePortalMountNode } from './usePortalMountNode';
|
|
15
15
|
disabled: !!element,
|
16
16
|
className
|
17
17
|
});
|
18
|
+
const mountNode = element !== null && element !== void 0 ? element : fallbackElement;
|
18
19
|
const state = {
|
19
20
|
children: props.children,
|
20
|
-
mountNode
|
21
|
+
mountNode,
|
21
22
|
virtualParentRootRef
|
22
23
|
};
|
23
24
|
React.useEffect(()=>{
|
24
|
-
if (
|
25
|
-
|
25
|
+
if (!mountNode) {
|
26
|
+
return;
|
27
|
+
}
|
28
|
+
const virtualParent = virtualParentRootRef.current;
|
29
|
+
// By default, we create a mount node for portal on `document.body` (see usePortalMountNode()) and have following structure:
|
30
|
+
//
|
31
|
+
// <body>
|
32
|
+
// <!-- ⚛️ application root -->
|
33
|
+
// <div id="root">
|
34
|
+
// <!-- ⬇️ portal node rendered in a tree to anchor (virtual parent node) -->
|
35
|
+
// <span aria-hidden="true"></span>
|
36
|
+
// </div>
|
37
|
+
// <div id="portal-mount-node">
|
38
|
+
// <!-- 🧩portal content -->
|
39
|
+
// </div>
|
40
|
+
// </body>
|
41
|
+
//
|
42
|
+
// 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):
|
43
|
+
// virtual.contains(mountNode) === false
|
44
|
+
// (while we need ⬇️⬇️⬇️)
|
45
|
+
// elementsContains(virtualParent, mountNode) === true
|
46
|
+
// elementsContains(mountNode, virtualParent) === false
|
47
|
+
//
|
48
|
+
// For more details, check docs for virtual parent utils.
|
49
|
+
//
|
50
|
+
// However, if a user provides a custom mount node (via `props`) the structure could be different:
|
51
|
+
//
|
52
|
+
// <body>
|
53
|
+
// <!-- application root -->
|
54
|
+
// <div id="root">
|
55
|
+
// <div id="portal-mount-node">
|
56
|
+
// <!-- 🧩portal content -->
|
57
|
+
//
|
58
|
+
// <span aria-hidden="true"></span>
|
59
|
+
// </div>
|
60
|
+
// </div>
|
61
|
+
// </body>
|
62
|
+
//
|
63
|
+
// 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.
|
64
|
+
//
|
65
|
+
// Otherwise, there is a circular reference - both elements are parents of each other:
|
66
|
+
// elementsContains(mountNode, virtualParent) === true
|
67
|
+
// elementsContains(virtualParent, mountNode) === true
|
68
|
+
const isVirtualParentInsideChild = mountNode.contains(virtualParent);
|
69
|
+
if (virtualParent && !isVirtualParentInsideChild) {
|
70
|
+
setVirtualParent(mountNode, virtualParent);
|
71
|
+
return ()=>{
|
72
|
+
setVirtualParent(mountNode, undefined);
|
73
|
+
};
|
26
74
|
}
|
27
|
-
return ()=>{
|
28
|
-
if (state.mountNode) {
|
29
|
-
setVirtualParent(state.mountNode, undefined);
|
30
|
-
}
|
31
|
-
};
|
32
75
|
}, [
|
33
|
-
|
34
|
-
|
76
|
+
virtualParentRootRef,
|
77
|
+
mountNode
|
35
78
|
]);
|
36
79
|
return state;
|
37
80
|
};
|
@@ -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 state: PortalState = {\n children: props.children,\n mountNode
|
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"}
|
@@ -20,23 +20,66 @@ const usePortal_unstable = (props)=>{
|
|
20
20
|
disabled: !!element,
|
21
21
|
className
|
22
22
|
});
|
23
|
+
const mountNode = element !== null && element !== void 0 ? element : fallbackElement;
|
23
24
|
const state = {
|
24
25
|
children: props.children,
|
25
|
-
mountNode
|
26
|
+
mountNode,
|
26
27
|
virtualParentRootRef
|
27
28
|
};
|
28
29
|
_react.useEffect(()=>{
|
29
|
-
if (
|
30
|
-
|
30
|
+
if (!mountNode) {
|
31
|
+
return;
|
32
|
+
}
|
33
|
+
const virtualParent = virtualParentRootRef.current;
|
34
|
+
// By default, we create a mount node for portal on `document.body` (see usePortalMountNode()) and have following structure:
|
35
|
+
//
|
36
|
+
// <body>
|
37
|
+
// <!-- ⚛️ application root -->
|
38
|
+
// <div id="root">
|
39
|
+
// <!-- ⬇️ portal node rendered in a tree to anchor (virtual parent node) -->
|
40
|
+
// <span aria-hidden="true"></span>
|
41
|
+
// </div>
|
42
|
+
// <div id="portal-mount-node">
|
43
|
+
// <!-- 🧩portal content -->
|
44
|
+
// </div>
|
45
|
+
// </body>
|
46
|
+
//
|
47
|
+
// 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):
|
48
|
+
// virtual.contains(mountNode) === false
|
49
|
+
// (while we need ⬇️⬇️⬇️)
|
50
|
+
// elementsContains(virtualParent, mountNode) === true
|
51
|
+
// elementsContains(mountNode, virtualParent) === false
|
52
|
+
//
|
53
|
+
// For more details, check docs for virtual parent utils.
|
54
|
+
//
|
55
|
+
// However, if a user provides a custom mount node (via `props`) the structure could be different:
|
56
|
+
//
|
57
|
+
// <body>
|
58
|
+
// <!-- application root -->
|
59
|
+
// <div id="root">
|
60
|
+
// <div id="portal-mount-node">
|
61
|
+
// <!-- 🧩portal content -->
|
62
|
+
//
|
63
|
+
// <span aria-hidden="true"></span>
|
64
|
+
// </div>
|
65
|
+
// </div>
|
66
|
+
// </body>
|
67
|
+
//
|
68
|
+
// 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.
|
69
|
+
//
|
70
|
+
// Otherwise, there is a circular reference - both elements are parents of each other:
|
71
|
+
// elementsContains(mountNode, virtualParent) === true
|
72
|
+
// elementsContains(virtualParent, mountNode) === true
|
73
|
+
const isVirtualParentInsideChild = mountNode.contains(virtualParent);
|
74
|
+
if (virtualParent && !isVirtualParentInsideChild) {
|
75
|
+
(0, _reactutilities.setVirtualParent)(mountNode, virtualParent);
|
76
|
+
return ()=>{
|
77
|
+
(0, _reactutilities.setVirtualParent)(mountNode, undefined);
|
78
|
+
};
|
31
79
|
}
|
32
|
-
return ()=>{
|
33
|
-
if (state.mountNode) {
|
34
|
-
(0, _reactutilities.setVirtualParent)(state.mountNode, undefined);
|
35
|
-
}
|
36
|
-
};
|
37
80
|
}, [
|
38
|
-
|
39
|
-
|
81
|
+
virtualParentRootRef,
|
82
|
+
mountNode
|
40
83
|
]);
|
41
84
|
return state;
|
42
85
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["usePortal.js"],"sourcesContent":["import { setVirtualParent } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { toMountNodeProps } from '../../utils/toMountNodeProps';\nimport { usePortalMountNode } from './usePortalMountNode';\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 */ export const usePortal_unstable = (props)=>{\n const { element, className } = toMountNodeProps(props.mountNode);\n const virtualParentRootRef = React.useRef(null);\n const fallbackElement = usePortalMountNode({\n disabled: !!element,\n className\n });\n const
|
1
|
+
{"version":3,"sources":["usePortal.js"],"sourcesContent":["import { setVirtualParent } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { toMountNodeProps } from '../../utils/toMountNodeProps';\nimport { usePortalMountNode } from './usePortalMountNode';\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 */ export const usePortal_unstable = (props)=>{\n const { element, className } = toMountNodeProps(props.mountNode);\n const virtualParentRootRef = React.useRef(null);\n const fallbackElement = usePortalMountNode({\n disabled: !!element,\n className\n });\n const mountNode = element !== null && element !== void 0 ? element : fallbackElement;\n const state = {\n children: props.children,\n mountNode,\n virtualParentRootRef\n };\n React.useEffect(()=>{\n if (!mountNode) {\n return;\n }\n const virtualParent = virtualParentRootRef.current;\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 if (virtualParent && !isVirtualParentInsideChild) {\n setVirtualParent(mountNode, virtualParent);\n return ()=>{\n setVirtualParent(mountNode, undefined);\n };\n }\n }, [\n virtualParentRootRef,\n 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"],"mappings":";;;;+BAUiBA;;;eAAAA;;;;gCAVgB;iEACV;kCACU;oCACE;AAOxB,MAAMA,qBAAqB,CAACC;IACnC,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAGC,IAAAA,kCAAgB,EAACH,MAAMI,SAAS;IAC/D,MAAMC,uBAAuBC,OAAMC,MAAM,CAAC;IAC1C,MAAMC,kBAAkBC,IAAAA,sCAAkB,EAAC;QACvCC,UAAU,CAAC,CAACT;QACZC;IACJ;IACA,MAAME,YAAYH,YAAY,QAAQA,YAAY,KAAK,IAAIA,UAAUO;IACrE,MAAMG,QAAQ;QACVC,UAAUZ,MAAMY,QAAQ;QACxBR;QACAC;IACJ;IACAC,OAAMO,SAAS,CAAC;QACZ,IAAI,CAACT,WAAW;YACZ;QACJ;QACA,MAAMU,gBAAgBT,qBAAqBU,OAAO;QAClD,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;QACtD,IAAIA,iBAAiB,CAACE,4BAA4B;YAC9CE,IAAAA,gCAAgB,EAACd,WAAWU;YAC5B,OAAO;gBACHI,IAAAA,gCAAgB,EAACd,WAAWe;YAChC;QACJ;IACJ,GAAG;QACCd;QACAD;KACH;IACD,OAAOO;AACX"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fluentui/react-portal",
|
3
|
-
"version": "9.4.
|
3
|
+
"version": "9.4.4",
|
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.13.
|
36
|
-
"@fluentui/react-tabster": "^9.15.
|
37
|
-
"@fluentui/react-utilities": "^9.15.
|
35
|
+
"@fluentui/react-shared-contexts": "^9.13.1",
|
36
|
+
"@fluentui/react-tabster": "^9.15.1",
|
37
|
+
"@fluentui/react-utilities": "^9.15.3",
|
38
38
|
"@griffel/react": "^1.5.14",
|
39
39
|
"@swc/helpers": "^0.5.1",
|
40
40
|
"use-disposable": "^1.0.1"
|