@rc-component/drawer 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/assets/index.css +1 -0
- package/es/Drawer.d.ts +2 -1
- package/es/Drawer.js +14 -2
- package/es/DrawerPopup.d.ts +2 -1
- package/es/DrawerPopup.js +8 -72
- package/es/hooks/useFocusable.d.ts +1 -0
- package/es/hooks/useFocusable.js +17 -0
- package/lib/Drawer.d.ts +2 -1
- package/lib/Drawer.js +14 -2
- package/lib/DrawerPopup.d.ts +2 -1
- package/lib/DrawerPopup.js +8 -72
- package/lib/hooks/useFocusable.d.ts +1 -0
- package/lib/hooks/useFocusable.js +24 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
# @rc-component/drawer
|
|
2
2
|
|
|
3
|
-
[![NPM version][npm-image]][npm-url]
|
|
3
|
+
[![NPM version][npm-image]][npm-url]
|
|
4
|
+
[![npm download][download-image]][download-url]
|
|
5
|
+
[![build status][github-actions-image]][github-actions-url]
|
|
6
|
+
[![codecov][codecov-image]][codecov-url]
|
|
7
|
+
[![dumi][dumi-image]][dumi-url]
|
|
4
8
|
|
|
5
9
|
[npm-image]: http://img.shields.io/npm/v/@rc-component/drawer.svg?style=flat-square
|
|
6
10
|
[npm-url]: http://npmjs.org/package/@rc-component/drawer
|
|
11
|
+
[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square
|
|
12
|
+
[dumi-url]: https://github.com/umijs/dumi
|
|
7
13
|
[github-actions-image]: https://github.com/react-component/drawer/actions/workflows/react-component-ci.yml/badge.svg
|
|
8
14
|
[github-actions-url]: https://github.com/react-component/drawer/actions/workflows/react-component-ci.yml
|
|
9
15
|
[download-image]: https://img.shields.io/npm/dm/@rc-component/drawer.svg?style=flat-square
|
|
10
16
|
[download-url]: https://npmjs.org/package/@rc-component/drawer
|
|
17
|
+
[codecov-image]: https://codecov.io/gh/react-component/drawer/branch/master/graph/badge.svg
|
|
18
|
+
[codecov-url]: https://codecov.io/gh/react-component/drawer
|
|
19
|
+
|
|
11
20
|
|
|
12
21
|
## Example
|
|
13
22
|
|
package/assets/index.css
CHANGED
package/es/Drawer.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type Placement = 'left' | 'top' | 'right' | 'bottom';
|
|
|
7
7
|
export interface DrawerProps extends Omit<DrawerPopupProps, 'prefixCls' | 'inline' | 'scrollLocker'>, DrawerPanelEvents, DrawerPanelAccessibility {
|
|
8
8
|
prefixCls?: string;
|
|
9
9
|
open?: boolean;
|
|
10
|
-
onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void;
|
|
10
|
+
onClose?: (e: React.MouseEvent | React.KeyboardEvent | KeyboardEvent) => void;
|
|
11
11
|
destroyOnHidden?: boolean;
|
|
12
12
|
getContainer?: PortalProps['getContainer'];
|
|
13
13
|
panelRef?: React.Ref<HTMLDivElement>;
|
|
@@ -33,6 +33,7 @@ export interface DrawerProps extends Omit<DrawerPopupProps, 'prefixCls' | 'inlin
|
|
|
33
33
|
onResizeStart?: () => void;
|
|
34
34
|
onResizeEnd?: () => void;
|
|
35
35
|
};
|
|
36
|
+
focusTriggerAfterClose?: boolean;
|
|
36
37
|
}
|
|
37
38
|
declare const Drawer: React.FC<DrawerProps>;
|
|
38
39
|
export default Drawer;
|
package/es/Drawer.js
CHANGED
|
@@ -27,8 +27,10 @@ const Drawer = props => {
|
|
|
27
27
|
onClick,
|
|
28
28
|
onKeyDown,
|
|
29
29
|
onKeyUp,
|
|
30
|
+
onClose,
|
|
30
31
|
resizable,
|
|
31
32
|
defaultSize,
|
|
33
|
+
focusTriggerAfterClose,
|
|
32
34
|
// Refs
|
|
33
35
|
panelRef
|
|
34
36
|
} = props;
|
|
@@ -59,7 +61,7 @@ const Drawer = props => {
|
|
|
59
61
|
const internalAfterOpenChange = nextVisible => {
|
|
60
62
|
setAnimatedVisible(nextVisible);
|
|
61
63
|
afterOpenChange?.(nextVisible);
|
|
62
|
-
if (!nextVisible && lastActiveRef.current && !popupRef.current?.contains(lastActiveRef.current)) {
|
|
64
|
+
if (!nextVisible && focusTriggerAfterClose !== false && lastActiveRef.current && !popupRef.current?.contains(lastActiveRef.current)) {
|
|
63
65
|
lastActiveRef.current?.focus({
|
|
64
66
|
preventScroll: true
|
|
65
67
|
});
|
|
@@ -103,13 +105,23 @@ const Drawer = props => {
|
|
|
103
105
|
resizable,
|
|
104
106
|
...eventHandlers
|
|
105
107
|
};
|
|
108
|
+
const onEsc = ({
|
|
109
|
+
top,
|
|
110
|
+
event
|
|
111
|
+
}) => {
|
|
112
|
+
if (top && keyboard) {
|
|
113
|
+
event.stopPropagation();
|
|
114
|
+
onClose?.(event);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
106
117
|
return /*#__PURE__*/React.createElement(RefContext.Provider, {
|
|
107
118
|
value: refContext
|
|
108
119
|
}, /*#__PURE__*/React.createElement(Portal, {
|
|
109
120
|
open: mergedOpen || forceRender || animatedVisible,
|
|
110
121
|
autoDestroy: false,
|
|
111
122
|
getContainer: getContainer,
|
|
112
|
-
autoLock: mask && (mergedOpen || animatedVisible)
|
|
123
|
+
autoLock: mask && (mergedOpen || animatedVisible),
|
|
124
|
+
onEsc: onEsc
|
|
113
125
|
}, /*#__PURE__*/React.createElement(DrawerPopup, drawerPopupProps)));
|
|
114
126
|
};
|
|
115
127
|
if (process.env.NODE_ENV !== 'production') {
|
package/es/DrawerPopup.d.ts
CHANGED
|
@@ -12,8 +12,9 @@ export interface DrawerPopupProps extends DrawerPanelEvents, DrawerPanelAccessib
|
|
|
12
12
|
inline?: boolean;
|
|
13
13
|
push?: boolean | PushConfig;
|
|
14
14
|
forceRender?: boolean;
|
|
15
|
-
autoFocus?: boolean;
|
|
16
15
|
keyboard?: boolean;
|
|
16
|
+
autoFocus?: boolean;
|
|
17
|
+
focusTrap?: boolean;
|
|
17
18
|
rootClassName?: string;
|
|
18
19
|
rootStyle?: React.CSSProperties;
|
|
19
20
|
zIndex?: number;
|
package/es/DrawerPopup.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import CSSMotion from '@rc-component/motion';
|
|
4
|
-
import KeyCode from "@rc-component/util/es/KeyCode";
|
|
5
4
|
import pickAttrs from "@rc-component/util/es/pickAttrs";
|
|
6
5
|
import * as React from 'react';
|
|
7
6
|
import DrawerContext from "./context";
|
|
@@ -9,13 +8,7 @@ import DrawerPanel from "./DrawerPanel";
|
|
|
9
8
|
import useDrag from "./hooks/useDrag";
|
|
10
9
|
import { parseWidthHeight } from "./util";
|
|
11
10
|
import { useEvent } from '@rc-component/util';
|
|
12
|
-
|
|
13
|
-
width: 0,
|
|
14
|
-
height: 0,
|
|
15
|
-
overflow: 'hidden',
|
|
16
|
-
outline: 'none',
|
|
17
|
-
position: 'absolute'
|
|
18
|
-
};
|
|
11
|
+
import useFocusable from "./hooks/useFocusable";
|
|
19
12
|
const DrawerPopup = (props, ref) => {
|
|
20
13
|
const {
|
|
21
14
|
prefixCls,
|
|
@@ -24,8 +17,9 @@ const DrawerPopup = (props, ref) => {
|
|
|
24
17
|
inline,
|
|
25
18
|
push,
|
|
26
19
|
forceRender,
|
|
20
|
+
// Focus
|
|
27
21
|
autoFocus,
|
|
28
|
-
|
|
22
|
+
focusTrap,
|
|
29
23
|
// classNames
|
|
30
24
|
classNames: drawerClassNames,
|
|
31
25
|
// Root
|
|
@@ -65,53 +59,10 @@ const DrawerPopup = (props, ref) => {
|
|
|
65
59
|
|
|
66
60
|
// ================================ Refs ================================
|
|
67
61
|
const panelRef = React.useRef(null);
|
|
68
|
-
const sentinelStartRef = React.useRef(null);
|
|
69
|
-
const sentinelEndRef = React.useRef(null);
|
|
70
62
|
React.useImperativeHandle(ref, () => panelRef.current);
|
|
71
|
-
const onPanelKeyDown = event => {
|
|
72
|
-
const {
|
|
73
|
-
keyCode,
|
|
74
|
-
shiftKey
|
|
75
|
-
} = event;
|
|
76
|
-
switch (keyCode) {
|
|
77
|
-
// Tab active
|
|
78
|
-
case KeyCode.TAB:
|
|
79
|
-
{
|
|
80
|
-
if (keyCode === KeyCode.TAB) {
|
|
81
|
-
if (!shiftKey && document.activeElement === sentinelEndRef.current) {
|
|
82
|
-
sentinelStartRef.current?.focus({
|
|
83
|
-
preventScroll: true
|
|
84
|
-
});
|
|
85
|
-
} else if (shiftKey && document.activeElement === sentinelStartRef.current) {
|
|
86
|
-
sentinelEndRef.current?.focus({
|
|
87
|
-
preventScroll: true
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Close
|
|
95
|
-
case KeyCode.ESC:
|
|
96
|
-
{
|
|
97
|
-
if (onClose && keyboard) {
|
|
98
|
-
event.stopPropagation();
|
|
99
|
-
onClose(event);
|
|
100
|
-
}
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
63
|
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
React.useEffect(() => {
|
|
109
|
-
if (open && autoFocus) {
|
|
110
|
-
panelRef.current?.focus({
|
|
111
|
-
preventScroll: true
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}, [open]);
|
|
64
|
+
// ========================= Focusable ==========================
|
|
65
|
+
useFocusable(() => panelRef.current, open, autoFocus, focusTrap, mask);
|
|
115
66
|
|
|
116
67
|
// ============================ Push ============================
|
|
117
68
|
const [pushed, setPushed] = React.useState(false);
|
|
@@ -253,9 +204,7 @@ const DrawerPopup = (props, ref) => {
|
|
|
253
204
|
}, motionProps, {
|
|
254
205
|
visible: open,
|
|
255
206
|
forceRender: forceRender,
|
|
256
|
-
onVisibleChanged:
|
|
257
|
-
afterOpenChange?.(nextVisible);
|
|
258
|
-
},
|
|
207
|
+
onVisibleChanged: afterOpenChange,
|
|
259
208
|
removeOnLeave: false,
|
|
260
209
|
leavedClassName: `${prefixCls}-content-wrapper-hidden`
|
|
261
210
|
}), ({
|
|
@@ -303,21 +252,8 @@ const DrawerPopup = (props, ref) => {
|
|
|
303
252
|
}),
|
|
304
253
|
style: containerStyle,
|
|
305
254
|
tabIndex: -1,
|
|
306
|
-
ref: panelRef
|
|
307
|
-
|
|
308
|
-
}, maskNode, /*#__PURE__*/React.createElement("div", {
|
|
309
|
-
tabIndex: 0,
|
|
310
|
-
ref: sentinelStartRef,
|
|
311
|
-
style: sentinelStyle,
|
|
312
|
-
"aria-hidden": "true",
|
|
313
|
-
"data-sentinel": "start"
|
|
314
|
-
}), panelNode, /*#__PURE__*/React.createElement("div", {
|
|
315
|
-
tabIndex: 0,
|
|
316
|
-
ref: sentinelEndRef,
|
|
317
|
-
style: sentinelStyle,
|
|
318
|
-
"aria-hidden": "true",
|
|
319
|
-
"data-sentinel": "end"
|
|
320
|
-
})));
|
|
255
|
+
ref: panelRef
|
|
256
|
+
}, maskNode, panelNode));
|
|
321
257
|
};
|
|
322
258
|
const RefDrawerPopup = /*#__PURE__*/React.forwardRef(DrawerPopup);
|
|
323
259
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function useFocusable(getContainer: () => HTMLElement, open: boolean, autoFocus?: boolean, focusTrap?: boolean, mask?: boolean): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useLockFocus } from "@rc-component/util/es/Dom/focus";
|
|
3
|
+
export default function useFocusable(getContainer, open, autoFocus, focusTrap, mask) {
|
|
4
|
+
const mergedFocusTrap = focusTrap ?? mask !== false;
|
|
5
|
+
|
|
6
|
+
// Focus lock
|
|
7
|
+
useLockFocus(open && mergedFocusTrap, getContainer);
|
|
8
|
+
|
|
9
|
+
// Auto Focus
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
if (open && autoFocus === true) {
|
|
12
|
+
getContainer()?.focus({
|
|
13
|
+
preventScroll: true
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}, [open]);
|
|
17
|
+
}
|
package/lib/Drawer.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type Placement = 'left' | 'top' | 'right' | 'bottom';
|
|
|
7
7
|
export interface DrawerProps extends Omit<DrawerPopupProps, 'prefixCls' | 'inline' | 'scrollLocker'>, DrawerPanelEvents, DrawerPanelAccessibility {
|
|
8
8
|
prefixCls?: string;
|
|
9
9
|
open?: boolean;
|
|
10
|
-
onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void;
|
|
10
|
+
onClose?: (e: React.MouseEvent | React.KeyboardEvent | KeyboardEvent) => void;
|
|
11
11
|
destroyOnHidden?: boolean;
|
|
12
12
|
getContainer?: PortalProps['getContainer'];
|
|
13
13
|
panelRef?: React.Ref<HTMLDivElement>;
|
|
@@ -33,6 +33,7 @@ export interface DrawerProps extends Omit<DrawerPopupProps, 'prefixCls' | 'inlin
|
|
|
33
33
|
onResizeStart?: () => void;
|
|
34
34
|
onResizeEnd?: () => void;
|
|
35
35
|
};
|
|
36
|
+
focusTriggerAfterClose?: boolean;
|
|
36
37
|
}
|
|
37
38
|
declare const Drawer: React.FC<DrawerProps>;
|
|
38
39
|
export default Drawer;
|
package/lib/Drawer.js
CHANGED
|
@@ -36,8 +36,10 @@ const Drawer = props => {
|
|
|
36
36
|
onClick,
|
|
37
37
|
onKeyDown,
|
|
38
38
|
onKeyUp,
|
|
39
|
+
onClose,
|
|
39
40
|
resizable,
|
|
40
41
|
defaultSize,
|
|
42
|
+
focusTriggerAfterClose,
|
|
41
43
|
// Refs
|
|
42
44
|
panelRef
|
|
43
45
|
} = props;
|
|
@@ -68,7 +70,7 @@ const Drawer = props => {
|
|
|
68
70
|
const internalAfterOpenChange = nextVisible => {
|
|
69
71
|
setAnimatedVisible(nextVisible);
|
|
70
72
|
afterOpenChange?.(nextVisible);
|
|
71
|
-
if (!nextVisible && lastActiveRef.current && !popupRef.current?.contains(lastActiveRef.current)) {
|
|
73
|
+
if (!nextVisible && focusTriggerAfterClose !== false && lastActiveRef.current && !popupRef.current?.contains(lastActiveRef.current)) {
|
|
72
74
|
lastActiveRef.current?.focus({
|
|
73
75
|
preventScroll: true
|
|
74
76
|
});
|
|
@@ -112,13 +114,23 @@ const Drawer = props => {
|
|
|
112
114
|
resizable,
|
|
113
115
|
...eventHandlers
|
|
114
116
|
};
|
|
117
|
+
const onEsc = ({
|
|
118
|
+
top,
|
|
119
|
+
event
|
|
120
|
+
}) => {
|
|
121
|
+
if (top && keyboard) {
|
|
122
|
+
event.stopPropagation();
|
|
123
|
+
onClose?.(event);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
115
126
|
return /*#__PURE__*/React.createElement(_context.RefContext.Provider, {
|
|
116
127
|
value: refContext
|
|
117
128
|
}, /*#__PURE__*/React.createElement(_portal.default, {
|
|
118
129
|
open: mergedOpen || forceRender || animatedVisible,
|
|
119
130
|
autoDestroy: false,
|
|
120
131
|
getContainer: getContainer,
|
|
121
|
-
autoLock: mask && (mergedOpen || animatedVisible)
|
|
132
|
+
autoLock: mask && (mergedOpen || animatedVisible),
|
|
133
|
+
onEsc: onEsc
|
|
122
134
|
}, /*#__PURE__*/React.createElement(_DrawerPopup.default, drawerPopupProps)));
|
|
123
135
|
};
|
|
124
136
|
if (process.env.NODE_ENV !== 'production') {
|
package/lib/DrawerPopup.d.ts
CHANGED
|
@@ -12,8 +12,9 @@ export interface DrawerPopupProps extends DrawerPanelEvents, DrawerPanelAccessib
|
|
|
12
12
|
inline?: boolean;
|
|
13
13
|
push?: boolean | PushConfig;
|
|
14
14
|
forceRender?: boolean;
|
|
15
|
-
autoFocus?: boolean;
|
|
16
15
|
keyboard?: boolean;
|
|
16
|
+
autoFocus?: boolean;
|
|
17
|
+
focusTrap?: boolean;
|
|
17
18
|
rootClassName?: string;
|
|
18
19
|
rootStyle?: React.CSSProperties;
|
|
19
20
|
zIndex?: number;
|
package/lib/DrawerPopup.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _clsx = require("clsx");
|
|
8
8
|
var _motion = _interopRequireDefault(require("@rc-component/motion"));
|
|
9
|
-
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
|
|
10
9
|
var _pickAttrs = _interopRequireDefault(require("@rc-component/util/lib/pickAttrs"));
|
|
11
10
|
var React = _interopRequireWildcard(require("react"));
|
|
12
11
|
var _context = _interopRequireDefault(require("./context"));
|
|
@@ -14,17 +13,11 @@ var _DrawerPanel = _interopRequireDefault(require("./DrawerPanel"));
|
|
|
14
13
|
var _useDrag = _interopRequireDefault(require("./hooks/useDrag"));
|
|
15
14
|
var _util = require("./util");
|
|
16
15
|
var _util2 = require("@rc-component/util");
|
|
16
|
+
var _useFocusable = _interopRequireDefault(require("./hooks/useFocusable"));
|
|
17
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
18
18
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
19
19
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
20
20
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
21
|
-
const sentinelStyle = {
|
|
22
|
-
width: 0,
|
|
23
|
-
height: 0,
|
|
24
|
-
overflow: 'hidden',
|
|
25
|
-
outline: 'none',
|
|
26
|
-
position: 'absolute'
|
|
27
|
-
};
|
|
28
21
|
const DrawerPopup = (props, ref) => {
|
|
29
22
|
const {
|
|
30
23
|
prefixCls,
|
|
@@ -33,8 +26,9 @@ const DrawerPopup = (props, ref) => {
|
|
|
33
26
|
inline,
|
|
34
27
|
push,
|
|
35
28
|
forceRender,
|
|
29
|
+
// Focus
|
|
36
30
|
autoFocus,
|
|
37
|
-
|
|
31
|
+
focusTrap,
|
|
38
32
|
// classNames
|
|
39
33
|
classNames: drawerClassNames,
|
|
40
34
|
// Root
|
|
@@ -74,53 +68,10 @@ const DrawerPopup = (props, ref) => {
|
|
|
74
68
|
|
|
75
69
|
// ================================ Refs ================================
|
|
76
70
|
const panelRef = React.useRef(null);
|
|
77
|
-
const sentinelStartRef = React.useRef(null);
|
|
78
|
-
const sentinelEndRef = React.useRef(null);
|
|
79
71
|
React.useImperativeHandle(ref, () => panelRef.current);
|
|
80
|
-
const onPanelKeyDown = event => {
|
|
81
|
-
const {
|
|
82
|
-
keyCode,
|
|
83
|
-
shiftKey
|
|
84
|
-
} = event;
|
|
85
|
-
switch (keyCode) {
|
|
86
|
-
// Tab active
|
|
87
|
-
case _KeyCode.default.TAB:
|
|
88
|
-
{
|
|
89
|
-
if (keyCode === _KeyCode.default.TAB) {
|
|
90
|
-
if (!shiftKey && document.activeElement === sentinelEndRef.current) {
|
|
91
|
-
sentinelStartRef.current?.focus({
|
|
92
|
-
preventScroll: true
|
|
93
|
-
});
|
|
94
|
-
} else if (shiftKey && document.activeElement === sentinelStartRef.current) {
|
|
95
|
-
sentinelEndRef.current?.focus({
|
|
96
|
-
preventScroll: true
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Close
|
|
104
|
-
case _KeyCode.default.ESC:
|
|
105
|
-
{
|
|
106
|
-
if (onClose && keyboard) {
|
|
107
|
-
event.stopPropagation();
|
|
108
|
-
onClose(event);
|
|
109
|
-
}
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
72
|
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
React.useEffect(() => {
|
|
118
|
-
if (open && autoFocus) {
|
|
119
|
-
panelRef.current?.focus({
|
|
120
|
-
preventScroll: true
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}, [open]);
|
|
73
|
+
// ========================= Focusable ==========================
|
|
74
|
+
(0, _useFocusable.default)(() => panelRef.current, open, autoFocus, focusTrap, mask);
|
|
124
75
|
|
|
125
76
|
// ============================ Push ============================
|
|
126
77
|
const [pushed, setPushed] = React.useState(false);
|
|
@@ -262,9 +213,7 @@ const DrawerPopup = (props, ref) => {
|
|
|
262
213
|
}, motionProps, {
|
|
263
214
|
visible: open,
|
|
264
215
|
forceRender: forceRender,
|
|
265
|
-
onVisibleChanged:
|
|
266
|
-
afterOpenChange?.(nextVisible);
|
|
267
|
-
},
|
|
216
|
+
onVisibleChanged: afterOpenChange,
|
|
268
217
|
removeOnLeave: false,
|
|
269
218
|
leavedClassName: `${prefixCls}-content-wrapper-hidden`
|
|
270
219
|
}), ({
|
|
@@ -312,21 +261,8 @@ const DrawerPopup = (props, ref) => {
|
|
|
312
261
|
}),
|
|
313
262
|
style: containerStyle,
|
|
314
263
|
tabIndex: -1,
|
|
315
|
-
ref: panelRef
|
|
316
|
-
|
|
317
|
-
}, maskNode, /*#__PURE__*/React.createElement("div", {
|
|
318
|
-
tabIndex: 0,
|
|
319
|
-
ref: sentinelStartRef,
|
|
320
|
-
style: sentinelStyle,
|
|
321
|
-
"aria-hidden": "true",
|
|
322
|
-
"data-sentinel": "start"
|
|
323
|
-
}), panelNode, /*#__PURE__*/React.createElement("div", {
|
|
324
|
-
tabIndex: 0,
|
|
325
|
-
ref: sentinelEndRef,
|
|
326
|
-
style: sentinelStyle,
|
|
327
|
-
"aria-hidden": "true",
|
|
328
|
-
"data-sentinel": "end"
|
|
329
|
-
})));
|
|
264
|
+
ref: panelRef
|
|
265
|
+
}, maskNode, panelNode));
|
|
330
266
|
};
|
|
331
267
|
const RefDrawerPopup = /*#__PURE__*/React.forwardRef(DrawerPopup);
|
|
332
268
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function useFocusable(getContainer: () => HTMLElement, open: boolean, autoFocus?: boolean, focusTrap?: boolean, mask?: boolean): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = useFocusable;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _focus = require("@rc-component/util/lib/Dom/focus");
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function useFocusable(getContainer, open, autoFocus, focusTrap, mask) {
|
|
11
|
+
const mergedFocusTrap = focusTrap ?? mask !== false;
|
|
12
|
+
|
|
13
|
+
// Focus lock
|
|
14
|
+
(0, _focus.useLockFocus)(open && mergedFocusTrap, getContainer);
|
|
15
|
+
|
|
16
|
+
// Auto Focus
|
|
17
|
+
_react.default.useEffect(() => {
|
|
18
|
+
if (open && autoFocus === true) {
|
|
19
|
+
getContainer()?.focus({
|
|
20
|
+
preventScroll: true
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}, [open]);
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rc-component/drawer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "drawer component for react",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@rc-component/motion": "^1.1.4",
|
|
47
|
-
"@rc-component/portal": "^2.
|
|
47
|
+
"@rc-component/portal": "^2.1.3",
|
|
48
48
|
"@rc-component/util": "^1.2.1",
|
|
49
49
|
"clsx": "^2.1.1"
|
|
50
50
|
},
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@testing-library/jest-dom": "^6.2.0",
|
|
56
56
|
"@testing-library/react": "^16.3.0",
|
|
57
57
|
"@types/jest": "^29.5.11",
|
|
58
|
-
"@types/node": "^
|
|
58
|
+
"@types/node": "^25.0.0",
|
|
59
59
|
"@types/raf": "^3.4.0",
|
|
60
60
|
"@types/react": "^19.0.0",
|
|
61
61
|
"@types/react-dom": "^19.0.0",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"react": "^19.0.0",
|
|
76
76
|
"react-dom": "^19.0.0",
|
|
77
77
|
"stylelint": "^16.2.1",
|
|
78
|
-
"stylelint-config-standard-less": "^
|
|
78
|
+
"stylelint-config-standard-less": "^4.0.0",
|
|
79
79
|
"typescript": "^5.3.3"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|