@fluentui/react-portal 9.0.8 → 9.0.10

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.json CHANGED
@@ -2,7 +2,100 @@
2
2
  "name": "@fluentui/react-portal",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 20 Oct 2022 08:35:17 GMT",
5
+ "date": "Fri, 11 Nov 2022 14:53:18 GMT",
6
+ "tag": "@fluentui/react-portal_v9.0.10",
7
+ "version": "9.0.10",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "author": "martinhochel@microsoft.com",
12
+ "package": "@fluentui/react-portal",
13
+ "commit": "b3907043bd8d7b650c55e8e7c3119b14f2606c38",
14
+ "comment": "fix: create valid export maps"
15
+ },
16
+ {
17
+ "author": "tristan.watanabe@gmail.com",
18
+ "package": "@fluentui/react-portal",
19
+ "commit": "792bd72b19e360afe9ac8e9da298dc3d85776c74",
20
+ "comment": "chore: Migrate to new package structure."
21
+ },
22
+ {
23
+ "author": "beachball",
24
+ "package": "@fluentui/react-portal",
25
+ "comment": "Bump @fluentui/react-shared-contexts to v9.1.1",
26
+ "commit": "b4c9a0ae8d7444bf746f1307ab01e2dc16310720"
27
+ },
28
+ {
29
+ "author": "beachball",
30
+ "package": "@fluentui/react-portal",
31
+ "comment": "Bump @fluentui/react-tabster to v9.3.0",
32
+ "commit": "b4c9a0ae8d7444bf746f1307ab01e2dc16310720"
33
+ },
34
+ {
35
+ "author": "beachball",
36
+ "package": "@fluentui/react-portal",
37
+ "comment": "Bump @fluentui/react-utilities to v9.2.1",
38
+ "commit": "b4c9a0ae8d7444bf746f1307ab01e2dc16310720"
39
+ }
40
+ ]
41
+ }
42
+ },
43
+ {
44
+ "date": "Wed, 02 Nov 2022 11:57:57 GMT",
45
+ "tag": "@fluentui/react-portal_v9.0.9",
46
+ "version": "9.0.9",
47
+ "comments": {
48
+ "patch": [
49
+ {
50
+ "author": "lingfangao@hotmail.com",
51
+ "package": "@fluentui/react-portal",
52
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b",
53
+ "comment": "refactor: usePortalMount node updates mount node attributes in memo"
54
+ },
55
+ {
56
+ "author": "olfedias@microsoft.com",
57
+ "package": "@fluentui/react-portal",
58
+ "commit": "c619ba066f11a8654e95375314824ba6b81b003e",
59
+ "comment": "chore: Update Griffel to latest version"
60
+ },
61
+ {
62
+ "author": "beachball",
63
+ "package": "@fluentui/react-portal",
64
+ "comment": "Bump @fluentui/react-shared-contexts to v9.1.0",
65
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
66
+ },
67
+ {
68
+ "author": "beachball",
69
+ "package": "@fluentui/react-portal",
70
+ "comment": "Bump @fluentui/react-tabster to v9.2.1",
71
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
72
+ },
73
+ {
74
+ "author": "beachball",
75
+ "package": "@fluentui/react-portal",
76
+ "comment": "Bump @fluentui/react-utilities to v9.2.0",
77
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
78
+ }
79
+ ]
80
+ }
81
+ },
82
+ {
83
+ "date": "Tue, 25 Oct 2022 00:35:34 GMT",
84
+ "tag": "@fluentui/react-portal_v9.0.8",
85
+ "version": "9.0.8",
86
+ "comments": {
87
+ "none": [
88
+ {
89
+ "author": "miroslav.stastny@microsoft.com",
90
+ "package": "@fluentui/react-portal",
91
+ "commit": "6ced976a8d0e6a0e2e207da8fe0eb810e2bd19bc",
92
+ "comment": "Update package readme"
93
+ }
94
+ ]
95
+ }
96
+ },
97
+ {
98
+ "date": "Thu, 20 Oct 2022 08:39:40 GMT",
6
99
  "tag": "@fluentui/react-portal_v9.0.8",
7
100
  "version": "9.0.8",
8
101
  "comments": {
@@ -23,19 +116,19 @@
23
116
  "author": "beachball",
24
117
  "package": "@fluentui/react-portal",
25
118
  "comment": "Bump @fluentui/react-shared-contexts to v9.0.2",
26
- "commit": "be27026d83b8a019bcb945d0f42635ae76c00385"
119
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
27
120
  },
28
121
  {
29
122
  "author": "beachball",
30
123
  "package": "@fluentui/react-portal",
31
124
  "comment": "Bump @fluentui/react-tabster to v9.2.0",
32
- "commit": "be27026d83b8a019bcb945d0f42635ae76c00385"
125
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
33
126
  },
34
127
  {
35
128
  "author": "beachball",
36
129
  "package": "@fluentui/react-portal",
37
130
  "comment": "Bump @fluentui/react-utilities to v9.1.2",
38
- "commit": "be27026d83b8a019bcb945d0f42635ae76c00385"
131
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
39
132
  }
40
133
  ]
41
134
  }
package/CHANGELOG.md CHANGED
@@ -1,21 +1,47 @@
1
1
  # Change Log - @fluentui/react-portal
2
2
 
