@@ -26,8 +26,7 @@ import {
26
26
MDCDismissibleDrawerFoundation ,
27
27
MDCModalDrawerFoundation ,
28
28
util ,
29
- // @ts -ignore no .d.ts file
30
- } from '@material/drawer/dist/mdc.drawer' ;
29
+ } from '@material/drawer' ;
31
30
// @ts -ignore no .d.ts file
32
31
import { MDCListFoundation } from '@material/list/dist/mdc.list' ;
33
32
import DrawerHeader from './Header' ;
@@ -39,6 +38,8 @@ import {FocusTrap} from 'focus-trap';
39
38
40
39
const { cssClasses : listCssClasses } = MDCListFoundation ;
41
40
41
+ type RefCallback < T > = ( node : T ) => void ;
42
+
42
43
export interface DrawerProps extends React . HTMLProps < HTMLElement > {
43
44
className ?: string ;
44
45
open ?: boolean ;
@@ -47,15 +48,20 @@ export interface DrawerProps extends React.HTMLProps<HTMLElement>{
47
48
tag ?: string ;
48
49
dismissible ?: boolean ;
49
50
modal ?: boolean ;
51
+ innerRef ?: RefCallback < HTMLElement > | React . RefObject < HTMLElement > ;
50
52
} ;
51
53
52
54
interface DrawerState {
53
55
classList : Set < string > ;
54
56
} ;
55
57
58
+ const isRefObject = function ( ref : DrawerProps [ 'innerRef' ] ) : ref is React . RefObject < HTMLElement > {
59
+ return typeof ref !== 'function' ;
60
+ } ;
61
+
56
62
class Drawer extends React . Component < DrawerProps , DrawerState > {
57
63
previousFocus : HTMLElement | null = null ;
58
- foundation : MDCDismissibleDrawerFoundation | MDCModalDrawerFoundation ;
64
+ foundation ? : MDCDismissibleDrawerFoundation | MDCModalDrawerFoundation ;
59
65
focusTrap ?: FocusTrap ;
60
66
drawerElement : React . RefObject < HTMLDivElement > = React . createRef ( ) ;
61
67
@@ -106,7 +112,7 @@ class Drawer extends React.Component<DrawerProps, DrawerState> {
106
112
if ( changedToModal || changedToDismissible ) {
107
113
this . initFoundation ( ) ;
108
114
}
109
- if ( open !== prevProps . open ) {
115
+ if ( open !== prevProps . open && this . foundation ) {
110
116
open ? this . foundation . open ( ) : this . foundation . close ( ) ;
111
117
}
112
118
}
@@ -117,7 +123,7 @@ class Drawer extends React.Component<DrawerProps, DrawerState> {
117
123
}
118
124
119
125
private initializeFocusTrap = ( ) => {
120
- this . focusTrap = util . createFocusTrapInstance ( this . drawerElement . current ) ;
126
+ this . focusTrap = util . createFocusTrapInstance ( this . drawerElement . current ! ) ;
121
127
} ;
122
128
123
129
get classes ( ) {
@@ -184,15 +190,34 @@ class Drawer extends React.Component<DrawerProps, DrawerState> {
184
190
handleKeyDown = ( evt : React . KeyboardEvent < HTMLElement > ) => {
185
191
this . props . onKeyDown ! ( evt ) ;
186
192
if ( ! this . foundation ) return ;
187
- this . foundation . handleKeydown ( evt ) ;
193
+ this . foundation . handleKeydown ( evt . nativeEvent ) ;
188
194
} ;
189
195
190
196
handleTransitionEnd = ( evt : React . TransitionEvent < HTMLElement > ) => {
191
197
this . props . onTransitionEnd ! ( evt ) ;
192
198
if ( ! this . foundation ) return ;
193
- this . foundation . handleTransitionEnd ( evt ) ;
199
+ this . foundation . handleTransitionEnd ( evt . nativeEvent ) ;
194
200
} ;
195
201
202
+ attachRef = ( node : HTMLElement ) => {
203
+ const { innerRef} = this . props ;
204
+
205
+ // https://github.com/facebook/react/issues/13029#issuecomment-410002316
206
+ // @ts -ignore this is acceptable according to the comment above
207
+ this . drawerElement . current = node ;
208
+
209
+ if ( ! innerRef ) {
210
+ return ;
211
+ }
212
+
213
+ if ( isRefObject ( innerRef ) ) {
214
+ // @ts -ignore same as above
215
+ innerRef . current = node ;
216
+ } else {
217
+ innerRef ( node ) ;
218
+ }
219
+ }
220
+
196
221
render ( ) {
197
222
const {
198
223
/* eslint-disable no-unused-vars */
@@ -203,9 +228,10 @@ class Drawer extends React.Component<DrawerProps, DrawerState> {
203
228
dismissible,
204
229
children,
205
230
className,
231
+ innerRef,
232
+ modal,
206
233
/* eslint-enable no-unused-vars */
207
234
tag : Tag ,
208
- modal,
209
235
...otherProps
210
236
} = this . props ;
211
237
@@ -215,7 +241,7 @@ class Drawer extends React.Component<DrawerProps, DrawerState> {
215
241
// @ts -ignore */ }
216
242
< Tag
217
243
className = { this . classes }
218
- ref = { this . drawerElement }
244
+ ref = { this . attachRef }
219
245
onKeyDown = { this . handleKeyDown }
220
246
onTransitionEnd = { this . handleTransitionEnd }
221
247
{ ...otherProps }
@@ -226,11 +252,12 @@ class Drawer extends React.Component<DrawerProps, DrawerState> {
226
252
</ React . Fragment >
227
253
) ;
228
254
}
255
+
229
256
renderScrim ( ) {
230
257
return (
231
258
< div
232
259
className = 'mdc-drawer-scrim'
233
- onClick = { ( ) => this . foundation . handleScrimClick ( ) }
260
+ onClick = { ( ) => ( this . foundation as MDCModalDrawerFoundation ) . handleScrimClick ( ) }
234
261
/>
235
262
) ;
236
263
}
0 commit comments