fix: zeroWidth trigger sider not collapsible (#28000)

* test: Test driven

* fix: Hooks for reuse

* test: More test case
This commit is contained in:
二货机器人 2020-11-25 17:28:17 +08:00 committed by GitHub
parent 0cec7ff982
commit e19d0e0357
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 27 deletions

View File

@ -1,4 +1,5 @@
import * as React from 'react';
import { useContext, useRef, useState, useEffect } from 'react';
import classNames from 'classnames';
import omit from 'omit.js';
import BarsOutlined from '@ant-design/icons/BarsOutlined';
@ -76,14 +77,14 @@ const Sider: React.FC<SiderProps> = ({
onBreakpoint,
...props
}) => {
const { siderHook } = React.useContext(LayoutContext);
const { siderHook } = useContext(LayoutContext);
const [collapsed, setCollapsed] = React.useState(
const [collapsed, setCollapsed] = useState(
'collapsed' in props ? props.collapsed : defaultCollapsed,
);
const [below, setBelow] = React.useState(false);
const [below, setBelow] = useState(false);
React.useEffect(() => {
useEffect(() => {
if ('collapsed' in props) {
setCollapsed(props.collapsed);
}
@ -98,16 +99,23 @@ const Sider: React.FC<SiderProps> = ({
}
};
React.useEffect(() => {
const responsiveHandler = (mql: MediaQueryListEvent | MediaQueryList) => {
setBelow(mql.matches);
if (onBreakpoint) {
onBreakpoint(mql.matches);
}
if (collapsed !== mql.matches) {
handleSetCollapsed(mql.matches, 'responsive');
}
};
// ========================= Responsive =========================
const responsiveHandlerRef = useRef<(mql: MediaQueryListEvent | MediaQueryList) => void>();
responsiveHandlerRef.current = (mql: MediaQueryListEvent | MediaQueryList) => {
setBelow(mql.matches);
if (onBreakpoint) {
onBreakpoint(mql.matches);
}
if (collapsed !== mql.matches) {
handleSetCollapsed(mql.matches, 'responsive');
}
};
useEffect(() => {
function responsiveHandler(mql: MediaQueryListEvent | MediaQueryList) {
return responsiveHandlerRef.current!(mql);
}
let mql: MediaQueryList;
if (typeof window !== 'undefined') {
@ -129,9 +137,9 @@ const Sider: React.FC<SiderProps> = ({
mql?.removeListener(responsiveHandler);
}
};
}, [onBreakpoint, collapsed]);
}, []);
React.useEffect(() => {
useEffect(() => {
const uniqueId = generateId('ant-sider-');
siderHook.addSider(uniqueId);
return () => siderHook.removeSider(uniqueId);
@ -141,7 +149,7 @@ const Sider: React.FC<SiderProps> = ({
handleSetCollapsed(!collapsed, 'clickTrigger');
};
const { getPrefixCls } = React.useContext(ConfigContext);
const { getPrefixCls } = useContext(ConfigContext);
const renderSider = () => {
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);

View File

@ -98,16 +98,65 @@ describe('Layout', () => {
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').flex).toBe('0 0 50%');
});
it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => {
const wrapper = mount(
<Layout>
<div>
<Sider width="0%">Sider</Sider>
</div>
<Content>Content</Content>
</Layout>,
);
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-zero-width')).toBe(true);
describe('zeroWidth', () => {
it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => {
const wrapper = mount(
<Layout>
<div>
<Sider width="0%">Sider</Sider>
</div>
<Content>Content</Content>
</Layout>,
);
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-zero-width')).toBe(true);
});
describe('should collapsible', () => {
it('uncontrolled', () => {
const onCollapse = jest.fn();
const wrapper = mount(
<Layout>
<Sider collapsible breakpoint="lg" collapsedWidth="0" onCollapse={onCollapse}>
Sider
</Sider>
<Content>Content</Content>
</Layout>,
);
onCollapse.mockReset();
wrapper.find('.ant-layout-sider-zero-width-trigger').simulate('click');
expect(onCollapse).toHaveBeenCalledTimes(1);
});
it('controlled', () => {
const Demo = () => {
const [collapsed, setCollapsed] = React.useState(true);
return (
<Layout>
<Sider
collapsed={collapsed}
collapsible
breakpoint="lg"
collapsedWidth="0"
onCollapse={setCollapsed}
>
Sider
</Sider>
<Content>Content</Content>
</Layout>
);
};
const wrapper = mount(<Demo />);
expect(wrapper.find(Sider).prop('collapsed')).toBeTruthy();
wrapper.find('.ant-layout-sider-zero-width-trigger').simulate('click');
expect(wrapper.find(Sider).prop('collapsed')).toBeFalsy();
});
});
});
it('detect ant-layout-sider-dark as default theme', async () => {