1
- import * as React from 'react' ;
2
- import Portal from '@rc-component/portal' ;
3
1
import type { PortalProps } from '@rc-component/portal' ;
2
+ import Portal from '@rc-component/portal' ;
4
3
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect' ;
5
- import DrawerPopup from './DrawerPopup' ;
4
+ import * as React from 'react' ;
5
+ import { RefContext } from './context' ;
6
+ import type { DrawerPanelEvents } from './DrawerPanel' ;
6
7
import type { DrawerPopupProps } from './DrawerPopup' ;
8
+ import DrawerPopup from './DrawerPopup' ;
7
9
import { warnCheck } from './util' ;
8
- import type { DrawerPanelEvents } from './DrawerPanel' ;
9
10
10
11
export type Placement = 'left' | 'top' | 'right' | 'bottom' ;
11
12
12
13
export interface DrawerProps
13
- extends Omit < DrawerPopupProps , 'prefixCls' | 'inline' | 'scrollLocker' > , DrawerPanelEvents {
14
+ extends Omit < DrawerPopupProps , 'prefixCls' | 'inline' | 'scrollLocker' > ,
15
+ DrawerPanelEvents {
14
16
prefixCls ?: string ;
15
17
open ?: boolean ;
16
18
onClose ?: ( e : React . MouseEvent | React . KeyboardEvent ) => void ;
17
19
destroyOnClose ?: boolean ;
18
20
getContainer ?: PortalProps [ 'getContainer' ] ;
21
+ panelRef ?: React . Ref < HTMLDivElement > ;
19
22
}
20
23
21
24
const Drawer : React . FC < DrawerProps > = props => {
@@ -38,6 +41,9 @@ const Drawer: React.FC<DrawerProps> = props => {
38
41
onClick,
39
42
onKeyDown,
40
43
onKeyUp,
44
+
45
+ // Refs
46
+ panelRef,
41
47
} = props ;
42
48
43
49
const [ animatedVisible , setAnimatedVisible ] = React . useState ( false ) ;
@@ -57,7 +63,7 @@ const Drawer: React.FC<DrawerProps> = props => {
57
63
const mergedOpen = mounted ? open : false ;
58
64
59
65
// ============================ Focus =============================
60
- const panelRef = React . useRef < HTMLDivElement > ( ) ;
66
+ const popupRef = React . useRef < HTMLDivElement > ( ) ;
61
67
62
68
const lastActiveRef = React . useRef < HTMLElement > ( ) ;
63
69
useLayoutEffect ( ( ) => {
@@ -75,12 +81,20 @@ const Drawer: React.FC<DrawerProps> = props => {
75
81
if (
76
82
! nextVisible &&
77
83
lastActiveRef . current &&
78
- ! panelRef . current ?. contains ( lastActiveRef . current )
84
+ ! popupRef . current ?. contains ( lastActiveRef . current )
79
85
) {
80
86
lastActiveRef . current ?. focus ( { preventScroll : true } ) ;
81
87
}
82
88
} ;
83
89
90
+ // =========================== Context ============================
91
+ const refContext = React . useMemo (
92
+ ( ) => ( {
93
+ panel : panelRef ,
94
+ } ) ,
95
+ [ panelRef ] ,
96
+ ) ;
97
+
84
98
// ============================ Render ============================
85
99
if ( ! forceRender && ! animatedVisible && ! mergedOpen && destroyOnClose ) {
86
100
return null ;
@@ -106,19 +120,21 @@ const Drawer: React.FC<DrawerProps> = props => {
106
120
maskClosable,
107
121
inline : getContainer === false ,
108
122
afterOpenChange : internalAfterOpenChange ,
109
- ref : panelRef ,
123
+ ref : popupRef ,
110
124
...eventHandlers ,
111
125
} ;
112
126
113
127
return (
114
- < Portal
115
- open = { mergedOpen || forceRender || animatedVisible }
116
- autoDestroy = { false }
117
- getContainer = { getContainer }
118
- autoLock = { mask && ( mergedOpen || animatedVisible ) }
119
- >
120
- < DrawerPopup { ...drawerPopupProps } />
121
- </ Portal >
128
+ < RefContext . Provider value = { refContext } >
129
+ < Portal
130
+ open = { mergedOpen || forceRender || animatedVisible }
131
+ autoDestroy = { false }
132
+ getContainer = { getContainer }
133
+ autoLock = { mask && ( mergedOpen || animatedVisible ) }
134
+ >
135
+ < DrawerPopup { ...drawerPopupProps } />
136
+ </ Portal >
137
+ </ RefContext . Provider >
122
138
) ;
123
139
} ;
124
140
0 commit comments