mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-03 04:30:06 +08:00
Merge branch 'master' into feature-3.6.0
This commit is contained in:
commit
21ca50fca1
@ -14,6 +14,17 @@ timeline: true
|
||||
* Major version release is not included in this schedule for breaking change and new features.
|
||||
|
||||
---
|
||||
|
||||
## 3.5.4
|
||||
|
||||
`2018-05-26`
|
||||
|
||||
- 🐞 Fix `showSearch` on `Cascader` not working.[968488a2](https://github.com/ant-design/ant-design/commit/968488a2fac9bcb16bee9f0c248f49bca00dbec6)
|
||||
- 🐞 `Badge[status]` support `Tooltip`.[#10626](https://github.com/ant-design/ant-design/issues/10626)
|
||||
- 🐞 Fix `text-align` on parent element affects `Spin`.[#10643](https://github.com/ant-design/ant-design/pull/10643) [@wmzhong](https://github.com/wmzhong)
|
||||
- 💄 `Table` break line style change from `break-all` to `break-word`.[#10655](https://github.com/ant-design/ant-design/pull/10655) [@clinyong](https://github.com/clinyong)
|
||||
- 🌟 When `Search` not define `enterButton`, click search icon will trigger `onSearch`. [36ffe7e1](https://github.com/ant-design/ant-design/commit/36ffe7e1dc9d9473c8c68168ab79b7a03a604702)
|
||||
|
||||
## 3.5.3
|
||||
|
||||
`2018-05-20`
|
||||
@ -456,7 +467,7 @@ Happy 2018 !~ 2018 2018 2018 coming!~~~
|
||||
|
||||
`2017-12-04`
|
||||
|
||||
Learn more in the [Ant Design 3.0 announcement post](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)!
|
||||
Learn more in the [Ant Design 3.0 announcement post](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c).
|
||||
|
||||
### Major Changes
|
||||
|
||||
|
@ -14,11 +14,21 @@ timeline: true
|
||||
* 主版本号:含有破坏性更新和新特性,不在发布周期内。
|
||||
|
||||
---
|
||||
|
||||
## 3.5.4
|
||||
|
||||
`2018-05-26`
|
||||
|
||||
- 🐞 修复 `Cascader` 的 `showSearch` 无效问题。[968488a2](https://github.com/ant-design/ant-design/commit/968488a2fac9bcb16bee9f0c248f49bca00dbec6)
|
||||
- 🐞 使 `Badge[status]` 支持 `Tooltip`。[#10626](https://github.com/ant-design/ant-design/issues/10626)
|
||||
- 🐞 修复父元素使用 `text-align` 会影响 `Spin` 的问题。[#10643](https://github.com/ant-design/ant-design/pull/10643) [@wmzhong](https://github.com/wmzhong)
|
||||
- 💄 `Table` 换行从 `break-all` 改为 `break-word`。[#10655](https://github.com/ant-design/ant-design/pull/10655) [@clinyong](https://github.com/clinyong)
|
||||
- 🌟 `Search` 在未定义 `enterButton` 时,点击搜索图标将触发 `onSearch`。 [36ffe7e1](https://github.com/ant-design/ant-design/commit/36ffe7e1dc9d9473c8c68168ab79b7a03a604702)
|
||||
|
||||
## 3.5.3
|
||||
|
||||
`2018-05-20`
|
||||
|
||||
|
||||
- 🐞 修复了 `Affix` 当 `offsetTop === 0`, 值将变为 `undefined` 的问题 [#10566](https://github.com/ant-design/ant-design/pull/10566)
|
||||
- 🐞 修复了 `Menu` item 中的高亮链接颜色问题 [09d5e36](https://github.com/ant-design/ant-design/commit/09d5e36cfa27e371a7b4d4e68276a279698ea901)
|
||||
- 🐞 修复了 `Input.Group` 组件阴影被遮盖的问题 [#10230](https://github.com/ant-design/ant-design/issues/10230)
|
||||
@ -459,11 +469,11 @@ timeline: true
|
||||
|
||||
`2017-12-04`
|
||||
|
||||
更多内容见 [Ant Design 3.0 发布公告](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)!
|
||||
更多内容见 [Ant Design 3.0 发布公告](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)。
|
||||
|
||||
### 主要变化
|
||||
|
||||
- 全新的[色彩系统](https://ant.design/docs/spec/colors-cn#Color-Palettes),组件主色由 『`#108EE9`』 改为 『`#1890FF`』,新主色我们称之为『拂晓蓝』。
|
||||
- 全新的[色彩系统](https://ant.design/docs/spec/colors-cn#Color-Palettes),组件主色由『`#108EE9`』改为『`#1890FF`』,新主色我们称之为『拂晓蓝』。
|
||||
- 全新的视觉样式和组件尺寸,更现代更美观。
|
||||
- 基础字体大小由 `12px` 增大到 `14px`。
|
||||
- 默认语言由中文改为英文。
|
||||
@ -475,6 +485,8 @@ timeline: true
|
||||
|
||||
### 不兼容改动
|
||||
|
||||
> 如果你从 2.x 升级到 3.x,建议直接升级到 3.x 的最新版本。
|
||||
|
||||
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。另外由于人肉查找代码中的废弃用法过于低效,所以我们提供了 [antd-migration-helper](https://github.com/ant-design/antd-migration-helper) 用于扫描代码中的废弃用法。
|
||||
|
||||
- Card 的 `noHovering` 属性重命名为 `hoverable`,且默认值改为 `true`。
|
||||
@ -521,7 +533,7 @@ timeline: true
|
||||
|
||||
- Form 下的表单控件不再默认为 `size="large"`。
|
||||
- `Input.Search` 默认的 🔍 图标只作为装饰,不再响应用户交互。需要添加可交互按钮请使用 `enterButton`。
|
||||
- UMD 版本的 `dist/antd.js` 不再包含 moment,使用的时候需要自己引入 moment。
|
||||
- UMD 版本的 `dist/antd.js` 不再包含 moment,使用的时候需要自己引入 moment。
|
||||
```diff
|
||||
<html>
|
||||
<head>
|
||||
|
31
components/alert/__tests__/index.test.js
Normal file
31
components/alert/__tests__/index.test.js
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Alert from '..';
|
||||
|
||||
describe('Alert', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('could be closed', () => {
|
||||
const onClose = jest.fn();
|
||||
const afterClose = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Alert
|
||||
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
|
||||
type="warning"
|
||||
closable
|
||||
onClose={onClose}
|
||||
afterClose={afterClose}
|
||||
/>
|
||||
);
|
||||
wrapper.find('.ant-alert-close-icon').simulate('click');
|
||||
expect(onClose).toBeCalled();
|
||||
jest.runAllTimers();
|
||||
expect(afterClose).toBeCalled();
|
||||
});
|
||||
});
|
@ -62,10 +62,10 @@ describe('Anchor Render', () => {
|
||||
wrapper.instance().handleScrollTo('##API');
|
||||
expect(wrapper.instance().state.activeLink).toBe('##API');
|
||||
expect(scrollToSpy).not.toHaveBeenCalled();
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
expect(scrollToSpy).toHaveBeenCalled();
|
||||
expect(wrapper.instance().animating).toBe(true);
|
||||
await new Promise(resolve => setTimeout(resolve, 400));
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
expect(wrapper.instance().animating).toBe(false);
|
||||
});
|
||||
|
||||
|
@ -196,7 +196,7 @@ exports[`Badge should render when count is changed 1`] = `
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
@ -206,7 +206,7 @@ exports[`Badge should render when count is changed 1`] = `
|
||||
className="ant-badge-count ant-badge-multiple-words"
|
||||
count={10}
|
||||
data-show={true}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
onAnimated={[Function]}
|
||||
prefixCls="ant-scroll-number"
|
||||
title={10}
|
||||
@ -445,7 +445,7 @@ exports[`Badge should render when count is changed 2`] = `
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
@ -455,7 +455,7 @@ exports[`Badge should render when count is changed 2`] = `
|
||||
className="ant-badge-count ant-badge-multiple-words"
|
||||
count={11}
|
||||
data-show={true}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
onAnimated={[Function]}
|
||||
prefixCls="ant-scroll-number"
|
||||
title={11}
|
||||
@ -887,7 +887,7 @@ exports[`Badge should render when count is changed 3`] = `
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
@ -897,7 +897,7 @@ exports[`Badge should render when count is changed 3`] = `
|
||||
className="ant-badge-count ant-badge-multiple-words"
|
||||
count={11}
|
||||
data-show={true}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
onAnimated={[Function]}
|
||||
prefixCls="ant-scroll-number"
|
||||
title={11}
|
||||
@ -1329,7 +1329,7 @@ exports[`Badge should render when count is changed 4`] = `
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
@ -1339,7 +1339,7 @@ exports[`Badge should render when count is changed 4`] = `
|
||||
className="ant-badge-count ant-badge-multiple-words"
|
||||
count={10}
|
||||
data-show={true}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
onAnimated={[Function]}
|
||||
prefixCls="ant-scroll-number"
|
||||
title={10}
|
||||
@ -1771,7 +1771,7 @@ exports[`Badge should render when count is changed 5`] = `
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
@ -1781,7 +1781,7 @@ exports[`Badge should render when count is changed 5`] = `
|
||||
className="ant-badge-count"
|
||||
count={9}
|
||||
data-show={true}
|
||||
key="rc_animate_1527238793036"
|
||||
key="scrollNumber"
|
||||
onAnimated={[Function]}
|
||||
prefixCls="ant-scroll-number"
|
||||
title={9}
|
||||
|
@ -107,6 +107,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
count={displayCount}
|
||||
title={title || count}
|
||||
style={styleWithOffset}
|
||||
key="scrollNumber"
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -0,0 +1,170 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`react router react router 3 1`] = `
|
||||
<Breadcrumb
|
||||
params={
|
||||
Object {
|
||||
"id": 1,
|
||||
}
|
||||
}
|
||||
prefixCls="ant-breadcrumb"
|
||||
routes={
|
||||
Array [
|
||||
Object {
|
||||
"breadcrumbName": "Home",
|
||||
"childRoutes": Array [
|
||||
Object {
|
||||
"breadcrumbName": "Application List",
|
||||
"childRoutes": Array [
|
||||
Object {
|
||||
"breadcrumbName": "Application:id",
|
||||
"childRoutes": Array [
|
||||
Object {
|
||||
"breadcrumbName": "Detail",
|
||||
"name": "detail",
|
||||
"path": "detail",
|
||||
},
|
||||
],
|
||||
"name": "app",
|
||||
"path": ":id",
|
||||
},
|
||||
],
|
||||
"name": "apps",
|
||||
"path": "apps",
|
||||
},
|
||||
],
|
||||
"name": "home",
|
||||
"path": "/",
|
||||
},
|
||||
Object {
|
||||
"breadcrumbName": "Application List",
|
||||
"childRoutes": Array [
|
||||
Object {
|
||||
"breadcrumbName": "Application:id",
|
||||
"childRoutes": Array [
|
||||
Object {
|
||||
"breadcrumbName": "Detail",
|
||||
"name": "detail",
|
||||
"path": "detail",
|
||||
},
|
||||
],
|
||||
"name": "app",
|
||||
"path": ":id",
|
||||
},
|
||||
],
|
||||
"name": "apps",
|
||||
"path": "apps",
|
||||
},
|
||||
Object {
|
||||
"breadcrumbName": "Application:id",
|
||||
"childRoutes": Array [
|
||||
Object {
|
||||
"breadcrumbName": "Detail",
|
||||
"name": "detail",
|
||||
"path": "detail",
|
||||
},
|
||||
],
|
||||
"name": "app",
|
||||
"path": ":id",
|
||||
},
|
||||
Object {
|
||||
"breadcrumbName": "Detail",
|
||||
"name": "detail",
|
||||
"path": "detail",
|
||||
},
|
||||
]
|
||||
}
|
||||
separator="/"
|
||||
>
|
||||
<div
|
||||
className="ant-breadcrumb"
|
||||
>
|
||||
<BreadcrumbItem
|
||||
key="Home"
|
||||
prefixCls="ant-breadcrumb"
|
||||
separator="/"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
className="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href="#/"
|
||||
>
|
||||
Home
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
className="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbItem
|
||||
key="Application List"
|
||||
prefixCls="ant-breadcrumb"
|
||||
separator="/"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
className="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href="#/apps"
|
||||
>
|
||||
Application List
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
className="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbItem
|
||||
key="Application:id"
|
||||
prefixCls="ant-breadcrumb"
|
||||
separator="/"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
className="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href="#/apps/1"
|
||||
>
|
||||
Application1
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
className="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbItem
|
||||
key="Detail"
|
||||
prefixCls="ant-breadcrumb"
|
||||
separator="/"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
className="ant-breadcrumb-link"
|
||||
>
|
||||
<span>
|
||||
Detail
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</BreadcrumbItem>
|
||||
</div>
|
||||
</Breadcrumb>
|
||||
`;
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Route, Switch, Link, withRouter, MemoryRouter } from 'react-router-dom';
|
||||
import { Breadcrumb } from 'antd';
|
||||
import { mount } from 'enzyme';
|
||||
import Breadcrumb from '../index';
|
||||
|
||||
const Apps = () => (
|
||||
<ul className="app-list">
|
||||
@ -78,4 +78,73 @@ describe('react router', () => {
|
||||
expect(wrapper.find('BreadcrumbItem').length).toBe(2);
|
||||
expect(wrapper.find('BreadcrumbItem .ant-breadcrumb-link').at(1).text()).toBe('Application List');
|
||||
});
|
||||
|
||||
it('react router 3', () => {
|
||||
const routes = [{
|
||||
name: 'home',
|
||||
breadcrumbName: 'Home',
|
||||
path: '/',
|
||||
childRoutes: [
|
||||
{
|
||||
name: 'apps',
|
||||
breadcrumbName: 'Application List',
|
||||
path: 'apps',
|
||||
childRoutes: [
|
||||
{
|
||||
name: 'app',
|
||||
breadcrumbName: 'Application:id',
|
||||
path: ':id',
|
||||
childRoutes: [
|
||||
{
|
||||
name: 'detail',
|
||||
breadcrumbName: 'Detail',
|
||||
path: 'detail',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'apps',
|
||||
breadcrumbName: 'Application List',
|
||||
path: 'apps',
|
||||
childRoutes: [
|
||||
{
|
||||
name: 'app',
|
||||
breadcrumbName: 'Application:id',
|
||||
path: ':id',
|
||||
childRoutes: [
|
||||
{
|
||||
name: 'detail',
|
||||
breadcrumbName: 'Detail',
|
||||
path: 'detail',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'app',
|
||||
breadcrumbName: 'Application:id',
|
||||
path: ':id',
|
||||
childRoutes: [
|
||||
{
|
||||
name: 'detail',
|
||||
breadcrumbName: 'Detail',
|
||||
path: 'detail',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'detail',
|
||||
breadcrumbName: 'Detail',
|
||||
path: 'detail',
|
||||
}];
|
||||
const wrapper = mount(
|
||||
<Breadcrumb routes={routes} params={{ id: 1 }} />
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -215,6 +215,632 @@ exports[`Cascader popup correctly with defaultValue 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Cascader should highlight keyword and filter when search in Cascader 1`] = `
|
||||
<Popup
|
||||
action={
|
||||
Array [
|
||||
"click",
|
||||
]
|
||||
}
|
||||
align={
|
||||
Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tl",
|
||||
"bl",
|
||||
],
|
||||
}
|
||||
}
|
||||
className=""
|
||||
destroyPopupOnHide={false}
|
||||
getClassNameFromAlign={[Function]}
|
||||
getRootDomNode={[Function]}
|
||||
mask={false}
|
||||
onAlign={[Function]}
|
||||
prefixCls="ant-cascader-menus"
|
||||
style={Object {}}
|
||||
transitionName="slide-up"
|
||||
visible={true}
|
||||
>
|
||||
<div>
|
||||
<Animate
|
||||
animation={Object {}}
|
||||
component=""
|
||||
componentProps={Object {}}
|
||||
exclusive={true}
|
||||
onAppear={[Function]}
|
||||
onEnd={[Function]}
|
||||
onEnter={[Function]}
|
||||
onLeave={[Function]}
|
||||
showProp="xVisible"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
transitionName="slide-up"
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="popup"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
transitionName="slide-up"
|
||||
>
|
||||
<Align
|
||||
align={
|
||||
Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tl",
|
||||
"bl",
|
||||
],
|
||||
}
|
||||
}
|
||||
childrenProps={
|
||||
Object {
|
||||
"visible": "xVisible",
|
||||
}
|
||||
}
|
||||
disabled={false}
|
||||
key="popup"
|
||||
monitorBufferTime={50}
|
||||
monitorWindowResize={true}
|
||||
onAlign={[Function]}
|
||||
target={[Function]}
|
||||
xVisible={true}
|
||||
>
|
||||
<PopupInner
|
||||
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
|
||||
hiddenClassName="ant-cascader-menus-hidden"
|
||||
prefixCls="ant-cascader-menus"
|
||||
style={Object {}}
|
||||
visible={true}
|
||||
>
|
||||
<div
|
||||
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
|
||||
style={Object {}}
|
||||
>
|
||||
<LazyRenderBox
|
||||
className="ant-cascader-menus-content"
|
||||
visible={true}
|
||||
>
|
||||
<Menus
|
||||
activeValue={Array []}
|
||||
allowClear={true}
|
||||
builtinPlacements={
|
||||
Object {
|
||||
"bottomLeft": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tl",
|
||||
"bl",
|
||||
],
|
||||
},
|
||||
"bottomRight": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tr",
|
||||
"br",
|
||||
],
|
||||
},
|
||||
"topLeft": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
-4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"bl",
|
||||
"tl",
|
||||
],
|
||||
},
|
||||
"topRight": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
-4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"br",
|
||||
"tr",
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
defaultFiledNames={
|
||||
Object {
|
||||
"children": "children",
|
||||
"label": "label",
|
||||
"value": "value",
|
||||
}
|
||||
}
|
||||
disabled={false}
|
||||
dropdownMenuColumnStyle={
|
||||
Object {
|
||||
"width": 0,
|
||||
}
|
||||
}
|
||||
expandTrigger="click"
|
||||
filedNames={
|
||||
Object {
|
||||
"children": "children",
|
||||
"label": "label",
|
||||
"value": "value",
|
||||
}
|
||||
}
|
||||
inputPrefixCls="ant-input"
|
||||
notFoundContent="Not Found"
|
||||
onChange={[Function]}
|
||||
onPopupVisibleChange={[Function]}
|
||||
onSelect={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"__IS_FILTERED_OPTION": true,
|
||||
"disabled": false,
|
||||
"label": Array [
|
||||
"Jiangsu",
|
||||
Array [
|
||||
" / ",
|
||||
"Nanjing",
|
||||
],
|
||||
Array [
|
||||
" / ",
|
||||
"Zhong Hua Men",
|
||||
],
|
||||
],
|
||||
"path": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"label": "Zhong Hua Men",
|
||||
"value": "zhonghuamen",
|
||||
},
|
||||
],
|
||||
"label": "Nanjing",
|
||||
"value": "nanjing",
|
||||
},
|
||||
],
|
||||
"label": "Jiangsu",
|
||||
"value": "jiangsu",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"label": "Zhong Hua Men",
|
||||
"value": "zhonghuamen",
|
||||
},
|
||||
],
|
||||
"label": "Nanjing",
|
||||
"value": "nanjing",
|
||||
},
|
||||
Object {
|
||||
"label": "Zhong Hua Men",
|
||||
"value": "zhonghuamen",
|
||||
},
|
||||
],
|
||||
"value": Array [
|
||||
"jiangsu",
|
||||
"nanjing",
|
||||
"zhonghuamen",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"__IS_FILTERED_OPTION": true,
|
||||
"disabled": false,
|
||||
"label": Array [
|
||||
"Zhejiang",
|
||||
Array [
|
||||
" / ",
|
||||
Array [
|
||||
"Hang",
|
||||
Array [
|
||||
<span
|
||||
className="ant-cascader-menu-item-keyword"
|
||||
>
|
||||
z
|
||||
</span>,
|
||||
"hou",
|
||||
],
|
||||
],
|
||||
],
|
||||
Array [
|
||||
" / ",
|
||||
"West Lake",
|
||||
],
|
||||
],
|
||||
"path": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"label": "West Lake",
|
||||
"value": "xihu",
|
||||
},
|
||||
],
|
||||
"label": "Hangzhou",
|
||||
"value": "hangzhou",
|
||||
},
|
||||
],
|
||||
"label": "Zhejiang",
|
||||
"value": "zhejiang",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"label": "West Lake",
|
||||
"value": "xihu",
|
||||
},
|
||||
],
|
||||
"label": "Hangzhou",
|
||||
"value": "hangzhou",
|
||||
},
|
||||
Object {
|
||||
"label": "West Lake",
|
||||
"value": "xihu",
|
||||
},
|
||||
],
|
||||
"value": Array [
|
||||
"zhejiang",
|
||||
"hangzhou",
|
||||
"xihu",
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
placeholder="Please select"
|
||||
popupClassName=""
|
||||
popupPlacement="bottomLeft"
|
||||
popupVisible={true}
|
||||
prefixCls="ant-cascader"
|
||||
showSearch={
|
||||
Object {
|
||||
"filter": [Function],
|
||||
}
|
||||
}
|
||||
transitionName="slide-up"
|
||||
value={Array []}
|
||||
visible={true}
|
||||
>
|
||||
<div>
|
||||
<ul
|
||||
className="ant-cascader-menu"
|
||||
key="0"
|
||||
style={
|
||||
Object {
|
||||
"width": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<li
|
||||
className="ant-cascader-menu-item"
|
||||
key="jiangsu,nanjing,zhonghuamen"
|
||||
onClick={[Function]}
|
||||
title=""
|
||||
>
|
||||
Jiangsu
|
||||
/
|
||||
Nanjing
|
||||
/
|
||||
Zhong Hua Men
|
||||
</li>
|
||||
<li
|
||||
className="ant-cascader-menu-item"
|
||||
key="zhejiang,hangzhou,xihu"
|
||||
onClick={[Function]}
|
||||
title=""
|
||||
>
|
||||
Zhejiang
|
||||
/
|
||||
Hang
|
||||
<span
|
||||
className="ant-cascader-menu-item-keyword"
|
||||
key="seperator"
|
||||
>
|
||||
z
|
||||
</span>
|
||||
hou
|
||||
/
|
||||
West Lake
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Menus>
|
||||
</LazyRenderBox>
|
||||
</div>
|
||||
</PopupInner>
|
||||
</Align>
|
||||
</AnimateChild>
|
||||
</Animate>
|
||||
</div>
|
||||
</Popup>
|
||||
`;
|
||||
|
||||
exports[`Cascader should render not found content 1`] = `
|
||||
<Popup
|
||||
action={
|
||||
Array [
|
||||
"click",
|
||||
]
|
||||
}
|
||||
align={
|
||||
Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tl",
|
||||
"bl",
|
||||
],
|
||||
}
|
||||
}
|
||||
className=""
|
||||
destroyPopupOnHide={false}
|
||||
getClassNameFromAlign={[Function]}
|
||||
getRootDomNode={[Function]}
|
||||
mask={false}
|
||||
onAlign={[Function]}
|
||||
prefixCls="ant-cascader-menus"
|
||||
style={Object {}}
|
||||
transitionName="slide-up"
|
||||
visible={true}
|
||||
>
|
||||
<div>
|
||||
<Animate
|
||||
animation={Object {}}
|
||||
component=""
|
||||
componentProps={Object {}}
|
||||
exclusive={true}
|
||||
onAppear={[Function]}
|
||||
onEnd={[Function]}
|
||||
onEnter={[Function]}
|
||||
onLeave={[Function]}
|
||||
showProp="xVisible"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
transitionName="slide-up"
|
||||
>
|
||||
<AnimateChild
|
||||
animation={Object {}}
|
||||
key="popup"
|
||||
transitionAppear={true}
|
||||
transitionEnter={true}
|
||||
transitionLeave={true}
|
||||
transitionName="slide-up"
|
||||
>
|
||||
<Align
|
||||
align={
|
||||
Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tl",
|
||||
"bl",
|
||||
],
|
||||
}
|
||||
}
|
||||
childrenProps={
|
||||
Object {
|
||||
"visible": "xVisible",
|
||||
}
|
||||
}
|
||||
disabled={false}
|
||||
key="popup"
|
||||
monitorBufferTime={50}
|
||||
monitorWindowResize={true}
|
||||
onAlign={[Function]}
|
||||
target={[Function]}
|
||||
xVisible={true}
|
||||
>
|
||||
<PopupInner
|
||||
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
|
||||
hiddenClassName="ant-cascader-menus-hidden"
|
||||
prefixCls="ant-cascader-menus"
|
||||
style={Object {}}
|
||||
visible={true}
|
||||
>
|
||||
<div
|
||||
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
|
||||
style={Object {}}
|
||||
>
|
||||
<LazyRenderBox
|
||||
className="ant-cascader-menus-content"
|
||||
visible={true}
|
||||
>
|
||||
<Menus
|
||||
activeValue={Array []}
|
||||
allowClear={true}
|
||||
builtinPlacements={
|
||||
Object {
|
||||
"bottomLeft": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tl",
|
||||
"bl",
|
||||
],
|
||||
},
|
||||
"bottomRight": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"tr",
|
||||
"br",
|
||||
],
|
||||
},
|
||||
"topLeft": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
-4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"bl",
|
||||
"tl",
|
||||
],
|
||||
},
|
||||
"topRight": Object {
|
||||
"offset": Array [
|
||||
0,
|
||||
-4,
|
||||
],
|
||||
"overflow": Object {
|
||||
"adjustX": 1,
|
||||
"adjustY": 1,
|
||||
},
|
||||
"points": Array [
|
||||
"br",
|
||||
"tr",
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
defaultFiledNames={
|
||||
Object {
|
||||
"children": "children",
|
||||
"label": "label",
|
||||
"value": "value",
|
||||
}
|
||||
}
|
||||
disabled={false}
|
||||
dropdownMenuColumnStyle={
|
||||
Object {
|
||||
"height": "auto",
|
||||
"width": 0,
|
||||
}
|
||||
}
|
||||
expandTrigger="click"
|
||||
filedNames={
|
||||
Object {
|
||||
"children": "children",
|
||||
"label": "label",
|
||||
"value": "value",
|
||||
}
|
||||
}
|
||||
inputPrefixCls="ant-input"
|
||||
notFoundContent="Not Found"
|
||||
onChange={[Function]}
|
||||
onPopupVisibleChange={[Function]}
|
||||
onSelect={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"disabled": true,
|
||||
"label": "Not Found",
|
||||
"value": "ANT_CASCADER_NOT_FOUND",
|
||||
},
|
||||
]
|
||||
}
|
||||
placeholder="Please select"
|
||||
popupClassName=""
|
||||
popupPlacement="bottomLeft"
|
||||
popupVisible={true}
|
||||
prefixCls="ant-cascader"
|
||||
showSearch={
|
||||
Object {
|
||||
"filter": [Function],
|
||||
}
|
||||
}
|
||||
transitionName="slide-up"
|
||||
value={Array []}
|
||||
visible={true}
|
||||
>
|
||||
<div>
|
||||
<ul
|
||||
className="ant-cascader-menu"
|
||||
key="0"
|
||||
style={
|
||||
Object {
|
||||
"height": "auto",
|
||||
"width": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<li
|
||||
className="ant-cascader-menu-item ant-cascader-menu-item-disabled"
|
||||
key="ANT_CASCADER_NOT_FOUND"
|
||||
onClick={[Function]}
|
||||
title="Not Found"
|
||||
>
|
||||
Not Found
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Menus>
|
||||
</LazyRenderBox>
|
||||
</div>
|
||||
</PopupInner>
|
||||
</Align>
|
||||
</AnimateChild>
|
||||
</Animate>
|
||||
</div>
|
||||
</Popup>
|
||||
`;
|
||||
|
||||
exports[`Cascader support controlled mode 1`] = `
|
||||
<span
|
||||
class="ant-cascader-picker"
|
||||
|
@ -28,6 +28,10 @@ const options = [{
|
||||
}],
|
||||
}];
|
||||
|
||||
function filter(inputValue, path) {
|
||||
return path.some(option => (option.label).toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
|
||||
}
|
||||
|
||||
describe('Cascader', () => {
|
||||
focusTest(Cascader);
|
||||
|
||||
@ -39,11 +43,13 @@ describe('Cascader', () => {
|
||||
});
|
||||
|
||||
it('popup correctly when panel is open', () => {
|
||||
const onPopupVisibleChange = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Cascader options={options} />
|
||||
<Cascader options={options} onPopupVisibleChange={onPopupVisibleChange} />
|
||||
);
|
||||
wrapper.find('input').simulate('click');
|
||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
||||
expect(onPopupVisibleChange).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('support controlled mode', () => {
|
||||
@ -64,8 +70,18 @@ describe('Cascader', () => {
|
||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should support popupVisible', () => {
|
||||
const wrapper = mount(
|
||||
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />
|
||||
);
|
||||
expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(false);
|
||||
wrapper.setProps({ popupVisible: true });
|
||||
expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(true);
|
||||
});
|
||||
|
||||
it('can be selected', () => {
|
||||
const wrapper = mount(<Cascader options={options} />);
|
||||
const onChange = jest.fn();
|
||||
const wrapper = mount(<Cascader options={options} onChange={onChange} />);
|
||||
wrapper.find('input').simulate('click');
|
||||
let popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
popupWrapper.find('.ant-cascader-menu').at(0).find('.ant-cascader-menu-item').at(0)
|
||||
@ -79,6 +95,7 @@ describe('Cascader', () => {
|
||||
popupWrapper.find('.ant-cascader-menu').at(2).find('.ant-cascader-menu-item').at(0)
|
||||
.simulate('click');
|
||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
||||
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
||||
});
|
||||
|
||||
it('backspace should work with `Cascader[showSearch]`', () => {
|
||||
@ -89,4 +106,88 @@ describe('Cascader', () => {
|
||||
// Simulate onKeyDown will not trigger onChange by default, so the value is still '123'
|
||||
expect(wrapper.state('inputValue')).toBe('123');
|
||||
});
|
||||
|
||||
it('should highlight keyword and filter when search in Cascader', () => {
|
||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||
wrapper.find('input').simulate('click');
|
||||
wrapper.find('input').simulate('change', { target: { value: 'z' } });
|
||||
expect(wrapper.state('inputValue')).toBe('z');
|
||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
expect(popupWrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render not found content', () => {
|
||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||
wrapper.find('input').simulate('click');
|
||||
wrapper.find('input').simulate('change', { target: { value: '__notfoundkeyword__' } });
|
||||
expect(wrapper.state('inputValue')).toBe('__notfoundkeyword__');
|
||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
expect(popupWrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should support to clear selection', () => {
|
||||
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
||||
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('Zhejiang / Hangzhou');
|
||||
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
|
||||
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('');
|
||||
});
|
||||
|
||||
it('should close popup when clear selection', () => {
|
||||
const onPopupVisibleChange = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Cascader
|
||||
options={options}
|
||||
popupVisible
|
||||
defaultValue={['zhejiang', 'hangzhou']}
|
||||
onPopupVisibleChange={onPopupVisibleChange}
|
||||
/>
|
||||
);
|
||||
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
|
||||
expect(onPopupVisibleChange).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('should clear search input when clear selection', () => {
|
||||
const wrapper = mount(
|
||||
<Cascader
|
||||
options={options}
|
||||
defaultValue={['zhejiang', 'hangzhou']}
|
||||
showSearch
|
||||
/>
|
||||
);
|
||||
wrapper.find('input').simulate('click');
|
||||
wrapper.find('input').simulate('change', { target: { value: 'xxx' } });
|
||||
expect(wrapper.state('inputValue')).toBe('xxx');
|
||||
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
|
||||
expect(wrapper.state('inputValue')).toBe('');
|
||||
});
|
||||
|
||||
it('should not trigger visible change when click search input', () => {
|
||||
const onPopupVisibleChange = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Cascader
|
||||
options={options}
|
||||
showSearch
|
||||
onPopupVisibleChange={onPopupVisibleChange}
|
||||
/>
|
||||
);
|
||||
wrapper.find('input').simulate('focus');
|
||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(0);
|
||||
wrapper.find('input').simulate('click');
|
||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(1);
|
||||
wrapper.find('input').simulate('click');
|
||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(1);
|
||||
wrapper.find('input').simulate('blur');
|
||||
wrapper.setState({ popupVisible: false });
|
||||
wrapper.find('input').simulate('click');
|
||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should change filtered item when options are changed', () => {
|
||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||
wrapper.find('input').simulate('click');
|
||||
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
||||
wrapper.setProps({ options: [options[0]] });
|
||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
@ -219,7 +219,9 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
// Prevent `Trigger` behaviour.
|
||||
if (inputFocused || popupVisible) {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
if (e.nativeEvent.stopImmediatePropagation) {
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,31 +41,31 @@ export default class Search extends React.Component<SearchProps, any> {
|
||||
|
||||
getButtonOrIcon() {
|
||||
const { enterButton, prefixCls, size, disabled } = this.props;
|
||||
if (!enterButton) {
|
||||
return <Icon className={`${prefixCls}-icon`} type="search" key="searchIcon" />;
|
||||
}
|
||||
const enterButtonAsElement = enterButton as React.ReactElement<any>;
|
||||
if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
|
||||
return React.cloneElement(enterButtonAsElement, enterButtonAsElement.type === Button ? {
|
||||
let node;
|
||||
if (!enterButton) {
|
||||
node = <Icon className={`${prefixCls}-icon`} type="search" key="searchIcon" />;
|
||||
} else if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
|
||||
node = React.cloneElement(enterButtonAsElement, enterButtonAsElement.type === Button ? {
|
||||
className: `${prefixCls}-button`,
|
||||
size,
|
||||
onClick: this.onSearch,
|
||||
} : {
|
||||
onClick: this.onSearch,
|
||||
});
|
||||
} : {});
|
||||
} else {
|
||||
node = (
|
||||
<Button
|
||||
className={`${prefixCls}-button`}
|
||||
type="primary"
|
||||
size={size}
|
||||
disabled={disabled}
|
||||
key="enterButton"
|
||||
>
|
||||
{enterButton === true ? <Icon type="search" /> : enterButton}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
className={`${prefixCls}-button`}
|
||||
type="primary"
|
||||
size={size}
|
||||
disabled={disabled}
|
||||
onClick={this.onSearch}
|
||||
key="enterButton"
|
||||
>
|
||||
{enterButton === true ? <Icon type="search" /> : enterButton}
|
||||
</Button>
|
||||
);
|
||||
return React.cloneElement(node, {
|
||||
onClick: this.onSearch,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -27,4 +27,64 @@ describe('Input.Search', () => {
|
||||
);
|
||||
expect(wrapper.find('.ant-btn-primary[disabled]')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should trigger onSearch when click search icon', () => {
|
||||
const onSearch = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Search defaultValue="search text" onSearch={onSearch} />
|
||||
);
|
||||
wrapper.find('Icon').simulate('click');
|
||||
expect(onSearch).toHaveBeenCalledTimes(1);
|
||||
expect(onSearch).toBeCalledWith('search text');
|
||||
});
|
||||
|
||||
it('should trigger onSearch when click search button', () => {
|
||||
const onSearch = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Search defaultValue="search text" enterButton onSearch={onSearch} />
|
||||
);
|
||||
wrapper.find('Button').simulate('click');
|
||||
expect(onSearch).toHaveBeenCalledTimes(1);
|
||||
expect(onSearch).toBeCalledWith('search text');
|
||||
});
|
||||
|
||||
it('should trigger onSearch when click search button with text', () => {
|
||||
const onSearch = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Search defaultValue="search text" enterButton="button text" onSearch={onSearch} />
|
||||
);
|
||||
wrapper.find('Button').simulate('click');
|
||||
expect(onSearch).toHaveBeenCalledTimes(1);
|
||||
expect(onSearch).toBeCalledWith('search text');
|
||||
});
|
||||
|
||||
it('should trigger onSearch when click search button with customize button', () => {
|
||||
const onSearch = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Search defaultValue="search text" enterButton={<Button>antd button</Button>} onSearch={onSearch} />
|
||||
);
|
||||
wrapper.find('Button').simulate('click');
|
||||
expect(onSearch).toHaveBeenCalledTimes(1);
|
||||
expect(onSearch).toBeCalledWith('search text');
|
||||
});
|
||||
|
||||
it('should trigger onSearch when click search button of native', () => {
|
||||
const onSearch = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Search defaultValue="search text" enterButton={<button>antd button</button>} onSearch={onSearch} />
|
||||
);
|
||||
wrapper.find('button').simulate('click');
|
||||
expect(onSearch).toHaveBeenCalledTimes(1);
|
||||
expect(onSearch).toBeCalledWith('search text');
|
||||
});
|
||||
|
||||
it('should trigger onSearch when press enter', () => {
|
||||
const onSearch = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Search defaultValue="search text" onSearch={onSearch} />
|
||||
);
|
||||
wrapper.find('input').simulate('keydown', { key: 'Enter', keyCode: 13 });
|
||||
expect(onSearch).toHaveBeenCalledTimes(1);
|
||||
expect(onSearch).toBeCalledWith('search text');
|
||||
});
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ exports[`Input.Search should support suffix 1`] = `
|
||||
"suffix",
|
||||
<Icon
|
||||
className="ant-input-search-icon"
|
||||
onClick={[Function]}
|
||||
type="search"
|
||||
/>,
|
||||
]
|
||||
@ -57,10 +58,12 @@ exports[`Input.Search should support suffix 1`] = `
|
||||
<Icon
|
||||
className="ant-input-search-icon"
|
||||
key="searchIcon"
|
||||
onClick={[Function]}
|
||||
type="search"
|
||||
>
|
||||
<i
|
||||
className="anticon anticon-search ant-input-search-icon"
|
||||
onClick={[Function]}
|
||||
/>
|
||||
</Icon>
|
||||
</span>
|
||||
|
@ -31,7 +31,12 @@ ReactDOM.render(
|
||||
enterButton
|
||||
/>
|
||||
<br /><br />
|
||||
<Search placeholder="input search text" enterButton="Search" size="large" />
|
||||
<Search
|
||||
placeholder="input search text"
|
||||
enterButton="Search"
|
||||
size="large"
|
||||
onSearch={value => console.log(value)}
|
||||
/>
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
@ -7,8 +7,12 @@
|
||||
|
||||
.@{search-prefix} {
|
||||
&-icon {
|
||||
pointer-events: none;
|
||||
color: @text-color-secondary;
|
||||
cursor: pointer;
|
||||
transition: all .3s;
|
||||
&:hover {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(&-small) > .@{ant-prefix}-input-suffix {
|
||||
|
@ -83,4 +83,19 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
||||
expect($$('.ant-btn')).toHaveLength(1);
|
||||
expect($$('.ant-btn')[0].innerHTML).toContain('OK');
|
||||
});
|
||||
|
||||
it('trigger onCancel once when click on cancel button', () => {
|
||||
jest.useFakeTimers();
|
||||
['info', 'success', 'warning', 'error'].forEach((type) => {
|
||||
Modal[type]({
|
||||
title: 'title',
|
||||
content: 'content',
|
||||
});
|
||||
expect($$(`.ant-confirm-${type}`)).toHaveLength(1);
|
||||
$$('.ant-btn')[0].click();
|
||||
jest.runAllTimers();
|
||||
expect($$(`.ant-confirm-${type}`)).toHaveLength(0);
|
||||
});
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
@ -45,4 +45,41 @@ describe('Popconfirm', () => {
|
||||
expect(popup.innerHTML).toMatchSnapshot();
|
||||
expect(popup.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should be controlled by visible', () => {
|
||||
jest.useFakeTimers();
|
||||
const popconfirm = mount(
|
||||
<Popconfirm title="code">
|
||||
<span>show me your code</span>
|
||||
</Popconfirm>
|
||||
);
|
||||
expect(popconfirm.instance().getPopupDomNode()).toBeFalsy();
|
||||
popconfirm.setProps({ visible: true });
|
||||
expect(popconfirm.instance().getPopupDomNode()).toBeTruthy();
|
||||
expect(popconfirm.instance().getPopupDomNode().className).not.toContain('ant-popover-hidden');
|
||||
popconfirm.setProps({ visible: false });
|
||||
jest.runAllTimers();
|
||||
expect(popconfirm.instance().getPopupDomNode().className).toContain('ant-popover-hidden');
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should trigger onConfirm and onCancel', () => {
|
||||
const confirm = jest.fn();
|
||||
const cancel = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const popconfirm = mount(
|
||||
<Popconfirm title="code" onConfirm={confirm} onCancel={cancel} onVisibleChange={onVisibleChange}>
|
||||
<span>show me your code</span>
|
||||
</Popconfirm>
|
||||
);
|
||||
const triggerNode = popconfirm.find('span').at(0);
|
||||
triggerNode.simulate('click');
|
||||
popconfirm.find('.ant-btn-primary').simulate('click');
|
||||
expect(confirm).toHaveBeenCalled();
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
||||
triggerNode.simulate('click');
|
||||
popconfirm.find('.ant-btn').at(0).simulate('click');
|
||||
expect(cancel).toHaveBeenCalled();
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
@ -2671,11 +2671,12 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
|
||||
exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn editable-add-btn"
|
||||
class="ant-btn ant-btn-primary"
|
||||
style="margin-bottom:16px"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Add
|
||||
Add a row
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
@ -2758,7 +2759,7 @@ exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = `
|
||||
class="editable-cell"
|
||||
>
|
||||
<div
|
||||
class="editable-cell-text-wrapper"
|
||||
style="padding-right:24px"
|
||||
>
|
||||
Edward King 0
|
||||
<i
|
||||
@ -2801,7 +2802,7 @@ exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = `
|
||||
class="editable-cell"
|
||||
>
|
||||
<div
|
||||
class="editable-cell-text-wrapper"
|
||||
style="padding-right:24px"
|
||||
>
|
||||
Edward King 1
|
||||
<i
|
||||
|
@ -39,21 +39,21 @@ class EditableCell extends React.Component {
|
||||
return (
|
||||
<div className="editable-cell">
|
||||
{
|
||||
editable ?
|
||||
<div className="editable-cell-input-wrapper">
|
||||
<Input
|
||||
value={value}
|
||||
onChange={this.handleChange}
|
||||
onPressEnter={this.check}
|
||||
/>
|
||||
<Icon
|
||||
type="check"
|
||||
className="editable-cell-icon-check"
|
||||
onClick={this.check}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
<div className="editable-cell-text-wrapper">
|
||||
editable ? (
|
||||
<Input
|
||||
value={value}
|
||||
onChange={this.handleChange}
|
||||
onPressEnter={this.check}
|
||||
suffix={
|
||||
<Icon
|
||||
type="check"
|
||||
className="editable-cell-icon-check"
|
||||
onClick={this.check}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div style={{ paddingRight: 24 }}>
|
||||
{value || ' '}
|
||||
<Icon
|
||||
type="edit"
|
||||
@ -61,6 +61,7 @@ class EditableCell extends React.Component {
|
||||
onClick={this.edit}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
@ -148,7 +149,9 @@ class EditableTable extends React.Component {
|
||||
const columns = this.columns;
|
||||
return (
|
||||
<div>
|
||||
<Button className="editable-add-btn" onClick={this.handleAdd}>Add</Button>
|
||||
<Button onClick={this.handleAdd} type="primary" style={{ marginBottom: 16 }}>
|
||||
Add a row
|
||||
</Button>
|
||||
<Table bordered dataSource={dataSource} columns={columns} />
|
||||
</div>
|
||||
);
|
||||
@ -163,33 +166,21 @@ ReactDOM.render(<EditableTable />, mountNode);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-input-wrapper,
|
||||
.editable-cell-text-wrapper {
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.editable-cell-text-wrapper {
|
||||
padding: 5px 24px 5px 5px;
|
||||
}
|
||||
|
||||
.editable-cell-icon,
|
||||
.editable-cell-icon-check {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editable-cell-icon {
|
||||
line-height: 18px;
|
||||
line-height: 14px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editable-cell-icon-check {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.editable-cell:hover .editable-cell-icon {
|
||||
td:hover .editable-cell-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@ -197,8 +188,4 @@ ReactDOM.render(<EditableTable />, mountNode);
|
||||
.editable-cell-icon-check:hover {
|
||||
color: #108ee9;
|
||||
}
|
||||
|
||||
.editable-add-btn {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
````
|
||||
|
@ -168,7 +168,7 @@
|
||||
&-thead > tr > th,
|
||||
&-tbody > tr > td {
|
||||
padding: @table-padding-vertical @table-padding-horizontal;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
&-thead > tr > th.@{table-prefix-cls}-selection-column-custom {
|
||||
|
@ -11,7 +11,7 @@ title:
|
||||
|
||||
## en-US
|
||||
|
||||
Tab can be slide to left or right(up or down), which is used for a lot of tabs.
|
||||
In order to fit in more tabs, they can slide left and right (or up and down).
|
||||
|
||||
````jsx
|
||||
import { Tabs, Radio } from 'antd';
|
||||
|
@ -1,9 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import Button from '../button';
|
||||
|
||||
function noop() {
|
||||
}
|
||||
|
||||
export interface TransferOperationProps {
|
||||
className?: string;
|
||||
leftArrowText?: string;
|
||||
@ -17,8 +14,8 @@ export interface TransferOperationProps {
|
||||
export default class Operation extends React.Component<TransferOperationProps, any> {
|
||||
render() {
|
||||
const {
|
||||
moveToLeft = noop,
|
||||
moveToRight = noop,
|
||||
moveToLeft,
|
||||
moveToRight,
|
||||
leftArrowText = '',
|
||||
rightArrowText = '',
|
||||
leftActive,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "3.5.3",
|
||||
"version": "3.5.5",
|
||||
"title": "Ant Design",
|
||||
"description": "An enterprise-class UI design language and React-based implementation",
|
||||
"homepage": "http://ant.design/",
|
||||
@ -82,7 +82,7 @@
|
||||
"react-lazy-load": "^3.0.12",
|
||||
"react-slick": "~0.23.1",
|
||||
"shallowequal": "^1.0.1",
|
||||
"warning": "~4.0.0"
|
||||
"warning": "~3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/types": "7.0.0-beta.44",
|
||||
|
Loading…
Reference in New Issue
Block a user