fix: layout provide not work

pull/2682/head
tanjinzhou 2020-07-31 18:19:50 +08:00
parent a19beced12
commit 85fcb138a2
5 changed files with 93 additions and 79 deletions

@ -1 +1 @@
Subproject commit bda092900405709ab19219754c43d68975a143be Subproject commit 549184a4fab38d9a234bc04e818ecc8b958ab4f4

View File

@ -14,6 +14,7 @@ import { ConfigConsumerProps } from '../config-provider';
import BarsOutlined from '@ant-design/icons-vue/BarsOutlined'; import BarsOutlined from '@ant-design/icons-vue/BarsOutlined';
import RightOutlined from '@ant-design/icons-vue/RightOutlined'; import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined'; import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
import omit from 'omit.js';
// matchMedia polyfill for // matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82 // https://github.com/WickyNilliams/enquire.js/issues/82
@ -53,6 +54,9 @@ export const SiderProps = {
collapsedWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), collapsedWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']), breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']),
theme: PropTypes.oneOf(['light', 'dark']).def('dark'), theme: PropTypes.oneOf(['light', 'dark']).def('dark'),
onBreakpoint: PropTypes.func,
onCollapse: PropTypes.func,
'onUpdate:collapse': PropTypes.func,
}; };
// export interface SiderState { // export interface SiderState {
@ -177,16 +181,29 @@ export default {
render() { render() {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
class: className,
theme, theme,
collapsible, collapsible,
reverseArrow, reverseArrow,
style,
width, width,
collapsedWidth, collapsedWidth,
zeroWidthTriggerStyle, zeroWidthTriggerStyle,
} = getOptionProps(this); ...others
} = { ...getOptionProps(this), ...this.$attrs };
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls); const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);
const divProps = omit(others, [
'collapsed',
'defaultCollapsed',
'onCollapse',
'breakpoint',
'onBreakpoint',
'siderHook',
'zeroWidthTriggerStyle',
'trigger',
'onUpdate:collapse',
]);
const trigger = getComponent(this, 'trigger'); const trigger = getComponent(this, 'trigger');
const rawWidth = this.sCollapsed ? collapsedWidth : width; const rawWidth = this.sCollapsed ? collapsedWidth : width;
// use "px" as fallback unit for width // use "px" as fallback unit for width
@ -219,24 +236,20 @@ export default {
) )
: null; : null;
const divStyle = { const divStyle = {
// ...style, ...style,
flex: `0 0 ${siderWidth}`, flex: `0 0 ${siderWidth}`,
maxWidth: siderWidth, // Fix width transition bug in IE11 maxWidth: siderWidth, // Fix width transition bug in IE11
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349 minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
width: siderWidth, width: siderWidth,
}; };
const siderCls = classNames(prefixCls, `${prefixCls}-${theme}`, { const siderCls = classNames(className, prefixCls, `${prefixCls}-${theme}`, {
[`${prefixCls}-collapsed`]: !!this.sCollapsed, [`${prefixCls}-collapsed`]: !!this.sCollapsed,
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger, [`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
[`${prefixCls}-below`]: !!this.below, [`${prefixCls}-below`]: !!this.below,
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0, [`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
}); });
const divProps = {
class: siderCls,
style: divStyle,
};
return ( return (
<aside {...divProps}> <aside class={siderCls} {...divProps} style={divStyle}>
<div class={`${prefixCls}-children`}>{getSlot(this)}</div> <div class={`${prefixCls}-children`}>{getSlot(this)}</div>
{collapsible || (this.below && zeroWidthTrigger) ? triggerDom : null} {collapsible || (this.below && zeroWidthTrigger) ? triggerDom : null}
</aside> </aside>

View File

@ -1,7 +1,7 @@
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import * as Vue from 'vue';
import Layout from '..'; import Layout from '..';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import { sleep } from '../../../tests/utils';
const { Sider, Content } = Layout; const { Sider, Content } = Layout;
@ -9,8 +9,9 @@ describe('Layout', () => {
mountTest(Layout); mountTest(Layout);
mountTest(Content); mountTest(Content);
mountTest(Sider); mountTest(Sider);
it('detect the sider as children', done => { it('detect the sider as children', async () => {
const wrapper = mount({ const wrapper = mount(
{
render() { render() {
return ( return (
<Layout> <Layout>
@ -19,15 +20,16 @@ describe('Layout', () => {
</Layout> </Layout>
); );
}, },
}); },
Vue.nextTick(() => { { sync: false },
);
await sleep();
expect(wrapper.find('.ant-layout').classes()).toContain('ant-layout-has-sider'); expect(wrapper.find('.ant-layout').classes()).toContain('ant-layout-has-sider');
done();
});
}); });
it('detect the sider inside the children', done => { it('detect the sider inside the children', async () => {
const wrapper = mount({ const wrapper = mount(
{
render() { render() {
return ( return (
<Layout> <Layout>
@ -38,15 +40,16 @@ describe('Layout', () => {
</Layout> </Layout>
); );
}, },
}); },
Vue.nextTick(() => { { sync: false },
);
await sleep();
expect(wrapper.find('.ant-layout').classes()).toContain('ant-layout-has-sider'); expect(wrapper.find('.ant-layout').classes()).toContain('ant-layout-has-sider');
done();
});
}); });
it('detect ant-layout-sider-has-trigger class in sider when ant-layout-sider-trigger div tag exists', done => { it('detect ant-layout-sider-has-trigger class in sider when ant-layout-sider-trigger div tag exists', async () => {
const wrapper = mount({ const wrapper = mount(
{
render() { render() {
return ( return (
<Layout> <Layout>
@ -57,10 +60,10 @@ describe('Layout', () => {
</Layout> </Layout>
); );
}, },
}); },
Vue.nextTick(() => { { sync: false },
);
await sleep();
expect(wrapper.find('.ant-layout-sider').classes()).toContain('ant-layout-sider-has-trigger'); expect(wrapper.find('.ant-layout-sider').classes()).toContain('ant-layout-sider-has-trigger');
done();
});
}); });
}); });

View File

@ -1,4 +1,4 @@
import { inject } from 'vue'; import { inject, provide } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { getOptionProps, getSlot } from '../_util/props-util'; import { getOptionProps, getSlot } from '../_util/props-util';
@ -54,17 +54,15 @@ const BasicLayout = {
siders: [], siders: [],
}; };
}, },
provide() { created() {
return { provide('siderHook', {
siderHook: {
addSider: id => { addSider: id => {
this.siders = [...this.siders, id]; this.siders = [...this.siders, id];
}, },
removeSider: id => { removeSider: id => {
this.siders = this.siders.filter(currentId => currentId !== id); this.siders = this.siders.filter(currentId => currentId !== id);
}, },
}, });
};
}, },
render() { render() {
const { prefixCls, hasSider, tagName: Tag } = this; const { prefixCls, hasSider, tagName: Tag } = this;

View File

@ -8,15 +8,15 @@ if (typeof window !== 'undefined') {
global.window.dispatchEvent(new Event('resize')); global.window.dispatchEvent(new Event('resize'));
}; };
global.window.scrollTo = () => {}; global.window.scrollTo = () => {};
if (!window.matchMedia) { // if (!window.matchMedia) {
Object.defineProperty(global.window, 'matchMedia', { // Object.defineProperty(global.window, 'matchMedia', {
value: jest.fn(query => ({ // value: jest.fn(query => ({
matches: query.includes('max-width'), // matches: query.includes('max-width'),
addListener: jest.fn(), // addListener: jest.fn(),
removeListener: jest.fn(), // removeListener: jest.fn(),
})), // })),
}); // });
} // }
} }
// The built-in requestAnimationFrame and cancelAnimationFrame not working with jest.runFakeTimes() // The built-in requestAnimationFrame and cancelAnimationFrame not working with jest.runFakeTimes()