@fluentui/react-portal 9.0.0-alpha.8 → 9.0.0-nightly.25435def33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. package/CHANGELOG.json +1486 -1
  2. package/CHANGELOG.md +568 -2
  3. package/README.md +114 -0
  4. package/Spec.md +100 -6
  5. package/dist/react-portal.d.ts +30 -9
  6. package/lib/Portal.js.map +1 -1
  7. package/lib/common/isConformant.d.ts +4 -2
  8. package/lib/common/isConformant.js.map +1 -1
  9. package/lib/components/Portal/Portal.d.ts +1 -1
  10. package/lib/components/Portal/Portal.js.map +1 -1
  11. package/lib/components/Portal/Portal.types.d.ts +11 -6
  12. package/lib/components/Portal/Portal.types.js.map +1 -1
  13. package/lib/components/Portal/index.js.map +1 -1
  14. package/lib/components/Portal/renderPortal.d.ts +2 -2
  15. package/lib/components/Portal/renderPortal.js +2 -4
  16. package/lib/components/Portal/renderPortal.js.map +1 -1
  17. package/lib/components/Portal/usePortal.d.ts +2 -3
  18. package/lib/components/Portal/usePortal.js +18 -8
  19. package/lib/components/Portal/usePortal.js.map +1 -1
  20. package/lib/components/Portal/usePortalMountNode.js +2 -0
  21. package/lib/components/Portal/usePortalMountNode.js.map +1 -1
  22. package/lib/index.d.ts +1 -0
  23. package/lib/index.js +1 -0
  24. package/lib/index.js.map +1 -1
  25. package/lib/tsdoc-metadata.json +1 -1
  26. package/lib/virtualParent/elementContains.d.ts +7 -0
  27. package/lib/virtualParent/elementContains.js +26 -0
  28. package/lib/virtualParent/elementContains.js.map +1 -0
  29. package/lib/virtualParent/getParent.d.ts +5 -0
  30. package/lib/virtualParent/getParent.js +9 -0
  31. package/lib/virtualParent/getParent.js.map +1 -0
  32. package/lib/virtualParent/getVirtualParent.d.ts +4 -0
  33. package/lib/virtualParent/getVirtualParent.js +12 -0
  34. package/lib/virtualParent/getVirtualParent.js.map +1 -0
  35. package/lib/virtualParent/index.d.ts +5 -0
  36. package/lib/virtualParent/index.js +6 -0
  37. package/lib/virtualParent/index.js.map +1 -0
  38. package/lib/virtualParent/isVirtualElement.d.ts +5 -0
  39. package/lib/virtualParent/isVirtualElement.js +7 -0
  40. package/lib/virtualParent/isVirtualElement.js.map +1 -0
  41. package/lib/virtualParent/setVirtualParent.d.ts +7 -0
  42. package/lib/virtualParent/setVirtualParent.js +17 -0
  43. package/lib/virtualParent/setVirtualParent.js.map +1 -0
  44. package/lib/virtualParent/types.d.ts +5 -0
  45. package/lib/virtualParent/types.js +2 -0
  46. package/lib/virtualParent/types.js.map +1 -0
  47. package/lib-commonjs/Portal.js.map +1 -1
  48. package/lib-commonjs/common/isConformant.d.ts +4 -2
  49. package/lib-commonjs/common/isConformant.js.map +1 -1
  50. package/lib-commonjs/components/Portal/Portal.d.ts +1 -1
  51. package/lib-commonjs/components/Portal/Portal.js.map +1 -1
  52. package/lib-commonjs/components/Portal/Portal.types.d.ts +11 -6
  53. package/lib-commonjs/components/Portal/Portal.types.js.map +1 -1
  54. package/lib-commonjs/components/Portal/index.js.map +1 -1
  55. package/lib-commonjs/components/Portal/renderPortal.d.ts +2 -2
  56. package/lib-commonjs/components/Portal/renderPortal.js +2 -4
  57. package/lib-commonjs/components/Portal/renderPortal.js.map +1 -1
  58. package/lib-commonjs/components/Portal/usePortal.d.ts +2 -3
  59. package/lib-commonjs/components/Portal/usePortal.js +17 -7
  60. package/lib-commonjs/components/Portal/usePortal.js.map +1 -1
  61. package/lib-commonjs/components/Portal/usePortalMountNode.js +2 -0
  62. package/lib-commonjs/components/Portal/usePortalMountNode.js.map +1 -1
  63. package/lib-commonjs/index.d.ts +1 -0
  64. package/lib-commonjs/index.js +4 -0
  65. package/lib-commonjs/index.js.map +1 -1
  66. package/lib-commonjs/virtualParent/elementContains.d.ts +7 -0
  67. package/lib-commonjs/virtualParent/elementContains.js +30 -0
  68. package/lib-commonjs/virtualParent/elementContains.js.map +1 -0
  69. package/lib-commonjs/virtualParent/getParent.d.ts +5 -0
  70. package/lib-commonjs/virtualParent/getParent.js +13 -0
  71. package/lib-commonjs/virtualParent/getParent.js.map +1 -0
  72. package/lib-commonjs/virtualParent/getVirtualParent.d.ts +4 -0
  73. package/lib-commonjs/virtualParent/getVirtualParent.js +16 -0
  74. package/lib-commonjs/virtualParent/getVirtualParent.js.map +1 -0
  75. package/lib-commonjs/virtualParent/index.d.ts +5 -0
  76. package/lib-commonjs/virtualParent/index.js +9 -0
  77. package/lib-commonjs/virtualParent/index.js.map +1 -0
  78. package/lib-commonjs/virtualParent/isVirtualElement.d.ts +5 -0
  79. package/lib-commonjs/virtualParent/isVirtualElement.js +11 -0
  80. package/lib-commonjs/virtualParent/isVirtualElement.js.map +1 -0
  81. package/lib-commonjs/virtualParent/setVirtualParent.d.ts +7 -0
  82. package/lib-commonjs/virtualParent/setVirtualParent.js +21 -0
  83. package/lib-commonjs/virtualParent/setVirtualParent.js.map +1 -0
  84. package/lib-commonjs/virtualParent/types.d.ts +5 -0
  85. package/lib-commonjs/virtualParent/types.js +3 -0
  86. package/lib-commonjs/virtualParent/types.js.map +1 -0
  87. package/package.json +15 -12
  88. package/config/api-extractor.json +0 -3
  89. package/config/tests.js +0 -7
  90. package/etc/react-portal.api.md +0 -32
  91. package/just.config.ts +0 -3
  92. package/lib-amd/Portal.d.ts +0 -1
  93. package/lib-amd/Portal.js +0 -6
  94. package/lib-amd/Portal.js.map +0 -1
  95. package/lib-amd/common/isConformant.d.ts +0 -2
  96. package/lib-amd/common/isConformant.js +0 -14
  97. package/lib-amd/common/isConformant.js.map +0 -1
  98. package/lib-amd/components/Portal/Portal.d.ts +0 -6
  99. package/lib-amd/components/Portal/Portal.js +0 -15
  100. package/lib-amd/components/Portal/Portal.js.map +0 -1
  101. package/lib-amd/components/Portal/Portal.types.d.ts +0 -16
  102. package/lib-amd/components/Portal/Portal.types.js +0 -5
  103. package/lib-amd/components/Portal/Portal.types.js.map +0 -1
  104. package/lib-amd/components/Portal/index.d.ts +0 -4
  105. package/lib-amd/components/Portal/index.js +0 -9
  106. package/lib-amd/components/Portal/index.js.map +0 -1
  107. package/lib-amd/components/Portal/renderPortal.d.ts +0 -6
  108. package/lib-amd/components/Portal/renderPortal.js +0 -16
  109. package/lib-amd/components/Portal/renderPortal.js.map +0 -1
  110. package/lib-amd/components/Portal/usePortal.d.ts +0 -10
  111. package/lib-amd/components/Portal/usePortal.js +0 -23
  112. package/lib-amd/components/Portal/usePortal.js.map +0 -1
  113. package/lib-amd/components/Portal/usePortalMountNode.d.ts +0 -10
  114. package/lib-amd/components/Portal/usePortalMountNode.js +0 -31
  115. package/lib-amd/components/Portal/usePortalMountNode.js.map +0 -1
  116. package/lib-amd/index.d.ts +0 -1
  117. package/lib-amd/index.js +0 -6
  118. package/lib-amd/index.js.map +0 -1
  119. package/src/components/Portal/Portal.types.ts +0 -24