3
- This log was last generated on Thu, 20 Oct 2022 08:35:17 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 11 Nov 2022 14:53:18 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.0.10](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.0.10)
8
+
9
+ Fri, 11 Nov 2022 14:53:18 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.0.9..@fluentui/react-portal_v9.0.10)
11
+
12
+ ### Patches
13
+
14
+ - fix: create valid export maps ([PR #25558](https://github.com/microsoft/fluentui/pull/25558) by martinhochel@microsoft.com)
15
+ - chore: Migrate to new package structure. ([PR #25481](https://github.com/microsoft/fluentui/pull/25481) by tristan.watanabe@gmail.com)
16
+ - Bump @fluentui/react-shared-contexts to v9.1.1 ([PR #25615](https://github.com/microsoft/fluentui/pull/25615) by beachball)
17
+ - Bump @fluentui/react-tabster to v9.3.0 ([PR #25615](https://github.com/microsoft/fluentui/pull/25615) by beachball)
18
+ - Bump @fluentui/react-utilities to v9.2.1 ([PR #25615](https://github.com/microsoft/fluentui/pull/25615) by beachball)
19
+
20
+ ## [9.0.9](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.0.9)
21
+
22
+ Wed, 02 Nov 2022 11:57:57 GMT
23
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.0.8..@fluentui/react-portal_v9.0.9)
24
+
25
+ ### Patches
26
+
27
+ - refactor: usePortalMount node updates mount node attributes in memo ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by lingfangao@hotmail.com)
28
+ - chore: Update Griffel to latest version ([PR #25412](https://github.com/microsoft/fluentui/pull/25412) by olfedias@microsoft.com)
29
+ - Bump @fluentui/react-shared-contexts to v9.1.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
30
+ - Bump @fluentui/react-tabster to v9.2.1 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
31
+ - Bump @fluentui/react-utilities to v9.2.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
32
+
7
33
  ## [9.0.8](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.0.8)
8
34
 
9
- Thu, 20 Oct 2022 08:35:17 GMT
35
+ Thu, 20 Oct 2022 08:39:40 GMT
10
36
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-portal_v9.0.7..@fluentui/react-portal_v9.0.8)
11
37
 
12
38
  ### Patches
13
39
 
14
40
  - chore: Update Griffel to latest version ([PR #25212](https://github.com/microsoft/fluentui/pull/25212) by olfedias@microsoft.com)
15
41
  - chore: Bump peer deps to support React 18 ([PR #24972](https://github.com/microsoft/fluentui/pull/24972) by mgodbolt@microsoft.com)
16
- - Bump @fluentui/react-shared-contexts to v9.0.2 ([commit](https://github.com/microsoft/fluentui/commit/be27026d83b8a019bcb945d0f42635ae76c00385) by beachball)
17
- - Bump @fluentui/react-tabster to v9.2.0 ([commit](https://github.com/microsoft/fluentui/commit/be27026d83b8a019bcb945d0f42635ae76c00385) by beachball)
18
- - Bump @fluentui/react-utilities to v9.1.2 ([commit](https://github.com/microsoft/fluentui/commit/be27026d83b8a019bcb945d0f42635ae76c00385) by beachball)
42
+ - Bump @fluentui/react-shared-contexts to v9.0.2 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
43
+ - Bump @fluentui/react-tabster to v9.2.0 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
44
+ - Bump @fluentui/react-utilities to v9.1.2 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
19
45
 
20
46
  ## [9.0.7](https://github.com/microsoft/fluentui/tree/@fluentui/react-portal_v9.0.7)
21
47
 
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # @fluentui/react-portal
2
2
 
3
- **React Portal components for [Fluent UI React](https://developer.microsoft.com/en-us/fluentui)**
4
-
5
- These are not production-ready components and **should never be used in product**. This space is useful for testing new components whose APIs might change before final release.
3
+ **React Portal components for [Fluent UI React](https://react.fluentui.dev)**
6
4
 
7
5
  This package contains the `Portal` component, which allow consumers to render [React portals](https://reactjs.org/docs/portals.html) with Fluent styling and RTL awareness.
8
6
 
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
3
2
  import { useThemeClassName_unstable as useThemeClassName, useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
4
3
  import { __styles, mergeClasses } from '@griffel/react';
5
4
  import { useFocusVisible } from '@fluentui/react-tabster';
@@ -34,8 +33,12 @@ export const usePortalMountNode = options => {
34
33
  const newElement = targetDocument.createElement('div');
35
34
  targetDocument.body.appendChild(newElement);
36
35
  return newElement;
37
- }, [targetDocument, options.disabled]);
38
- useIsomorphicLayoutEffect(() => {
36
+ }, [targetDocument, options.disabled]); // This useMemo call is intentional
37
+ // We don't want to re-create the portal element when its attributes change.
38
+ // This also should not be done in an effect because, changing the value of css variables
39
+ // after initial mount can trigger interesting CSS side effects like transitions.
40
+
41
+ React.useMemo(() => {
39
42
  if (element) {
40
43
  const classesToApply = className.split(' ').filter(Boolean);
41
44
  element.classList.add(...classesToApply);
@@ -1 +1 @@
1
- {"version":3,"sources":["components/Portal/usePortalMountNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAZ,MAAuB,OAAvB;AACA,SAAS,yBAAT,QAA0C,2BAA1C;AACA,SACE,0BAA0B,IAAI,iBADhC,EAEE,kBAAkB,IAAI,SAFxB,QAGO,iCAHP;AAIA,mBAAqB,YAArB,QAAyC,gBAAzC;AACA,SAAS,eAAT,QAAgC,yBAAhC;;AASA,MAAM,SAAS,gBAAG;EAAA;IAAA;IAAA;EAAA;AAAA;EAAA;AAAA,EAAlB;AAOA;;AAEG;;;AACH,OAAO,MAAM,kBAAkB,GAAI,OAAD,IAA2D;EAC3F,MAAM;IAAE,cAAF;IAAkB;EAAlB,IAA0B,SAAS,EAAzC;EACA,MAAM,eAAe,GAAG,eAAe,EAAvC;EAEA,MAAM,OAAO,GAAG,SAAS,EAAzB;EACA,MAAM,cAAc,GAAG,iBAAiB,EAAxC;EAEA,MAAM,SAAS,GAAG,YAAY,CAAC,cAAD,EAAiB,OAAO,CAAC,IAAzB,CAA9B;EAEA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAN,CAAc,MAAK;IACjC,IAAI,cAAc,KAAK,SAAnB,IAAgC,OAAO,CAAC,QAA5C,EAAsD;MACpD,OAAO,IAAP;IACD;;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,aAAf,CAA6B,KAA7B,CAAnB;IACA,cAAc,CAAC,IAAf,CAAoB,WAApB,CAAgC,UAAhC;IAEA,OAAO,UAAP;EACD,CATe,EASb,CAAC,cAAD,EAAiB,OAAO,CAAC,QAAzB,CATa,CAAhB;EAWA,yBAAyB,CAAC,MAAK;IAC7B,IAAI,OAAJ,EAAa;MACX,MAAM,cAAc,GAAG,SAAS,CAAC,KAAV,CAAgB,GAAhB,EAAqB,MAArB,CAA4B,OAA5B,CAAvB;MAEA,OAAO,CAAC,SAAR,CAAkB,GAAlB,CAAsB,GAAG,cAAzB;MACA,OAAO,CAAC,YAAR,CAAqB,KAArB,EAA4B,GAA5B;MACA,eAAe,CAAC,OAAhB,GAA0B,OAA1B;MAEA,OAAO,MAAK;QACV,OAAO,CAAC,SAAR,CAAkB,MAAlB,CAAyB,GAAG,cAA5B;QACA,OAAO,CAAC,eAAR,CAAwB,KAAxB;MACD,CAHD;IAID;EACF,CAbwB,EAatB,CAAC,SAAD,EAAY,GAAZ,EAAiB,OAAjB,EAA0B,eAA1B,CAbsB,CAAzB;EAeA,KAAK,CAAC,SAAN,CAAgB,MAAK;IACnB,OAAO,MAAK;;;MACV,CAAA,EAAA,GAAA,OAAO,KAAA,IAAP,IAAA,OAAO,KAAA,KAAA,CAAP,GAAO,KAAA,CAAP,GAAA,OAAO,CAAE,aAAT,MAAsB,IAAtB,IAAsB,EAAA,KAAA,KAAA,CAAtB,GAAsB,KAAA,CAAtB,GAAsB,EAAA,CAAE,WAAF,CAAc,OAAd,CAAtB;IACD,CAFD;EAGD,CAJD,EAIG,CAAC,OAAD,CAJH;EAMA,OAAO,OAAP;AACD,CA1CM","sourcesContent":["import * as React from 'react';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n} from '@fluentui/react-shared-contexts';\nimport { makeStyles, mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\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\nconst useStyles = makeStyles({\n root: {\n position: 'relative',\n zIndex: 1000000,\n },\n});\n\n/**\n * Creates a new element on a document.body to mount portals\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n const { targetDocument, dir } = useFluent();\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n\n const classes = useStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root);\n\n const element = React.useMemo(() => {\n if (targetDocument === undefined || options.disabled) {\n return null;\n }\n\n const newElement = targetDocument.createElement('div');\n targetDocument.body.appendChild(newElement);\n\n return newElement;\n }, [targetDocument, options.disabled]);\n\n useIsomorphicLayoutEffect(() => {\n if (element) {\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }\n }, [className, dir, element, focusVisibleRef]);\n\n React.useEffect(() => {\n return () => {\n element?.parentElement?.removeChild(element);\n };\n }, [element]);\n\n return element;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/Portal/usePortalMountNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAZ,MAAuB,OAAvB;AACA,SACE,0BAA0B,IAAI,iBADhC,EAEE,kBAAkB,IAAI,SAFxB,QAGO,iCAHP;AAIA,mBAAqB,YAArB,QAAyC,gBAAzC;AACA,SAAS,eAAT,QAAgC,yBAAhC;;AASA,MAAM,SAAS,gBAAG;EAAA;IAAA;IAAA;EAAA;AAAA;EAAA;AAAA,EAAlB;AAOA;;AAEG;;;AACH,OAAO,MAAM,kBAAkB,GAAI,OAAD,IAA2D;EAC3F,MAAM;IAAE,cAAF;IAAkB;EAAlB,IAA0B,SAAS,EAAzC;EACA,MAAM,eAAe,GAAG,eAAe,EAAvC;EAEA,MAAM,OAAO,GAAG,SAAS,EAAzB;EACA,MAAM,cAAc,GAAG,iBAAiB,EAAxC;EAEA,MAAM,SAAS,GAAG,YAAY,CAAC,cAAD,EAAiB,OAAO,CAAC,IAAzB,CAA9B;EAEA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAN,CAAc,MAAK;IACjC,IAAI,cAAc,KAAK,SAAnB,IAAgC,OAAO,CAAC,QAA5C,EAAsD;MACpD,OAAO,IAAP;IACD;;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,aAAf,CAA6B,KAA7B,CAAnB;IACA,cAAc,CAAC,IAAf,CAAoB,WAApB,CAAgC,UAAhC;IAEA,OAAO,UAAP;EACD,CATe,EASb,CAAC,cAAD,EAAiB,OAAO,CAAC,QAAzB,CATa,CAAhB,CAT2F,CAoB3F;EACA;EACA;EACA;;EACA,KAAK,CAAC,OAAN,CAAc,MAAK;IACjB,IAAI,OAAJ,EAAa;MACX,MAAM,cAAc,GAAG,SAAS,CAAC,KAAV,CAAgB,GAAhB,EAAqB,MAArB,CAA4B,OAA5B,CAAvB;MAEA,OAAO,CAAC,SAAR,CAAkB,GAAlB,CAAsB,GAAG,cAAzB;MACA,OAAO,CAAC,YAAR,CAAqB,KAArB,EAA4B,GAA5B;MACA,eAAe,CAAC,OAAhB,GAA0B,OAA1B;MAEA,OAAO,MAAK;QACV,OAAO,CAAC,SAAR,CAAkB,MAAlB,CAAyB,GAAG,cAA5B;QACA,OAAO,CAAC,eAAR,CAAwB,KAAxB;MACD,CAHD;IAID;EACF,CAbD,EAaG,CAAC,SAAD,EAAY,GAAZ,EAAiB,OAAjB,EAA0B,eAA1B,CAbH;EAeA,KAAK,CAAC,SAAN,CAAgB,MAAK;IACnB,OAAO,MAAK;;;MACV,CAAA,EAAA,GAAA,OAAO,KAAA,IAAP,IAAA,OAAO,KAAA,KAAA,CAAP,GAAO,KAAA,CAAP,GAAA,OAAO,CAAE,aAAT,MAAsB,IAAtB,IAAsB,EAAA,KAAA,KAAA,CAAtB,GAAsB,KAAA,CAAtB,GAAsB,EAAA,CAAE,WAAF,CAAc,OAAd,CAAtB;IACD,CAFD;EAGD,CAJD,EAIG,CAAC,OAAD,CAJH;EAMA,OAAO,OAAP;AACD,CA9CM","sourcesContent":["import * as React from 'react';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n} from '@fluentui/react-shared-contexts';\nimport { makeStyles, mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\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\nconst useStyles = makeStyles({\n root: {\n position: 'relative',\n zIndex: 1000000,\n },\n});\n\n/**\n * Creates a new element on a document.body to mount portals\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n const { targetDocument, dir } = useFluent();\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n\n const classes = useStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root);\n\n const element = React.useMemo(() => {\n if (targetDocument === undefined || options.disabled) {\n return null;\n }\n\n const newElement = targetDocument.createElement('div');\n targetDocument.body.appendChild(newElement);\n\n return newElement;\n }, [targetDocument, options.disabled]);\n\n // This useMemo call is intentional\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 React.useMemo(() => {\n if (element) {\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }\n }, [className, dir, element, focusVisibleRef]);\n\n React.useEffect(() => {\n return () => {\n element?.parentElement?.removeChild(element);\n };\n }, [element]);\n\n return element;\n};\n"],"sourceRoot":"../src/"}
@@ -7,8 +7,6 @@ exports.usePortalMountNode = void 0;
7
7
 
8
8
  const React = /*#__PURE__*/require("react");
9
9
 
10
- const react_utilities_1 = /*#__PURE__*/require("@fluentui/react-utilities");
11
-
12
10
  const react_shared_contexts_1 = /*#__PURE__*/require("@fluentui/react-shared-contexts");
13
11
 
14
12
  const react_1 = /*#__PURE__*/require("@griffel/react");
@@ -45,8 +43,12 @@ const usePortalMountNode = options => {
45
43
  const newElement = targetDocument.createElement('div');
46
44
  targetDocument.body.appendChild(newElement);
47
45
  return newElement;
48
- }, [targetDocument, options.disabled]);
49
- react_utilities_1.useIsomorphicLayoutEffect(() => {
46
+ }, [targetDocument, options.disabled]); // This useMemo call is intentional
47
+ // We don't want to re-create the portal element when its attributes change.
48
+ // This also should not be done in an effect because, changing the value of css variables
49
+ // after initial mount can trigger interesting CSS side effects like transitions.
50
+
51
+ React.useMemo(() => {
50
52
  if (element) {
51
53
  const classesToApply = className.split(' ').filter(Boolean);
52
54
  element.classList.add(...classesToApply);
@@ -1 +1 @@
1
- {"version":3,"sources":["components/Portal/usePortalMountNode.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,KAAA,gBAAA,OAAA,CAAA,OAAA,CAAA;;AACA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;;AACA,MAAA,uBAAA,gBAAA,OAAA,CAAA,iCAAA,CAAA;;AAIA,MAAA,OAAA,gBAAA,OAAA,CAAA,gBAAA,CAAA;;AACA,MAAA,eAAA,gBAAA,OAAA,CAAA,yBAAA,CAAA;;AASA,MAAM,SAAS,gBAAG,OAAA,SAAA;EAAA;IAAA;IAAA;EAAA;AAAA;EAAA;AAAA,EAAlB;AAOA;;AAEG;;;AACI,MAAM,kBAAkB,GAAI,OAAD,IAA2D;EAC3F,MAAM;IAAE,cAAF;IAAkB;EAAlB,IAA0B,uBAAA,CAAA,kBAAA,EAAhC;EACA,MAAM,eAAe,GAAG,eAAA,CAAA,eAAA,EAAxB;EAEA,MAAM,OAAO,GAAG,SAAS,EAAzB;EACA,MAAM,cAAc,GAAG,uBAAA,CAAA,0BAAA,EAAvB;EAEA,MAAM,SAAS,GAAG,OAAA,CAAA,YAAA,CAAa,cAAb,EAA6B,OAAO,CAAC,IAArC,CAAlB;EAEA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAN,CAAc,MAAK;IACjC,IAAI,cAAc,KAAK,SAAnB,IAAgC,OAAO,CAAC,QAA5C,EAAsD;MACpD,OAAO,IAAP;IACD;;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,aAAf,CAA6B,KAA7B,CAAnB;IACA,cAAc,CAAC,IAAf,CAAoB,WAApB,CAAgC,UAAhC;IAEA,OAAO,UAAP;EACD,CATe,EASb,CAAC,cAAD,EAAiB,OAAO,CAAC,QAAzB,CATa,CAAhB;EAWA,iBAAA,CAAA,yBAAA,CAA0B,MAAK;IAC7B,IAAI,OAAJ,EAAa;MACX,MAAM,cAAc,GAAG,SAAS,CAAC,KAAV,CAAgB,GAAhB,EAAqB,MAArB,CAA4B,OAA5B,CAAvB;MAEA,OAAO,CAAC,SAAR,CAAkB,GAAlB,CAAsB,GAAG,cAAzB;MACA,OAAO,CAAC,YAAR,CAAqB,KAArB,EAA4B,GAA5B;MACA,eAAe,CAAC,OAAhB,GAA0B,OAA1B;MAEA,OAAO,MAAK;QACV,OAAO,CAAC,SAAR,CAAkB,MAAlB,CAAyB,GAAG,cAA5B;QACA,OAAO,CAAC,eAAR,CAAwB,KAAxB;MACD,CAHD;IAID;EACF,CAbD,EAaG,CAAC,SAAD,EAAY,GAAZ,EAAiB,OAAjB,EAA0B,eAA1B,CAbH;EAeA,KAAK,CAAC,SAAN,CAAgB,MAAK;IACnB,OAAO,MAAK;;;MACV,CAAA,EAAA,GAAA,OAAO,KAAA,IAAP,IAAA,OAAO,KAAA,KAAA,CAAP,GAAO,KAAA,CAAP,GAAA,OAAO,CAAE,aAAT,MAAsB,IAAtB,IAAsB,EAAA,KAAA,KAAA,CAAtB,GAAsB,KAAA,CAAtB,GAAsB,EAAA,CAAE,WAAF,CAAc,OAAd,CAAtB;IACD,CAFD;EAGD,CAJD,EAIG,CAAC,OAAD,CAJH;EAMA,OAAO,OAAP;AACD,CA1CM;;AAAM,OAAA,CAAA,kBAAA,GAAkB,kBAAlB","sourcesContent":["import * as React from 'react';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n} from '@fluentui/react-shared-contexts';\nimport { makeStyles, mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\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\nconst useStyles = makeStyles({\n root: {\n position: 'relative',\n zIndex: 1000000,\n },\n});\n\n/**\n * Creates a new element on a document.body to mount portals\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n const { targetDocument, dir } = useFluent();\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n\n const classes = useStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root);\n\n const element = React.useMemo(() => {\n if (targetDocument === undefined || options.disabled) {\n return null;\n }\n\n const newElement = targetDocument.createElement('div');\n targetDocument.body.appendChild(newElement);\n\n return newElement;\n }, [targetDocument, options.disabled]);\n\n useIsomorphicLayoutEffect(() => {\n if (element) {\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }\n }, [className, dir, element, focusVisibleRef]);\n\n React.useEffect(() => {\n return () => {\n element?.parentElement?.removeChild(element);\n };\n }, [element]);\n\n return element;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/Portal/usePortalMountNode.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,KAAA,gBAAA,OAAA,CAAA,OAAA,CAAA;;AACA,MAAA,uBAAA,gBAAA,OAAA,CAAA,iCAAA,CAAA;;AAIA,MAAA,OAAA,gBAAA,OAAA,CAAA,gBAAA,CAAA;;AACA,MAAA,eAAA,gBAAA,OAAA,CAAA,yBAAA,CAAA;;AASA,MAAM,SAAS,gBAAG,OAAA,SAAA;EAAA;IAAA;IAAA;EAAA;AAAA;EAAA;AAAA,EAAlB;AAOA;;AAEG;;;AACI,MAAM,kBAAkB,GAAI,OAAD,IAA2D;EAC3F,MAAM;IAAE,cAAF;IAAkB;EAAlB,IAA0B,uBAAA,CAAA,kBAAA,EAAhC;EACA,MAAM,eAAe,GAAG,eAAA,CAAA,eAAA,EAAxB;EAEA,MAAM,OAAO,GAAG,SAAS,EAAzB;EACA,MAAM,cAAc,GAAG,uBAAA,CAAA,0BAAA,EAAvB;EAEA,MAAM,SAAS,GAAG,OAAA,CAAA,YAAA,CAAa,cAAb,EAA6B,OAAO,CAAC,IAArC,CAAlB;EAEA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAN,CAAc,MAAK;IACjC,IAAI,cAAc,KAAK,SAAnB,IAAgC,OAAO,CAAC,QAA5C,EAAsD;MACpD,OAAO,IAAP;IACD;;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,aAAf,CAA6B,KAA7B,CAAnB;IACA,cAAc,CAAC,IAAf,CAAoB,WAApB,CAAgC,UAAhC;IAEA,OAAO,UAAP;EACD,CATe,EASb,CAAC,cAAD,EAAiB,OAAO,CAAC,QAAzB,CATa,CAAhB,CAT2F,CAoB3F;EACA;EACA;EACA;;EACA,KAAK,CAAC,OAAN,CAAc,MAAK;IACjB,IAAI,OAAJ,EAAa;MACX,MAAM,cAAc,GAAG,SAAS,CAAC,KAAV,CAAgB,GAAhB,EAAqB,MAArB,CAA4B,OAA5B,CAAvB;MAEA,OAAO,CAAC,SAAR,CAAkB,GAAlB,CAAsB,GAAG,cAAzB;MACA,OAAO,CAAC,YAAR,CAAqB,KAArB,EAA4B,GAA5B;MACA,eAAe,CAAC,OAAhB,GAA0B,OAA1B;MAEA,OAAO,MAAK;QACV,OAAO,CAAC,SAAR,CAAkB,MAAlB,CAAyB,GAAG,cAA5B;QACA,OAAO,CAAC,eAAR,CAAwB,KAAxB;MACD,CAHD;IAID;EACF,CAbD,EAaG,CAAC,SAAD,EAAY,GAAZ,EAAiB,OAAjB,EAA0B,eAA1B,CAbH;EAeA,KAAK,CAAC,SAAN,CAAgB,MAAK;IACnB,OAAO,MAAK;;;MACV,CAAA,EAAA,GAAA,OAAO,KAAA,IAAP,IAAA,OAAO,KAAA,KAAA,CAAP,GAAO,KAAA,CAAP,GAAA,OAAO,CAAE,aAAT,MAAsB,IAAtB,IAAsB,EAAA,KAAA,KAAA,CAAtB,GAAsB,KAAA,CAAtB,GAAsB,EAAA,CAAE,WAAF,CAAc,OAAd,CAAtB;IACD,CAFD;EAGD,CAJD,EAIG,CAAC,OAAD,CAJH;EAMA,OAAO,OAAP;AACD,CA9CM;;AAAM,OAAA,CAAA,kBAAA,GAAkB,kBAAlB","sourcesContent":["import * as React from 'react';\nimport {\n useThemeClassName_unstable as useThemeClassName,\n useFluent_unstable as useFluent,\n} from '@fluentui/react-shared-contexts';\nimport { makeStyles, mergeClasses } from '@griffel/react';\nimport { useFocusVisible } from '@fluentui/react-tabster';\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\nconst useStyles = makeStyles({\n root: {\n position: 'relative',\n zIndex: 1000000,\n },\n});\n\n/**\n * Creates a new element on a document.body to mount portals\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions): HTMLElement | null => {\n const { targetDocument, dir } = useFluent();\n const focusVisibleRef = useFocusVisible<HTMLDivElement>() as React.MutableRefObject<HTMLElement | null>;\n\n const classes = useStyles();\n const themeClassName = useThemeClassName();\n\n const className = mergeClasses(themeClassName, classes.root);\n\n const element = React.useMemo(() => {\n if (targetDocument === undefined || options.disabled) {\n return null;\n }\n\n const newElement = targetDocument.createElement('div');\n targetDocument.body.appendChild(newElement);\n\n return newElement;\n }, [targetDocument, options.disabled]);\n\n // This useMemo call is intentional\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 React.useMemo(() => {\n if (element) {\n const classesToApply = className.split(' ').filter(Boolean);\n\n element.classList.add(...classesToApply);\n element.setAttribute('dir', dir);\n focusVisibleRef.current = element;\n\n return () => {\n element.classList.remove(...classesToApply);\n element.removeAttribute('dir');\n };\n }\n }, [className, dir, element, focusVisibleRef]);\n\n React.useEffect(() => {\n return () => {\n element?.parentElement?.removeChild(element);\n };\n }, [element]);\n\n return element;\n};\n"],"sourceRoot":"../src/"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@fluentui/react-portal",
3
- "version": "9.0.8",
3
+ "version": "9.0.10",
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",
7
- "typings": "dist/index.d.ts",
7
+ "typings": "./dist/index.d.ts",
8
8
  "sideEffects": false,
9
9
  "repository": {
10
10
  "type": "git",
@@ -31,10 +31,10 @@
31
31
  "@fluentui/scripts": "^1.0.0"
32
32
  },
33
33
  "dependencies": {
34
- "@fluentui/react-shared-contexts": "^9.0.2",
35
- "@fluentui/react-tabster": "^9.2.0",
36
- "@fluentui/react-utilities": "^9.1.2",
37
- "@griffel/react": "^1.4.1",
34
+ "@fluentui/react-shared-contexts": "^9.1.1",
35
+ "@fluentui/react-tabster": "^9.3.0",
36
+ "@fluentui/react-utilities": "^9.2.1",
37
+ "@griffel/react": "^1.4.2",
38
38
  "tslib": "^2.1.0"
39
39
  },
40
40
  "peerDependencies": {
@@ -51,9 +51,10 @@
51
51
  },
52
52
  "exports": {
53
53
  ".": {
54
- "types": "./lib/index.d.ts",
54
+ "types": "./dist/index.d.ts",
55
55
  "import": "./lib/index.js",
56
56
  "require": "./lib-commonjs/index.js"
57
- }
57
+ },
58
+ "./package.json": "./package.json"
58
59
  }
59
60
  }
package/Spec.md DELETED
@@ -1,254 +0,0 @@
1
- # Portal Spec
2
-
3
- ## Background
4
-
5
- Components that require positioning out of the normal DOM order such as Menu and Tooltip are generally rendered through React portals. This is very useful when the components need to break out of the bounds of a parent component so that the content is not overflowed or covered by another element with zIndex. Portals also support event bubbling in the React tree.
6
-
7
- Since our styling system uses css variables that are written onto DOM, we need to ensure that all portals are rendered onto a part of the DOM where the css variables are available.
8
-
9
- Portals also need need to include the same dir attribute as the parent react tree, so that RTL/LTR is displayed correctly in the portal and the parent content.
10
-
11
- ## Prior Art
12
-
13
- Open UI research was not done for this component. `Portal` does not actually represent a UI control, but a utility component specific to React that makes the rendering of out of order DOM elements easy from within the React tree.
14
-
15
- ### v0/v8 Comparison
16
-
17
- This section compares the noteworthy differences/similarities between the `Layer` and `Portal` components of v8 and v0 respectively that share functionality with this proposed converged component.
18
-
19
- #### Portal Trigger
20
-
21
- The v0 Portal component includes a `trigger` prop that allows consumers to open a React portal. The adoption is not widely used across v0's main consumer, Teams.
22
-
23
- The v8 `Layer` component fills a similar role to `PortalInner` which is the component that actually renders a React portal.
24
-
25
- #### Event propagation
26
-
27
- v8 `Layer` users must explicitly use the `enableEventBubbling` behaviour, which is default in React portals. This is mainly because `Layer` is older than `React.Portal`. Since synthetic event propagation was only introduced with React portals, it had to be enabled to preserve backwards compat.
28
-
29
- Meanwhile v0 does not allow any kind of way to disable native React event bubbling through portals, to achieve a similar effect, the user must manage this themselves.
30
-
31
- #### DOM insertion
32
-
33
- Both `Layer` and `Portal` allow insertion of portals to the same part of the DOM element.
34
-
35
- v8 Layer does this through a `LayerHost` which can be rendered at any part of the React tree. The result is a HTMLDiv element with a specific CSS class and unique Id. `Layer` will attempt to find a `LayerHost` to mount either by CSS class or user provided `hostId`. The default fallback is `document.body`. Each `Layer` will render its own `Fabric` provider. The `insertFirst` property supported by `Layer` was introduced in #8065 for modeless Dialogs which was achieved through `position: static` and DOM insertion order. The same effect can be achieved through `pointer-events: none`.
36
-
37
- The v0 `PortalBoxContext` stores a single HTMLDiv that is usually a child of `document.body` where all `Portal` components are rendered by default. The v0 `Provider` is rendered for the default portal element, where style and RTL overrides could be applied for all portals within.
38
-
39
- #### Lifecycle methods
40
-
41
- v0 `Portal` only supports the following lifecycle methods:
42
-
43
- - onMount
44
- - onUnmount
45
-
46
- `Layer` supports the following:
47
-
48
- - onLayerMounted
49
- - onLayerWillUnmount
50
-
51
- The lifecycle events are very similar, with the only difference being that `onLayerWillUnmount` is called with `hostId` changes. v0 does not consider the mountNode changing as an unmount of the component itself.
52
-
53
- #### Focus Management
54
-
55
- v0 `Portal` can be configured to focus trap its contents while v8 `Layer` does not offer this and users would need to use `FocusTrapZone` for this purpose.
56
-
57
- ## Sample Code
58
-
59
- `Portal` by default mounts the content to `document.body`. In the event a consumer needs to target a specific mount node for Portal content this should be configurable via prop. Both variants should still be able to access theme and fluent context if available.
60
-
61
- ```
62
- const customElement = document.createElement('div');
63
-
64
- <App> // using FluentProvider of ThemeProvider but not PortalProvider
65
- <Portal /> // attached to document.body
66
- <Portal mountNode={customElement} /> // mounted on custom element
67
- </App>
68
- ```
69
-
70
- `Portal` should be used as a component at any part of the React tree:
71
-
72
- ```tsx
73
- <ContextProvider>
74
- <Portal>
75
- <ContextConsumer /> // should be able to access context
76
- </Portal>
77
- </ContextProvider>
78
- ```
79
-
80
- `Portal` should be able to access theme values as css variables:
81
-
82
- ```tsx
83
- const useStyles = makeStyles({
84
- portalContent: theme => {...}
85
- })
86
-
87
-
88
- const styles = useStyles();
89
-
90
- <ThemeProvider>
91
- <Portal>
92
- <div className={styles.portalContent}>
93
- Can use all theme CSS variables from the parent ThemeProvider
94
- </div>
95
- </Portal>
96
- </ThemeProvider>
97
- ```
98
-
99
- ## Variants
100
-
101
- - Mounting the portal on a custom node
102
-
103
- ## API
104
-
105
- ### Portal
106
-
107
- | Name | Description | Required | Type | Default value |
108
- | --------- | -------------------------------------- | -------- | ----------- | -------------------------------- |
109
- | mountNode | Where the portal is mounted to the DOM | No | HTMLElement | ProviderContext or document.body |
110
-
111
- ### Virtual parents
112
-
113
- Out of order DOM elements can be problematic when using 'click outside' event listeners since you cannot rely on `element.contains(event.target)` because the `Portal` elements are out of DOM order.
114
-
115
- ```tsx
116
-
117
- const outerButtonRef = React.useRef();
118
- const innerButtonRef = React.useRef();
119
-
120
-
121
- <Portal>
122
- <div>
123
- <button ref={outerButtonRef}> Outer button </button>
124
- <Portal>
125
- <div>
126
- <button ref={innerButtonRef}> Inner button </button>
127
- </div>
128
- </Portal>
129
- </div>
130
- </Portal>
131
-
132
- // DOM output
133
- <div>
134
- <button>Outer button</button>
135
- </div>
136
-
137
- <div>
138
- <button>Inner button</button>
139
- </div>
140
-
141
- // Let's add an event listener to 'dismss' the outer portal when clicked outside
142
- // ⚠⚠⚠ This will always be called when clicking on the inner button
143
- document.addEventListener((event) => {
144
- if (outerButtonRef.current.contains(event.target)) {
145
- dismissOuterPortal();
146
- }
147
- })
148
- ```
149
-
150
- When the above case is not required, using `element.contains` is perfectly fine. But nested cases should still be handled appropriately. We do this using the concept of `virtual parents`
151
-
152
- `Portal` will make public 2 utilities that will only be used in cases where the user needs to know if an out of order DOM element will need to be used or not.
153
-
154
- - `setVirtualParent` - sets virtual parent
155
- - `elementContains` - similar to `element.contains` but uses the virtual hierarchy as reference
156
-
157
- Below shows what a virtual parent is
158
-
159
- ```tsx
160
- // Setting a virtual parent
161
-
162
- const parent document.getElementById('parent')
163
- const child document.getElement.ById('child');
164
-
165
- child._virtual.parent = parent;
166
- ```
167
-
168
- ## Structure
169
-
170
- ```tsx
171
- <FluentProvider>
172
- <Portal id="portal-1" />
173
- <Portal id="portal-2" />
174
- </FluentProvider>
175
- ```
176
-
177
- DOM output:
178
-
179
- ```tsx
180
- <body>
181
- <div>
182
- {/* Virtual parent for portal*/}
183
- <span aria-hidden />
184
- {/* Virtual parent for portal*/}
185
- <span aria-hidden />
186
- </div>
187
-
188
- <div id="portal-1" class="theme-provider-0">
189
- {children}
190
- </div>
191
- <div id="portal-2" class="theme-provider-0">
192
- {children}
193
- </div>
194
- </body>
195
- ```
196
-
197
- ```tsx
198
- <FluentProvider>
199
- <Portal id="portal-1">
200
- <Portal id="portal-2" />
201
- </Portal>
202
- </FluentProvider>
203
- ```
204
-
205
- DOM output:
206
-
207
- ```tsx
208
- <body>
209
- <div>
210
- {/* Virtual parent for outer portal*/}
211
- <span aria-hidden></span>
212
- </div>
213
-
214
- <div id="portal-1" class="theme-provider-0">
215
- {/* Virtual parent for inner portal*/}
216
- <span aria-hidden />
217
- {children}
218
- </div>
219
- <div id="portal-2" class="theme-provider-0">
220
- {children}
221
- </div>
222
- </body>
223
- ```
224
-
225
- ## Migration
226
-
227
- _Describe what will need to be done to upgrade from the existing implementations:_
228
-
229
- ### v8 migration
230
-
231
- - There will be no way to disable event bubbling, it will be up to consumers to call `stopPropagation` themselves or create extra utilities that do so
232
- - No more concept of `LayerHost` and id/class selectors, raw HTML elements/refs can be stored in context on the consumer app and used in `mountNode` for `Portals` if required
233
- - No more mount lifecycle methods, users can remedy this easily with `useEffect` or `useLayoutEffect` hooks
234
- - `insertFirst` will no longer be supported, and can be handled by a custom `mountNode` if necessary, sticky Dialog can be implmented with `pointer-events: none`
235
-
236
- ### v0 migration
237
-
238
- - No more openable portals - should use future converged `Popup`
239
- - No more focus trapping in `Portals` do that manually (Tabster)
240
- - No more mount lifecycle methods, users can remedy this easily with `useEffect` or `useLayoutEffect` hooks
241
-
242
- ## Behaviors
243
-
244
- ### Server Side Rendering (SSR)
245
-
246
- The ReactDOM `createPortal` requires a valid DOM node to render. This is problematic when `document` does not actually exist during the server render. Instead during the server render `null` will be used. This is not a big problem for most components that use portals such as popups or dialogs since they must be opened from some kind of trigger element (i.e. button)
247
-
248
- However, there are some cases where a `Portal` content will always need to be rendered on the page. Tooltips should always be rendered so that `aria` attributes will refer to actual elements. This is problematic since the Tooltip (or higher order component) needs to be aware of the server render where `null`is rendered and render the actual content on the first client render.
249
-
250
- The `Portal` component should handle this SSR case, and should be aware of the server and client renders when calling `ReactDOM.createPortal`.
251
-
252
- ## Accessibility
253
-
254
- This component is considered a utility to render its children to an out of order DOM element. Since the component itself does not render DOM it is up to the consumer to handle the A11y requirements of their portal content.