Merge branch 'master' into antd-3.0

This commit is contained in:
afc163 2017-11-09 20:37:30 +08:00
commit b53e76cbd5
7 changed files with 105 additions and 19 deletions

View File

@ -3,6 +3,9 @@ import throttleByAnimationFrame from '../throttleByAnimationFrame';
jest.useFakeTimers(); jest.useFakeTimers();
describe('Test utils function', () => { describe('Test utils function', () => {
afterAll(() => {
jest.useRealTimers();
});
it('throttle function should work', () => { it('throttle function should work', () => {
const callback = jest.fn(); const callback = jest.fn();
const throttled = throttleByAnimationFrame(callback); const throttled = throttleByAnimationFrame(callback);

View File

@ -48,6 +48,9 @@ class AffixMounter extends React.Component {
} }
describe('Affix Render', () => { describe('Affix Render', () => {
afterAll(() => {
jest.useRealTimers();
});
it('Anchor render perfectly', () => { it('Anchor render perfectly', () => {
document.body.innerHTML = '<div id="mounter" />'; document.body.innerHTML = '<div id="mounter" />';

View File

@ -43,6 +43,14 @@ export interface SiderProps {
breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
} }
const generateId = (() => {
let i = 0;
return (prefix: string = '') => {
i += 1;
return `${prefix}${i}`;
};
})();
export default class Sider extends React.Component<SiderProps, any> { export default class Sider extends React.Component<SiderProps, any> {
static __ANT_LAYOUT_SIDER: any = true; static __ANT_LAYOUT_SIDER: any = true;
@ -60,10 +68,16 @@ export default class Sider extends React.Component<SiderProps, any> {
siderCollapsed: PropTypes.bool, siderCollapsed: PropTypes.bool,
}; };
static contextTypes = {
siderHook: PropTypes.object,
};
private mql: any; private mql: any;
private uniqueId: string;
constructor(props) { constructor(props) {
super(props); super(props);
this.uniqueId = generateId('ant-sider-');
let matchMedia; let matchMedia;
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
matchMedia = window.matchMedia; matchMedia = window.matchMedia;
@ -102,12 +116,20 @@ export default class Sider extends React.Component<SiderProps, any> {
this.mql.addListener(this.responsiveHandler); this.mql.addListener(this.responsiveHandler);
this.responsiveHandler(this.mql); this.responsiveHandler(this.mql);
} }
if (this.context.siderHook) {
this.context.siderHook.addSider(this.uniqueId);
}
} }
componentWillUnmount() { componentWillUnmount() {
if (this.mql) { if (this.mql) {
this.mql.removeListener(this.responsiveHandler); this.mql.removeListener(this.responsiveHandler);
} }
if (this.context.siderHook) {
this.context.siderHook.removeSider(this.uniqueId);
}
} }
responsiveHandler = (mql) => { responsiveHandler = (mql) => {

View File

@ -30,7 +30,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
Header Header
</div> </div>
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-sider" class="ant-layout-sider"
@ -63,7 +63,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
Header Header
</div> </div>
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-content" class="ant-layout-content"
@ -88,7 +88,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
</div> </div>
</div> </div>
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-sider" class="ant-layout-sider"
@ -125,7 +125,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = ` exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-sider" class="ant-layout-sider"
@ -309,7 +309,7 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = ` exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-sider" class="ant-layout-sider"
@ -574,7 +574,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
exports[`renders ./components/layout/demo/responsive.md correctly 1`] = ` exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-sider" class="ant-layout-sider"
@ -684,7 +684,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
exports[`renders ./components/layout/demo/side.md correctly 1`] = ` exports[`renders ./components/layout/demo/side.md correctly 1`] = `
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
style="min-height:100vh" style="min-height:100vh"
> >
<div <div
@ -1041,7 +1041,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
</span> </span>
</div> </div>
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
style="padding:24px 0;background:#fff" style="padding:24px 0;background:#fff"
> >
<div <div
@ -1221,7 +1221,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
</ul> </ul>
</div> </div>
<div <div
class="ant-layout ant-layout-has-sider" class="ant-layout"
> >
<div <div
class="ant-layout-sider" class="ant-layout-sider"

View File

@ -0,0 +1,27 @@
import React from 'react';
import { mount } from 'enzyme';
import Layout from '..';
const { Sider, Content } = Layout;
describe('Layout', () => {
it('detect the sider as children', async () => {
const wrapper = mount(
<Layout>
<Sider>Sider</Sider>
<Content>Content</Content>
</Layout>
);
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(true);
});
it('detect the sider inside the children', async () => {
const wrapper = mount(
<Layout>
<div><Sider>Sider</Sider></div>
<Content>Content</Content>
</Layout>
);
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(true);
});
});

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { SiderProps } from './Sider'; import { SiderProps } from './Sider';
@ -9,7 +10,7 @@ export interface BasicProps {
} }
function generator(props) { function generator(props) {
return (BacicComponent): any => { return (BasicComponent): any => {
return class Adapter extends React.Component<BasicProps, any> { return class Adapter extends React.Component<BasicProps, any> {
static Header: any; static Header: any;
static Footer: any; static Footer: any;
@ -17,7 +18,7 @@ function generator(props) {
static Sider: any; static Sider: any;
render() { render() {
const { prefixCls } = props; const { prefixCls } = props;
return <BacicComponent prefixCls={prefixCls} {...this.props} />; return <BasicComponent prefixCls={prefixCls} {...this.props} />;
} }
}; };
}; };
@ -26,14 +27,40 @@ function generator(props) {
class Basic extends React.Component<BasicProps, any> { class Basic extends React.Component<BasicProps, any> {
render() { render() {
const { prefixCls, className, children, ...others } = this.props; const { prefixCls, className, children, ...others } = this.props;
let hasSider; const divCls = classNames(className, prefixCls);
React.Children.forEach(children, (element: any) => { return (
if (element && element.type && element.type.__ANT_LAYOUT_SIDER) { <div className={divCls} {...others}>{children}</div>
hasSider = true; );
} }
}); }
class BasicLayout extends React.Component<BasicProps, any> {
static childContextTypes = {
siderHook: PropTypes.object,
};
state = { siders: [] };
getChildContext() {
return {
siderHook: {
addSider: (id: string) => {
this.setState({
siders: [...this.state.siders, id],
});
},
removeSider: (id: string) => {
this.setState({
siders: this.state.siders.filter(currentId => currentId !== id),
});
},
},
};
}
render() {
const { prefixCls, className, children, ...others } = this.props;
const divCls = classNames(className, prefixCls, { const divCls = classNames(className, prefixCls, {
[`${prefixCls}-has-sider`]: hasSider, [`${prefixCls}-has-sider`]: this.state.siders.length > 0,
}); });
return ( return (
<div className={divCls} {...others}>{children}</div> <div className={divCls} {...others}>{children}</div>
@ -48,7 +75,7 @@ const Layout: React.ComponentClass<BasicProps> & {
Sider: React.ComponentClass<SiderProps>; Sider: React.ComponentClass<SiderProps>;
} = generator({ } = generator({
prefixCls: 'ant-layout', prefixCls: 'ant-layout',
})(Basic); })(BasicLayout);
const Header = generator({ const Header = generator({
prefixCls: 'ant-layout-header', prefixCls: 'ant-layout-header',

View File

@ -3,6 +3,10 @@ import notification from '..';
jest.useFakeTimers(); jest.useFakeTimers();
describe('notification', () => { describe('notification', () => {
afterAll(() => {
jest.useRealTimers();
});
afterEach(() => { afterEach(() => {
notification.destroy(); notification.destroy();
}); });