package/README.md CHANGED
@@ -31,3 +31,117 @@ const node = document.getElementById('customNode');
31
31
  ### Styling
32
32
 
33
33
  `Portal` renders React children directly to the default/configured DOM node. Therefore styling should be applied to the `children` by users directly.
34
+
35
+ ### Virtual parents
36
+
37
+ 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.
38
+
39
+ ```tsx
40
+
41
+ const outerButtonRef = React.useRef();
42
+ const innerButtonRef = React.useRef();
43
+
44
+
45
+ <Portal>
46
+ <div>
47
+ <button ref={outerButtonRef}> Outer button </button>
48
+ <Portal>
49
+ <div>
50
+ <button ref={innerButtonRef}> Inner button </button>
51
+ </div>
52
+ </Portal>
53
+ </div>
54
+ </Portal>
55
+
56
+ // DOM output
57
+ <div>
58
+ <button>Outer button</button>
59
+ </div>
60
+
61
+ <div>
62
+ <button>Inner button</button>
63
+ </div>
64
+
65
+ // Let's add an event listener to 'dismss' the outer portal when clicked outside
66
+ // ⚠⚠⚠ This will always be called when clicking on the inner button
67
+ document.addEventListener((event) => {
68
+ if (outerButtonRef.current.contains(event.target)) {
69
+ dismissOuterPortal();
70
+ }
71
+ })
72
+ ```
73
+
74
+ 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`
75
+
76
+ `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.
77
+
78
+ - `setVirtualParent` - sets virtual parent. Portal uses this already internally.
79
+ - `elementContains` - similar to `element.contains` but uses the virtual hierarchy as reference
80
+
81
+ Below shows what a virtual parent is
82
+
83
+ ```tsx
84
+ // Setting a virtual parent
85
+
86
+ const parent document.getElementById('parent')
87
+ const child document.getElement.ById('child');
88
+
89
+ child._virtual.parent = parent;
90
+ ```
91
+
92
+ `Portals` will render a hidden span that will be the virtual parent, by nesting portals virtual parens will also be nested so that `elementContains` will work predictably.
93
+
94
+ ```tsx
95
+ <FluentProvider>
96
+ <Portal id="portal-1" />
97
+ <Portal id="portal-2" />
98
+ </FluentProvider>
99
+ ```
100
+
101
+ DOM output:
102
+
103
+ ```tsx
104
+ <body>
105
+ <div>
106
+ {/* Virtual parent for portal*/}
107
+ <span aria-hidden />
108
+ {/* Virtual parent for portal*/}
109
+ <span aria-hidden />
110
+ </div>
111
+
112
+ <div id="portal-1" class="theme-provider-0">
113
+ {children}
114
+ </div>
115
+ <div id="portal-2" class="theme-provider-0">
116
+ {children}
117
+ </div>
118
+ </body>
119
+ ```
120
+
121
+ ```tsx
122
+ <FluentProvider>
123
+ <Portal id="portal-1">
124
+ <Portal id="portal-2" />
125
+ </Portal>
126
+ </FluentProvider>
127
+ ```
128
+
129
+ DOM output:
130
+
131
+ ```tsx
132
+ <body>
133
+ <div>
134
+ {/* Virtual parent for outer portal*/}
135
+ <span aria-hidden></span>
136
+ </div>
137
+
138
+ <div id="portal-1" class="theme-provider-0">
139
+ {/* Virtual parent for inner portal*/}
140
+ <span aria-hidden />
141
+ {children}
142
+ </div>
143
+ <div id="portal-2" class="theme-provider-0">
144
+ {children}
145
+ </div>
146
+ </body>
147
+ ```
package/Spec.md CHANGED
@@ -108,23 +108,117 @@ const styles = useStyles();
108
108
  | --------- | -------------------------------------- | -------- | ----------- | -------------------------------- |
