@@ -5,6 +5,7 @@ import contains from 'rc-util/lib/Dom/contains';
5
5
import addEventListener from 'rc-util/lib/Dom/addEventListener' ;
6
6
import Popup from './Popup' ;
7
7
import { getAlignFromPlacement , getPopupClassNameFromAlign } from './utils' ;
8
+ import getContainerRenderMixin from 'rc-util/lib/getContainerRenderMixin' ;
8
9
9
10
function noop ( ) {
10
11
}
@@ -50,6 +51,56 @@ const Trigger = React.createClass({
50
51
maskAnimation : PropTypes . string ,
51
52
} ,
52
53
54
+ mixins : [
55
+ getContainerRenderMixin ( {
56
+ autoMount : false ,
57
+
58
+ isVisible ( instance ) {
59
+ return instance . state . popupVisible ;
60
+ } ,
61
+
62
+ getContainer ( instance ) {
63
+ const popupContainer = document . createElement ( 'div' ) ;
64
+ const mountNode = instance . props . getPopupContainer ?
65
+ instance . props . getPopupContainer ( findDOMNode ( instance ) ) : document . body ;
66
+ mountNode . appendChild ( popupContainer ) ;
67
+ return popupContainer ;
68
+ } ,
69
+
70
+ getComponent ( instance ) {
71
+ const { props, state } = instance ;
72
+ const mouseProps = { } ;
73
+ if ( instance . isMouseEnterToShow ( ) ) {
74
+ mouseProps . onMouseEnter = instance . onMouseEnter ;
75
+ }
76
+ if ( instance . isMouseLeaveToHide ( ) ) {
77
+ mouseProps . onMouseLeave = instance . onMouseLeave ;
78
+ }
79
+ return ( < Popup
80
+ prefixCls = { props . prefixCls }
81
+ destroyPopupOnHide = { props . destroyPopupOnHide }
82
+ visible = { state . popupVisible }
83
+ className = { props . popupClassName }
84
+ action = { props . action }
85
+ align = { instance . getPopupAlign ( ) }
86
+ onAlign = { props . onPopupAlign }
87
+ animation = { props . popupAnimation }
88
+ getClassNameFromAlign = { instance . getPopupClassNameFromAlign }
89
+ { ...mouseProps }
90
+ getRootDomNode = { instance . getRootDomNode }
91
+ style = { props . popupStyle }
92
+ mask = { props . mask }
93
+ zIndex = { props . zIndex }
94
+ transitionName = { props . popupTransitionName }
95
+ maskAnimation = { props . maskAnimation }
96
+ maskTransitionName = { props . maskTransitionName }
97
+ >
98
+ { typeof props . popup === 'function' ? props . popup ( ) : props . popup }
99
+ </ Popup > ) ;
100
+ } ,
101
+ } ) ,
102
+ ] ,
103
+
53
104
getDefaultProps ( ) {
54
105
return {
55
106
prefixCls : 'rc-trigger-popup' ,
@@ -92,54 +143,42 @@ const Trigger = React.createClass({
92
143
} ) ;
93
144
} ,
94
145
95
- componentWillReceiveProps ( nextProps ) {
96
- if ( ' popupVisible' in nextProps ) {
146
+ componentWillReceiveProps ( { popupVisible } ) {
147
+ if ( popupVisible !== undefined ) {
97
148
this . setState ( {
98
- popupVisible : ! ! nextProps . popupVisible ,
149
+ popupVisible,
99
150
} ) ;
100
151
}
101
152
} ,
102
153
103
- componentDidUpdate ( prevProps , prevState ) {
154
+ componentDidUpdate ( _ , prevState ) {
104
155
const props = this . props ;
105
156
const state = this . state ;
106
- if ( this . popupRendered ) {
107
- const self = this ;
108
- ReactDOM . unstable_renderSubtreeIntoContainer ( this ,
109
- this . getPopupElement ( ) ,
110
- this . getPopupContainer ( ) , function mounted ( ) {
111
- self . popupInstance = this ;
112
- if ( prevState . popupVisible !== state . popupVisible ) {
113
- props . afterPopupVisibleChange ( state . popupVisible ) ;
114
- }
115
- } ) ;
116
- if ( this . isClickToHide ( ) ) {
117
- if ( state . popupVisible ) {
118
- if ( ! this . clickOutsideHandler ) {
119
- this . clickOutsideHandler = addEventListener ( document ,
120
- 'mousedown' , this . onDocumentClick ) ;
121
- this . touchOutsideHandler = addEventListener ( document ,
122
- 'touchstart' , this . onDocumentClick ) ;
123
- }
124
- return ;
125
- }
157
+ this . renderComponent ( ( ) => {
158
+ if ( prevState . popupVisible !== state . popupVisible ) {
159
+ props . afterPopupVisibleChange ( state . popupVisible ) ;
126
160
}
127
- if ( this . clickOutsideHandler ) {
128
- this . clickOutsideHandler . remove ( ) ;
129
- this . touchOutsideHandler . remove ( ) ;
130
- this . clickOutsideHandler = null ;
131
- this . touchOutsideHandler = null ;
161
+ } ) ;
162
+ if ( this . isClickToHide ( ) ) {
163
+ if ( state . popupVisible ) {
164
+ if ( ! this . clickOutsideHandler ) {
165
+ this . clickOutsideHandler = addEventListener ( document ,
166
+ 'mousedown' , this . onDocumentClick ) ;
167
+ this . touchOutsideHandler = addEventListener ( document ,
168
+ 'touchstart' , this . onDocumentClick ) ;
169
+ }
170
+ return ;
132
171
}
133
172
}
173
+ if ( this . clickOutsideHandler ) {
174
+ this . clickOutsideHandler . remove ( ) ;
175
+ this . touchOutsideHandler . remove ( ) ;
176
+ this . clickOutsideHandler = null ;
177
+ this . touchOutsideHandler = null ;
178
+ }
134
179
} ,
135
180
136
181
componentWillUnmount ( ) {
137
- const popupContainer = this . popupContainer ;
138
- if ( popupContainer ) {
139
- ReactDOM . unmountComponentAtNode ( popupContainer ) ;
140
- popupContainer . parentNode . removeChild ( popupContainer ) ;
141
- this . popupContainer = null ;
142
- }
143
182
this . clearDelayTimer ( ) ;
144
183
if ( this . clickOutsideHandler ) {
145
184
this . clickOutsideHandler . remove ( ) ;
@@ -223,8 +262,8 @@ const Trigger = React.createClass({
223
262
224
263
getPopupDomNode ( ) {
225
264
// for test
226
- if ( this . popupInstance ) {
227
- return this . popupInstance . isMounted ( ) ? this . popupInstance . getPopupDomNode ( ) : null ;
265
+ if ( this . _component ) {
266
+ return this . _component . isMounted ( ) ? this . _component . getPopupDomNode ( ) : null ;
228
267
}
229
268
return null ;
230
269
} ,
@@ -233,16 +272,6 @@ const Trigger = React.createClass({
233
272
return ReactDOM . findDOMNode ( this ) ;
234
273
} ,
235
274
236
- getPopupContainer ( ) {
237
- if ( ! this . popupContainer ) {
238
- this . popupContainer = document . createElement ( 'div' ) ;
239
- const mountNode = this . props . getPopupContainer ?
240
- this . props . getPopupContainer ( findDOMNode ( this ) ) : document . body ;
241
- mountNode . appendChild ( this . popupContainer ) ;
242
- }
243
- return this . popupContainer ;
244
- } ,
245
-
246
275
getPopupClassNameFromAlign ( align ) {
247
276
const className = [ ] ;
248
277
const props = this . props ;
@@ -265,38 +294,6 @@ const Trigger = React.createClass({
265
294
return popupAlign ;
266
295
} ,
267
296
268
- getPopupElement ( ) {
269
- const { props, state } = this ;
270
- const mouseProps = { } ;
271
- if ( this . isMouseEnterToShow ( ) ) {
272
- mouseProps . onMouseEnter = this . onMouseEnter ;
273
- }
274
- if ( this . isMouseLeaveToHide ( ) ) {
275
- mouseProps . onMouseLeave = this . onMouseLeave ;
276
- }
277
- return ( < Popup
278
- prefixCls = { props . prefixCls }
279
- destroyPopupOnHide = { props . destroyPopupOnHide }
280
- visible = { state . popupVisible }
281
- className = { props . popupClassName }
282
- action = { props . action }
283
- align = { this . getPopupAlign ( ) }
284
- onAlign = { props . onPopupAlign }
285
- animation = { props . popupAnimation }
286
- getClassNameFromAlign = { this . getPopupClassNameFromAlign }
287
- { ...mouseProps }
288
- getRootDomNode = { this . getRootDomNode }
289
- style = { props . popupStyle }
290
- mask = { props . mask }
291
- zIndex = { props . zIndex }
292
- transitionName = { props . popupTransitionName }
293
- maskAnimation = { props . maskAnimation }
294
- maskTransitionName = { props . maskTransitionName }
295
- >
296
- { typeof props . popup === 'function' ? props . popup ( ) : props . popup }
297
- </ Popup > ) ;
298
- } ,
299
-
300
297
setPopupVisible ( popupVisible ) {
301
298
this . clearDelayTimer ( ) ;
302
299
if ( this . state . popupVisible !== popupVisible ) {
@@ -365,7 +362,6 @@ const Trigger = React.createClass({
365
362
} ,
366
363
367
364
render ( ) {
368
- this . popupRendered = this . popupRendered || this . state . popupVisible ;
369
365
const props = this . props ;
370
366
const children = props . children ;
371
367
const child = React . Children . only ( children ) ;
0 commit comments