Skip to content

Commit 52084c2

Browse files
authored
fix: drawer order esc (#396)
1 parent f356b79 commit 52084c2

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

docs/examples/multiple.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ class Demo extends React.Component {
2727
openChild: !this.state.openChild,
2828
});
2929
};
30-
public onChildrenClick = () => {
30+
public onChildrenClick = e => {
3131
this.setState({
32-
openChildren: !this.state.openChildren,
32+
openChildren: e.currentTarget instanceof HTMLButtonElement,
3333
});
3434
};
3535

@@ -55,6 +55,7 @@ class Demo extends React.Component {
5555
className="drawer1"
5656
placement="right"
5757
push={{ distance: 64 }}
58+
rootClassName="level-0"
5859
// zIndex={99999}
5960
{...motionProps}
6061
>
@@ -66,6 +67,7 @@ class Demo extends React.Component {
6667
className="drawer2"
6768
placement="right"
6869
// zIndex={88888}
70+
rootClassName="level-1"
6971
{...motionProps}
7072
>
7173
<div style={{ width: 200 }}>
@@ -75,6 +77,7 @@ class Demo extends React.Component {
7577
open={this.state.openChildren}
7678
onClose={this.onChildrenClick}
7779
placement="right"
80+
rootClassName="level-2"
7881
{...motionProps}
7982
>
8083
<div style={{ width: 200 }}>三级抽屉</div>

src/Drawer.tsx

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import Portal from '@rc-component/portal';
33
import type { PortalProps } from '@rc-component/portal';
4+
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
45
import DrawerPopup from './DrawerPopup';
56
import type { DrawerPopupProps } from './DrawerPopup';
67
import { warnCheck } from './util';
@@ -39,11 +40,29 @@ const Drawer: React.FC<DrawerProps> = props => {
3940
warnCheck(props);
4041
}
4142

43+
// ============================ Focus =============================
44+
const panelRef = React.useRef<HTMLDivElement>();
45+
46+
const lastActiveRef = React.useRef<HTMLElement>();
47+
useLayoutEffect(() => {
48+
if (open) {
49+
lastActiveRef.current = document.activeElement as HTMLElement;
50+
}
51+
}, [open]);
52+
4253
// ============================= Open =============================
4354
const internalAfterOpenChange: DrawerProps['afterOpenChange'] =
4455
nextVisible => {
4556
setAnimatedVisible(nextVisible);
4657
afterOpenChange?.(nextVisible);
58+
59+
if (
60+
!nextVisible &&
61+
lastActiveRef.current &&
62+
!panelRef.current?.contains(lastActiveRef.current)
63+
) {
64+
lastActiveRef.current?.focus();
65+
}
4766
};
4867

4968
// ============================ Render ============================
@@ -63,6 +82,7 @@ const Drawer: React.FC<DrawerProps> = props => {
6382
maskClosable,
6483
inline: getContainer === false,
6584
afterOpenChange: internalAfterOpenChange,
85+
ref: panelRef,
6686
};
6787

6888
return (

src/DrawerPopup.tsx

+13-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import classNames from 'classnames';
33
import CSSMotion from 'rc-motion';
44
import type { CSSMotionProps } from 'rc-motion';
55
import DrawerPanel from './DrawerPanel';
6-
// import type ScrollLocker from 'rc-util/lib/Dom/scrollLocker';
76
import DrawerContext from './context';
87
import type { DrawerContextProps } from './context';
98
import KeyCode from 'rc-util/lib/KeyCode';
@@ -63,7 +62,7 @@ export interface DrawerPopupProps {
6362
) => void;
6463
}
6564

66-
export default function DrawerPopup(props: DrawerPopupProps) {
65+
function DrawerPopup(props: DrawerPopupProps, ref: React.Ref<HTMLDivElement>) {
6766
const {
6867
prefixCls,
6968
open,
@@ -105,6 +104,8 @@ export default function DrawerPopup(props: DrawerPopupProps) {
105104
const sentinelStartRef = React.useRef<HTMLDivElement>();
106105
const sentinelEndRef = React.useRef<HTMLDivElement>();
107106

107+
React.useImperativeHandle(ref, () => panelRef.current);
108+
108109
const onPanelKeyDown: React.KeyboardEventHandler<HTMLDivElement> = event => {
109110
const { keyCode, shiftKey } = event;
110111

@@ -127,6 +128,7 @@ export default function DrawerPopup(props: DrawerPopupProps) {
127128
// Close
128129
case KeyCode.ESC: {
129130
if (onClose && keyboard) {
131+
event.stopPropagation();
130132
onClose(event);
131133
}
132134
break;
@@ -140,7 +142,7 @@ export default function DrawerPopup(props: DrawerPopupProps) {
140142
if (open && autoFocus) {
141143
panelRef.current?.focus({ preventScroll: true });
142144
}
143-
}, [open, autoFocus]);
145+
}, [open]);
144146

145147
// ============================ Push ============================
146148
const [pushed, setPushed] = React.useState(false);
@@ -332,3 +334,11 @@ export default function DrawerPopup(props: DrawerPopupProps) {
332334
</DrawerContext.Provider>
333335
);
334336
}
337+
338+
const RefDrawerPopup = React.forwardRef(DrawerPopup);
339+
340+
if (process.env.NODE_ENV !== 'production') {
341+
RefDrawerPopup.displayName = 'DrawerPopup';
342+
}
343+
344+
export default RefDrawerPopup;

0 commit comments

Comments
 (0)