Skip to content

Commit 9fbc8ad

Browse files
author
Naoki Kobayashi
authored
OverlayContainer createPortal when document is ready (#3186)
1 parent 7beca86 commit 9fbc8ad

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

packages/@react-aria/overlays/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@babel/runtime": "^7.6.2",
2121
"@react-aria/i18n": "^3.4.1",
2222
"@react-aria/interactions": "^3.9.1",
23+
"@react-aria/ssr": "^3.2.0",
2324
"@react-aria/utils": "^3.13.1",
2425
"@react-aria/visually-hidden": "^3.3.1",
2526
"@react-stately/overlays": "^3.3.1",

packages/@react-aria/overlays/src/useModal.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import React, {AriaAttributes, HTMLAttributes, ReactNode, useContext, useEffect, useMemo, useState} from 'react';
1414
import ReactDOM from 'react-dom';
15+
import {useIsSSR} from '@react-aria/ssr';
1516

1617
interface ModalProviderProps extends HTMLAttributes<HTMLElement> {
1718
children: ReactNode
@@ -122,14 +123,19 @@ interface OverlayContainerProps extends ModalProviderProps {
122123
* be accessible at once.
123124
*/
124125
export function OverlayContainer(props: OverlayContainerProps): React.ReactPortal {
125-
let {portalContainer = document.body, ...rest} = props;
126+
let isSSR = useIsSSR();
127+
let {portalContainer = isSSR ? null : document.body, ...rest} = props;
126128

127129
React.useEffect(() => {
128-
if (portalContainer.closest('[data-overlay-container]')) {
130+
if (portalContainer?.closest('[data-overlay-container]')) {
129131
throw new Error('An OverlayContainer must not be inside another container. Please change the portalContainer prop.');
130132
}
131133
}, [portalContainer]);
132134

135+
if (!portalContainer) {
136+
return null;
137+
}
138+
133139
let contents = <OverlayProvider {...rest} />;
134140
return ReactDOM.createPortal(contents, portalContainer);
135141
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2020 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import {testSSR} from '@react-spectrum/test-utils';
14+
15+
describe('OverlayContainer SSR', function () {
16+
it('should render without errors', async function () {
17+
await testSSR(__filename, `
18+
import {OverlayContainer, OverlayProvider} from '..';
19+
import React from 'react';
20+
21+
<OverlayProvider data-testid="root-provider">
22+
<OverlayContainer data-testid="modal-provider">
23+
<div data-testid="modal"></div>
24+
</OverlayContainer>
25+
</OverlayProvider>
26+
`);
27+
});
28+
});

0 commit comments

Comments
 (0)