From 5924b8729a1cc16f7d7e332dc70fce0687fe0bc8 Mon Sep 17 00:00:00 2001 From: baxtergu Date: Thu, 1 Apr 2021 11:21:16 +0800 Subject: [PATCH 1/3] feat: add autoFocus props for drawer --- README.md | 1 + src/DrawerChild.tsx | 20 +++++++++++++++----- src/DrawerWrapper.tsx | 2 ++ src/IDrawerPropTypes.ts | 1 + tests/drawer.spec.tsx | 36 ++++++++++++++++++++++++++++++++---- 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2185a620..fd4b2095 100755 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ ReactDom.render( | onHandleClick | func | nul | handle icon click function | | keyboard | Boolean | true | Whether support press esc to close | | contentWrapperStyle | CSSProperties | null | content wrapper style | +| autoFocus | Boolean | true | Whether focusing on the drawer after it opened | > 2.0 Rename `onMaskClick` -> `onClose`, add `maskClosable`. diff --git a/src/DrawerChild.tsx b/src/DrawerChild.tsx index 65cb74fb..bcdf9346 100644 --- a/src/DrawerChild.tsx +++ b/src/DrawerChild.tsx @@ -93,7 +93,7 @@ class DrawerChild extends React.Component { } catch (err) {} this.passive = passiveSupported ? { passive: false } : false; } - const { open, getContainer, showMask } = this.props; + const { open, getContainer, showMask, autoFocus } = this.props; const container = getContainer && getContainer(); this.drawerId = `drawer_id_${Number( (Date.now() + Math.random()) @@ -108,7 +108,9 @@ class DrawerChild extends React.Component { // 默认打开状态时推出 level; this.openLevelTransition(); this.forceUpdate(() => { - this.domFocus(); + if (autoFocus) { + this.domFocus(); + } }); if (showMask) { this.props.scrollLocker?.lock(); @@ -117,7 +119,13 @@ class DrawerChild extends React.Component { } public componentDidUpdate(prevProps: IDrawerChildProps) { - const { open, getContainer, scrollLocker, showMask } = this.props; + const { + open, + getContainer, + scrollLocker, + showMask, + autoFocus, + } = this.props; const container = getContainer && getContainer(); if (open !== prevProps.open) { if (container && container.parentNode === document.body) { @@ -125,7 +133,9 @@ class DrawerChild extends React.Component { } this.openLevelTransition(); if (open) { - this.domFocus(); + if (autoFocus) { + this.domFocus(); + } if (showMask) { scrollLocker?.lock(); } @@ -547,7 +557,7 @@ class DrawerChild extends React.Component { msTransform: transform, width: isNumeric(width) ? `${width}px` : width, height: isNumeric(height) ? `${height}px` : height, - ...contentWrapperStyle + ...contentWrapperStyle, }} ref={c => { this.contentWrapper = c as HTMLElement; diff --git a/src/DrawerWrapper.tsx b/src/DrawerWrapper.tsx index 4ed262f5..adfaa33e 100644 --- a/src/DrawerWrapper.tsx +++ b/src/DrawerWrapper.tsx @@ -35,6 +35,7 @@ class DrawerWrapper extends React.Component { className: '', keyboard: true, forceRender: false, + autoFocus: true, }; public static getDerivedStateFromProps( @@ -100,6 +101,7 @@ class DrawerWrapper extends React.Component { wrapperClassName, forceRender, handler, + autoFocus, ...props } = this.props; const { open } = this.state; diff --git a/src/IDrawerPropTypes.ts b/src/IDrawerPropTypes.ts index 028b3572..e8637b2c 100644 --- a/src/IDrawerPropTypes.ts +++ b/src/IDrawerPropTypes.ts @@ -35,6 +35,7 @@ interface IProps extends Omit, 'onChange'> { onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void; keyboard?: boolean; contentWrapperStyle?: React.CSSProperties; + autoFocus?: boolean; } export interface IDrawerProps extends IProps { diff --git a/tests/drawer.spec.tsx b/tests/drawer.spec.tsx index 5b1ff853..6972d3fe 100644 --- a/tests/drawer.spec.tsx +++ b/tests/drawer.spec.tsx @@ -1,11 +1,11 @@ +/* eslint-disable max-classes-per-file */ // eslint-disable react/no-multi-comp import { mount } from 'enzyme'; import * as React from 'react'; import Drawer from '../src/'; -import { IDrawerProps } from '../src/IDrawerPropTypes'; +import type { IDrawerProps } from '../src/IDrawerPropTypes'; import toJson from 'enzyme-to-json'; - class DrawerTesterRef extends React.Component { public container: HTMLDivElement; public getContainer = () => { @@ -51,7 +51,11 @@ class DrawerTesterDom extends React.Component {
{this.state.visible ? ( - +

Here is content of Drawer

) : null} @@ -62,7 +66,7 @@ class DrawerTesterDom extends React.Component { /* eslint react/no-multi-comp: 0 */ // tslint:disable-next-line:max-classes-per-file -const DrawerTesterBoolean = (props) => ( +const DrawerTesterBoolean = props => (

Here is content of Drawer

@@ -70,6 +74,22 @@ const DrawerTesterBoolean = (props) => (
); +/* eslint react/no-multi-comp: 0 */ +// tslint:disable-next-line:max-classes-per-file +const DrawerTesterAutoFocus = props => ( +
+ +

Here is content of Drawer

+
+
+); + describe('Drawer', () => { it('render function', () => { const wrapper = mount(); @@ -85,4 +105,12 @@ describe('Drawer', () => { const wrapper = mount(); expect(toJson(wrapper.render())).toMatchSnapshot(); }); + + it('render autoFocus', () => { + const wrapper = mount(); + expect( + wrapper.find('.autofocus-test-wrapper-class-name').is(':focus'), + ).toBe(false); + expect(toJson(wrapper.render())).toMatchSnapshot(); + }); }); From 9c42d35ed89b51578059b1a46eb0404a4ad30c2e Mon Sep 17 00:00:00 2001 From: baxtergu Date: Thu, 1 Apr 2021 13:19:47 +0800 Subject: [PATCH 2/3] fix: autoFocus keeps in props. move test case --- src/DrawerWrapper.tsx | 1 - tests/drawer.spec.tsx | 24 ------------------------ tests/index.spec.tsx | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/DrawerWrapper.tsx b/src/DrawerWrapper.tsx index adfaa33e..3446a4b6 100644 --- a/src/DrawerWrapper.tsx +++ b/src/DrawerWrapper.tsx @@ -101,7 +101,6 @@ class DrawerWrapper extends React.Component { wrapperClassName, forceRender, handler, - autoFocus, ...props } = this.props; const { open } = this.state; diff --git a/tests/drawer.spec.tsx b/tests/drawer.spec.tsx index 6972d3fe..a3986ac9 100644 --- a/tests/drawer.spec.tsx +++ b/tests/drawer.spec.tsx @@ -74,22 +74,6 @@ const DrawerTesterBoolean = props => (
); -/* eslint react/no-multi-comp: 0 */ -// tslint:disable-next-line:max-classes-per-file -const DrawerTesterAutoFocus = props => ( -
- -

Here is content of Drawer

-
-
-); - describe('Drawer', () => { it('render function', () => { const wrapper = mount(); @@ -105,12 +89,4 @@ describe('Drawer', () => { const wrapper = mount(); expect(toJson(wrapper.render())).toMatchSnapshot(); }); - - it('render autoFocus', () => { - const wrapper = mount(); - expect( - wrapper.find('.autofocus-test-wrapper-class-name').is(':focus'), - ).toBe(false); - expect(toJson(wrapper.render())).toMatchSnapshot(); - }); }); diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index c0414796..e5b73ac1 100755 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -225,4 +225,23 @@ describe('rc-drawer-menu', () => { const content = instance.find('.drawer-content-wrapper').instance() as any; expect(content.style.background).toBe('rgb(255, 0, 0)'); }); + + it('autoFocus:false', () => { + instance = mount( +
+ +

Here is content of Drawer

+
+
, + ); + + expect( + instance.find('.autofocus-test-wrapper-class-name').is(':focus'), + ).toBe(false); + }); }); From dbae1bb8f8f302537a37acd83f53424927383c4f Mon Sep 17 00:00:00 2001 From: baxtergu Date: Thu, 1 Apr 2021 13:58:59 +0800 Subject: [PATCH 3/3] feat: add autoFocus test case --- tests/index.spec.tsx | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index e5b73ac1..69ffe00f 100755 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -226,22 +226,31 @@ describe('rc-drawer-menu', () => { expect(content.style.background).toBe('rgb(255, 0, 0)'); }); - it('autoFocus:false', () => { + it('autoFocus', () => { instance = mount( -
- -

Here is content of Drawer

-
-
, + +

Here is content of Drawer

+
, ); - expect( - instance.find('.autofocus-test-wrapper-class-name').is(':focus'), - ).toBe(false); + // In case { autoFocus: false }, default activeElement shouldn't be drawer node + expect(document.activeElement).not.toBe( + instance.find('.auto-focus-test-wrapper .drawer').at(0).getDOMNode(), + ); + + // Close and reopen drawer with props {autoFocus: true} + instance.setProps({ open: false, autoFocus: true }); + + instance.setProps({ open: true }); + + // In case { autoFocus: true }, by which is also 's default, the activeElement will be drawer by itself + expect(document.activeElement).toBe( + instance.find('.auto-focus-test-wrapper .drawer').at(0).getDOMNode(), + ); }); });