109
109
  | mountNode | Where the portal is mounted to the DOM | No | HTMLElement | ProviderContext or document.body |
110
110
 
111
- ## Structure
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();
112
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
+ })
113
148
  ```
114
- <FluentProvider
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>
115
172
  <Portal id="portal-1" />
116
173
  <Portal id="portal-2" />
117
- </FluentProvider
174
+ </FluentProvider>
118
175
  ```
119
176
 
120
177
  DOM output:
121
178
 
122
179
  ```tsx
123
180
  <body>
124
- <div>Maintree</div>
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
+ ```
125
196
 
126
- <div id="portal-1" class="theme-provider-0"}>{children}</div>
127
- <div id="portal-2" class="theme-provider-0"}>{children}</div>
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>
128
222
  </body>
129
223
  ```
130
224
 
@@ -1,31 +1,53 @@
1
1
  import * as React_2 from 'react';
2
2
 
3
+ /**
4
+ * Similar functionality to `element.contains` DOM API for use with out of order DOM elements that
5
+ * checks the virtual parent hierarchy. If a virtual parents exists, it is chosen over the actual parent
6
+ *
7
+ * @returns true if the child can find the parent in its virtual hierarchy
8
+ */
9
+ export declare function elementContains(parent: HTMLElement | null, child: HTMLElement | null): boolean;
10
+
3
11
  /**
4
12
  * Component that renders children in a React portal
5
13
  */
6
14
  export declare const Portal: React_2.FC<PortalProps>;
7
15
 
8
- export declare interface PortalProps {
16
+ export declare type PortalCommons = {
9
17
  /**
10
18
  * React children
11
19
  */
12
- children?: React_2.ReactNode;
20
+ children: React_2.ReactNode;
13
21
  /**
14
22
  * Where the portal children are mounted on DOM
15
23
  * @defaultValue a new element on document.body without any styling
16
24
  */
17
- mountNode?: HTMLDivElement | null;
18
- }
25
+ mountNode: HTMLDivElement | undefined;
26
+ };
27
+
28
+ export declare type PortalProps = Partial<PortalCommons>;
19
29
 
20
- export declare interface PortalState extends PortalProps {
30
+ export declare type PortalState = PortalCommons & {
21
31
  /** Indicates if a Portal should be rendered. */
22
32
  shouldRender: boolean;
23
- }
33
+ /**
34
+ * Ref to the root span element as virtual parent
35
+ */
36
+ virtualParentRootRef: React_2.MutableRefObject<HTMLSpanElement | null>;
37
+ };
24
38
 
25
39
  /**
26
40
  * Render the final JSX of Portal
27
41
  */
28
- export declare const renderPortal: (state: PortalState) => React_2.ReactPortal | null;
42
+ export declare const renderPortal: (state: PortalState) => React_2.ReactElement;
43
+
44
+ /**
45
+ * Sets the virtual parent of an element.
46
+ *
47
+ * @param child - Theme element to set the virtual parent
48
+ * @param parent - The virtual parent, use `undefined` to remove a virtual parent relationship
49
+ */
50
+ export declare function setVirtualParent(child: HTMLElement, parent?: HTMLElement): void;
29
51
 
30
52
  /**
31
53
  * Create the state required to render Portal.
@@ -33,8 +55,7 @@ export declare const renderPortal: (state: PortalState) => React_2.ReactPortal |
33
55
  * The returned state can be modified with hooks such as usePortalStyles, before being passed to renderPortal.
34
56
  *
35
57
  * @param props - props from this instance of Portal
36
- * @param defaultProps - (optional) default prop values provided by the implementing type
37
58
  */
38
- export declare const usePortal: (props: PortalProps, defaultProps?: PortalProps | undefined) => PortalState;
59
+ export declare const usePortal: (props: PortalProps) => PortalState;
39
60
 
40
61
  export { }
package/lib/Portal.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Portal.js","sourceRoot":"../src/","sources":["Portal.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC","sourcesContent":["export * from './components/Portal/index';\n"]}
1
+ {"version":3,"file":"Portal.js","sourceRoot":"","sources":["../src/Portal.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC"}
@@ -1,2 +1,4 @@
1
- import { IsConformantOptions } from '@fluentui/react-conformance';
2
- export declare function isConformant(testInfo: Omit<IsConformantOptions, 'componentPath'>): void;
1
+ import type { IsConformantOptions } from '@fluentui/react-conformance';
2
+ export declare function isConformant<TProps = {}>(testInfo: Omit<IsConformantOptions<TProps>, 'componentPath'> & {
3
+ componentPath?: string;
4
+ }): void;
@@ -1 +1 @@
1
- {"version":3,"file":"isConformant.js","sourceRoot":"../src/","sources":["common/isConformant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAuB,MAAM,6BAA6B,CAAC;AAEpG,MAAM,UAAU,YAAY,CAAC,QAAoD;IAC/E,IAAM,cAAc,GAAG;QACrB,gBAAgB,EAAE,IAAI;QACtB,aAAa,EAAE,MAAO,CAAC,MAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;KAC7D,CAAC;IAEF,gBAAgB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { isConformant as baseIsConformant, IsConformantOptions } from '@fluentui/react-conformance';\n\nexport function isConformant(testInfo: Omit<IsConformantOptions, 'componentPath'>) {\n const defaultOptions = {\n asPropHandlesRef: true,\n componentPath: module!.parent!.filename.replace('.test', ''),\n };\n\n baseIsConformant(defaultOptions, testInfo);\n}\n"]}
1
+ {"version":3,"file":"isConformant.js","sourceRoot":"","sources":["../../src/common/isConformant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/E,MAAM,UAAU,YAAY,CAC1B,QAAyF;IAEzF,IAAM,cAAc,GAAyC;QAC3D,gBAAgB,EAAE,IAAI;QACtB,aAAa,EAAE,MAAO,CAAC,MAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;KAC7D,CAAC;IAEF,gBAAgB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAC7C,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { PortalProps } from './Portal.types';
2
+ import type { PortalProps } from './Portal.types';
3
3
  /**
4
4
  * Component that renders children in a React portal
5
5
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Portal.js","sourceRoot":"../src/","sources":["components/Portal/Portal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,IAAM,MAAM,GAA0B,UAAA,KAAK;IAChD,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAE/B,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC","sourcesContent":["import * as React from 'react';\n\nimport { usePortal } from './usePortal';\nimport { PortalProps } from './Portal.types';\nimport { renderPortal } from './renderPortal';\n\n/**\n * Component that renders children in a React portal\n */\nexport const Portal: React.FC<PortalProps> = props => {\n const state = usePortal(props);\n\n return renderPortal(state);\n};\n\nPortal.displayName = 'Portal';\n"]}
1
+ {"version":3,"file":"Portal.js","sourceRoot":"","sources":["../../../src/components/Portal/Portal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,MAAM,CAAC,IAAM,MAAM,GAA0B,UAAA,KAAK;IAChD,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAE/B,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC"}
@@ -1,16 +1,21 @@
1
1
  import * as React from 'react';
2
- export interface PortalProps {
2
+ export declare type PortalCommons = {
3
3
  /**
4
4
  * React children
5
5
  */
6
- children?: React.ReactNode;
6
+ children: React.ReactNode;
7
7
  /**
8
8
  * Where the portal children are mounted on DOM
9
9
  * @defaultValue a new element on document.body without any styling
10
10
  */
11
- mountNode?: HTMLDivElement | null;
12
- }
13
- export interface PortalState extends PortalProps {
11
+ mountNode: HTMLDivElement | undefined;
12
+ };
13
+ export declare type PortalProps = Partial<PortalCommons>;
14
+ export declare type PortalState = PortalCommons & {
14
15
  /** Indicates if a Portal should be rendered. */
15
16
  shouldRender: boolean;
16
- }
17
+ /**
18
+ * Ref to the root span element as virtual parent
19
+ */
20
+ virtualParentRootRef: React.MutableRefObject<HTMLSpanElement | null>;
21
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"Portal.types.js","sourceRoot":"../src/","sources":["components/Portal/Portal.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\n\nexport interface PortalProps {\n /**\n * React children\n */\n children?: React.ReactNode;\n /**\n * Where the portal children are mounted on DOM\n * @defaultValue a new element on document.body without any styling\n */\n mountNode?: HTMLDivElement | null;\n\n /**\n * React events should not bubble up the portal\n */\n // TODO clarify if this is still needed\n // disableEventBubbling?: 'first' | 'last';\n}\n\nexport interface PortalState extends PortalProps {\n /** Indicates if a Portal should be rendered. */\n shouldRender: boolean;\n}\n"]}
1
+ {"version":3,"file":"Portal.types.js","sourceRoot":"","sources":["../../../src/components/Portal/Portal.types.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/Portal/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC","sourcesContent":["export * from './Portal';\nexport * from './Portal.types';\nexport * from './renderPortal';\nexport * from './usePortal';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Portal/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { PortalState } from './Portal.types';
2
+ import type { PortalState } from './Portal.types';
3
3
  /**
4
4
  * Render the final JSX of Portal
5
5
  */
6
- export declare const renderPortal: (state: PortalState) => React.ReactPortal | null;
6
+ export declare const renderPortal: (state: PortalState) => React.ReactElement;
@@ -1,11 +1,9 @@
1
1
  import * as ReactDOM from 'react-dom';
2
+ import * as React from 'react';
2
3
  /**
3
4
  * Render the final JSX of Portal
4
5
  */
5
6
  export var renderPortal = function (state) {
6
- if (state.shouldRender && state.mountNode) {
7
- return ReactDOM.createPortal(state.children, state.mountNode);
8
- }
9
- return null;
7
+ return (React.createElement("span", { hidden: true, ref: state.virtualParentRootRef }, state.shouldRender && state.mountNode && ReactDOM.createPortal(state.children, state.mountNode)));
10
8
  };
11
9
  //# sourceMappingURL=renderPortal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderPortal.js","sourceRoot":"../src/","sources":["components/Portal/renderPortal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAC;AAItC;;GAEG;AACH,MAAM,CAAC,IAAM,YAAY,GAAG,UAAC,KAAkB;IAC7C,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,SAAS,EAAE;QACzC,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;KAC/D;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC","sourcesContent":["import * as ReactDOM from 'react-dom';\nimport * as React from 'react';\nimport { PortalState } from './Portal.types';\n\n/**\n * Render the final JSX of Portal\n */\nexport const renderPortal = (state: PortalState): React.ReactPortal | null => {\n if (state.shouldRender && state.mountNode) {\n return ReactDOM.createPortal(state.children, state.mountNode);\n }\n\n return null;\n};\n"]}
1
+ {"version":3,"file":"renderPortal.js","sourceRoot":"","sources":["../../../src/components/Portal/renderPortal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;GAEG;AACH,MAAM,CAAC,IAAM,YAAY,GAAG,UAAC,KAAkB;IAC7C,OAAO,CACL,8BAAM,MAAM,QAAC,GAAG,EAAE,KAAK,CAAC,oBAAoB,IACzC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,SAAS,IAAI,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAC3F,CACR,CAAC;AACJ,CAAC,CAAC"}
@@ -1,10 +1,9 @@
1
- import { PortalProps, PortalState } from './Portal.types';
1
+ import type { PortalProps, PortalState } from './Portal.types';
2
2
  /**
3
3
  * Create the state required to render Portal.
4
4
  *
5
5
  * The returned state can be modified with hooks such as usePortalStyles, before being passed to renderPortal.
6
6
  *
7
7
  * @param props - props from this instance of Portal
8
- * @param defaultProps - (optional) default prop values provided by the implementing type
9
8
  */
10
- export declare const usePortal: (props: PortalProps, defaultProps?: PortalProps | undefined) => PortalState;
9
+ export declare const usePortal: (props: PortalProps) => PortalState;
@@ -1,19 +1,29 @@
1
- import { makeMergeProps, useIsSSR } from '@fluentui/react-utilities';
1
+ import * as React from 'react';
2
+ import { useIsSSR } from '@fluentui/react-utilities';
2
3
  import { usePortalMountNode } from './usePortalMountNode';
3
- var mergeProps = makeMergeProps();
4
+ import { setVirtualParent } from '../../virtualParent/index';
4
5
  /**
5
6
  * Create the state required to render Portal.
6
7
  *
7
8
  * The returned state can be modified with hooks such as usePortalStyles, before being passed to renderPortal.
8
9
  *
9
10
  * @param props - props from this instance of Portal
10
- * @param defaultProps - (optional) default prop values provided by the implementing type
11
11
  */
12
- export var usePortal = function (props, defaultProps) {
13
- var _a;
14
- var state = mergeProps({ shouldRender: !useIsSSR() }, defaultProps, props);
15
- var fallbackMountNode = usePortalMountNode({ disabled: !!state.mountNode });
16
- state.mountNode = (_a = state.mountNode) !== null && _a !== void 0 ? _a : fallbackMountNode;
12
+ export var usePortal = function (props) {
13
+ var children = props.children, mountNode = props.mountNode;
14
+ var virtualParentRootRef = React.useRef(null);
15
+ var fallbackMountNode = usePortalMountNode({ disabled: !!mountNode });
16
+ var state = {
17
+ children: children,
18
+ mountNode: mountNode !== null && mountNode !== void 0 ? mountNode : fallbackMountNode,
19
+ shouldRender: !useIsSSR(),
20
+ virtualParentRootRef: virtualParentRootRef,
21
+ };
22
+ React.useEffect(function () {
23
+ if (state.virtualParentRootRef.current && state.mountNode) {
24
+ setVirtualParent(state.mountNode, state.virtualParentRootRef.current);
25
+ }
26
+ }, [state.virtualParentRootRef, state.mountNode]);
17
27
  return state;
18
28
  };
19
29
  //# sourceMappingURL=usePortal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePortal.js","sourceRoot":"../src/","sources":["components/Portal/usePortal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAGrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,IAAM,UAAU,GAAG,cAAc,EAAe,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,CAAC,IAAM,SAAS,GAAG,UAAC,KAAkB,EAAE,YAA0B;;IACtE,IAAM,KAAK,GAAG,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IAC7E,IAAM,iBAAiB,GAAG,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;IAE9E,KAAK,CAAC,SAAS,SAAG,KAAK,CAAC,SAAS,mCAAI,iBAAiB,CAAC;IAEvD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["import { makeMergeProps, useIsSSR } from '@fluentui/react-utilities';\n\nimport { PortalProps, PortalState } from './Portal.types';\nimport { usePortalMountNode } from './usePortalMountNode';\n\nconst mergeProps = makeMergeProps<PortalState>();\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.\n *\n * @param props - props from this instance of Portal\n * @param defaultProps - (optional) default prop values provided by the implementing type\n */\nexport const usePortal = (props: PortalProps, defaultProps?: PortalProps): PortalState => {\n const state = mergeProps({ shouldRender: !useIsSSR() }, defaultProps, props);\n const fallbackMountNode = usePortalMountNode({ disabled: !!state.mountNode });\n\n state.mountNode = state.mountNode ?? fallbackMountNode;\n\n return state;\n};\n"]}
1
+ {"version":3,"file":"usePortal.js","sourceRoot":"","sources":["../../../src/components/Portal/usePortal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG7D;;;;;;GAMG;AACH,MAAM,CAAC,IAAM,SAAS,GAAG,UAAC,KAAkB;IAClC,IAAA,QAAQ,GAAgB,KAAK,SAArB,EAAE,SAAS,GAAK,KAAK,UAAV,CAAW;IAEtC,IAAM,oBAAoB,GAAG,KAAK,CAAC,MAAM,CAAkB,IAAI,CAAC,CAAC;IACjE,IAAM,iBAAiB,GAAG,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAExE,IAAM,KAAK,GAAgB;QACzB,QAAQ,UAAA;QACR,SAAS,EAAE,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,iBAAiB;QACzC,YAAY,EAAE,CAAC,QAAQ,EAAE;QACzB,oBAAoB,sBAAA;KACrB,CAAC;IAEF,KAAK,CAAC,SAAS,CAAC;QACd,IAAI,KAAK,CAAC,oBAAoB,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE;YACzD,gBAAgB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;SACvE;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAElD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
3
3
  import { useThemeClassName, useFluent } from '@fluentui/react-shared-contexts';
4
+ import { useKeyboardNavAttribute } from '@fluentui/react-tabster';
4
5
  /**
5
6
  * Creates a new element on a document.body to mount portals
6
7
  */
@@ -17,6 +18,7 @@ export var usePortalMountNode = function (options) {
17
18
  targetDocument.body.appendChild(newElement);
18
19
  return newElement;
19
20
  }, [targetDocument, themeClassName, dir, options.disabled]);
21
+ useKeyboardNavAttribute().current = element;
20
22
  useIsomorphicLayoutEffect(function () {
21
23
  return function () {
22
24
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"usePortalMountNode.js","sourceRoot":"../src/","sources":["components/Portal/usePortalMountNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAS/E;;GAEG;AACH,MAAM,CAAC,IAAM,kBAAkB,GAAG,UAAC,OAAkC;IACnE,IAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IACrC,IAAA,KAA0B,SAAS,EAAE,EAAnC,cAAc,oBAAA,EAAE,GAAG,SAAgB,CAAC;IAE5C,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC5B,IAAI,cAAc,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE;YACpD,OAAO,SAAS,CAAC;SAClB;QAED,IAAM,UAAU,GAAG,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACjD,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACpC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAE5C,OAAO,UAAU,CAAC;IACpB,CAAC,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE5D,yBAAyB,CAAC;QACxB,OAAO;;YACL,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa,0CAAE,WAAW,CAAC,OAAO,EAAE;QAC/C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport { useThemeClassName, useFluent } from '@fluentui/react-shared-contexts';\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\n/**\n * Creates a new element on a document.body to mount portals\n */\nexport const usePortalMountNode = (options: UsePortalMountNodeOptions) => {\n const themeClassName = useThemeClassName();\n const { targetDocument, dir } = useFluent();\n\n const element = React.useMemo(() => {\n if (targetDocument === undefined || options.disabled) {\n return undefined;\n }\n\n const newElement = targetDocument.createElement('div');\n newElement.setAttribute('class', themeClassName);\n newElement.setAttribute('dir', dir);\n targetDocument.body.appendChild(newElement);\n\n return newElement;\n }, [targetDocument, themeClassName, dir, options.disabled]);\n\n useIsomorphicLayoutEffect(() => {\n return () => {\n element?.parentElement?.removeChild(element);\n };\n }, [element]);\n\n return element;\n};\n"]}
1
+ {"version":3,"file":"usePortalMountNode.js","sourceRoot":"","sources":["../../../src/components/Portal/usePortalMountNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AASlE;;GAEG;AACH,MAAM,CAAC,IAAM,kBAAkB,GAAG,UAAC,OAAkC;IACnE,IAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IACrC,IAAA,KAA0B,SAAS,EAAE,EAAnC,cAAc,oBAAA,EAAE,GAAG,SAAgB,CAAC;IAE5C,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC5B,IAAI,cAAc,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE;YACpD,OAAO,SAAS,CAAC;SAClB;QAED,IAAM,UAAU,GAAG,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACjD,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACpC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAE5C,OAAO,UAAU,CAAC;IACpB,CAAC,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE3D,uBAAuB,EAA0C,CAAC,OAAO,GAAG,OAAQ,CAAC;IAEtF,yBAAyB,CAAC;QACxB,OAAO;;YACL,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa,0CAAE,WAAW,CAAC,OAAO,EAAE;QAC/C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
package/lib/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './components/Portal/index';
2
+ export { elementContains, setVirtualParent } from './virtualParent/index';
package/lib/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './components/Portal/index';
2
+ export { elementContains, setVirtualParent } from './virtualParent/index';
2
3
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../src/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC","sourcesContent":["export * from './components/Portal/index';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.13.0"
8
+ "packageVersion": "7.18.1"
9
9
  }
10
10
  ]
11
11
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Similar functionality to `element.contains` DOM API for use with out of order DOM elements that
3
+ * checks the virtual parent hierarchy. If a virtual parents exists, it is chosen over the actual parent
4
+ *
5
+ * @returns true if the child can find the parent in its virtual hierarchy
6
+ */
7
+ export declare function elementContains(parent: HTMLElement | null, child: HTMLElement | null): boolean;
@@ -0,0 +1,26 @@
1
+ import { getParent } from './getParent';
2
+ /**
3
+ * Similar functionality to `element.contains` DOM API for use with out of order DOM elements that
4
+ * checks the virtual parent hierarchy. If a virtual parents exists, it is chosen over the actual parent
5
+ *
6
+ * @returns true if the child can find the parent in its virtual hierarchy
7
+ */
8
+ export function elementContains(parent, child) {
9
+ if (!parent || !child) {
10
+ return false;
11
+ }
12
+ if (parent === child) {
13
+ return true;
14
+ }
15
+ else {
16
+ while (child) {
17
+ var nextParent = getParent(child);
18
+ if (nextParent === parent) {
19
+ return true;
20
+ }
21
+ child = nextParent;
22
+ }
23
+ }
24
+ return false;
25
+ }
26
+ //# sourceMappingURL=elementContains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elementContains.js","sourceRoot":"","sources":["../../src/virtualParent/elementContains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAA0B,EAAE,KAAyB;IACnF,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE;QACrB,OAAO,KAAK,CAAC;KACd;IAED,IAAI,MAAM,KAAK,KAAK,EAAE;QACpB,OAAO,IAAI,CAAC;KACb;SAAM;QACL,OAAO,KAAK,EAAE;YACZ,IAAM,UAAU,GAAuB,SAAS,CAAC,KAAK,CAAC,CAAC;YAExD,IAAI,UAAU,KAAK,MAAM,EAAE;gBACzB,OAAO,IAAI,CAAC;aACb;YAED,KAAK,GAAG,UAAU,CAAC;SACpB;KACF;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Gets the element which is the parent of a given element.
3
+ * This method prefers the virtual parent over real DOM parent when present.
4
+ */
5
+ export declare function getParent(child: HTMLElement | null): HTMLElement | null;
@@ -0,0 +1,9 @@
1
+ import { getVirtualParent } from './getVirtualParent';
2
+ /**
3
+ * Gets the element which is the parent of a given element.
4
+ * This method prefers the virtual parent over real DOM parent when present.
5
+ */
6
+ export function getParent(child) {
7
+ return (child && getVirtualParent(child)) || (child === null || child === void 0 ? void 0 : child.parentNode);
8
+ }
9
+ //# sourceMappingURL=getParent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getParent.js","sourceRoot":"","sources":["../../src/virtualParent/getParent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAyB;IACjD,OAAO,CAAC,KAAK,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,UAAiC,CAAA,CAAC;AACzF,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Gets the virtual parent given the child element, if it exists.
3
+ */
4
+ export declare function getVirtualParent(child: HTMLElement): HTMLElement | undefined;
@@ -0,0 +1,12 @@
1
+ import { isVirtualElement } from './isVirtualElement';
2
+ /**
3
+ * Gets the virtual parent given the child element, if it exists.
4
+ */
5
+ export function getVirtualParent(child) {
6
+ var parent;
7
+ if (isVirtualElement(child)) {
8
+ parent = child._virtual.parent;
9
+ }
10
+ return parent;
11
+ }
12
+ //# sourceMappingURL=getVirtualParent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getVirtualParent.js","sourceRoot":"","sources":["../../src/virtualParent/getVirtualParent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IACjD,IAAI,MAA+B,CAAC;IACpC,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;QAC3B,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;KAChC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './elementContains';
2
+ export * from './getParent';
3
+ export * from './getVirtualParent';
4
+ export * from './isVirtualElement';
5
+ export * from './setVirtualParent';
@@ -0,0 +1,6 @@
1
+ export * from './elementContains';
2
+ export * from './getParent';
3
+ export * from './getVirtualParent';
4
+ export * from './isVirtualElement';
5
+ export * from './setVirtualParent';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/virtualParent/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}