21
21
// THE SOFTWARE.
22
22
23
23
import * as React from 'react' ;
24
+ import * as ReactDOM from 'react-dom' ;
24
25
import * as classnames from 'classnames' ;
25
26
// @ts -ignore no .d.ts file
26
27
import { MDCMenuSurfaceFoundation , MDCMenuSurfaceAdapter , Corner } from '@material/menu-surface/dist/mdc.menuSurface' ;
@@ -56,6 +57,7 @@ export interface MenuSurfaceState {
56
57
styleTop ?: number ;
57
58
styleBottom ?: number ;
58
59
classList : Set < string > ;
60
+ mounted : boolean ;
59
61
} ;
60
62
61
63
interface Position {
@@ -83,6 +85,7 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
83
85
styleTop : undefined ,
84
86
styleBottom : undefined ,
85
87
classList : new Set ( ) ,
88
+ mounted : false ,
86
89
} ;
87
90
88
91
static defaultProps : Partial < MenuSurfaceProps > = {
@@ -104,7 +107,6 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
104
107
anchorMargin,
105
108
coordinates,
106
109
fixed,
107
- open,
108
110
quickOpen,
109
111
} = this . props ;
110
112
this . handleWindowClick = ( evt ) => this . foundation . handleBodyClick ( evt ) ;
@@ -114,7 +116,10 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
114
116
window . removeEventListener ( 'click' , this . handleWindowClick ! ) ;
115
117
this . foundation = new MDCMenuSurfaceFoundation ( this . adapter ) ;
116
118
this . foundation . init ( ) ;
117
- this . hoistToBody ( ) ;
119
+ // this deviates from the mdc web version.
120
+ // here we force the menu to hoist, and require either
121
+ // this.props.(x,y) or this.props.anchorElement.
122
+ this . foundation . setIsHoisted ( true ) ;
118
123
this . foundation . setFixedPosition ( fixed ) ;
119
124
if ( coordinates ) {
120
125
this . setCoordinates ( ) ;
@@ -128,13 +133,14 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
128
133
if ( quickOpen ) {
129
134
this . foundation . setQuickOpen ( quickOpen ) ;
130
135
}
131
- if ( open ) {
132
- this . open_ ( ) ;
133
- }
136
+ this . setState ( { mounted : true } ) ;
134
137
}
135
138
136
- componentDidUpdate ( prevProps : MenuSurfaceProps ) {
137
- if ( this . props . open !== prevProps . open ) {
139
+ componentDidUpdate ( prevProps : MenuSurfaceProps , prevState : MenuSurfaceState ) {
140
+ // if this.props.open was true for the initial render
141
+ // then it will not be changed but the mounted state will be,
142
+ // so this.open_() should also be called in that case.
143
+ if ( this . props . open !== prevProps . open || ( this . props . open && this . state . mounted !== prevState . mounted ) ) {
138
144
this . open_ ( ) ;
139
145
}
140
146
if ( this . props . coordinates !== prevProps . coordinates ) {
@@ -160,19 +166,6 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
160
166
}
161
167
}
162
168
163
- private hoistToBody ( ) : void {
164
- // this deviates from the mdc web version.
165
- // here we force the menu to hoist, and require either
166
- // this.props.(x,y) or this.props.anchorElement.
167
- const menuSurfaceElement = this . menuSurfaceElement . current ;
168
- if ( ! menuSurfaceElement ) return ;
169
- if ( ! menuSurfaceElement . parentElement ) return ;
170
- document . body . appendChild (
171
- menuSurfaceElement . parentElement . removeChild ( menuSurfaceElement )
172
- ) ;
173
- this . foundation . setIsHoisted ( true ) ;
174
- }
175
-
176
169
private setCoordinates ( ) : void {
177
170
if ( ! this . props . coordinates ) return ;
178
171
const { x, y} = this . props . coordinates ;
@@ -359,7 +352,8 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
359
352
children,
360
353
...otherProps
361
354
} = this . props ;
362
- return (
355
+ if ( ! this . state . mounted ) return null ;
356
+ return ReactDOM . createPortal (
363
357
< div
364
358
className = { this . classes }
365
359
onKeyDown = { this . handleKeydown }
@@ -368,7 +362,8 @@ class MenuSurface extends React.Component<MenuSurfaceProps, MenuSurfaceState> {
368
362
{ ...otherProps }
369
363
>
370
364
{ children }
371
- </ div >
365
+ </ div > ,
366
+ document . body
372
367
) ;
373
368
}
374
369
}
0 commit comments