Merge branch 'master' into feature

This commit is contained in:
诸岳 2019-03-24 08:41:22 +08:00
commit 6ae2ee4e31
147 changed files with 1691 additions and 780 deletions

18
.depslintrc.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
ignore: [
'**/~*/**',
'**/_*/**',
'**/icon/**',
'**/__tests__/**',
'**/style/**',
'**/locale/**',
'**/*-provider/**',
'**/*.json',
],
modulePattern: [
{
pattern: /ConfigConsumer.*renderEmpty/sm,
module: '../empty',
},
],
};

View File

@ -1,3 +1,4 @@
<!--
First of all, thank you for your contribution! 😄 First of all, thank you for your contribution! 😄
New feature please send pull request to feature branch, and rest to master branch. New feature please send pull request to feature branch, and rest to master branch.
@ -5,7 +6,7 @@ Pull request will be merged after one of collaborators approve.
Please makes sure that these form are filled before submitting your pull request, thank you! Please makes sure that these form are filled before submitting your pull request, thank you!
[[中文版模板 / Chinese template](https://github.com/ant-design/ant-design/blob/master/.github/PULL_REQUEST_TEMPLATE/pr_cn.md)] [[中文版模板 / Chinese template](https://github.com/ant-design/ant-design/blob/master/.github/PULL_REQUEST_TEMPLATE/pr_cn.md)]
-->
### 🤔 This is a ... ### 🤔 This is a ...
- [ ] New feature - [ ] New feature
@ -32,7 +33,7 @@ Please makes sure that these form are filled before submitting your pull request
### 📝 Changelog description ### 📝 Changelog description
> Describe changes from user side, and list all potential break changes or other risks. > Describe changes from userside, and list all potential break changes or other risks.
1. English description 1. English description

View File

@ -1,3 +1,4 @@
<!--
首先,感谢你的贡献!😄 首先,感谢你的贡献!😄
新特性请提交至 feature 分支,其余可提交至 master 分支。 新特性请提交至 feature 分支,其余可提交至 master 分支。
@ -5,7 +6,7 @@
请确保填写以下 pull request 的信息,谢谢!~ 请确保填写以下 pull request 的信息,谢谢!~
[[English Template / 英文模板](?expand=1)] [[English Template / 英文模板](?expand=1)]
-->
### 🤔 这个变动的性质是? ### 🤔 这个变动的性质是?
- [ ] 新特性提交 - [ ] 新特性提交

View File

@ -15,6 +15,71 @@ timeline: true
--- ---
## 3.15.2
`2019-03-23`
- 📖 New English translation for [Data Display](https://ant.design/docs/spec/data-display) and [Feedback](https://ant.design/docs/spec/feedback). [#15454](https://github.com/ant-design/ant-design/pull/15454) [@klouskingsley](https://github.com/klouskingsley) [#15460](https://github.com/ant-design/ant-design/pull/15460) [@klouskingsley](https://github.com/klouskingsley)
- 🌟 Add two less variables `@font-feature-settings` and `@select-item-selected-font-weight`. [#15506](https://github.com/ant-design/ant-design/pull/15506) [@dancerphil](https://github.com/dancerphil) [#15515](https://github.com/ant-design/ant-design/pull/15515) [@willc001](https://github.com/willc001)
- 🐞 Fix the scale calculate logic when Avatar is remounted. [#15503](https://github.com/ant-design/ant-design/pull/15503)
- 🐞 Fix inefficient custom `width` for DatePicker. [#15547](https://github.com/ant-design/ant-design/pull/15547) [@DiamondYuan](https://github.com/DiamondYuan)
- 🐞 Fix the incorrect priority of icon style for Notification. [#15530](https://github.com/ant-design/ant-design/pull/15530)
- 🐞 Fix that `notFound` content is not aligned for Select. [#15570](https://github.com/ant-design/ant-design/pull/15570)
- 🐞 Fix empty missing when `loading` property is true for Table. [#15583](https://github.com/ant-design/ant-design/pull/15583)
- 🐞 Fix the incorrect `white-space` style for Tag. [#15526](https://github.com/ant-design/ant-design/pull/15526) [@Kapiroska](https://github.com/Kapiroska)
- 🐞 Fix the incorrect judgement on image type for Upload. [#15354](https://github.com/ant-design/ant-design/pull/15354)
## 3.15.1
`2019-03-17`
- 🌟 Add four less variables `@pagination-item-bg-active`, `@icon-color`. [#15302](https://github.com/ant-design/ant-design/pull/15302) [#15343](https://github.com/ant-design/ant-design/issues/15343)
- 🐞 Fix tree-shaking not working for importing PageHeader. [#15354](https://github.com/ant-design/ant-design/pull/15354)
- List
- 🐞 Fix some List Item styling issues. [#15328](https://github.com/ant-design/ant-design/pull/15328)
- 🐞 Keep same content color of List like previous version. [#15301](https://github.com/ant-design/ant-design/pull/15301)
- 🐞 Fix Calendar can't switch type. [#15338](https://github.com/ant-design/ant-design/pull/15338) [@zy410419243](https://github.com/zy410419243)
- Badge
- 🐞 Fix the issue that customized color is not supported in Badge. [#15356](https://github.com/ant-design/ant-design/pull/15356) [@DiamondYuan](https://github.com/DiamondYuan)
- 🐞 Fix height problem of Badge with dot. [#15395](https://github.com/ant-design/ant-design/pull/15395)
- 🐞 Fix tabbar style of Tabs in card mode when browser is zoomed out. [#15299](https://github.com/ant-design/ant-design/pull/15299) [@rinick](https://github.com/rinick)
- 🐞 Fix Avatar component cannot calculate the offset when `display: none` is set. [#15351](https://github.com/ant-design/ant-design/pull/15351) [@ppbl](https://github.com/ppbl)
- 🐞 Correct suffix icon in Input.Password. [#15381](https://github.com/ant-design/ant-design/pull/15381) [@melchior-voidwolf](https://github.com/melchior-voidwolf)
- 🐞 Fix Layout has classname `ant-layout-has-sider` even if `hasFixer` is set to `false`. [#15396](https://github.com/ant-design/ant-design/pull/15396) [@SoraYama](https://github.com/SoraYama)
- 🐞 Fix Divider alignment issue in PageHeader. [#15400](https://github.com/ant-design/ant-design/pull/15400)
- 🐞 Fix a style issue of Skeleton. [#15421](https://github.com/ant-design/ant-design/pull/15421) [@Maktel](https://github.com/Maktel)
- 🌟 Adjust multiple TypeScript types
- 🌟 FormComponentProps added a generic type of form values. [#15355](https://github.com/ant-design/ant-design/pull/15355)
- 🌟 Export ConfigProviderProps interface. [#15446](https://github.com/ant-design/ant-design/pull/15446) [@DiamondYuan](https://github.com/DiamondYuan)
- 🐞 Add `onClick` prop for Breadcrumb.Item. [#15331](https://github.com/ant-design/ant-design/pull/15331) [@tgxpuisb](https://github.com/tgxpuisb)
- 🐞 Add `style` prop for Steps.Step component. [#15393](https://github.com/ant-design/ant-design/pull/15393) [@pavolgolias](https://github.com/pavolgolias)
- 🐞 Fix `itemRender` definition of Pagination. [#15428](https://github.com/ant-design/ant-design/pull/15428) [@DiamondYuan](https://github.com/DiamondYuan)
## 3.15.0
`2019-03-08`
- 🌟 Tree supports new prop `blockNode`. [#14858](https://github.com/ant-design/ant-design/pull/14858) [@kimochg](https://github.com/kimochg)
- Form
- 🌟 Supports `colon` prop in Form. [#15276](https://github.com/ant-design/ant-design/pull/15276) [@DiamondYuan](https://github.com/DiamondYuan)
- 🌟 Add new prop `labelAlign`. [#15252](https://github.com/ant-design/ant-design/pull/15252) [@yoyo837](https://github.com/yoyo837)
- 🐞 Fix two colons will appear in FormItem label. [15285](https://github.com/ant-design/ant-design/pull/15285) [@jinxin0112](https://github.com/jinxin0112)
- 🐞 Fix Typography dom structure. [#15210](https://github.com/ant-design/ant-design/pull/15210)
- 🐞 Fix Affix position update logic. [#15150](https://github.com/ant-design/ant-design/pull/15150)
- Input
- 🐞 Fix Password lost focus when change `visibilityToggle`. [#15184](https://github.com/ant-design/ant-design/pull/15184)
- 🐞 Fix `allowClear` do not focus after clear content. [#15184](https://github.com/ant-design/ant-design/pull/15184)
- 🐞 Fix Search style with `allowClear` or `suffix`/`prefix`. [#15242](https://github.com/ant-design/ant-design/pull/15242)
- 🐞 Fix Input warning logic for focus lose. [#15251](https://github.com/ant-design/ant-design/pull/15251)
- 🐞 Fix DatePicker and TimePicker cursor style. [#15218](https://github.com/ant-design/ant-design/pull/15218)
- 🐞 Fix Steps label text not align center. [#15256](https://github.com/ant-design/ant-design/pull/15256) [@yoyo837](https://github.com/yoyo837)
- TypeScript
- ⚡️ Refactor and simplify List Item dom structure, and fix spaces lost inside List Item. [#15197](https://github.com/ant-design/ant-design/pull/15197)
- 🐞 Fix Layout `tagName` definition. [#15181](https://github.com/ant-design/ant-design/pull/15181) [@ngolin](https://github.com/ngolin)
- 🐞 Fix Text `ellipsis` definition. [#15209](https://github.com/ant-design/ant-design/pull/15209) [@xiaohuoni](https://github.com/xiaohuoni)
- 🐞 Fix Badge `text` types. [#15264](https://github.com/ant-design/ant-design/pull/15264)
- 🇹🇷 Turkish translations of new components. [#15238](https://github.com/ant-design/ant-design/pull/15238) [@codesignist](https://github.com/codesignist)
## 3.14.1 ## 3.14.1
`2019-03-04` `2019-03-04`
@ -52,7 +117,7 @@ timeline: true
- 🐞 Fix the TypeScript type problem for Table `Column Filter`. [#15056](https://github.com/ant-design/ant-design/pull/15056) - 🐞 Fix the TypeScript type problem for Table `Column Filter`. [#15056](https://github.com/ant-design/ant-design/pull/15056)
- 🌟 Support goto button in Pagination. [#14819](https://github.com/ant-design/ant-design/pull/14819) - 🌟 Support goto button in Pagination. [#14819](https://github.com/ant-design/ant-design/pull/14819)
- 🐞 Fix the problem that Carousel response prop TypeScript declaration is missing. [#15071](https://github.com/ant-design/ant-design/pull/15071) - 🐞 Fix the problem that Carousel response prop TypeScript declaration is missing. [#15071](https://github.com/ant-design/ant-design/pull/15071)
## 3.13.6 ## 3.13.6
`2019-02-23` `2019-02-23`

View File

@ -14,6 +14,73 @@ timeline: true
* 主版本号:含有破坏性更新和新特性,不在发布周期内。 * 主版本号:含有破坏性更新和新特性,不在发布周期内。
--- ---
## 3.15.2
`2019-03-23`
- 📖 翻译[模式-数据展示](https://ant.design/docs/spec/data-display)和[模式-反馈](https://ant.design/docs/spec/feedback)文档到英文。[#15454](https://github.com/ant-design/ant-design/pull/15454) [@klouskingsley](https://github.com/klouskingsley) [#15460](https://github.com/ant-design/ant-design/pull/15460) [@klouskingsley](https://github.com/klouskingsley)
- 🌟 新增 less 变量 `@font-feature-settings``@select-item-selected-font-weight`。[#15506](https://github.com/ant-design/ant-design/pull/15506) [@dancerphil](https://github.com/dancerphil) [#15515](https://github.com/ant-design/ant-design/pull/15515) [@willc001](https://github.com/willc001)
- 🐞 修复 Avatar 组件在重新挂载后字符大小和长度计算错误的问题。[#15503](https://github.com/ant-design/ant-design/pull/15503)
- 🐞 修复 DatePicker 组件的宽度无法自定义的问题。[#15547](https://github.com/ant-design/ant-design/pull/15547) [@DiamondYuan](https://github.com/DiamondYuan)
- 🐞 修复 Notification 组件的 icon 样式被全局默认样式覆盖的问题。[#15530](https://github.com/ant-design/ant-design/pull/15530)
- 🐞 修复 Select 组件的空状态文本和图片没有对齐的问题。[#15570](https://github.com/ant-design/ant-design/pull/15570)
- 🐞 修复 Table 组件在加载中时空状态丢失的问题。[#15583](https://github.com/ant-design/ant-design/pull/15583)
- 🐞 修复 Tag 组件的内容长度超过屏幕宽度时不可见的问题。[#15526](https://github.com/ant-design/ant-design/pull/15526) [@Kapiroska](https://github.com/Kapiroska)
- 🐞 修复 Upload 组件对图片类型文件判断不准确的问题。[#15354](https://github.com/ant-design/ant-design/pull/15354)
## 3.15.1
`2019-03-17`
- 🌟 补充了 less 变量 `@pagination-item-bg-active`、`@icon-color`。 [#15302](https://github.com/ant-design/ant-design/pull/15302) [#15345](https://github.com/ant-design/ant-design/pull/15345)
- 🐞 修复引入 PageHeader 导致 tree-shaking 失效的问题。[#15354](https://github.com/ant-design/ant-design/pull/15354)
- List
- 🐞 修复 List 的一些样式问题。[#15328](https://github.com/ant-design/ant-design/pull/15328)
- 🐞 保持 List 组件内容颜色与之前的版本一致。[#15301](https://github.com/ant-design/ant-design/pull/15301)
- 🐞 修复 Calendar 无法切换类型的问题。[#15338](https://github.com/ant-design/ant-design/pull/15338) [@zy410419243](https://github.com/zy410419243)
- Badge
- 🐞 修复 Badge 组件不支持自定义颜色的问题。[#15356](https://github.com/ant-design/ant-design/pull/15356) [@DiamondYuan](https://github.com/DiamondYuan)
- 🐞 修复 Badge 组件内带小圆点时的高度问题。[#15395](https://github.com/ant-design/ant-design/pull/15395)
- 🐞 微调 Tabs 标签模式在浏览器放大时丢失边框的问题。[#15299](https://github.com/ant-design/ant-design/pull/15299) [@rinick](https://github.com/rinick)
- 🐞 修复 Avatar 组件设置了 `display: none` 的时候无法计算偏移量的问题。[#15351](https://github.com/ant-design/ant-design/pull/15351) [@ppbl](https://github.com/ppbl)
- 🐞 修复 Input.Password 组件的 `suffix` 失效问题。[#15381](https://github.com/ant-design/ant-design/pull/15381) [@melchior-voidwolf](https://github.com/melchior-voidwolf)
- 🐞 修复 Layout 即使在 `hasSider` 属性为 `false` 的时候依然会加 `ant-layout-has-sider` 类名的问题[#15396](https://github.com/ant-design/ant-design/pull/15396) [@SoraYama](https://github.com/SoraYama)
- 🐞 修复 Divider 在 PageHeader 组件中的对齐问题。[#15400](https://github.com/ant-design/ant-design/pull/15400)
- 🐞 修复 Menu 收缩后SubMenu 异常渲染的问题。[#15409](https://github.com/ant-design/ant-design/pull/15409) [@zy410419243](https://github.com/zy410419243)
- 🐞 修复 Skeleton 组件的样式问题。[#15421](https://github.com/ant-design/ant-design/pull/15421) [@Maktel](https://github.com/Maktel)
- 调整了多处 Typescript 类型
- 🌟 FormComponentProps 新增 Form 值的泛型。[#15355](https://github.com/ant-design/ant-design/pull/15355)
- 🌟 导出 ConfigProviderProps 定义。[#15446](https://github.com/ant-design/ant-design/pull/15446) [@DiamondYuan](https://github.com/DiamondYuan)
- 🐞 添加 Breadcrumb.Item 的 `onClick` 定义。[#15331](https://github.com/ant-design/ant-design/pull/15331) [@tgxpuisb](https://github.com/tgxpuisb)
- 🐞 添加 Steps.Step 组件的 `style` 定义。[#15393](https://github.com/ant-design/ant-design/pull/15393) [@pavolgolias](https://github.com/pavolgolias)
- 🐞 修复 PaginationProps 组件 `itemRender` 函数的类型错误。[#15428](https://github.com/ant-design/ant-design/pull/15428) [@DiamondYuan](https://github.com/DiamondYuan)
## 3.15.0
`2019-03-08`
- 🌟 Tree 组件支持 `blockNode` 属性。[#14858](https://github.com/ant-design/ant-design/pull/14858) [@kimochg](https://github.com/kimochg)
- Form
- 🌟 支持直接在 Form 上面配置 `colon` 属性。[#15276](https://github.com/ant-design/ant-design/pull/15276) [@DiamondYuan](https://github.com/DiamondYuan)
- 🌟 支持 `labelAlign` 属性。[#15252](https://github.com/ant-design/ant-design/pull/15252) [@yoyo837](https://github.com/yoyo837)
- 🐞 修复可能出现两个冒号的问题。[15285](https://github.com/ant-design/ant-design/pull/15285) [@jinxin0112](https://github.com/jinxin0112)
- ⚡️ 重构并简化了 List Item 的 dom 结构,并且修复了 Item 中内容空格丢失的问题。[#15210](https://github.com/ant-design/ant-design/pull/15210)
- 🐞 修复 Affix 组件定位更新的逻辑问题。[#15150](https://github.com/ant-design/ant-design/pull/15150)
- Input
- 🐞 修复 Password 当 `visibilityToggle` 变化时丢失焦点的问题。[#15184](https://github.com/ant-design/ant-design/pull/15184)
- 🐞 修复通过 `allowClear` 清除内容后没有获得焦点的问题。[#15184](https://github.com/ant-design/ant-design/pull/15184)
- 🐞 修复 Search 当使用了 `allowClear` 或者 `suffix`/`prefix` 时的样式问题。[#15242](https://github.com/ant-design/ant-design/pull/15242)
- 🐞 修复 Input 丢失焦点时的警告问题。[#15251](https://github.com/ant-design/ant-design/pull/15251)
- 🐞 修复 DatePicker 和 TimePicker 的 cursor 样式问题。[#15218](https://github.com/ant-design/ant-design/pull/15218)
- 🐞 修复 Steps 的 label 不居中的问题。[#15256](https://github.com/ant-design/ant-design/pull/15256) [@yoyo837](https://github.com/yoyo837)
- TypeScript
- 🐞 修复 Typography 的 `setContentRef` 定义。[#15197](https://github.com/ant-design/ant-design/pull/15197)
- 🐞 修复 Layout 的 `tagName` 定义。[#15181](https://github.com/ant-design/ant-design/pull/15181) [@ngolin](https://github.com/ngolin)
- 🐞 修复 Text 的 `ellipsis` 定义。[#15209](https://github.com/ant-design/ant-design/pull/15209) [@xiaohuoni](https://github.com/xiaohuoni)
- 🐞 修复 Badge 的 `text` 定义。[#15264](https://github.com/ant-design/ant-design/pull/15264)
- 🇹🇷 添加一些新组件的土耳其语翻译。[#15238](https://github.com/ant-design/ant-design/pull/15238) [@codesignist](https://github.com/codesignist)
## 3.14.1 ## 3.14.1
`2019-03-04` `2019-03-04`
@ -49,7 +116,7 @@ timeline: true
- 🐞 调整了多处 TypeScript 的类型 - 🐞 调整了多处 TypeScript 的类型
- 🐞 修复 `onPanelChange` TypeScript 声明缺失的问题。[#15043](https://github.com/ant-design/ant-design/pull/15043) - 🐞 修复 `onPanelChange` TypeScript 声明缺失的问题。[#15043](https://github.com/ant-design/ant-design/pull/15043)
- 🐞 订正了 Table `column filter` 的 TypeScript 类型问题。[#14777](https://github.com/ant-design/ant-design/issues/14777) - 🐞 订正了 Table `column filter` 的 TypeScript 类型问题。[#14777](https://github.com/ant-design/ant-design/issues/14777)
- 🌟 Pagination 支持添加分页跳转按钮。[#14819](https://github.com/ant-design/ant-design/pull/14819) - 🌟 Pagination 支持添加分页跳转按钮。[#14819](https://github.com/ant-design/ant-design/pull/14819)
- 🐞 修复 Carousel 的 responsive prop TypeScript 声明缺失的问题。[#15071](https://github.com/ant-design/ant-design/pull/15071) - 🐞 修复 Carousel 的 responsive prop TypeScript 声明缺失的问题。[#15071](https://github.com/ant-design/ant-design/pull/15071)
## 3.13.6 ## 3.13.6

1
CNAME Normal file
View File

@ -0,0 +1 @@
ant.design

View File

@ -48,7 +48,7 @@ describe('Affix Render', () => {
}; };
const originGetBoundingClientRect = HTMLElement.prototype.getBoundingClientRect; const originGetBoundingClientRect = HTMLElement.prototype.getBoundingClientRect;
HTMLElement.prototype.getBoundingClientRect = function() { HTMLElement.prototype.getBoundingClientRect = function getBoundingClientRect() {
return ( return (
classRect[this.className] || { classRect[this.className] || {
top: 0, top: 0,

View File

@ -24,7 +24,7 @@ Please note that Affix should not cover other content on the page, especially wh
**Note:** Children of `Affix` can not be `position: absolute`, but you can set `Affix` as `position: absolute`: **Note:** Children of `Affix` can not be `position: absolute`, but you can set `Affix` as `position: absolute`:
```jsx ```jsx
<Affix style={{ position: 'absolute', top: y, left: x}}> <Affix style={{ position: 'absolute', top: y, left: x }}>
... ...
</Affix> </Affix>
``` ```

View File

@ -25,7 +25,7 @@ title: Affix
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位: **注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
```jsx ```jsx
<Affix style={{ position: 'absolute', top: y, left: x}}> <Affix style={{ position: 'absolute', top: y, left: x }}>
... ...
</Affix> </Affix>
``` ```

View File

@ -1,2 +1,5 @@
import '../../style/index.less'; import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies
import '../../affix/style';

View File

@ -1,4 +1,6 @@
import '../../style/index.less'; import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies
import '../../select/style'; import '../../select/style';
import '../../input/style';

View File

@ -3,6 +3,27 @@ import { mount } from 'enzyme';
import Avatar from '..'; import Avatar from '..';
describe('Avatar Render', () => { describe('Avatar Render', () => {
let originOffsetWidth;
beforeAll(() => {
// Mock offsetHeight
originOffsetWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetWidth').get;
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
get() {
if (this.className === 'ant-avatar-string') {
return 100;
}
return 80;
},
});
});
afterAll(() => {
// Restore Mock offsetHeight
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
get: originOffsetWidth,
});
});
it('Render long string correctly', () => { it('Render long string correctly', () => {
const wrapper = mount(<Avatar>TestString</Avatar>); const wrapper = mount(<Avatar>TestString</Avatar>);
const children = wrapper.find('.ant-avatar-string'); const children = wrapper.find('.ant-avatar-string');
@ -14,8 +35,12 @@ describe('Avatar Render', () => {
global.document.body.appendChild(div); global.document.body.appendChild(div);
const wrapper = mount(<Avatar src="http://error.url">Fallback</Avatar>, { attachTo: div }); const wrapper = mount(<Avatar src="http://error.url">Fallback</Avatar>, { attachTo: div });
wrapper.instance().setScale = jest.fn(() => wrapper.instance().setState({ scale: 0.5 })); wrapper.instance().setScale = jest.fn(() => {
if (wrapper.state().scale === 0.5) {
return;
}
wrapper.instance().setState({ scale: 0.5 });
});
wrapper.find('img').simulate('error'); wrapper.find('img').simulate('error');
const children = wrapper.find('.ant-avatar-string'); const children = wrapper.find('.ant-avatar-string');
@ -90,4 +115,19 @@ describe('Avatar Render', () => {
wrapper.detach(); wrapper.detach();
global.document.body.removeChild(div); global.document.body.removeChild(div);
}); });
it('should calculate scale of avatar children correctly', () => {
const wrapper = mount(<Avatar>Avatar</Avatar>);
expect(wrapper.state().scale).toBe(0.72);
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
get() {
if (this.className === 'ant-avatar-string') {
return 100;
}
return 40;
},
});
wrapper.setProps({ children: 'xx' });
expect(wrapper.state().scale).toBe(0.32);
});
}); });

View File

@ -439,6 +439,81 @@ exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
</div> </div>
`; `;
exports[`renders ./components/avatar/demo/toggle-debug.md correctly 1`] = `
<div>
<button
class="ant-btn"
type="button"
>
<span>
Toggle Avatar visibility
</span>
</button>
<button
class="ant-btn"
type="button"
>
<span>
Toggle Avatar size
</span>
</button>
<button
class="ant-btn"
type="button"
>
<span>
Change Avatar scale
</span>
</button>
<br />
<br />
<div
style="text-align:center;transform:scale(1);margin-top:24px"
>
<span
class="ant-avatar ant-avatar-lg ant-avatar-circle"
style="background:#7265e6;display:none"
>
<span
class="ant-avatar-string"
>
Avatar
</span>
</span>
<span
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-image"
style="background:#00a2ae;display:none"
>
<img
src="invalid"
/>
</span>
<div
style="display:none"
>
<span
class="ant-avatar ant-avatar-lg ant-avatar-circle"
style="background:#7265e6"
>
<span
class="ant-avatar-string"
>
Avatar
</span>
</span>
<span
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-image"
style="background:#00a2ae"
>
<img
src="invalid"
/>
</span>
</div>
</div>
</div>
`;
exports[`renders ./components/avatar/demo/type.md correctly 1`] = ` exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
<div> <div>
<span <span

View File

@ -50,6 +50,5 @@ class Autoset extends React.Component {
} }
} }
ReactDOM.render(<Autoset />, ReactDOM.render(<Autoset />, mountNode);
mountNode);
```` ````

View File

@ -0,0 +1,80 @@
---
order: 4
title:
zh-CN: 隐藏情况下计算字符对齐
en-US: Calculate text style when hiding
debug: true
---
## zh-CN
切换 Avatar 显示的时候,文本样式应该居中并正确调整字体大小。
## en-US
Text inside Avatar should be set a proper font size when toggle it's visibility.
````jsx
import { Avatar, Button } from 'antd';
class App extends React.Component {
state = {
hide: true,
size: 'large',
scale: 1,
};
toggle = () => {
this.setState({
hide: !this.state.hide,
});
}
toggleSize = () => {
const sizes = ['small', 'default', 'large'];
let current = sizes.indexOf(this.state.size) + 1;
if (current > 2) {
current = 0;
}
this.setState({
size: sizes[current],
});
}
changeScale = () => {
this.setState({
scale: this.state.scale === 1 ? 2 : 1,
});
}
render() {
const { hide, size, scale } = this.state;
return (
<div>
<Button onClick={this.toggle}>Toggle Avatar visibility</Button>
<Button onClick={this.toggleSize}>Toggle Avatar size</Button>
<Button onClick={this.changeScale}>Change Avatar scale</Button>
<br />
<br />
<div style={{ textAlign: 'center', transform: `scale(${scale})`, marginTop: 24 }}>
<Avatar size={size} style={{ background: '#7265e6', display: hide ? 'none' : '' }}>
Avatar
</Avatar>
<Avatar size={size} src="invalid" style={{ background: '#00a2ae', display: hide ? 'none' : '' }}>
Invalid
</Avatar>
<div style={{ display: hide ? 'none' : '' }}>
<Avatar size={size} style={{ background: '#7265e6' }}>
Avatar
</Avatar>
<Avatar size={size} src="invalid" style={{ background: '#00a2ae' }}>
Invalid
</Avatar>
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);

View File

@ -1,5 +1,4 @@
import * as React from 'react'; import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Icon from '../icon'; import Icon from '../icon';
import classNames from 'classnames'; import classNames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
@ -44,43 +43,42 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
isImgExist: true, isImgExist: true,
}; };
private avatarChildren: any; private avatarNode: HTMLElement;
private avatarChildren: HTMLElement;
private lastChildrenWidth: number;
private lastNodeWidth: number;
componentDidMount() { componentDidMount() {
this.setScale(); this.setScale();
} }
componentDidUpdate(prevProps: AvatarProps, prevState: AvatarState) { componentDidUpdate(prevProps: AvatarProps) {
if ( this.setScale();
prevProps.children !== this.props.children ||
(prevState.scale !== this.state.scale && this.state.scale === 1) ||
prevState.isImgExist !== this.state.isImgExist
) {
this.setScale();
}
if (prevProps.src !== this.props.src) { if (prevProps.src !== this.props.src) {
this.setState({ isImgExist: true, scale: 1 }); this.setState({ isImgExist: true, scale: 1 });
} }
} }
setScale = () => { setScale = () => {
const childrenNode = this.avatarChildren; if (!this.avatarChildren || !this.avatarNode) {
if (childrenNode) { return;
const childrenWidth = childrenNode.offsetWidth;
const avatarNode = ReactDOM.findDOMNode(this) as Element;
const avatarWidth = avatarNode.getBoundingClientRect().width;
// add 4px gap for each side to get better performance
if (avatarWidth - 8 < childrenWidth) {
this.setState({
scale: (avatarWidth - 8) / childrenWidth,
});
} else {
this.setState({
scale: 1,
});
}
} }
const childrenWidth = this.avatarChildren.offsetWidth; // offsetWidth avoid affecting be transform scale
const nodeWidth = this.avatarNode.offsetWidth;
// denominator is 0 is no meaning
if (
childrenWidth === 0 ||
nodeWidth === 0 ||
(this.lastChildrenWidth === childrenWidth && this.lastNodeWidth === nodeWidth)
) {
return;
}
this.lastChildrenWidth = childrenWidth;
this.lastNodeWidth = nodeWidth;
// add 4px gap for each side to get better performance
this.setState({
scale: nodeWidth - 8 < childrenWidth ? (nodeWidth - 8) / childrenWidth : 1,
});
}; };
handleImgLoadError = () => { handleImgLoadError = () => {
@ -152,7 +150,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
children = ( children = (
<span <span
className={`${prefixCls}-string`} className={`${prefixCls}-string`}
ref={span => (this.avatarChildren = span)} ref={(node: HTMLElement) => (this.avatarChildren = node)}
style={{ ...sizeChildrenStyle, ...childrenStyle }} style={{ ...sizeChildrenStyle, ...childrenStyle }}
> >
{children} {children}
@ -160,14 +158,22 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
); );
} else { } else {
children = ( children = (
<span className={`${prefixCls}-string`} ref={span => (this.avatarChildren = span)}> <span
className={`${prefixCls}-string`}
ref={(node: HTMLElement) => (this.avatarChildren = node)}
>
{children} {children}
</span> </span>
); );
} }
} }
return ( return (
<span {...others} style={{ ...sizeStyle, ...others.style }} className={classString}> <span
{...others}
style={{ ...sizeStyle, ...others.style }}
className={classString}
ref={(node: HTMLElement) => (this.avatarNode = node)}
>
{children} {children}
</span> </span>
); );

View File

@ -42,7 +42,9 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
if (nextState.count === nextProps.count) { if (nextState.count === nextProps.count) {
return null; return null;
} }
return { animateStarted: true }; return {
animateStarted: true,
};
} }
return null; return null;
} }
@ -78,13 +80,20 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
componentDidUpdate(_: any, prevState: ScrollNumberState) { componentDidUpdate(_: any, prevState: ScrollNumberState) {
this.lastCount = prevState.count; this.lastCount = prevState.count;
if (this.state.animateStarted) { const { animateStarted } = this.state;
this.setState({ animateStarted: false, count: this.props.count }, () => { const { onAnimated } = this.props;
const { onAnimated } = this.props; if (animateStarted) {
if (onAnimated) { this.setState(
onAnimated(); {
} animateStarted: false,
}); count: this.props.count,
},
() => {
if (onAnimated) {
onAnimated();
}
},
);
} }
} }

View File

@ -89,4 +89,10 @@ describe('Badge', () => {
); );
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
// https://github.com/ant-design/ant-design/issues/15349
it('should color style works on Badge', () => {
const wrapper = mount(<Badge style={{ color: 'red' }} status="success" text="Success" />);
expect(wrapper.find('.ant-badge-status-text').props().style.color).toBe('red');
});
}); });

View File

@ -183,14 +183,14 @@ export default class Badge extends React.Component<BadgeProps, any> {
// <Badge status="success" /> // <Badge status="success" />
if (!children && status) { if (!children && status) {
const styleWithOffset = this.getStyleWithOffset();
const statusTextColor = styleWithOffset && styleWithOffset.color;
return ( return (
<span <span {...restProps} className={this.getBadgeClassName(prefixCls)} style={styleWithOffset}>
{...restProps}
className={this.getBadgeClassName(prefixCls)}
style={this.getStyleWithOffset()}
>
<span className={statusCls} /> <span className={statusCls} />
<span className={`${prefixCls}-status-text`}>{text}</span> <span style={{ color: statusTextColor }} className={`${prefixCls}-status-text`}>
{text}
</span>
</span> </span>
); );
} }

View File

@ -113,7 +113,9 @@
} }
&-not-a-wrapper { &-not-a-wrapper {
vertical-align: middle; &:not(.@{badge-prefix-cls}-status) {
vertical-align: middle;
}
.@{ant-prefix}-scroll-number { .@{ant-prefix}-scroll-number {
position: relative; position: relative;

View File

@ -6,6 +6,7 @@ export interface BreadcrumbItemProps {
prefixCls?: string; prefixCls?: string;
separator?: React.ReactNode; separator?: React.ReactNode;
href?: string; href?: string;
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
} }
export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps, any> { export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps, any> {

View File

@ -144,14 +144,14 @@ export default class Header extends React.Component<HeaderProps, any> {
const prefixCls = getPrefixCls('fullcalendar', customizePrefixCls); const prefixCls = getPrefixCls('fullcalendar', customizePrefixCls);
const yearSelect = this.getYearSelectElement(prefixCls, value.year()); const yearSelect = this.getYearSelectElement(prefixCls, value.year());
const monthSelect = const monthSelect =
type === 'date' type === 'month'
? this.getMonthSelectElement(prefixCls, value.month(), this.getMonthsLocale(value)) ? this.getMonthSelectElement(prefixCls, value.month(), this.getMonthsLocale(value))
: null; : null;
const size = (fullscreen ? 'default' : 'small') as any; const size = (fullscreen ? 'default' : 'small') as any;
const typeSwitch = ( const typeSwitch = (
<Group onChange={this.onTypeChange} value={type} size={size}> <Group onChange={this.onTypeChange} value={type} size={size}>
<Button value="date">{locale.month}</Button> <Button value="month">{locale.month}</Button>
<Button value="month">{locale.year}</Button> <Button value="year">{locale.year}</Button>
</Group> </Group>
); );

View File

@ -120,7 +120,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -139,7 +139,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -1165,7 +1165,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -1184,7 +1184,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -2208,7 +2208,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -2227,7 +2227,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -3661,7 +3661,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -3680,7 +3680,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"

View File

@ -120,7 +120,7 @@ exports[`Calendar Calendar should support locale 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -139,7 +139,7 @@ exports[`Calendar Calendar should support locale 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"

View File

@ -161,4 +161,18 @@ describe('Calendar', () => {
expect(onPanelChange).toBeCalled(); expect(onPanelChange).toBeCalled();
expect(onPanelChange.mock.calls[0][0].month()).toEqual(date.month() - 1); expect(onPanelChange.mock.calls[0][0].month()).toEqual(date.month() - 1);
}); });
it('switch should work correctly without prop mode', async () => {
const onPanelChange = jest.fn();
const date = new Moment(new Date(Date.UTC(2017, 7, 9, 8)));
const wrapper = mount(<Calendar onPanelChange={onPanelChange} value={date} />);
expect(wrapper.state().mode).toBe('month');
expect(wrapper.find('.ant-fullcalendar-table').length).toBe(1);
expect(wrapper.find('.ant-fullcalendar-month-panel-table').length).toBe(0);
wrapper.find('.ant-radio-button-input[value="year"]').simulate('change');
expect(wrapper.find('.ant-fullcalendar-table').length).toBe(0);
expect(wrapper.find('.ant-fullcalendar-month-panel-table').length).toBe(1);
expect(onPanelChange).toBeCalled();
expect(onPanelChange.mock.calls[0][1]).toEqual('year');
});
}); });

View File

@ -53,7 +53,6 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
static defaultProps = { static defaultProps = {
locale: {}, locale: {},
fullscreen: true, fullscreen: true,
mode: 'month' as CalendarMode,
onSelect: noop, onSelect: noop,
onPanelChange: noop, onPanelChange: noop,
onChange: noop, onChange: noop,
@ -100,7 +99,7 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
} }
this.state = { this.state = {
value, value,
mode: props.mode, mode: props.mode || 'month',
}; };
} }
@ -145,20 +144,13 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
} }
}; };
setType = (type: string) => {
const mode = type === 'date' ? 'month' : 'year';
if (this.state.mode !== mode) {
this.setState({ mode });
this.onPanelChange(this.state.value, mode);
}
};
onHeaderValueChange = (value: moment.Moment) => { onHeaderValueChange = (value: moment.Moment) => {
this.setValue(value, 'changePanel'); this.setValue(value, 'changePanel');
}; };
onHeaderTypeChange = (type: string) => { onHeaderTypeChange = (mode: CalendarMode) => {
this.setType(type); this.setState({ mode });
this.onPanelChange(this.state.value, mode);
}; };
onPanelChange(value: moment.Moment, mode: CalendarMode | undefined) { onPanelChange(value: moment.Moment, mode: CalendarMode | undefined) {
@ -216,8 +208,6 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
dateFullCellRender, dateFullCellRender,
monthFullCellRender, monthFullCellRender,
} = props; } = props;
const type = mode === 'year' ? 'month' : 'date';
const monthCellRender = monthFullCellRender || this.monthCellRender; const monthCellRender = monthFullCellRender || this.monthCellRender;
const dateCellRender = dateFullCellRender || this.dateCellRender; const dateCellRender = dateFullCellRender || this.dateCellRender;
@ -246,7 +236,7 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
<div className={cls} style={style}> <div className={cls} style={style}>
<Header <Header
fullscreen={fullscreen} fullscreen={fullscreen}
type={type} type={mode}
value={value} value={value}
locale={locale.lang} locale={locale.lang}
prefixCls={prefixCls} prefixCls={prefixCls}
@ -259,7 +249,7 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
disabledDate={disabledDate} disabledDate={disabledDate}
Select={noop} Select={noop}
locale={locale.lang} locale={locale.lang}
type={type} type={mode === 'year' ? 'month' : 'date'}
prefixCls={prefixCls} prefixCls={prefixCls}
showHeader={false} showHeader={false}
value={value} value={value}

View File

@ -3,3 +3,5 @@ import './index.less';
// style dependencies // style dependencies
import '../../tabs/style'; import '../../tabs/style';
import '../../row/style';
import '../../col/style';

View File

@ -1,2 +1,5 @@
import '../../style/index.less'; import '../../style/index.less';
import '../../grid/style/index.less';
// style dependencies
// deps-lint-skip: grid
import '../../grid/style';

View File

@ -1276,7 +1276,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
checked="" checked=""
class="config-radio-button-input" class="config-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="config-radio-button-inner" class="config-radio-button-inner"
@ -1295,7 +1295,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
<input <input
class="config-radio-button-input" class="config-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="config-radio-button-inner" class="config-radio-button-inner"
@ -2264,7 +2264,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
<input <input
class="config-radio-button-input" class="config-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="config-radio-button-inner" class="config-radio-button-inner"
@ -2284,7 +2284,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
checked="" checked=""
class="config-radio-button-input" class="config-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="config-radio-button-inner" class="config-radio-button-inner"
@ -2672,7 +2672,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -2691,7 +2691,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -3660,7 +3660,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -3680,7 +3680,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -4068,7 +4068,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -4087,7 +4087,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -5056,7 +5056,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -5076,7 +5076,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"

View File

@ -27,7 +27,7 @@ export const configConsumerProps = [
'autoInsertSpaceInButton', 'autoInsertSpaceInButton',
]; ];
interface ConfigProviderProps { export interface ConfigProviderProps {
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement; getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
prefixCls?: string; prefixCls?: string;
children?: React.ReactNode; children?: React.ReactNode;

View File

@ -348,7 +348,7 @@ exports[`renders ./components/date-picker/demo/disabled-date.md correctly 1`] =
<div> <div>
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input
@ -493,7 +493,7 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
</span> </span>
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input
@ -872,7 +872,7 @@ exports[`renders ./components/date-picker/demo/mode.md correctly 1`] = `
<div> <div>
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input
@ -1264,7 +1264,7 @@ exports[`renders ./components/date-picker/demo/start-end.md correctly 1`] = `
<div> <div>
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input
@ -1295,7 +1295,7 @@ exports[`renders ./components/date-picker/demo/start-end.md correctly 1`] = `
</span> </span>
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input
@ -1567,7 +1567,7 @@ exports[`renders ./components/date-picker/demo/time.md correctly 1`] = `
<div> <div>
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input

View File

@ -1029,7 +1029,7 @@ exports[`Picker format by locale date 1`] = `
exports[`Picker format by locale dateTime 1`] = ` exports[`Picker format by locale dateTime 1`] = `
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
style="width: 195px;" style="min-width: 195px;"
> >
<div> <div>
<input <input

View File

@ -34,7 +34,7 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
static getDerivedStateFromProps(nextProps: PickerProps, prevState: PickerState) { static getDerivedStateFromProps(nextProps: PickerProps, prevState: PickerState) {
const state: Partial<PickerState> = {}; const state: Partial<PickerState> = {};
let open: boolean = prevState.open; let { open } = prevState;
if ('open' in nextProps) { if ('open' in nextProps) {
state.open = nextProps.open; state.open = nextProps.open;
@ -53,6 +53,7 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
} }
private input: any; private input: any;
private prefixCls?: string; private prefixCls?: string;
constructor(props: any) { constructor(props: any) {
@ -92,7 +93,7 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
}; };
handleChange = (value: moment.Moment | null) => { handleChange = (value: moment.Moment | null) => {
const props = this.props; const { props } = this;
if (!('value' in props)) { if (!('value' in props)) {
this.setState({ this.setState({
value, value,
@ -155,13 +156,13 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
let pickerProps: Object = {}; let pickerProps: Object = {};
let calendarProps: any = {}; let calendarProps: any = {};
const pickerStyle: { width?: number } = {}; const pickerStyle: { minWidth?: number } = {};
if (props.showTime) { if (props.showTime) {
calendarProps = { calendarProps = {
// fix https://github.com/ant-design/ant-design/issues/1902 // fix https://github.com/ant-design/ant-design/issues/1902
onSelect: this.handleChange, onSelect: this.handleChange,
}; };
pickerStyle.width = 195; pickerStyle.minWidth = 195;
} else { } else {
pickerProps = { pickerProps = {
onChange: this.handleChange, onChange: this.handleChange,

View File

@ -77,7 +77,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| defaultValue | to set default date | [moment](http://momentjs.com/) | - | | defaultValue | to set default date, if start time or end time is null or undefined, the date range will be an open interval | [moment](http://momentjs.com/) | - |
| defaultPickerValue | to set default picker date | [moment](http://momentjs.com/) | - | | defaultPickerValue | to set default picker date | [moment](http://momentjs.com/) | - |
| disabledTime | to specify the time that cannot be selected | function(date) | - | | disabledTime | to specify the time that cannot be selected | function(date) | - |
| format | to set the date format, refer to [moment.js](http://momentjs.com/). When an array is provided, all values are used for parsing and first value is used for formatting. | string \| string[] | "YYYY-MM-DD" | | format | to set the date format, refer to [moment.js](http://momentjs.com/). When an array is provided, all values are used for parsing and first value is used for formatting. | string \| string[] | "YYYY-MM-DD" |

View File

@ -78,7 +78,7 @@ moment.locale('zh-cn');
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | 无 | | defaultValue | 默认日期,如果开始时间或结束时间为 `null` 或者 `undefined`,日期范围将是一个开区间 | [moment](http://momentjs.com/) | 无 |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | 无 | | defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | 无 |
| disabledTime | 不可选择的时间 | function(date) | 无 | | disabledTime | 不可选择的时间 | function(date) | 无 |
| format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [moment.js](http://momentjs.com/) | string \| string[] | "YYYY-MM-DD" | | format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [moment.js](http://momentjs.com/) | string \| string[] | "YYYY-MM-DD" |

View File

@ -2,6 +2,7 @@ import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies // style dependencies
// deps-lint-skip: input
import '../../input/style'; import '../../input/style';
import '../../time-picker/style'; import '../../time-picker/style';
import '../../tag/style'; import '../../tag/style';

View File

@ -1,5 +1,2 @@
import '../../style/index.less'; import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies
import '../../button/style';

View File

@ -43,9 +43,3 @@
} }
} }
} }
// Patch for popup adjust
.@{ant-prefix}-select-dropdown--empty .@{ant-prefix}-select-dropdown-menu-item {
padding-right: 0;
padding-left: 0;
}

View File

@ -75,7 +75,7 @@ export type ValidationRule = {
validator?: (rule: any, value: any, callback: any, source?: any, options?: any) => any; validator?: (rule: any, value: any, callback: any, source?: any, options?: any) => any;
}; };
export type ValidateCallback = (errors: any, values: any) => void; export type ValidateCallback<V> = (errors: any, values: V) => void;
export type GetFieldDecoratorOptions = { export type GetFieldDecoratorOptions = {
/** 子节点的值的属性,如 Checkbox 的是 'checked' */ /** 子节点的值的属性,如 Checkbox 的是 'checked' */
@ -134,7 +134,7 @@ export type ValidateFieldsOptions = {
}; };
// function create // function create
export type WrappedFormUtils = { export type WrappedFormUtils<V = any> = {
/** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */ /** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */
getFieldsValue(fieldNames?: Array<string>): { [field: string]: any }; getFieldsValue(fieldNames?: Array<string>): { [field: string]: any };
/** 获取一个输入控件的值 */ /** 获取一个输入控件的值 */
@ -147,26 +147,26 @@ export type WrappedFormUtils = {
validateFields( validateFields(
fieldNames: Array<string>, fieldNames: Array<string>,
options: ValidateFieldsOptions, options: ValidateFieldsOptions,
callback: ValidateCallback, callback: ValidateCallback<V>,
): void; ): void;
validateFields(options: ValidateFieldsOptions, callback: ValidateCallback): void; validateFields(options: ValidateFieldsOptions, callback: ValidateCallback<V>): void;
validateFields(fieldNames: Array<string>, callback: ValidateCallback): void; validateFields(fieldNames: Array<string>, callback: ValidateCallback<V>): void;
validateFields(fieldNames: Array<string>, options: ValidateFieldsOptions): void; validateFields(fieldNames: Array<string>, options: ValidateFieldsOptions): void;
validateFields(fieldNames: Array<string>): void; validateFields(fieldNames: Array<string>): void;
validateFields(callback: ValidateCallback): void; validateFields(callback: ValidateCallback<V>): void;
validateFields(options: ValidateFieldsOptions): void; validateFields(options: ValidateFieldsOptions): void;
validateFields(): void; validateFields(): void;
/** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */ /** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */
validateFieldsAndScroll( validateFieldsAndScroll(
fieldNames: Array<string>, fieldNames: Array<string>,
options: ValidateFieldsOptions, options: ValidateFieldsOptions,
callback: ValidateCallback, callback: ValidateCallback<V>,
): void; ): void;
validateFieldsAndScroll(options: ValidateFieldsOptions, callback: ValidateCallback): void; validateFieldsAndScroll(options: ValidateFieldsOptions, callback: ValidateCallback<V>): void;
validateFieldsAndScroll(fieldNames: Array<string>, callback: ValidateCallback): void; validateFieldsAndScroll(fieldNames: Array<string>, callback: ValidateCallback<V>): void;
validateFieldsAndScroll(fieldNames: Array<string>, options: ValidateFieldsOptions): void; validateFieldsAndScroll(fieldNames: Array<string>, options: ValidateFieldsOptions): void;
validateFieldsAndScroll(fieldNames: Array<string>): void; validateFieldsAndScroll(fieldNames: Array<string>): void;
validateFieldsAndScroll(callback: ValidateCallback): void; validateFieldsAndScroll(callback: ValidateCallback<V>): void;
validateFieldsAndScroll(options: ValidateFieldsOptions): void; validateFieldsAndScroll(options: ValidateFieldsOptions): void;
validateFieldsAndScroll(): void; validateFieldsAndScroll(): void;
/** 获取某个输入控件的 Error */ /** 获取某个输入控件的 Error */
@ -185,8 +185,8 @@ export type WrappedFormUtils = {
): (node: React.ReactNode) => React.ReactNode; ): (node: React.ReactNode) => React.ReactNode;
}; };
export interface FormComponentProps { export interface FormComponentProps<V = any> {
form: WrappedFormUtils; form: WrappedFormUtils<V>;
} }
export interface RcBaseFormProps { export interface RcBaseFormProps {

View File

@ -2550,7 +2550,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
<span <span
class="ant-calendar-picker" class="ant-calendar-picker"
id="time_related_controls_date-time-picker" id="time_related_controls_date-time-picker"
style="width:195px" style="min-width:195px"
> >
<div> <div>
<input <input

View File

@ -10,11 +10,12 @@
@form-component-max-height: @input-height-lg; @form-component-max-height: @input-height-lg;
@form-feedback-icon-size: @font-size-base; @form-feedback-icon-size: @font-size-base;
@form-help-margin-top: (@form-component-height - @form-component-max-height) / 2 + 2px; @form-help-margin-top: (@form-component-height - @form-component-max-height) / 2 + 2px;
@form-explain-font-size: @font-size-base;
// Extends additional 1px to fix precision issue. // Extends additional 1px to fix precision issue.
// https://github.com/ant-design/ant-design/issues/12803 // https://github.com/ant-design/ant-design/issues/12803
// https://github.com/ant-design/ant-design/issues/8220 // https://github.com/ant-design/ant-design/issues/8220
@form-explain-precision: 1px; @form-explain-precision: 1px;
@form-explain-height: floor(@font-size-base * @line-height-base); @form-explain-height: floor(@form-explain-font-size * @line-height-base);
.@{form-prefix-cls} { .@{form-prefix-cls} {
.reset-component; .reset-component;
@ -137,6 +138,7 @@ input[type='checkbox'] {
min-height: @form-explain-height + @form-explain-precision; min-height: @form-explain-height + @form-explain-precision;
margin-top: @form-help-margin-top; margin-top: @form-help-margin-top;
color: @text-color-secondary; color: @text-color-secondary;
font-size: @form-explain-font-size;
line-height: @line-height-base; line-height: @line-height-base;
transition: color 0.3s @ease-out; // sync input color transition transition: color 0.3s @ease-out; // sync input color transition
} }

View File

@ -42,6 +42,8 @@ We introduced SVG icons in `3.9.0` version replacing font icons which brings ben
More discussion of SVG icon reference to [#10353](https://github.com/ant-design/ant-design/issues/10353). More discussion of SVG icon reference to [#10353](https://github.com/ant-design/ant-design/issues/10353).
> ⚠️ About the extra bundle size brought by all SVG icons we imported in 3.9.0, we will provide new API to allow developers importing icons as your need, you can trace [#12011](https://github.com/ant-design/ant-design/issues/12011) for further progress. > ⚠️ About the extra bundle size brought by all SVG icons we imported in 3.9.0, we will provide new API to allow developers importing icons as your need, you can trace [#12011](https://github.com/ant-design/ant-design/issues/12011) for further progress.
>
> Before this, you can use [webpack plugin](https://github.com/Beven91/webpack-ant-icon-loader) from community to chunk the icon file.
The properties `theme`, `component` and `twoToneColor` are added in `3.9.0`. The best practice is to pass the property `theme` to every `<Icon />` components. The properties `theme`, `component` and `twoToneColor` are added in `3.9.0`. The best practice is to pass the property `theme` to every `<Icon />` components.

View File

@ -47,6 +47,8 @@ ReactDOM.render(<IconDisplay />, mountNode);
更多讨论可参考:[#10353](https://github.com/ant-design/ant-design/issues/10353)。 更多讨论可参考:[#10353](https://github.com/ant-design/ant-design/issues/10353)。
> ⚠️ 3.9.0 之后我们全量引入了所有图标,导致 antd 默认的包体积有一定增加,我们会在不远的未来增加新的 API 来实现图标的按需使用,更多相关讨论可关注:[#12011](https://github.com/ant-design/ant-design/issues/12011)。 > ⚠️ 3.9.0 之后我们全量引入了所有图标,导致 antd 默认的包体积有一定增加,我们会在不远的未来增加新的 API 来实现图标的按需使用,更多相关讨论可关注:[#12011](https://github.com/ant-design/ant-design/issues/12011)。
>
> 在此之前,你可以通过来自社区同学的 [webpack 插件](https://github.com/Beven91/webpack-ant-icon-loader)将图标文件拆分。
其中 `theme`, `component`, `twoToneColor``3.9.x` 版本新增加的属性。最佳实践是给使用的 `<Icon />` 组件传入属性 `theme` 以明确图标的主题风格。例如: 其中 `theme`, `component`, `twoToneColor``3.9.x` 版本新增加的属性。最佳实践是给使用的 `<Icon />` 组件传入属性 `theme` 以明确图标的主题风格。例如:

View File

@ -42,7 +42,7 @@ export default class Password extends React.Component<PasswordProps, PasswordSta
const iconProps = { const iconProps = {
[iconTrigger]: this.onChange, [iconTrigger]: this.onChange,
className: `${prefixCls}-icon`, className: `${prefixCls}-icon`,
type: this.state.visible ? 'eye-invisible' : 'eye', type: this.state.visible ? 'eye' : 'eye-invisible',
key: 'passwordIcon', key: 'passwordIcon',
onMouseDown: (e: MouseEvent) => { onMouseDown: (e: MouseEvent) => {
// Prevent focused state lost // Prevent focused state lost

View File

@ -941,21 +941,24 @@ exports[`renders ./components/input/demo/password-input.md correctly 1`] = `
class="ant-input-suffix" class="ant-input-suffix"
> >
<i <i
aria-label="icon: eye" aria-label="icon: eye-invisible"
class="anticon anticon-eye ant-input-password-icon" class="anticon anticon-eye-invisible ant-input-password-icon"
tabindex="-1" tabindex="-1"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
class="" class=""
data-icon="eye" data-icon="eye-invisible"
fill="currentColor" fill="currentColor"
height="1em" height="1em"
viewBox="64 64 896 896" viewBox="64 64 896 896"
width="1em" width="1em"
> >
<path <path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z" d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 0 0 0-51.5zm-63.57-320.64L836 122.88a8 8 0 0 0-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 0 0 0 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 0 0 0 11.31L155.17 889a8 8 0 0 0 11.31 0l712.15-712.12a8 8 0 0 0 0-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 0 0-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 0 1 146.2-106.69L401.31 546.2A112 112 0 0 1 396 512z"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 0 0 227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 0 1-112 112z"
/> />
</svg> </svg>
</i> </i>

View File

@ -298,7 +298,7 @@ exports[`Input.Password should change type when click 1`] = `
className="ant-input-password-icon" className="ant-input-password-icon"
onClick={[Function]} onClick={[Function]}
onMouseDown={[Function]} onMouseDown={[Function]}
type="eye" type="eye-invisible"
/> />
} }
type="password" type="password"
@ -317,92 +317,6 @@ exports[`Input.Password should change type when click 1`] = `
type="password" type="password"
value="111" value="111"
/> />
<span
className="ant-input-suffix"
>
<Icon
className="ant-input-password-icon"
key="passwordIcon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye"
>
<LocaleReceiver
componentName="Icon"
>
<i
aria-label="icon: eye"
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
tabIndex={-1}
>
<IconReact
className=""
type="eye-o"
>
<svg
aria-hidden="true"
className=""
data-icon="eye"
fill="currentColor"
height="1em"
key="svg-eye"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
key="svg-eye-svg-0"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>
</Consumer>
</Input>
</Password>
`;
exports[`Input.Password should change type when click 2`] = `
<Password
action="click"
inputPrefixCls="ant-input"
prefixCls="ant-input-password"
visibilityToggle={true}
>
<Input
action="click"
className="ant-input-password"
disabled={false}
prefixCls="ant-input"
suffix={
<Icon
className="ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye-invisible"
/>
}
type="text"
>
<Consumer>
<span
className="ant-input-password ant-input-affix-wrapper"
>
<input
action="click"
className="ant-input"
disabled={false}
onChange={[Function]}
onKeyDown={[Function]}
style={null}
type="text"
value="111"
/>
<span <span
className="ant-input-suffix" className="ant-input-suffix"
> >
@ -457,7 +371,7 @@ exports[`Input.Password should change type when click 2`] = `
</Password> </Password>
`; `;
exports[`Input.Password should change type when click 3`] = ` exports[`Input.Password should change type when click 2`] = `
<Password <Password
action="click" action="click"
inputPrefixCls="ant-input" inputPrefixCls="ant-input"
@ -477,7 +391,7 @@ exports[`Input.Password should change type when click 3`] = `
type="eye" type="eye"
/> />
} }
type="password" type="text"
> >
<Consumer> <Consumer>
<span <span
@ -490,7 +404,7 @@ exports[`Input.Password should change type when click 3`] = `
onChange={[Function]} onChange={[Function]}
onKeyDown={[Function]} onKeyDown={[Function]}
style={null} style={null}
type="password" type="text"
value="111" value="111"
/> />
<span <span
@ -543,6 +457,96 @@ exports[`Input.Password should change type when click 3`] = `
</Password> </Password>
`; `;
exports[`Input.Password should change type when click 3`] = `
<Password
action="click"
inputPrefixCls="ant-input"
prefixCls="ant-input-password"
visibilityToggle={true}
>
<Input
action="click"
className="ant-input-password"
disabled={false}
prefixCls="ant-input"
suffix={
<Icon
className="ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye-invisible"
/>
}
type="password"
>
<Consumer>
<span
className="ant-input-password ant-input-affix-wrapper"
>
<input
action="click"
className="ant-input"
disabled={false}
onChange={[Function]}
onKeyDown={[Function]}
style={null}
type="password"
value="111"
/>
<span
className="ant-input-suffix"
>
<Icon
className="ant-input-password-icon"
key="passwordIcon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye-invisible"
>
<LocaleReceiver
componentName="Icon"
>
<i
aria-label="icon: eye-invisible"
className="anticon anticon-eye-invisible ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
tabIndex={-1}
>
<IconReact
className=""
type="eye-invisible-o"
>
<svg
aria-hidden="true"
className=""
data-icon="eye-invisible"
fill="currentColor"
height="1em"
key="svg-eye-invisible"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 0 0 0-51.5zm-63.57-320.64L836 122.88a8 8 0 0 0-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 0 0 0 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 0 0 0 11.31L155.17 889a8 8 0 0 0 11.31 0l712.15-712.12a8 8 0 0 0 0-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 0 0-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 0 1 146.2-106.69L401.31 546.2A112 112 0 0 1 396 512z"
key="svg-eye-invisible-svg-0"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 0 0 227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 0 1-112 112z"
key="svg-eye-invisible-svg-1"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>
</Consumer>
</Input>
</Password>
`;
exports[`Input.Search should support suffix 1`] = ` exports[`Input.Search should support suffix 1`] = `
<Search <Search
enterButton={false} enterButton={false}

View File

@ -236,7 +236,7 @@ describe('Input.Password', () => {
const wrapper = mount(<Input.Password visibilityToggle={false} />); const wrapper = mount(<Input.Password visibilityToggle={false} />);
expect(wrapper.find('.anticon-eye').length).toBe(0); expect(wrapper.find('.anticon-eye').length).toBe(0);
wrapper.setProps({ visibilityToggle: true }); wrapper.setProps({ visibilityToggle: true });
expect(wrapper.find('.anticon-eye').length).toBe(1); expect(wrapper.find('.anticon-eye-invisible').length).toBe(1);
}); });
it('should keep focus state', () => { it('should keep focus state', () => {

View File

@ -69,6 +69,10 @@
.disabled(); .disabled();
} }
&[disabled] {
.disabled();
}
// Reset height for `textarea`s // Reset height for `textarea`s
textarea& { textarea& {
max-width: 100%; // prevent textearea resize from coming out of its container max-width: 100%; // prevent textearea resize from coming out of its container

View File

@ -95,6 +95,15 @@ describe('Layout', () => {
wrapper.setProps({ collapsed: true }); wrapper.setProps({ collapsed: true });
expect(wrapper.instance().state.collapsed).toBe(true); expect(wrapper.instance().state.collapsed).toBe(true);
}); });
it('should not add ant-layout-has-sider when `hasSider` is `false`', () => {
const wrapper = mount(
<Layout hasSider={false}>
<Sider>Sider</Sider>
</Layout>,
);
expect(wrapper.find('.ant-layout').hasClass('ant-layout-has-sider')).toBe(false);
});
}); });
describe('Sider onBreakpoint', () => { describe('Sider onBreakpoint', () => {

View File

@ -10,7 +10,7 @@ title:
侧边两列式布局。页面横向空间有限时,侧边导航可收起。 侧边两列式布局。页面横向空间有限时,侧边导航可收起。
侧边导航在页面布局上采用的是左右的结构,一般主导航放置于页面的左侧固定位置,辅助菜单放置于工作区顶部。内容根据浏览器终端进行自适应,能提高横向空间的使用率,但是整个页面排版不稳定。侧边导航的模式层级扩展性强,一、二、三级导航项目可以更为顺畅且具关联性的被展示,同时侧边导航可以固定,使得用户在操作和浏览中可以快速的定位和切换当前位置,有很高的操作效率。但这类导航横向页面内容的空间会被牺牲一部 侧边导航在页面布局上采用的是左右的结构,一般主导航放置于页面的左侧固定位置,辅助菜单放置于工作区顶部。内容根据浏览器终端进行自适应,能提高横向空间的使用率,但是整个页面排版不稳定。侧边导航的模式层级扩展性强,一、二、三级导航项目可以更为顺畅且具关联性的被展示,同时侧边导航可以固定,使得用户在操作和浏览中可以快速的定位和切换当前位置,有很高的操作效率。但这类导航横向页面内容的空间会被牺牲一部
## en-US ## en-US

View File

@ -13,8 +13,8 @@ Handling the overall layout of a page.
The first level navigation is inclined left near a logo, and the secondary menu is inclined right. The first level navigation is inclined left near a logo, and the secondary menu is inclined right.
- Top Navigation (almost systems): the height of the first level navigation `64px`, the second level navigation `48px`. - Top Navigation: the height of the first level navigation `64px`, the second level navigation `48px`.
- Top Navigation(contents page): the height of the first level navigation `80px`, the second level navigation `56px`. - Top Navigation (for landing pages): the height of the first level navigation `80px`, the second level navigation `56px`.
- Calculation formula of a top navigation: `48+8n`. - Calculation formula of a top navigation: `48+8n`.
- Calculation formula of an aside navigation: `200+8n`. - Calculation formula of an aside navigation: `200+8n`.

View File

@ -77,7 +77,8 @@ class BasicLayout extends React.Component<BasicPropsWithTagName, BasicLayoutStat
render() { render() {
const { prefixCls, className, children, hasSider, tagName, ...others } = this.props; const { prefixCls, className, children, hasSider, tagName, ...others } = this.props;
const classString = classNames(className, prefixCls, { const classString = classNames(className, prefixCls, {
[`${prefixCls}-has-sider`]: hasSider || this.state.siders.length > 0, [`${prefixCls}-has-sider`]:
typeof hasSider === 'boolean' ? hasSider : this.state.siders.length > 0,
}); });
return React.createElement(tagName, { className: classString, ...others }, children); return React.createElement(tagName, { className: classString, ...others }, children);
} }

View File

@ -66,6 +66,7 @@ export default class Item extends React.Component<ListItemProps, any> {
static contextTypes = { static contextTypes = {
grid: PropTypes.any, grid: PropTypes.any,
itemLayout: PropTypes.string,
}; };
context: any; context: any;
@ -81,8 +82,17 @@ export default class Item extends React.Component<ListItemProps, any> {
return result; return result;
} }
isFlexMode() {
const { extra } = this.props;
const { itemLayout } = this.context;
if (itemLayout === 'vertical') {
return !!extra;
}
return !this.isItemContainsTextNode();
}
renderItem = ({ getPrefixCls }: ConfigConsumerProps) => { renderItem = ({ getPrefixCls }: ConfigConsumerProps) => {
const { grid } = this.context; const { grid, itemLayout } = this.context;
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
children, children,
@ -106,10 +116,10 @@ export default class Item extends React.Component<ListItemProps, any> {
<div <div
{...others} {...others}
className={classNames(`${prefixCls}-item`, className, { className={classNames(`${prefixCls}-item`, className, {
[`${prefixCls}-item-no-flex`]: !extra && this.isItemContainsTextNode(), [`${prefixCls}-item-no-flex`]: !this.isFlexMode(),
})} })}
> >
{extra {itemLayout === 'vertical' && extra
? [ ? [
<div className={`${prefixCls}-item-main`} key="content"> <div className={`${prefixCls}-item-main`} key="content">
{children} {children}
@ -119,7 +129,11 @@ export default class Item extends React.Component<ListItemProps, any> {
{extra} {extra}
</div>, </div>,
] ]
: [children, actionsContent]} : [
children,
actionsContent,
extra ? React.cloneElement(extra as React.ReactElement<any>, { key: 'extra' }) : null,
]}
</div> </div>
); );

View File

@ -0,0 +1,123 @@
import React from 'react';
import { mount } from 'enzyme';
import List from '..';
describe('List Item Layout', () => {
const data = [
{
key: 1,
href: 'http://ant.design',
title: `ant design`,
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team.',
content:
'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
extra: 'extra',
},
];
it('horizontal itemLayout List which contains string nodes should not be flex container', () => {
const wrapper = mount(
<List
dataSource={data}
renderItem={item => (
<List.Item key={item.title}>
I am <span>ant</span> design list item
</List.Item>
)}
/>,
);
expect(
wrapper
.find('.ant-list-item')
.at(0)
.hasClass('ant-list-item-no-flex'),
).toBe(true);
});
it('horizontal itemLayout List should be flex container defaultly', () => {
const wrapper = mount(
<List
dataSource={data}
renderItem={item => (
<List.Item key={item.title}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
description={item.description}
/>
</List.Item>
)}
/>,
);
expect(
wrapper
.find('.ant-list-item')
.at(0)
.hasClass('ant-list-item-no-flex'),
).toBe(false);
});
it('vertical itemLayout List should be flex container when there is extra node', () => {
const wrapper = mount(
<List
itemLayout="vertical"
dataSource={data}
renderItem={item => (
<List.Item key={item.title} extra={item.extra}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
description={item.description}
/>
</List.Item>
)}
/>,
);
expect(
wrapper
.find('.ant-list-item')
.at(0)
.hasClass('ant-list-item-no-flex'),
).toBe(false);
});
it('vertical itemLayout List should not be flex container when there is not extra node', () => {
const wrapper = mount(
<List
itemLayout="vertical"
dataSource={data}
renderItem={item => (
<List.Item key={item.title}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
description={item.description}
/>
</List.Item>
)}
/>,
);
expect(
wrapper
.find('.ant-list-item')
.at(0)
.hasClass('ant-list-item-no-flex'),
).toBe(true);
});
it('horizontal itemLayout List should accept extra node', () => {
const wrapper = mount(
<List
dataSource={data}
renderItem={item => (
<List.Item key={item.title} actions={[<a>Action</a>]} extra={<span>{item.extra}</span>}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
description={item.description}
/>
</List.Item>
)}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
});
});

View File

@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`List Item Layout horizontal itemLayout List should accept extra node 1`] = `
<div
class="ant-list ant-list-split"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-list-item"
>
<div
class="ant-list-item-meta"
>
<div
class="ant-list-item-meta-content"
>
<h4
class="ant-list-item-meta-title"
>
<a
href="http://ant.design"
>
ant design
</a>
</h4>
<div
class="ant-list-item-meta-description"
>
Ant Design, a design language for background applications, is refined by Ant UED Team.
</div>
</div>
</div>
<ul
class="ant-list-item-action"
>
<li>
<a>
Action
</a>
</li>
</ul>
<span>
extra
</span>
</div>
</div>
</div>
</div>
`;

View File

@ -29,6 +29,8 @@ export interface ListGridType {
export type ListSize = 'small' | 'default' | 'large'; export type ListSize = 'small' | 'default' | 'large';
export type ListItemLayout = 'horizontal' | 'vertical';
export interface ListProps { export interface ListProps {
bordered?: boolean; bordered?: boolean;
className?: string; className?: string;
@ -37,7 +39,7 @@ export interface ListProps {
extra?: React.ReactNode; extra?: React.ReactNode;
grid?: ListGridType; grid?: ListGridType;
id?: string; id?: string;
itemLayout?: string; itemLayout?: ListItemLayout;
loading?: boolean | SpinProps; loading?: boolean | SpinProps;
loadMore?: React.ReactNode; loadMore?: React.ReactNode;
pagination?: PaginationConfig | false; pagination?: PaginationConfig | false;
@ -52,7 +54,7 @@ export interface ListProps {
} }
export interface ListLocale { export interface ListLocale {
emptyText: string; emptyText: React.ReactNode | (() => React.ReactNode);
} }
export default class List extends React.Component<ListProps> { export default class List extends React.Component<ListProps> {
@ -60,6 +62,7 @@ export default class List extends React.Component<ListProps> {
static childContextTypes = { static childContextTypes = {
grid: PropTypes.any, grid: PropTypes.any,
itemLayout: PropTypes.string,
}; };
static defaultProps = { static defaultProps = {
@ -94,6 +97,7 @@ export default class List extends React.Component<ListProps> {
getChildContext() { getChildContext() {
return { return {
grid: this.props.grid, grid: this.props.grid,
itemLayout: this.props.itemLayout,
}; };
} }

View File

@ -6,13 +6,16 @@
.@{list-prefix-cls} { .@{list-prefix-cls} {
.reset-component; .reset-component;
position: relative; position: relative;
* { * {
outline: none; outline: none;
} }
&-pagination { &-pagination {
margin-top: 24px; margin-top: 24px;
text-align: right; text-align: right;
} }
&-more { &-more {
margin-top: 12px; margin-top: 12px;
text-align: center; text-align: center;
@ -21,24 +24,32 @@
padding-left: 32px; padding-left: 32px;
} }
} }
&-spin { &-spin {
min-height: 40px; min-height: 40px;
text-align: center; text-align: center;
} }
&-empty-text { &-empty-text {
padding: @list-empty-text-padding; padding: @list-empty-text-padding;
color: @text-color-secondary; color: @text-color-secondary;
font-size: @font-size-base; font-size: @font-size-base;
text-align: center; text-align: center;
} }
&-item { &-item {
display: flex; display: flex;
align-items: center;
padding: @list-item-padding; padding: @list-item-padding;
&-no-flex { &-no-flex {
display: block; display: block;
} }
&-content {
color: @text-color;
}
&-meta { &-meta {
display: flex; display: flex;
flex: 1; flex: 1;
@ -151,6 +162,8 @@
} }
&-vertical &-item { &-vertical &-item {
align-items: initial;
&-main { &-main {
display: block; display: block;
flex: 1; flex: 1;

View File

@ -800,7 +800,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -819,7 +819,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"

View File

@ -6438,7 +6438,7 @@ exports[`Locale Provider should display the text as ar 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -6457,7 +6457,7 @@ exports[`Locale Provider should display the text as ar 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -11505,7 +11505,7 @@ exports[`Locale Provider should display the text as bg 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -11524,7 +11524,7 @@ exports[`Locale Provider should display the text as bg 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -16572,7 +16572,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -16591,7 +16591,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -21639,7 +21639,7 @@ exports[`Locale Provider should display the text as cs 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -21658,7 +21658,7 @@ exports[`Locale Provider should display the text as cs 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -26706,7 +26706,7 @@ exports[`Locale Provider should display the text as da 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -26725,7 +26725,7 @@ exports[`Locale Provider should display the text as da 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -31773,7 +31773,7 @@ exports[`Locale Provider should display the text as de 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -31792,7 +31792,7 @@ exports[`Locale Provider should display the text as de 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -36840,7 +36840,7 @@ exports[`Locale Provider should display the text as el 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -36859,7 +36859,7 @@ exports[`Locale Provider should display the text as el 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -41907,7 +41907,7 @@ exports[`Locale Provider should display the text as en 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -41926,7 +41926,7 @@ exports[`Locale Provider should display the text as en 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -46974,7 +46974,7 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -46993,7 +46993,7 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -52041,7 +52041,7 @@ exports[`Locale Provider should display the text as es 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -52060,7 +52060,7 @@ exports[`Locale Provider should display the text as es 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -57108,7 +57108,7 @@ exports[`Locale Provider should display the text as et 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -57127,7 +57127,7 @@ exports[`Locale Provider should display the text as et 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -62175,7 +62175,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -62194,7 +62194,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -67242,7 +67242,7 @@ exports[`Locale Provider should display the text as fi 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -67261,7 +67261,7 @@ exports[`Locale Provider should display the text as fi 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -72309,7 +72309,7 @@ exports[`Locale Provider should display the text as fr 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -72328,7 +72328,7 @@ exports[`Locale Provider should display the text as fr 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -77376,7 +77376,7 @@ exports[`Locale Provider should display the text as fr 2`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -77395,7 +77395,7 @@ exports[`Locale Provider should display the text as fr 2`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -82443,7 +82443,7 @@ exports[`Locale Provider should display the text as he 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -82462,7 +82462,7 @@ exports[`Locale Provider should display the text as he 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -87510,7 +87510,7 @@ exports[`Locale Provider should display the text as hi 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -87529,7 +87529,7 @@ exports[`Locale Provider should display the text as hi 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -92577,7 +92577,7 @@ exports[`Locale Provider should display the text as hu 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -92596,7 +92596,7 @@ exports[`Locale Provider should display the text as hu 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -97644,7 +97644,7 @@ exports[`Locale Provider should display the text as id 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -97663,7 +97663,7 @@ exports[`Locale Provider should display the text as id 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -102711,7 +102711,7 @@ exports[`Locale Provider should display the text as is 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -102730,7 +102730,7 @@ exports[`Locale Provider should display the text as is 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -107778,7 +107778,7 @@ exports[`Locale Provider should display the text as it 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -107797,7 +107797,7 @@ exports[`Locale Provider should display the text as it 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -112845,7 +112845,7 @@ exports[`Locale Provider should display the text as ja 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -112864,7 +112864,7 @@ exports[`Locale Provider should display the text as ja 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -117912,7 +117912,7 @@ exports[`Locale Provider should display the text as kn 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -117931,7 +117931,7 @@ exports[`Locale Provider should display the text as kn 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -122979,7 +122979,7 @@ exports[`Locale Provider should display the text as ko 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -122998,7 +122998,7 @@ exports[`Locale Provider should display the text as ko 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -128046,7 +128046,7 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -128065,7 +128065,7 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -133113,7 +133113,7 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -133132,7 +133132,7 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -138180,7 +138180,7 @@ exports[`Locale Provider should display the text as nb 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -138199,7 +138199,7 @@ exports[`Locale Provider should display the text as nb 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -143247,7 +143247,7 @@ exports[`Locale Provider should display the text as ne-np 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -143266,7 +143266,7 @@ exports[`Locale Provider should display the text as ne-np 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -148314,7 +148314,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -148333,7 +148333,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -153381,7 +153381,7 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -153400,7 +153400,7 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -158448,7 +158448,7 @@ exports[`Locale Provider should display the text as pl 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -158467,7 +158467,7 @@ exports[`Locale Provider should display the text as pl 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -163515,7 +163515,7 @@ exports[`Locale Provider should display the text as pt 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -163534,7 +163534,7 @@ exports[`Locale Provider should display the text as pt 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -168582,7 +168582,7 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -168601,7 +168601,7 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -173649,7 +173649,7 @@ exports[`Locale Provider should display the text as ru 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -173668,7 +173668,7 @@ exports[`Locale Provider should display the text as ru 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -178716,7 +178716,7 @@ exports[`Locale Provider should display the text as sk 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -178735,7 +178735,7 @@ exports[`Locale Provider should display the text as sk 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -183783,7 +183783,7 @@ exports[`Locale Provider should display the text as sl 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -183802,7 +183802,7 @@ exports[`Locale Provider should display the text as sl 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -188850,7 +188850,7 @@ exports[`Locale Provider should display the text as sr 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -188869,7 +188869,7 @@ exports[`Locale Provider should display the text as sr 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -193917,7 +193917,7 @@ exports[`Locale Provider should display the text as sv 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -193936,7 +193936,7 @@ exports[`Locale Provider should display the text as sv 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -198984,7 +198984,7 @@ exports[`Locale Provider should display the text as th 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -199003,7 +199003,7 @@ exports[`Locale Provider should display the text as th 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -204051,7 +204051,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -204070,7 +204070,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -209118,7 +209118,7 @@ exports[`Locale Provider should display the text as uk 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -209137,7 +209137,7 @@ exports[`Locale Provider should display the text as uk 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -214185,7 +214185,7 @@ exports[`Locale Provider should display the text as vi 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -214204,7 +214204,7 @@ exports[`Locale Provider should display the text as vi 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -219252,7 +219252,7 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -219271,7 +219271,7 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -224319,7 +224319,7 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
checked="" checked=""
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="date" value="month"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"
@ -224338,7 +224338,7 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
<input <input
class="ant-radio-button-input" class="ant-radio-button-input"
type="radio" type="radio"
value="month" value="year"
/> />
<span <span
class="ant-radio-button-inner" class="ant-radio-button-inner"

View File

@ -15,6 +15,7 @@ export default {
filterReset: 'Reiniciar', filterReset: 'Reiniciar',
selectAll: 'Selecionar página atual', selectAll: 'Selecionar página atual',
selectInvert: 'Inverter seleção', selectInvert: 'Inverter seleção',
sortTitle: 'Ordenação',
}, },
Modal: { Modal: {
okText: 'OK', okText: 'OK',

View File

@ -38,7 +38,7 @@ When need to mention someone or something.
| getSuggestionContainer | rendered to the root of the menu. Default rendered to the body dom. If gets any problem of the menu while scrolling. Try to make the root the dom scrolled, and make it position relative. | function | () => document.body | | getSuggestionContainer | rendered to the root of the menu. Default rendered to the body dom. If gets any problem of the menu while scrolling. Try to make the root the dom scrolled, and make it position relative. | function | () => document.body |
| loading | loading mode | boolean | false | | loading | loading mode | boolean | false |
| multiLines | multilines mode | boolean | false | | multiLines | multilines mode | boolean | false |
| notFoundContent | suggestion when suggestions empty | string | '无匹配结果,轻敲空格完成输入' | | notFoundContent | suggestion when suggestions empty | string | 'No matches found' |
| placeholder | placeholder of input | string | null | | placeholder | placeholder of input | string | null |
| placement | The position of the suggestion relative to the target, which can be one of `top` and `bottom` | string | 'bottom'. | | placement | The position of the suggestion relative to the target, which can be one of `top` and `bottom` | string | 'bottom'. |
| prefix | character which will trigger Mention to show mention list | string or Array&lt;string> | '@' | | prefix | character which will trigger Mention to show mention list | string or Array&lt;string> | '@' |

View File

@ -40,7 +40,7 @@ export interface MentionState {
class Mention extends React.Component<MentionProps, MentionState> { class Mention extends React.Component<MentionProps, MentionState> {
static getMentions = getMentions; static getMentions = getMentions;
static defaultProps = { static defaultProps = {
notFoundContent: '无匹配结果,轻敲空格完成输入', notFoundContent: 'No matches found',
loading: false, loading: false,
multiLines: false, multiLines: false,
placement: 'bottom' as MentionPlacement, placement: 'bottom' as MentionPlacement,

View File

@ -31,9 +31,11 @@ class SubMenu extends React.Component<SubMenuProps, any> {
onKeyDown = (e: React.MouseEvent<HTMLElement>) => { onKeyDown = (e: React.MouseEvent<HTMLElement>) => {
this.subMenu.onKeyDown(e); this.subMenu.onKeyDown(e);
}; };
saveSubMenu = (subMenu: any) => { saveSubMenu = (subMenu: any) => {
this.subMenu = subMenu; this.subMenu = subMenu;
}; };
render() { render() {
const { rootPrefixCls, className } = this.props; const { rootPrefixCls, className } = this.props;
const theme = this.context.antdMenuTheme; const theme = this.context.antdMenuTheme;

View File

@ -2,6 +2,7 @@ import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import Menu from '..'; import Menu from '..';
import Icon from '../../icon'; import Icon from '../../icon';
import Layout from '../../layout';
jest.mock('mutationobserver-shim', () => { jest.mock('mutationobserver-shim', () => {
global.MutationObserver = function MutationObserver() { global.MutationObserver = function MutationObserver() {
@ -494,4 +495,46 @@ describe('Menu', () => {
const text = wrapper.find('.ant-tooltip-inner').text(); const text = wrapper.find('.ant-tooltip-inner').text();
expect(text).toBe('bamboo lucky'); expect(text).toBe('bamboo lucky');
}); });
it('render correctly when using with Layout.Sider', () => {
class Demo extends React.Component {
state = {
collapsed: false,
};
onCollapse = collapsed => this.setState({ collapsed });
render() {
const { collapsed } = this.state;
return (
<Layout style={{ minHeight: '100vh' }}>
<Layout.Sider collapsible collapsed={collapsed} onCollapse={this.onCollapse}>
<div className="logo" />
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline">
<SubMenu
key="sub1"
title={
<span>
<Icon type="user" />
<span>User</span>
</span>
}
>
<Menu.Item key="3">Tom</Menu.Item>
<Menu.Item key="4">Bill</Menu.Item>
<Menu.Item key="5">Alex</Menu.Item>
</SubMenu>
</Menu>
</Layout.Sider>
</Layout>
);
}
}
const wrapper = mount(<Demo />);
wrapper.find('.ant-menu-submenu-title').simulate('click');
wrapper.find('.ant-layout-sider-trigger').simulate('click');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-menu-submenu-popup').length).toBe(0);
});
}); });

View File

@ -28,7 +28,7 @@ More layouts with navigation: [layout](/components/layout).
| Param | Description | Type | Default value | | Param | Description | Type | Default value |
| ----- | ----------- | ---- | ------------- | | ----- | ----------- | ---- | ------------- |
| defaultOpenKeys | array with the keys of default opened sub menus | | | | defaultOpenKeys | array with the keys of default opened sub menus | string\[] | |
| defaultSelectedKeys | array with the keys of default selected menu items | string\[] | | | defaultSelectedKeys | array with the keys of default selected menu items | string\[] | |
| forceSubMenuRender | render submenu into DOM before it shows | boolean | false | | forceSubMenuRender | render submenu into DOM before it shows | boolean | false |
| inlineCollapsed | specifies the collapsed status when menu is inline mode | boolean | - | | inlineCollapsed | specifies the collapsed status when menu is inline mode | boolean | - |

View File

@ -90,6 +90,7 @@ class Menu extends React.Component<MenuProps, MenuState> {
context: any; context: any;
switchingModeFromInline: boolean; switchingModeFromInline: boolean;
inlineOpenKeys: string[] = []; inlineOpenKeys: string[] = [];
contextSiderCollapsed: boolean = true;
constructor(props: MenuProps) { constructor(props: MenuProps) {
super(props); super(props);
@ -130,12 +131,20 @@ class Menu extends React.Component<MenuProps, MenuState> {
if (prevProps.mode === 'inline' && this.props.mode !== 'inline') { if (prevProps.mode === 'inline' && this.props.mode !== 'inline') {
this.switchingModeFromInline = true; this.switchingModeFromInline = true;
} }
if (this.props.inlineCollapsed && !prevProps.inlineCollapsed) { if (
(this.props.inlineCollapsed && !prevProps.inlineCollapsed) ||
(this.getInlineCollapsed() && this.contextSiderCollapsed)
) {
this.contextSiderCollapsed = false;
this.switchingModeFromInline = true; this.switchingModeFromInline = true;
this.inlineOpenKeys = this.state.openKeys; this.inlineOpenKeys = this.state.openKeys;
this.setState({ openKeys: [] }); this.setState({ openKeys: [] });
} }
if (!this.props.inlineCollapsed && prevProps.inlineCollapsed) { if (
(!this.props.inlineCollapsed && prevProps.inlineCollapsed) ||
(!this.getInlineCollapsed() && !this.contextSiderCollapsed)
) {
this.contextSiderCollapsed = true;
this.setState({ openKeys: this.inlineOpenKeys }); this.setState({ openKeys: this.inlineOpenKeys });
this.inlineOpenKeys = []; this.inlineOpenKeys = [];
} }
@ -158,6 +167,7 @@ class Menu extends React.Component<MenuProps, MenuState> {
onMouseEnter(e); onMouseEnter(e);
} }
}; };
handleTransitionEnd = (e: TransitionEvent) => { handleTransitionEnd = (e: TransitionEvent) => {
// when inlineCollapsed menu width animation finished // when inlineCollapsed menu width animation finished
// https://github.com/ant-design/ant-design/issues/12864 // https://github.com/ant-design/ant-design/issues/12864
@ -170,6 +180,7 @@ class Menu extends React.Component<MenuProps, MenuState> {
this.restoreModeVerticalFromInline(); this.restoreModeVerticalFromInline();
} }
}; };
handleClick = (e: ClickParam) => { handleClick = (e: ClickParam) => {
this.handleOpenChange([]); this.handleOpenChange([]);
@ -186,6 +197,7 @@ class Menu extends React.Component<MenuProps, MenuState> {
onOpenChange(openKeys); onOpenChange(openKeys);
} }
}; };
setOpenKeys(openKeys: string[]) { setOpenKeys(openKeys: string[]) {
if (!('openKeys' in this.props)) { if (!('openKeys' in this.props)) {
this.setState({ openKeys }); this.setState({ openKeys });

View File

@ -29,7 +29,7 @@ subtitle: 导航菜单
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| defaultOpenKeys | 初始展开的 SubMenu 菜单项 key 数组 | | | | defaultOpenKeys | 初始展开的 SubMenu 菜单项 key 数组 | string\[] | |
| defaultSelectedKeys | 初始选中的菜单项 key 数组 | string\[] | | | defaultSelectedKeys | 初始选中的菜单项 key 数组 | string\[] | |
| forceSubMenuRender | 在子菜单展示之前就渲染进 DOM | boolean | false | | forceSubMenuRender | 在子菜单展示之前就渲染进 DOM | boolean | false |
| inlineCollapsed | inline 时菜单是否收起状态 | boolean | - | | inlineCollapsed | inline 时菜单是否收起状态 | boolean | - |

View File

@ -1,5 +1,7 @@
@dialog-prefix-cls: ~'@{ant-prefix}-modal'; @dialog-prefix-cls: ~'@{ant-prefix}-modal';
@table-prefix-cls: ~'@{ant-prefix}-table'; @table-prefix-cls: ~'@{ant-prefix}-table';
@modal-footer-padding-vertical: 10px;
@modal-footer-padding-horizontal: 16px;
.@{dialog-prefix-cls} { .@{dialog-prefix-cls} {
.reset-component; .reset-component;
@ -89,7 +91,7 @@
} }
&-footer { &-footer {
padding: 10px 16px; padding: @modal-footer-padding-vertical @modal-footer-padding-horizontal;
text-align: right; text-align: right;
background: @modal-footer-bg; background: @modal-footer-bg;
border-top: @border-width-base @border-style-base @border-color-split; border-top: @border-width-base @border-style-base @border-color-split;

View File

@ -83,7 +83,7 @@
font-size: @font-size-base; font-size: @font-size-base;
} }
&-icon { .@{iconfont-css-prefix}&-icon {
position: absolute; position: absolute;
margin-left: 4px; margin-left: 4px;
font-size: 24px; font-size: 24px;

View File

@ -3,7 +3,8 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Icon from '../icon'; import Icon from '../icon';
import classnames from 'classnames'; import classnames from 'classnames';
import { BreadcrumbProps } from '../breadcrumb'; import { BreadcrumbProps } from '../breadcrumb';
import { Divider, Breadcrumb } from '../index'; import Divider from '../divider';
import Breadcrumb from '../breadcrumb';
import Tag from '../tag'; import Tag from '../tag';
import Wave from '../_util/wave'; import Wave from '../_util/wave';

View File

@ -28,8 +28,6 @@
.@{ant-prefix}-divider { .@{ant-prefix}-divider {
height: 14px; height: 14px;
margin: 0 12px; margin: 0 12px;
margin-top: 3px;
vertical-align: top;
} }
.@{ant-prefix}-breadcrumb { .@{ant-prefix}-breadcrumb {

View File

@ -1,5 +1,5 @@
import './index.less'; import './index.less';
// style dependencies
import '../../divider/style'; import '../../divider/style';
import '../../breadcrumb/style'; import '../../breadcrumb/style';
import '../../typography/style';

View File

@ -31,7 +31,7 @@ export interface PaginationProps {
itemRender?: ( itemRender?: (
page: number, page: number,
type: 'page' | 'prev' | 'next' | 'jump-prev' | 'jump-next', type: 'page' | 'prev' | 'next' | 'jump-prev' | 'jump-next',
originalElement: HTMLElement, originalElement: React.ReactElement<HTMLElement>,
) => React.ReactNode; ) => React.ReactNode;
role?: string; role?: string;
} }

View File

@ -66,6 +66,7 @@
&-active { &-active {
font-weight: @pagination-font-weight-active; font-weight: @pagination-font-weight-active;
background: @pagination-item-bg-active;
border-color: @primary-color; border-color: @primary-color;
a { a {

View File

@ -3,4 +3,3 @@ import './index.less';
// style dependencies // style dependencies
import '../../select/style'; import '../../select/style';
import '../../input/style';

View File

@ -1,5 +1,6 @@
import '../../style/index.less'; import '../../style/index.less';
// style dependencies // style dependencies
// deps-lint-skip: tooltip, popover
import '../../popover/style'; import '../../popover/style';
import '../../button/style'; import '../../button/style';

View File

@ -1,2 +1,5 @@
import '../../style/index.less'; import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies
// deps-lint-skip: tooltip

View File

@ -1,2 +1,5 @@
import '../../style/index.less'; import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies
import '../../tooltip/style';

View File

@ -1,2 +1,5 @@
import '../../style/index.less'; import '../../style/index.less';
import '../../grid/style/index.less';
// style dependencies
// deps-lint-skip: grid
import '../../grid/style';

View File

@ -530,7 +530,7 @@
&, &,
&:hover { &:hover {
color: @text-color; color: @text-color;
font-weight: 600; font-weight: @select-item-selected-font-weight;
background-color: @background-color-light; background-color: @background-color-light;
} }
} }
@ -580,6 +580,12 @@
} }
} }
// Patch for popup adjust
// https://github.com/ant-design/ant-design/issues/14422
&--empty&--multiple &-menu-item {
padding-right: @control-padding-horizontal;
}
&-container-open, &-container-open,
&-open { &-open {
.@{select-prefix-cls}-dropdown { .@{select-prefix-cls}-dropdown {

View File

@ -3,4 +3,3 @@ import './index.less';
// style dependencies // style dependencies
import '../../empty/style'; import '../../empty/style';
import '../../input/style';

View File

@ -123,7 +123,7 @@ exports[`renders ./components/skeleton/demo/list.md correctly 1`] = `
class="ant-spin-container" class="ant-spin-container"
> >
<div <div
class="ant-list-item" class="ant-list-item ant-list-item-no-flex"
> >
<div <div
class="ant-skeleton ant-skeleton-with-avatar ant-skeleton-active" class="ant-skeleton ant-skeleton-with-avatar ant-skeleton-active"
@ -152,7 +152,7 @@ exports[`renders ./components/skeleton/demo/list.md correctly 1`] = `
</div> </div>
</div> </div>
<div <div
class="ant-list-item" class="ant-list-item ant-list-item-no-flex"
> >
<div <div
class="ant-skeleton ant-skeleton-with-avatar ant-skeleton-active" class="ant-skeleton ant-skeleton-with-avatar ant-skeleton-active"
@ -181,7 +181,7 @@ exports[`renders ./components/skeleton/demo/list.md correctly 1`] = `
</div> </div>
</div> </div>
<div <div
class="ant-list-item" class="ant-list-item ant-list-item-no-flex"
> >
<div <div
class="ant-skeleton ant-skeleton-with-avatar ant-skeleton-active" class="ant-skeleton ant-skeleton-with-avatar ant-skeleton-active"

View File

@ -11,7 +11,7 @@ Provide a placeholder at the place which need waiting for loading.
- When resource needs long time to load, like low network speed. - When resource needs long time to load, like low network speed.
- The component contains much information. Such as List or Card. - The component contains much information. Such as List or Card.
- Only works when loading data at first time. - Only works when loading data at first time.
- Could be replaced by Spin in all situation, but provide better user experience then spin if it works. - Could be replaced by Spin in all situation, but provide better user experience than spin if it works.
## API ## API

View File

@ -54,6 +54,8 @@
// paragraph // paragraph
.@{skeleton-paragraph-prefix-cls} { .@{skeleton-paragraph-prefix-cls} {
padding: 0;
> li { > li {
width: 100%; width: 100%;
height: 16px; height: 16px;

View File

@ -25,6 +25,7 @@ export interface StepProps {
onClick?: React.MouseEventHandler<any>; onClick?: React.MouseEventHandler<any>;
status?: 'wait' | 'process' | 'finish' | 'error'; status?: 'wait' | 'process' | 'finish' | 'error';
title?: React.ReactNode; title?: React.ReactNode;
style?: React.CSSProperties;
} }
export default class Steps extends React.Component<StepsProps, any> { export default class Steps extends React.Component<StepsProps, any> {

View File

@ -77,7 +77,7 @@ body {
font-variant: @font-variant-base; font-variant: @font-variant-base;
line-height: @line-height-base; line-height: @line-height-base;
background-color: @body-background; // 2 background-color: @body-background; // 2
font-feature-settings: 'tnum'; font-feature-settings: @font-feature-settings-base;
} }
// Suppress the focus outline on elements that cannot be accessed via keyboard. // Suppress the focus outline on elements that cannot be accessed via keyboard.

View File

@ -1,5 +1,6 @@
.iconfont-mixin() { .iconfont-mixin() {
display: inline-block; display: inline-block;
color: @icon-color;
font-style: normal; font-style: normal;
line-height: 0; line-height: 0;
text-align: center; text-align: center;

View File

@ -9,5 +9,5 @@
font-variant: @font-variant-base; font-variant: @font-variant-base;
line-height: @line-height-base; line-height: @line-height-base;
list-style: none; list-style: none;
font-feature-settings: 'tnum'; font-feature-settings: @font-feature-settings-base;
} }

View File

@ -47,12 +47,14 @@
@text-color-warning: @gold-7; @text-color-warning: @gold-7;
@text-color-danger: @red-7; @text-color-danger: @red-7;
@text-color-inverse: @white; @text-color-inverse: @white;
@icon-color: inherit;
@icon-color-hover: fade(@black, 75%); @icon-color-hover: fade(@black, 75%);
@heading-color: fade(#000, 85%); @heading-color: fade(#000, 85%);
@heading-color-dark: fade(@white, 100%); @heading-color-dark: fade(@white, 100%);
@text-color-dark: fade(@white, 85%); @text-color-dark: fade(@white, 85%);
@text-color-secondary-dark: fade(@white, 65%); @text-color-secondary-dark: fade(@white, 65%);
@font-variant-base: tabular-nums; @font-variant-base: tabular-nums;
@font-feature-settings-base: 'tnum';
@font-size-base: 14px; @font-size-base: 14px;
@font-size-lg: @font-size-base + 2px; @font-size-lg: @font-size-base + 2px;
@font-size-sm: 12px; @font-size-sm: 12px;
@ -304,6 +306,7 @@
// Select // Select
// --- // ---
@select-border-color: @border-color-base; @select-border-color: @border-color-base;
@select-item-selected-font-weight: 600;
// Tooltip // Tooltip
// --- // ---
@ -498,6 +501,7 @@
@pagination-item-size-sm: 24px; @pagination-item-size-sm: 24px;
@pagination-font-family: Arial; @pagination-font-family: Arial;
@pagination-font-weight-active: 500; @pagination-font-weight-active: 500;
@pagination-item-bg-active: transparent;
// Breadcrumb // Breadcrumb
// --- // ---

View File

@ -1121,7 +1121,6 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
renderEmpty: RenderEmptyHandler, renderEmpty: RenderEmptyHandler,
dropdownPrefixCls: string, dropdownPrefixCls: string,
contextLocale: TableLocale, contextLocale: TableLocale,
loading: SpinProps,
) => { ) => {
const { style, className, showHeader, locale, ...restProps } = this.props; const { style, className, showHeader, locale, ...restProps } = this.props;
const data = this.getCurrentPageData(); const data = this.getCurrentPageData();
@ -1164,7 +1163,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
className={classString} className={classString}
expandIconColumnIndex={expandIconColumnIndex} expandIconColumnIndex={expandIconColumnIndex}
expandIconAsCell={expandIconAsCell} expandIconAsCell={expandIconAsCell}
emptyText={!loading.spinning && mergedLocale.emptyText} emptyText={mergedLocale.emptyText}
/> />
); );
}; };
@ -1189,7 +1188,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
const dropdownPrefixCls = getPrefixCls('dropdown', customizeDropdownPrefixCls); const dropdownPrefixCls = getPrefixCls('dropdown', customizeDropdownPrefixCls);
const table = ( const table = (
<LocaleReceiver componentName="Table" defaultLocale={defaultLocale.Table}> <LocaleReceiver componentName="Table" defaultLocale={defaultLocale.Table}>
{locale => this.renderTable(prefixCls, renderEmpty, dropdownPrefixCls, locale, loading)} {locale => this.renderTable(prefixCls, renderEmpty, dropdownPrefixCls, locale)}
</LocaleReceiver> </LocaleReceiver>
); );

View File

@ -600,7 +600,25 @@ exports[`Table renders empty table without emptyText when loading 1`] = `
</div> </div>
<div <div
class="ant-table-placeholder" class="ant-table-placeholder"
/> >
<div
class="ant-empty ant-empty-normal"
>
<div
class="ant-empty-image"
>
<img
alt="No Data"
src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAxKSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgIDxlbGxpcHNlIGZpbGw9IiNGNUY1RjUiIGN4PSIzMiIgY3k9IjMzIiByeD0iMzIiIHJ5PSI3Ii8+CiAgICA8ZyBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0iI0Q5RDlEOSI+CiAgICAgIDxwYXRoIGQ9Ik01NSAxMi43Nkw0NC44NTQgMS4yNThDNDQuMzY3LjQ3NCA0My42NTYgMCA0Mi45MDcgMEgyMS4wOTNjLS43NDkgMC0xLjQ2LjQ3NC0xLjk0NyAxLjI1N0w5IDEyLjc2MVYyMmg0NnYtOS4yNHoiLz4KICAgICAgPHBhdGggZD0iTTQxLjYxMyAxNS45MzFjMC0xLjYwNS45OTQtMi45MyAyLjIyNy0yLjkzMUg1NXYxOC4xMzdDNTUgMzMuMjYgNTMuNjggMzUgNTIuMDUgMzVoLTQwLjFDMTAuMzIgMzUgOSAzMy4yNTkgOSAzMS4xMzdWMTNoMTEuMTZjMS4yMzMgMCAyLjIyNyAxLjMyMyAyLjIyNyAyLjkyOHYuMDIyYzAgMS42MDUgMS4wMDUgMi45MDEgMi4yMzcgMi45MDFoMTQuNzUyYzEuMjMyIDAgMi4yMzctMS4zMDggMi4yMzctMi45MTN2LS4wMDd6IiBmaWxsPSIjRkFGQUZBIi8+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4K"
/>
</div>
<p
class="ant-empty-description"
>
No Data
</p>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -43,10 +43,10 @@ class EditableCell extends React.Component {
}); });
} }
save = () => { save = (e) => {
const { record, handleSave } = this.props; const { record, handleSave } = this.props;
this.form.validateFields((error, values) => { this.form.validateFields((error, values) => {
if (error) { if (error && error[e.currentTarget.id]) {
return; return;
} }
this.toggleEdit(); this.toggleEdit();
@ -66,7 +66,7 @@ class EditableCell extends React.Component {
...restProps ...restProps
} = this.props; } = this.props;
return ( return (
<td ref={node => (this.cell = node)} {...restProps}> <td {...restProps}>
{editable ? ( {editable ? (
<EditableContext.Consumer> <EditableContext.Consumer>
{(form) => { {(form) => {

View File

@ -30,14 +30,6 @@ for (let i = 0; i < 100; i++) {
const FormItem = Form.Item; const FormItem = Form.Item;
const EditableContext = React.createContext(); const EditableContext = React.createContext();
const EditableRow = ({ form, index, ...props }) => (
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
);
const EditableFormRow = Form.create()(EditableRow);
class EditableCell extends React.Component { class EditableCell extends React.Component {
getInput = () => { getInput = () => {
if (this.props.inputType === 'number') { if (this.props.inputType === 'number') {
@ -108,6 +100,7 @@ class EditableTable extends React.Component {
title: 'operation', title: 'operation',
dataIndex: 'operation', dataIndex: 'operation',
render: (text, record) => { render: (text, record) => {
const { editingKey } = this.state;
const editable = this.isEditing(record); const editable = this.isEditing(record);
return ( return (
<div> <div>
@ -132,7 +125,7 @@ class EditableTable extends React.Component {
</Popconfirm> </Popconfirm>
</span> </span>
) : ( ) : (
<a onClick={() => this.edit(record.key)}>Edit</a> <a disabled={editingKey !== ''} onClick={() => this.edit(record.key)}>Edit</a>
)} )}
</div> </div>
); );
@ -175,7 +168,6 @@ class EditableTable extends React.Component {
render() { render() {
const components = { const components = {
body: { body: {
row: EditableFormRow,
cell: EditableCell, cell: EditableCell,
}, },
}; };
@ -197,21 +189,25 @@ class EditableTable extends React.Component {
}); });
return ( return (
<Table <EditableContext.Provider value={this.props.form}>
components={components} <Table
bordered components={components}
dataSource={this.state.data} bordered
columns={columns} dataSource={this.state.data}
rowClassName="editable-row" columns={columns}
pagination={{ rowClassName="editable-row"
onChange: this.cancel, pagination={{
}} onChange: this.cancel,
/> }}
/>
</EditableContext.Provider>
); );
} }
} }
ReactDOM.render(<EditableTable />, mountNode); const EditableFormTable = Form.create()(EditableTable);
ReactDOM.render(<EditableFormTable />, mountNode);
``` ```
```css ```css

View File

@ -127,6 +127,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| render | Renderer of the table cell. The return value should be a ReactNode, or an object for [colSpan/rowSpan config](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - | | render | Renderer of the table cell. The return value should be a ReactNode, or an object for [colSpan/rowSpan config](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - |
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - | | sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - |
| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - | | sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - |
| sortDirections | supported sort way, could be `'ascend'`, `'descend'` | Array | `['ascend', 'descend']` |
| title | Title of this column | ReactNode\|({ sortOrder, filters }) => ReactNode | - | | title | Title of this column | ReactNode\|({ sortOrder, filters }) => ReactNode | - |
| width | Width of this column | string\|number | - | | width | Width of this column | string\|number | - |
| onCell | Set props on per cell | Function(record, rowIndex) | - | | onCell | Set props on per cell | Function(record, rowIndex) | - |

View File

@ -132,6 +132,7 @@ const columns = [{
| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return里面可以设置表格[行/列合并](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - | | render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return里面可以设置表格[行/列合并](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - | | sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - |
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - | | sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - |
| sortDirections | 支持的排序方式,取值为 `'ascend'` `'descend'` | Array | `['ascend', 'descend']` |
| title | 列头显示文字 | ReactNode\|({ sortOrder, filters }) => ReactNode | - | | title | 列头显示文字 | ReactNode\|({ sortOrder, filters }) => ReactNode | - |
| width | 列宽度 | string\|number | - | | width | 列宽度 | string\|number | - |
| onCell | 设置单元格属性 | Function(record, rowIndex) | - | | onCell | 设置单元格属性 | Function(record, rowIndex) | - |

View File

@ -2,6 +2,7 @@ import '../../style/index.less';
import './index.less'; import './index.less';
// style dependencies // style dependencies
// deps-lint-skip: menu
import '../../empty/style'; import '../../empty/style';
import '../../radio/style'; import '../../radio/style';
import '../../checkbox/style'; import '../../checkbox/style';

View File

@ -1,3 +1,3 @@
import demoTest from '../../../tests/shared/demoTest'; import demoTest from '../../../tests/shared/demoTest';
demoTest('tabs', { skip: process.env.REACT === '15' ? ['custom-tab-bar-node.md'] : [] }); demoTest('tabs', { skip: process.env.REACT === '15' ? ['custom-tab-bar-node.md'] : [] });

View File

@ -36,7 +36,9 @@ Ant Design has 3 types of Tabs for different situations.
| onEdit | Callback executed when tab is added or removed. Only works while `type="editable-card"` | (targetKey, action): void | - | | onEdit | Callback executed when tab is added or removed. Only works while `type="editable-card"` | (targetKey, action): void | - |
| onNextClick | Callback executed when next button is clicked | Function | - | | onNextClick | Callback executed when next button is clicked | Function | - |
| onPrevClick | Callback executed when prev button is clicked | Function | - | | onPrevClick | Callback executed when prev button is clicked | Function | - |
| onTabClick | Callback executed when tab is clicked | Function | - | | onTabClick | Callback executed when tab is clicked | Function(key: string, event: MouseEvent) | - |
More option at [rc-tabs option](https://github.com/react-component/tabs#tabs)
### Tabs.TabPane ### Tabs.TabPane
@ -45,3 +47,5 @@ Ant Design has 3 types of Tabs for different situations.
| forceRender | Forced render of content in tabs, not lazy render after clicking on tabs | boolean | false | | forceRender | Forced render of content in tabs, not lazy render after clicking on tabs | boolean | false |
| key | TabPane's key | string | - | | key | TabPane's key | string | - |
| tab | Show text in TabPane's head | string\|ReactNode | - | | tab | Show text in TabPane's head | string\|ReactNode | - |
More option at [rc-tabs option](https://github.com/react-component/tabs#tabpane)

View File

@ -12,21 +12,22 @@
visibility: hidden; visibility: hidden;
} }
&&-card &-card-bar &-tab { &&-card &-card-bar &-tab {
height: @tabs-card-height;
margin: 0; margin: 0;
margin-right: 2px; margin-right: 2px;
padding: 0 16px; padding: 0 16px;
line-height: @tabs-card-height - 2px; line-height: @tabs-card-height - 2px;
background: @tabs-card-head-background; background: @tabs-card-head-background;
border: @border-width-base @border-style-base @border-color-split; border: @border-width-base @border-style-base @border-color-split;
border-bottom: 0;
border-radius: @border-radius-base @border-radius-base 0 0; border-radius: @border-radius-base @border-radius-base 0 0;
transition: all 0.3s @ease-in-out; transition: all 0.3s @ease-in-out;
} }
&&-card &-card-bar &-tab-active { &&-card &-card-bar &-tab-active {
padding-bottom: 1px; height: @tabs-card-height;
color: @tabs-card-active-color; color: @tabs-card-active-color;
background: @component-background; background: @component-background;
border-color: @border-color-split; border-color: @border-color-split;
border-bottom: @border-width-base solid @component-background;
} }
&&-card &-card-bar &-tab-inactive { &&-card &-card-bar &-tab-inactive {
padding: 0; padding: 0;

View File

@ -6,12 +6,12 @@
.@{tag-prefix-cls} { .@{tag-prefix-cls} {
.reset-component; .reset-component;
display: inline-block; display: inline-block;
height: 22px; height: auto;
margin-right: 8px; margin-right: 8px;
padding: 0 7px; padding: 0 7px;
font-size: @tag-font-size; font-size: @tag-font-size;
line-height: 20px; line-height: 20px;
white-space: nowrap; white-space: normal;
background: @tag-default-bg; background: @tag-default-bg;
border: @border-width-base @border-style-base @border-color-base; border: @border-width-base @border-style-base @border-color-base;
border-radius: @border-radius-base; border-radius: @border-radius-base;

Some files were not shown because too many files have changed in this diff Show More