@@ -21,7 +21,7 @@ function ModalDOM(props) {
21
21
22
22
function Modal ( props ) {
23
23
return (
24
- < OverlayContainer data-testid = { props . providerId || 'modal-provider' } >
24
+ < OverlayContainer portalContainer = { props . container } data-testid = { props . providerId || 'modal-provider' } >
25
25
< ModalDOM modalId = { props . modalId } > { props . children } </ ModalDOM >
26
26
</ OverlayContainer >
27
27
) ;
@@ -32,7 +32,7 @@ function Example(props) {
32
32
< OverlayProvider data-testid = "root-provider" >
33
33
This is the root provider.
34
34
{ props . showModal &&
35
- < Modal > { props . children } </ Modal >
35
+ < Modal container = { props . container } > { props . children } </ Modal >
36
36
}
37
37
</ OverlayProvider >
38
38
) ;
@@ -88,4 +88,102 @@ describe('useModal', function () {
88
88
res . rerender ( < Example /> ) ;
89
89
expect ( rootProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
90
90
} ) ;
91
+
92
+ it ( 'can specify a different container from the default document.body' , function ( ) {
93
+ let res = render (
94
+ < div id = "alternateContainer" data-testid = "alternate-container" >
95
+ < Example container = { document . getElementById ( 'alternateContainer' ) } />
96
+ </ div >
97
+ ) ;
98
+ let rootProvider = res . getByTestId ( 'root-provider' ) ;
99
+
100
+ expect ( rootProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
101
+
102
+ res . rerender (
103
+ < div id = "alternateContainer" data-testid = "alternate-container" >
104
+ < Example showModal container = { document . getElementById ( 'alternateContainer' ) } />
105
+ </ div >
106
+ ) ;
107
+
108
+ let modalProvider = res . getByTestId ( 'modal-provider' ) ;
109
+
110
+ expect ( rootProvider ) . toHaveAttribute ( 'aria-hidden' , 'true' ) ;
111
+ expect ( modalProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
112
+
113
+ res . rerender (
114
+ < div id = "alternateContainer" data-testid = "alternate-container" >
115
+ < Example showModal container = { document . getElementById ( 'alternateContainer' ) } >
116
+ < Modal providerId = "inner-modal-provider" modalId = "inner-modal" > Inner</ Modal >
117
+ </ Example >
118
+ </ div >
119
+ ) ;
120
+
121
+ let innerModalProvider = res . getByTestId ( 'inner-modal-provider' ) ;
122
+
123
+ expect ( rootProvider ) . toHaveAttribute ( 'aria-hidden' , 'true' ) ;
124
+ expect ( modalProvider ) . toHaveAttribute ( 'aria-hidden' ) ;
125
+ expect ( innerModalProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
126
+
127
+ res . rerender (
128
+ < div id = "alternateContainer" data-testid = "alternate-container" >
129
+ < Example container = { document . getElementById ( 'alternateContainer' ) } />
130
+ </ div >
131
+ ) ;
132
+ expect ( rootProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
133
+ } ) ;
134
+
135
+ describe ( 'error state' , function ( ) {
136
+ const consoleError = console . error ;
137
+ beforeEach ( ( ) => {
138
+ console . error = jest . fn ( ) ;
139
+ } ) ;
140
+
141
+ afterEach ( ( ) => {
142
+ console . error = consoleError ;
143
+ } ) ;
144
+ it ( 'if inside another container, throws an error' , function ( ) {
145
+ let res = render (
146
+ < div id = "alternateContainer" data-testid = "alternate-container" >
147
+ < Example container = { document . getElementById ( 'alternateContainer' ) } >
148
+ < div id = "nestedContainer" />
149
+ </ Example >
150
+ </ div >
151
+ ) ;
152
+ let rootProvider = res . getByTestId ( 'root-provider' ) ;
153
+
154
+ expect ( rootProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
155
+
156
+ res . rerender (
157
+ < div id = "alternateContainer" data-testid = "alternate-container" >
158
+ < Example showModal container = { document . getElementById ( 'alternateContainer' ) } >
159
+ < div id = "nestedContainer" />
160
+ </ Example >
161
+ </ div >
162
+ ) ;
163
+
164
+ let modalProvider = res . getByTestId ( 'modal-provider' ) ;
165
+
166
+ expect ( rootProvider ) . toHaveAttribute ( 'aria-hidden' , 'true' ) ;
167
+ expect ( modalProvider ) . not . toHaveAttribute ( 'aria-hidden' ) ;
168
+ expect ( ( ) =>
169
+ res . rerender (
170
+ < div id = "alternateContainer" data-testid = "alternate-container" >
171
+ < Example showModal container = { document . getElementById ( 'alternateContainer' ) } >
172
+ < div id = "nestedContainer" />
173
+ < Modal
174
+ container = { document . getElementById ( 'nestedContainer' ) }
175
+ providerId = "inner-modal-provider"
176
+ modalId = "inner-modal" >
177
+ Inner
178
+ </ Modal >
179
+ </ Example >
180
+ </ div >
181
+ )
182
+ ) . toThrow ( ) ;
183
+ expect ( console . error ) . toHaveBeenCalledWith (
184
+ expect . stringContaining ( 'An OverlayContainer must not be inside another container. Please change the portalContainer prop.' ) ,
185
+ expect . anything ( )
186
+ ) ;
187
+ } ) ;
188
+ } ) ;
91
189
} ) ;
0 commit comments