mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-04 13:08:41 +08:00
Merge pull request #15202 from ant-design/master
Merge branch master into feature
This commit is contained in:
commit
fb8b1982e9
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -6,7 +6,7 @@ Please makes sure that these form are filled before submitting your pull request
|
||||
|
||||
[[中文版模板 / 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
|
||||
- [ ] Bug fix
|
||||
@ -18,36 +18,29 @@ Please makes sure that these form are filled before submitting your pull request
|
||||
- [ ] Branch merge
|
||||
- [ ] Other (about what?)
|
||||
|
||||
### What's the background?
|
||||
### 👻 What's the background?
|
||||
|
||||
> 1. Describe the source of requirement.
|
||||
> 2. Resolve what problem.
|
||||
> 3. Related issue link.
|
||||
1. Describe the source of requirement, like related issue link.
|
||||
|
||||
### API Realization (Optional if not new feature)
|
||||
2. Describe the problem and the scenario.
|
||||
|
||||
> 1. Basic thought of solution and other optional proposal.
|
||||
> 2. List final API realization and usage sample.
|
||||
> 3. GIF or snapshot should be provided if includes UI/interactive modification.
|
||||
### 💡 Solution
|
||||
|
||||
### What's the effect? (Optional if not new feature)
|
||||
1. How to fix the problem, and list final API implementation and usage sample if that is an new feature.
|
||||
|
||||
> 1. Does this PR affect user? Which part will be affected?
|
||||
> 2. What will say in changelog?
|
||||
> 3. Does this PR contains potential break change or other risk?
|
||||
2. GIF or snapshot should be provided if includes UI/interactive modification.
|
||||
|
||||
### Changelog description (Optional if not new feature)
|
||||
### 📝 Changelog description
|
||||
|
||||
> 1. English description
|
||||
> 2. Chinese description (optional)
|
||||
> Describe changes from user side, and list all potential break changes or other risks.
|
||||
|
||||
### Self Check before Merge
|
||||
1. English description
|
||||
|
||||
2. Chinese description (optional)
|
||||
|
||||
### ☑️ Self Check before Merge
|
||||
|
||||
- [ ] Doc is updated/provided or not needed
|
||||
- [ ] Demo is updated/provided or not needed
|
||||
- [ ] TypeScript definition is updated/provided or not needed
|
||||
- [ ] Changelog is provided or not needed
|
||||
|
||||
### Additional Plan? (Optional if not new feature)
|
||||
|
||||
> If this PR related with other PR or following info. You can type here.
|
||||
|
36
.github/PULL_REQUEST_TEMPLATE/pr_cn.md
vendored
36
.github/PULL_REQUEST_TEMPLATE/pr_cn.md
vendored
@ -1,4 +1,4 @@
|
||||
首先,感谢你的贡献! 😄
|
||||
首先,感谢你的贡献!😄
|
||||
|
||||
新特性请提交至 feature 分支,其余可提交至 master 分支。
|
||||
在一个维护者审核通过后合并。
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
[[English Template / 英文模板](?expand=1)]
|
||||
|
||||
### 这个变动的性质是
|
||||
### 🤔 这个变动的性质是?
|
||||
|
||||
- [ ] 新特性提交
|
||||
- [ ] 日常 bug 修复
|
||||
@ -18,35 +18,29 @@
|
||||
- [ ] 分支合并
|
||||
- [ ] 其他改动(是关于什么的改动?)
|
||||
|
||||
### 需求背景
|
||||
### 👻 需求背景
|
||||
|
||||
> 1. 描述相关需求的来源。
|
||||
> 2. 要解决的问题。
|
||||
> 3. 相关的 issue 讨论链接。
|
||||
1. 描述相关需求的来源,如相关的 issue 讨论链接。
|
||||
|
||||
### 实现方案和 API(非新功能可选)
|
||||
2. 要解决的具体问题。
|
||||
|
||||
> 1. 基本的解决思路和其他可选方案。
|
||||
> 2. 列出最终的 API 实现和用法。
|
||||
> 3. 涉及UI/交互变动需要有截图或 GIF。
|
||||
### 💡 解决方案和最终实现是?
|
||||
|
||||
### 对用户的影响和可能的风险(非新功能可选)
|
||||
1. 列出最终的 API 实现和用法。
|
||||
|
||||
> 1. 这个改动对用户端是否有影响?影响的方面有哪些?
|
||||
> 2. 是否有可能隐含的 break change 和其他风险?
|
||||
2. 涉及UI/交互变动需要有截图或 GIF。
|
||||
|
||||
### Changelog 描述(非新功能可选)
|
||||
### 📝 更新日志怎么写?
|
||||
|
||||
> 1. 英文描述
|
||||
> 2. 中文描述(可选)
|
||||
> 从用户角度描述具体变化,以及可能的 breaking change 和其他风险?
|
||||
|
||||
### 请求合并前的自查清单
|
||||
1. 英文描述
|
||||
|
||||
2. 中文描述(可选)
|
||||
|
||||
### ☑️ 请求合并前的自查清单
|
||||
|
||||
- [ ] 文档已补充或无须补充
|
||||
- [ ] 代码演示已提供或无须提供
|
||||
- [ ] TypeScript 定义已补充或无须补充
|
||||
- [ ] Changelog 已提供或无须提供
|
||||
|
||||
### 后续计划(非新功能可选)
|
||||
|
||||
> 如果这个提交后面还有相关的其他提交和跟进信息,可以写在这里。
|
||||
|
@ -14,13 +14,23 @@ timeline: true
|
||||
* Major version release is not included in this schedule for breaking change and new features.
|
||||
|
||||
---
|
||||
|
||||
## 3.14.1
|
||||
|
||||
`2019-03-04`
|
||||
|
||||
- 🌟 PageHeader support `className` prop. [#15159](https://github.com/ant-design/ant-design/pull/15159)
|
||||
- 🐞 Fix Form warning with unique key & additional attributes. [#15160](https://github.com/ant-design/ant-design/pull/15160)
|
||||
- 🐞 Fix `getPopupContainer` of ConfigProvider not work with DatePicker. [#15156](https://github.com/ant-design/ant-design/pull/15156)
|
||||
- 🐞 Fix Collapse `extra` node style missing. [#15176](https://github.com/ant-design/ant-design/pull/15176)
|
||||
|
||||
## 3.14.0
|
||||
|
||||
`2019-03-02`
|
||||
|
||||
- Two new components added this month:
|
||||
- 🔥🔥🔥[Typography](https://github.com/ant-design/ant-design/pull/14250) provides basic formatting and common operations for text.
|
||||
- 🔥🔥🔥[PageHeader](https://github.com/ant-design/ant-design/pull/13637) can be used to declare the page theme, display important information about the page that the user is interested in, and host the relevant page. Action item.
|
||||
- 🔥🔥🔥[Typography](https://ant.design/components/typography/) provides basic formatting and common operations for text.
|
||||
- 🔥🔥🔥[PageHeader](https://ant.design/components/page-header/) can be used to declare the page theme, display important information about the page that the user is interested in, and host the relevant page. Action item.
|
||||
- 🌟 TimePicker provides `clearIcon` prop for customizing clear icon. [#14556](https://github.com/ant-design/ant-design/pull/14556)
|
||||
- 🌟 Statistic.Countdown supports `onFinish` prop. [#14791](https://github.com/ant-design/ant-design/pull/14791)
|
||||
- 🌟 Collapse.Panel support `extra` prop. [62e65d](https://github.com/ant-design/ant-design/commit/62e65d955065b1862240f9f30d84de44349a0cf9)
|
||||
@ -33,10 +43,15 @@ timeline: true
|
||||
- 🐞 Fix Spin `wrapperClassName` setting `padding` icon is not centered. [#15056](https://github.com/ant-design/ant-design/pull/15056)
|
||||
- 🐞 Fix Calendar won't trigger `onPanelChange` correctly in some cases. [#15063](https://github.com/ant-design/ant-design/pull/15063)
|
||||
- 🌟 Select supports `showArrow` in multi-select mode. [#15091](https://github.com/ant-design/ant-design/pull/15091)
|
||||
- 🐞 Fix closable Drawer hiding without transition. [#15147](https://github.com/ant-design/ant-design/pull/15147)
|
||||
- 🌟 Two less variables `@drawer-header-padding` and `@drawer-body-padding` have been added to control Drawer padding. [#15120](https://github.com/ant-design/ant-design/pull/15120)
|
||||
- 🐞 Fix Cascader should tab twice to exist. [#15117](https://github.com/ant-design/ant-design/pull/15117)
|
||||
- 🐞 The `onChange` of InputNumber will return `null` instead of `undefined` to fix the problem that the value of the control cannot be properly collected and emptied. [#14960](https://github.com/ant-design/ant-design/pull/14960)
|
||||
- 🌟 Adjusted multiple TypeScript types
|
||||
- 🐞 Fixed a problem with the `onPanelChange` TypeScript declaration missing. [#15043](https://github.com/ant-design/ant-design/pull/15043)
|
||||
- 🐞 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)
|
||||
|
||||
## 3.13.6
|
||||
|
||||
|
@ -14,16 +14,24 @@ timeline: true
|
||||
* 主版本号:含有破坏性更新和新特性,不在发布周期内。
|
||||
|
||||
---
|
||||
## 3.14.1
|
||||
|
||||
`2019-03-04`
|
||||
|
||||
- 🌟 PageHeader 支持 `className` prop。 [#15159](https://github.com/ant-design/ant-design/pull/15159)
|
||||
- 🐞 修复 Form 输出警告信息的问题。 [#15160](https://github.com/ant-design/ant-design/pull/15160)
|
||||
- 🐞 修复 ConfigProvider 中 getPopupContainer 对于 DatePicker 无效的问题。[#15156](https://github.com/ant-design/ant-design/pull/15156)
|
||||
- 🐞 修复 Collapse `extra` 位置错误的问题。[#15176](https://github.com/ant-design/ant-design/pull/15176)
|
||||
|
||||
## 3.14.0
|
||||
|
||||
`2019-03-02`
|
||||
|
||||
- 本月新增了两个组件:
|
||||
- 🔥🔥🔥 [Typography](https://github.com/ant-design/ant-design/pull/14250) 提供了文本的基本格式及常见操作。
|
||||
- 🔥🔥🔥 [PageHeader](https://github.com/ant-design/ant-design/pull/13637) 可用于声明页面主题、展示用户所关注的页面重要信息,以及承载与当前页相关的操作项。
|
||||
- 🔥🔥🔥 [Typography](https://ant.design/components/typography-cn/) 提供了文本的基本格式及常见操作。
|
||||
- 🔥🔥🔥 [PageHeader](https://ant.design/components/page-header-cn/) 可用于声明页面主题、展示用户所关注的页面重要信息,以及承载与当前页相关的操作项。
|
||||
- 🌟 TimePicker 新增了 `clearIcon` prop,用于自定义清除图标。[#14556](https://github.com/ant-design/ant-design/pull/14556)
|
||||
- 🌟Statistic.Countdown 支持 `onFinish` prop。[#14791](https://github.com/ant-design/ant-design/pull/14791)
|
||||
- 🌟 Statistic.Countdown 支持 `onFinish` prop。[#14791](https://github.com/ant-design/ant-design/pull/14791)
|
||||
- 🌟 Collapse.Panel 新增了 `extra`。[62e65d](https://github.com/ant-design/ant-design/commit/62e65d955065b1862240f9f30d84de44349a0cf9)
|
||||
- DatePicker
|
||||
- 🐞 修复 `name` prop 无效的问题。[#15029](https://github.com/ant-design/ant-design/pull/15029)
|
||||
@ -34,10 +42,15 @@ timeline: true
|
||||
- 🐞 修复 Spin `wrapperClassName` 设置 `padding` 图标不居中的问题。[#15056](https://github.com/ant-design/ant-design/pull/15056)
|
||||
- 🐞 修复 Calendar `onPanelChange` 在某些情况下不会触发的问题。[#15063](https://github.com/ant-design/ant-design/pull/15063)
|
||||
- 🌟 Select 在多选模式下支持 `showArrow`。[#15091](https://github.com/ant-design/ant-design/pull/15091)
|
||||
- 🐞 修复关闭抽屉时浮层阴影没有缓动消失的细节。[#15147](https://github.com/ant-design/ant-design/pull/15147)
|
||||
- 🌟 增加了两个 less 变量 `@drawer-header-padding` 和 `@drawer-body-padding` 以控制 Drawer 的 padding。[#15120](https://github.com/ant-design/ant-design/pull/15120)
|
||||
- 🐞 修复 Cascader 需要按 Tab 两次切换聚焦的问题。[#15117](https://github.com/ant-design/ant-design/pull/15117)
|
||||
- 🐞 InputNumber 的 `onChange` 将会返回 `null` 而不是 `undefined`,以修复组件的值无法正确收集和清空的问题。[#14960](https://github.com/ant-design/ant-design/pull/14960)
|
||||
- 🐞 调整了多处 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)
|
||||
- 🌟 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)
|
||||
|
||||
## 3.13.6
|
||||
|
||||
|
@ -52,7 +52,7 @@ English | [简体中文](./README-zh_CN.md)
|
||||
## 📦 Install
|
||||
|
||||
```bash
|
||||
npm install antd --save
|
||||
npm install antd
|
||||
```
|
||||
|
||||
```bash
|
||||
|
@ -438,6 +438,185 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/collapse/demo/extra.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-collapse"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-item-active"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
class="ant-collapse-header"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: right"
|
||||
class="anticon anticon-right ant-collapse-arrow"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
style="-ms-transform:rotate(90deg);transform:rotate(90deg)"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
This is panel header 1
|
||||
<div
|
||||
class="ant-collapse-extra"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: setting"
|
||||
class="anticon anticon-setting"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="setting"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 0 0 9.3-35.2l-.9-2.6a443.74 443.74 0 0 0-79.7-137.9l-1.8-2.1a32.12 32.12 0 0 0-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 0 0-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 0 0-25.8 25.7l-15.8 85.4a351.86 351.86 0 0 0-99 57.4l-81.9-29.1a32 32 0 0 0-35.1 9.5l-1.8 2.1a446.02 446.02 0 0 0-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 0 0-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0 0 35.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0 0 25.8 25.7l2.7.5a449.4 449.4 0 0 0 159 0l2.7-.5a32.05 32.05 0 0 0 25.8-25.7l15.7-85a350 350 0 0 0 99.7-57.6l81.3 28.9a32 32 0 0 0 35.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 0 1-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 0 1-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 0 1 512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 0 1 400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 0 1 624 502c0 29.9-11.7 58-32.8 79.2z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-content ant-collapse-content-active"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-content-box"
|
||||
>
|
||||
<div>
|
||||
|
||||
A dog is a type of domesticated animal.
|
||||
Known for its loyalty and faithfulness,
|
||||
it can be found as a welcome guest in many households across the world.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: right"
|
||||
class="anticon anticon-right ant-collapse-arrow"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
This is panel header 2
|
||||
<div
|
||||
class="ant-collapse-extra"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: setting"
|
||||
class="anticon anticon-setting"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="setting"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 0 0 9.3-35.2l-.9-2.6a443.74 443.74 0 0 0-79.7-137.9l-1.8-2.1a32.12 32.12 0 0 0-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 0 0-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 0 0-25.8 25.7l-15.8 85.4a351.86 351.86 0 0 0-99 57.4l-81.9-29.1a32 32 0 0 0-35.1 9.5l-1.8 2.1a446.02 446.02 0 0 0-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 0 0-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0 0 35.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0 0 25.8 25.7l2.7.5a449.4 449.4 0 0 0 159 0l2.7-.5a32.05 32.05 0 0 0 25.8-25.7l15.7-85a350 350 0 0 0 99.7-57.6l81.3 28.9a32 32 0 0 0 35.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 0 1-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 0 1-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 0 1 512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 0 1 400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 0 1 624 502c0 29.9-11.7 58-32.8 79.2z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: right"
|
||||
class="anticon anticon-right ant-collapse-arrow"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
This is panel header 3
|
||||
<div
|
||||
class="ant-collapse-extra"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: setting"
|
||||
class="anticon anticon-setting"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="setting"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 0 0 9.3-35.2l-.9-2.6a443.74 443.74 0 0 0-79.7-137.9l-1.8-2.1a32.12 32.12 0 0 0-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 0 0-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 0 0-25.8 25.7l-15.8 85.4a351.86 351.86 0 0 0-99 57.4l-81.9-29.1a32 32 0 0 0-35.1 9.5l-1.8 2.1a446.02 446.02 0 0 0-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 0 0-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0 0 35.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0 0 25.8 25.7l2.7.5a449.4 449.4 0 0 0 159 0l2.7-.5a32.05 32.05 0 0 0 25.8-25.7l15.7-85a350 350 0 0 0 99.7-57.6l81.3 28.9a32 32 0 0 0 35.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 0 1-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 0 1-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 0 1 512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 0 1 400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 0 1 624 502c0 29.9-11.7 58-32.8 79.2z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-collapse"
|
||||
|
45
components/collapse/demo/extra.md
Normal file
45
components/collapse/demo/extra.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 额外节点
|
||||
en-US: Extra node
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以同时展开多个面板,这个例子默认展开了第一个。
|
||||
|
||||
## en-US
|
||||
|
||||
More than one panel can be expanded at a time, the first panel is initialized to be active in this case.
|
||||
|
||||
````jsx
|
||||
import { Collapse, Icon } from 'antd';
|
||||
|
||||
const Panel = Collapse.Panel;
|
||||
|
||||
function callback(key) {
|
||||
console.log(key);
|
||||
}
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
Known for its loyalty and faithfulness,
|
||||
it can be found as a welcome guest in many households across the world.
|
||||
`;
|
||||
|
||||
ReactDOM.render(
|
||||
<Collapse defaultActiveKey={['1']} onChange={callback}>
|
||||
<Panel header="This is panel header 1" key="1" extra={<Icon type="setting" />}>
|
||||
<div>{text}</div>
|
||||
</Panel>
|
||||
<Panel header="This is panel header 2" key="2" extra={<Icon type="setting" />}>
|
||||
<div>{text}</div>
|
||||
</Panel>
|
||||
<Panel header="This is panel header 3" key="3" extra={<Icon type="setting" />}>
|
||||
<div>{text}</div>
|
||||
</Panel>
|
||||
</Collapse>,
|
||||
mountNode
|
||||
);
|
||||
````
|
@ -44,6 +44,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.@{collapse-prefix-cls}-extra {
|
||||
float: right;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
@ -130,13 +130,15 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
|
||||
|
||||
return (
|
||||
<ConfigConsumer>
|
||||
{({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
{({ getPrefixCls, getPopupContainer: getContextPopupContainer }: ConfigConsumerProps) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
inputPrefixCls: customizeInputPrefixCls,
|
||||
getCalendarContainer,
|
||||
size,
|
||||
disabled,
|
||||
} = this.props;
|
||||
const getPopupContainer = getCalendarContainer || getContextPopupContainer;
|
||||
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
|
||||
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
|
||||
const pickerClass = classNames(`${prefixCls}-picker`, {
|
||||
@ -170,6 +172,7 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
|
||||
return (
|
||||
<Picker
|
||||
{...this.props}
|
||||
getCalendarContainer={getPopupContainer}
|
||||
format={mergedFormat}
|
||||
ref={this.savePicker}
|
||||
pickerClass={pickerClass}
|
||||
|
@ -12,8 +12,10 @@
|
||||
z-index: @zindex-modal;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
|
||||
> * {
|
||||
transition: transform @animation-duration-slow @ease-base-in;
|
||||
transition: transform @animation-duration-slow @ease-base-in,
|
||||
box-shadow @animation-duration-slow @ease-base-in;
|
||||
}
|
||||
|
||||
&-content-wrapper {
|
||||
|
@ -249,6 +249,8 @@ export default class Form extends React.Component<FormProps, any> {
|
||||
'layout',
|
||||
'form',
|
||||
'hideRequiredMark',
|
||||
'wrapperCol',
|
||||
'labelCol',
|
||||
]);
|
||||
|
||||
return <form {...formProps} className={formClassName} />;
|
||||
|
@ -259,7 +259,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
|
||||
renderWrapper(prefixCls: string, children: React.ReactNode) {
|
||||
return (
|
||||
<FormContext.Consumer>
|
||||
<FormContext.Consumer key="wrapper">
|
||||
{({ wrapperCol: contextWrapperCol, vertical }: FormContextProps) => {
|
||||
const { wrapperCol } = this.props;
|
||||
const mergedWrapperCol: ColProps =
|
||||
@ -273,7 +273,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
// No pass FormContext since it's useless
|
||||
return (
|
||||
<FormContext.Provider value={{ vertical }}>
|
||||
<Col {...mergedWrapperCol} className={className} key="wrapper">
|
||||
<Col {...mergedWrapperCol} className={className}>
|
||||
{children}
|
||||
</Col>
|
||||
</FormContext.Provider>
|
||||
@ -328,7 +328,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
|
||||
renderLabel(prefixCls: string) {
|
||||
return (
|
||||
<FormContext.Consumer>
|
||||
<FormContext.Consumer key="label">
|
||||
{({ vertical, labelCol: contextLabelCol }: FormContextProps) => {
|
||||
const { label, labelCol, colon, id } = this.props;
|
||||
const required = this.isRequired();
|
||||
@ -350,7 +350,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
}
|
||||
|
||||
return label ? (
|
||||
<Col {...mergedLabelCol} className={labelColClassName} key="label">
|
||||
<Col {...mergedLabelCol} className={labelColClassName}>
|
||||
<label
|
||||
htmlFor={id || this.getId()}
|
||||
className={labelClassName}
|
||||
|
@ -481,8 +481,6 @@ exports[`renders ./components/form/demo/advanced-search.md correctly 1`] = `
|
||||
exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
|
||||
<form
|
||||
class="ant-form ant-form-horizontal"
|
||||
labelcol="[object Object]"
|
||||
wrappercol="[object Object]"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item"
|
||||
@ -1513,8 +1511,6 @@ exports[`renders ./components/form/demo/normal-login.md correctly 1`] = `
|
||||
exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
<form
|
||||
class="ant-form ant-form-horizontal"
|
||||
labelcol="[object Object]"
|
||||
wrappercol="[object Object]"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item"
|
||||
@ -2469,8 +2465,6 @@ exports[`renders ./components/form/demo/style-check-debug.md correctly 1`] = `
|
||||
exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] = `
|
||||
<form
|
||||
class="ant-form ant-form-horizontal"
|
||||
labelcol="[object Object]"
|
||||
wrappercol="[object Object]"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item"
|
||||
@ -2889,8 +2883,6 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
|
||||
exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
<form
|
||||
class="ant-form ant-form-horizontal"
|
||||
labelcol="[object Object]"
|
||||
wrappercol="[object Object]"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item"
|
||||
@ -4107,8 +4099,6 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
||||
<form
|
||||
class="ant-form ant-form-horizontal"
|
||||
labelcol="[object Object]"
|
||||
wrappercol="[object Object]"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item ant-form-item-with-help"
|
||||
|
@ -62,4 +62,16 @@ describe('Grid', () => {
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('when component has been unmounted, componentWillUnmount should be called', () => {
|
||||
const wrapper = mount(<Row />);
|
||||
const willUnmount = jest.spyOn(wrapper.instance(), 'componentWillUnmount');
|
||||
wrapper.unmount();
|
||||
expect(willUnmount).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('when typeof getGutter is object', () => {
|
||||
const wrapper = mount(<Row gutter={{ xs: 8, sm: 16, md: 24 }} />).instance();
|
||||
expect(wrapper.getGutter()).toBe(8);
|
||||
});
|
||||
});
|
||||
|
@ -142,9 +142,10 @@ class Input extends React.Component<InputProps, any> {
|
||||
setValue(
|
||||
value: string,
|
||||
e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement, MouseEvent>,
|
||||
callback?: () => void,
|
||||
) {
|
||||
if (!('value' in this.props)) {
|
||||
this.setState({ value });
|
||||
this.setState({ value }, callback);
|
||||
}
|
||||
const { onChange } = this.props;
|
||||
if (onChange) {
|
||||
@ -167,7 +168,9 @@ class Input extends React.Component<InputProps, any> {
|
||||
}
|
||||
|
||||
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
this.setValue('', e);
|
||||
this.setValue('', e, () => {
|
||||
this.focus();
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
|
@ -39,15 +39,18 @@ export default class Password extends React.Component<PasswordProps, PasswordSta
|
||||
getIcon() {
|
||||
const { prefixCls, action } = this.props;
|
||||
const iconTrigger = ActionMap[action] || '';
|
||||
const iconProps = { [iconTrigger]: this.onChange };
|
||||
return React.cloneElement(
|
||||
<Icon
|
||||
{...iconProps}
|
||||
className={`${prefixCls}-icon`}
|
||||
type={this.state.visible ? 'eye-invisible' : 'eye'}
|
||||
key="passwordIcon"
|
||||
/>,
|
||||
);
|
||||
const iconProps = {
|
||||
[iconTrigger]: this.onChange,
|
||||
className: `${prefixCls}-icon`,
|
||||
type: this.state.visible ? 'eye-invisible' : 'eye',
|
||||
key: 'passwordIcon',
|
||||
onMouseDown: (e: MouseEvent) => {
|
||||
// Prevent focused state lost
|
||||
// https://github.com/ant-design/ant-design/issues/15173
|
||||
e.preventDefault();
|
||||
},
|
||||
};
|
||||
return <Icon {...iconProps} />;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -494,6 +494,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
/>
|
||||
<span
|
||||
class="ant-calendar-picker"
|
||||
style="width:50%"
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
@ -1144,6 +1145,7 @@ exports[`renders ./components/input/demo/textarea-resize.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn"
|
||||
style="margin-bottom:16px"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
|
@ -297,6 +297,7 @@ exports[`Input.Password should change type when click 1`] = `
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye"
|
||||
/>
|
||||
}
|
||||
@ -323,6 +324,7 @@ exports[`Input.Password should change type when click 1`] = `
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye"
|
||||
>
|
||||
<LocaleReceiver
|
||||
@ -332,6 +334,7 @@ exports[`Input.Password should change type when click 1`] = `
|
||||
aria-label="icon: eye"
|
||||
className="anticon anticon-eye ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<IconReact
|
||||
@ -380,6 +383,7 @@ exports[`Input.Password should change type when click 2`] = `
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye-invisible"
|
||||
/>
|
||||
}
|
||||
@ -406,6 +410,7 @@ exports[`Input.Password should change type when click 2`] = `
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye-invisible"
|
||||
>
|
||||
<LocaleReceiver
|
||||
@ -415,6 +420,7 @@ exports[`Input.Password should change type when click 2`] = `
|
||||
aria-label="icon: eye-invisible"
|
||||
className="anticon anticon-eye-invisible ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<IconReact
|
||||
@ -467,6 +473,7 @@ exports[`Input.Password should change type when click 3`] = `
|
||||
<Icon
|
||||
className="ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye"
|
||||
/>
|
||||
}
|
||||
@ -493,6 +500,7 @@ exports[`Input.Password should change type when click 3`] = `
|
||||
className="ant-input-password-icon"
|
||||
key="passwordIcon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
type="eye"
|
||||
>
|
||||
<LocaleReceiver
|
||||
@ -502,6 +510,7 @@ exports[`Input.Password should change type when click 3`] = `
|
||||
aria-label="icon: eye"
|
||||
className="anticon anticon-eye ant-input-password-icon"
|
||||
onClick={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<IconReact
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
import { mount } from 'enzyme';
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
import Form from '../../form';
|
||||
import Input from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
import calculateNodeHeight, { calculateNodeStyling } from '../calculateNodeHeight';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
@ -70,6 +70,70 @@ describe('TextArea', () => {
|
||||
const wrapper = mount(<TextArea maxLength={10} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calculateNodeStyling works correctly', () => {
|
||||
const wrapper = document.createElement('textarea');
|
||||
wrapper.id = 'test';
|
||||
wrapper.wrap = 'wrap';
|
||||
calculateNodeStyling(wrapper, true);
|
||||
const value = calculateNodeStyling(wrapper, true);
|
||||
expect(value).toEqual({
|
||||
borderSize: 2,
|
||||
boxSizing: '',
|
||||
paddingSize: 4,
|
||||
sizingStyle:
|
||||
'letter-spacing:normal;line-height:normal;padding-top:2px;padding-bottom:2px;font-family:-webkit-small-control;font-weight:;font-size:;font-variant:;text-rendering:auto;text-transform:none;width:;text-indent:0;padding-left:2px;padding-right:2px;border-width:1px;box-sizing:',
|
||||
});
|
||||
});
|
||||
|
||||
it('boxSizing === "border-box"', () => {
|
||||
const wrapper = document.createElement('textarea');
|
||||
wrapper.style.boxSizing = 'border-box';
|
||||
const { height } = calculateNodeHeight(wrapper);
|
||||
expect(height).toBe(2);
|
||||
});
|
||||
|
||||
it('boxSizing === "content-box"', () => {
|
||||
const wrapper = document.createElement('textarea');
|
||||
wrapper.style.boxSizing = 'content-box';
|
||||
const { height } = calculateNodeHeight(wrapper);
|
||||
expect(height).toBe(-4);
|
||||
});
|
||||
|
||||
it('minRows or maxRows is not null', () => {
|
||||
const wrapper = document.createElement('textarea');
|
||||
expect(calculateNodeHeight(wrapper, 1, 1)).toEqual({
|
||||
height: 0,
|
||||
maxHeight: 9007199254740991,
|
||||
minHeight: -4,
|
||||
overflowY: undefined,
|
||||
});
|
||||
wrapper.style.boxSizing = 'content-box';
|
||||
expect(calculateNodeHeight(wrapper, 1, 1)).toEqual({
|
||||
height: -4,
|
||||
maxHeight: 9007199254740991,
|
||||
minHeight: -4,
|
||||
overflowY: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('when prop value not in this.props, resizeTextarea should be called', () => {
|
||||
const wrapper = mount(<TextArea aria-label="textarea" />);
|
||||
const resizeTextarea = jest.spyOn(wrapper.instance(), 'resizeTextarea');
|
||||
wrapper.find('textarea').simulate('change', 'test');
|
||||
expect(resizeTextarea).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handleKeyDown', () => {
|
||||
const onPressEnter = jest.fn();
|
||||
const onKeyDown = jest.fn();
|
||||
const wrapper = mount(
|
||||
<TextArea onPressEnter={onPressEnter} onKeyDown={onKeyDown} aria-label="textarea" />,
|
||||
);
|
||||
wrapper.instance().handleKeyDown({ keyCode: 13 });
|
||||
expect(onPressEnter).toBeCalled();
|
||||
expect(onKeyDown).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('As Form Control', () => {
|
||||
@ -137,6 +201,24 @@ describe('Input.Password', () => {
|
||||
wrapper.setProps({ visibilityToggle: true });
|
||||
expect(wrapper.find('.anticon-eye').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should keep focus state', () => {
|
||||
const wrapper = mount(<Input.Password defaultValue="111" autoFocus />);
|
||||
expect(document.activeElement).toBe(
|
||||
wrapper.find('input').at(0).getDOMNode()
|
||||
);
|
||||
wrapper
|
||||
.find('.ant-input-password-icon')
|
||||
.at(0)
|
||||
.simulate('mousedown');
|
||||
wrapper
|
||||
.find('.ant-input-password-icon')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(document.activeElement).toBe(
|
||||
wrapper.find('input').at(0).getDOMNode()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Input allowClear', () => {
|
||||
@ -216,4 +298,15 @@ describe('Input allowClear', () => {
|
||||
.getDOMNode().value,
|
||||
).toBe('111');
|
||||
});
|
||||
|
||||
it('should focus input after clear', () => {
|
||||
const wrapper = mount(<Input allowClear defaultValue="111" />);
|
||||
wrapper
|
||||
.find('.ant-input-clear-icon')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(document.activeElement).toBe(
|
||||
wrapper.find('input').at(0).getDOMNode()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -45,7 +45,7 @@ export interface NodeType {
|
||||
const computedStyleCache: { [key: string]: NodeType } = {};
|
||||
let hiddenTextarea: HTMLTextAreaElement;
|
||||
|
||||
function calculateNodeStyling(node: HTMLElement, useCache = false) {
|
||||
export function calculateNodeStyling(node: HTMLElement, useCache = false) {
|
||||
const nodeRef = (node.getAttribute('id') ||
|
||||
node.getAttribute('data-reactid') ||
|
||||
node.getAttribute('name')) as string;
|
||||
|
@ -102,7 +102,7 @@ class CompactDemo extends React.Component {
|
||||
<br />
|
||||
<InputGroup compact>
|
||||
<Input style={{ width: '50%' }} defaultValue="input content" />
|
||||
<DatePicker />
|
||||
<DatePicker style={{ width: '50%' }} />
|
||||
</InputGroup>
|
||||
<br />
|
||||
<InputGroup compact>
|
||||
|
@ -31,7 +31,7 @@ class Demo extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={() => this.setState({ autoResize: !autoResize })}>
|
||||
<Button onClick={() => this.setState({ autoResize: !autoResize })} style={{ marginBottom: 16 }}>
|
||||
Auto Resize: {String(autoResize)}
|
||||
</Button>
|
||||
<TextArea rows={4} autosize={autoResize} defaultValue={defaultValue} />
|
||||
|
@ -11,11 +11,14 @@ export interface GeneratorProps {
|
||||
export interface BasicProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
prefixCls?: string;
|
||||
hasSider?: boolean;
|
||||
}
|
||||
|
||||
interface BasicPropsWithTagName extends BasicProps {
|
||||
tagName: 'header' | 'footer' | 'main' | 'section';
|
||||
}
|
||||
|
||||
function generator({ suffixCls, tagName }: GeneratorProps) {
|
||||
return (BasicComponent: React.ComponentClass<BasicProps>): any => {
|
||||
return (BasicComponent: React.ComponentClass<BasicPropsWithTagName>): any => {
|
||||
return class Adapter extends React.Component<BasicProps, any> {
|
||||
static Header: any;
|
||||
static Footer: any;
|
||||
@ -36,15 +39,11 @@ function generator({ suffixCls, tagName }: GeneratorProps) {
|
||||
};
|
||||
}
|
||||
|
||||
class Basic extends React.Component<BasicProps, any> {
|
||||
class Basic extends React.Component<BasicPropsWithTagName, any> {
|
||||
render() {
|
||||
const { prefixCls, className, children, tagName: CustomElement, ...others } = this.props;
|
||||
const { prefixCls, className, children, tagName, ...others } = this.props;
|
||||
const classString = classNames(className, prefixCls);
|
||||
return (
|
||||
<CustomElement className={classString} {...others}>
|
||||
{children}
|
||||
</CustomElement>
|
||||
);
|
||||
return React.createElement(tagName, { className: classString, ...others }, children);
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +51,7 @@ interface BasicLayoutState {
|
||||
siders: string[];
|
||||
}
|
||||
|
||||
class BasicLayout extends React.Component<BasicProps, BasicLayoutState> {
|
||||
class BasicLayout extends React.Component<BasicPropsWithTagName, BasicLayoutState> {
|
||||
static childContextTypes = {
|
||||
siderHook: PropTypes.object,
|
||||
};
|
||||
@ -76,15 +75,11 @@ class BasicLayout extends React.Component<BasicProps, BasicLayoutState> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, className, children, hasSider, tagName: CustomElement, ...others } = this.props;
|
||||
const { prefixCls, className, children, hasSider, tagName, ...others } = this.props;
|
||||
const classString = classNames(className, prefixCls, {
|
||||
[`${prefixCls}-has-sider`]: hasSider || this.state.siders.length > 0,
|
||||
});
|
||||
return (
|
||||
<CustomElement className={classString} {...others}>
|
||||
{children}
|
||||
</CustomElement>
|
||||
);
|
||||
return React.createElement(tagName, { className: classString, ...others }, children);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import * as PropTypes from 'prop-types';
|
||||
import Tooltip from '../tooltip';
|
||||
import { ClickParam } from './index';
|
||||
|
||||
interface MenuItemProps {
|
||||
export interface MenuItemProps {
|
||||
rootPrefixCls?: string;
|
||||
disabled?: boolean;
|
||||
level?: number;
|
||||
|
@ -0,0 +1,17 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PageHeader pageHeader should support className 1`] = `
|
||||
<div
|
||||
class="ant-page-header not-works"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-title-view"
|
||||
>
|
||||
<span
|
||||
class="ant-page-header-title-view-title"
|
||||
>
|
||||
Page Title
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { mount, render } from 'enzyme';
|
||||
import PageHeader from '..';
|
||||
|
||||
describe('PageHeader', () => {
|
||||
@ -21,7 +21,7 @@ describe('PageHeader', () => {
|
||||
const wrapper = mount(<PageHeader title="Page Title" breadcrumb={{ routes }} />);
|
||||
expect(wrapper.find('.ant-page-header-back-icon')).toHaveLength(0);
|
||||
});
|
||||
it('pageHeader should no contain back it back', () => {
|
||||
it('pageHeader should no contain back it back', () => {
|
||||
const wrapper = mount(<PageHeader title="Page Title" backIcon={false} />);
|
||||
expect(wrapper.find('.ant-page-header-back-icon')).toHaveLength(0);
|
||||
});
|
||||
@ -38,4 +38,11 @@ describe('PageHeader', () => {
|
||||
wrapper.find('.ant-page-header-back-icon').simulate('click');
|
||||
expect(callback).toBeCalled();
|
||||
});
|
||||
|
||||
it('pageHeader should support className', () => {
|
||||
const wrapper = render(
|
||||
<PageHeader title="Page Title" className="not-works" backIcon={false} />,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -18,6 +18,7 @@ export interface PageHeaderProps {
|
||||
footer?: React.ReactNode;
|
||||
extra?: React.ReactNode;
|
||||
onBack?: (e: React.MouseEvent<HTMLElement>) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const renderBack = (
|
||||
@ -78,11 +79,23 @@ const renderFooter = (prefixCls: string, footer: React.ReactNode) => {
|
||||
const PageHeader: React.SFC<PageHeaderProps> = props => (
|
||||
<ConfigConsumer>
|
||||
{({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { prefixCls: customizePrefixCls, style, footer, children } = props;
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
style,
|
||||
footer,
|
||||
children,
|
||||
className: customizeClassName,
|
||||
} = props;
|
||||
|
||||
const prefixCls = getPrefixCls('page-header', customizePrefixCls);
|
||||
const className = classnames(prefixCls, {
|
||||
[`${prefixCls}-has-footer`]: footer,
|
||||
});
|
||||
const className = classnames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-has-footer`]: footer,
|
||||
},
|
||||
customizeClassName,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={className} style={style}>
|
||||
{renderHeader(prefixCls, props)}
|
||||
|
@ -532,7 +532,7 @@
|
||||
|
||||
// Collapse
|
||||
// ---
|
||||
@collapse-header-padding: 12px 0 12px 40px;
|
||||
@collapse-header-padding: 12px 16px 12px 40px;
|
||||
@collapse-header-bg: @background-color-light;
|
||||
@collapse-content-padding: @padding-md;
|
||||
@collapse-content-bg: @component-background;
|
||||
|
@ -40,4 +40,18 @@ describe('List', () => {
|
||||
.prop('checked'),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('when component has been unmounted, componentWillUnmount should be called', () => {
|
||||
const wrapper = mount(<List {...listCommonProps} />);
|
||||
const willUnmount = jest.spyOn(wrapper.instance(), 'componentWillUnmount');
|
||||
wrapper.unmount();
|
||||
expect(willUnmount).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('when value is not exists, handleFilter should return', () => {
|
||||
const handleFilter = jest.fn();
|
||||
const wrapper = mount(<List {...listCommonProps} handleFilter={handleFilter} />);
|
||||
expect(wrapper.instance().handleFilter({ target: 'test' })).toBe(undefined);
|
||||
expect(handleFilter).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
@ -13,7 +13,7 @@ export interface TypographyProps {
|
||||
|
||||
interface InternalTypographyProps extends TypographyProps {
|
||||
component?: string;
|
||||
setContentRef: (node: HTMLElement) => void;
|
||||
setContentRef?: (node: HTMLElement) => void;
|
||||
}
|
||||
|
||||
const Typography: React.SFC<InternalTypographyProps> = ({
|
||||
|
@ -21,7 +21,7 @@ When need to display title or text content. Like:
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| copyable | Config copy. Can set copy text and callback when is an object | boolean \| { text: string, onCopy: Function } | false |boolean \| string | false |
|
||||
| copyable | Config copy. Can set copy text and callback when is an object | boolean \| { text: string, onCopy: Function } | false |
|
||||
| delete | delete line style | boolean | false |
|
||||
| disabled | Disable content | boolean | false |
|
||||
| editable | Editable. Can control edit state when is object | boolean \| { editing: boolean, onStart: Function, onChange: Function(string) } | false |
|
||||
@ -36,7 +36,7 @@ When need to display title or text content. Like:
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| copyable | Config copy. Can set copy text and callback when is an object | boolean \| { text: string, onCopy: Function } | false |boolean \| string | false |
|
||||
| copyable | Config copy. Can set copy text and callback when is an object | boolean \| { text: string, onCopy: Function } | false |
|
||||
| delete | delete line style | boolean | false |
|
||||
| disabled | Disable content | boolean | false |
|
||||
| editable | Editable. Can control edit state when is object | boolean \| { editing: boolean, onStart: Function, onChange: Function(string) } | false |
|
||||
@ -51,7 +51,7 @@ When need to display title or text content. Like:
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| copyable | Config copy. Can set copy text and callback when is an object | boolean \| { text: string, onCopy: Function } | false |boolean \| string | false |
|
||||
| copyable | Config copy. Can set copy text and callback when is an object | boolean \| { text: string, onCopy: Function } | false |
|
||||
| delete | delete line style | boolean | false |
|
||||
| disabled | Disable content | boolean | false |
|
||||
| editable | Editable. Can control edit state when is object | boolean \| { editing: boolean, onStart: Function, onChange: Function(string) } | false |
|
||||
|
@ -51,7 +51,7 @@ cols: 1
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
|
||||
| copyable | 是否可拷贝,为对象时可设置复制文本以回调函数 | boolean \| { text: string, onCopy: Function } | false |
|
||||
| delete | 添加删除线样式 | boolean | false |
|
||||
| disabled | 禁用文本 | boolean | false |
|
||||
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, onStart: Function, onChange: Function(string) } | false |
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "3.14.0",
|
||||
"version": "3.14.1",
|
||||
"title": "Ant Design",
|
||||
"description": "An enterprise-class UI design language and React-based implementation",
|
||||
"homepage": "http://ant.design/",
|
||||
|
@ -46,6 +46,10 @@ ul.anticons-list {
|
||||
}
|
||||
}
|
||||
|
||||
&.outlined:hover {
|
||||
background-color: #8ecafe;
|
||||
}
|
||||
|
||||
&.copied:hover {
|
||||
color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import { Icon as AntdIcon, Badge } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { ThemeType, IconProps } from '../../../../components/icon';
|
||||
|
||||
const Icon: React.SFC<IconProps> = AntdIcon;
|
||||
@ -20,6 +21,10 @@ const CopyableIcon: React.SFC<CopyableIconProps> = ({
|
||||
justCopied,
|
||||
onCopied,
|
||||
}) => {
|
||||
const className = classNames({
|
||||
copied: justCopied === type,
|
||||
outlined: theme === 'twoTone',
|
||||
});
|
||||
return (
|
||||
<CopyToClipboard
|
||||
text={
|
||||
@ -29,7 +34,7 @@ const CopyableIcon: React.SFC<CopyableIconProps> = ({
|
||||
}
|
||||
onCopy={(text: string) => onCopied(type, text)}
|
||||
>
|
||||
<li className={justCopied === type ? 'copied' : ''}>
|
||||
<li className={className}>
|
||||
<Icon type={type} theme={theme} />
|
||||
<span className="anticon-class">
|
||||
<Badge dot={isNew}>{type}</Badge>
|
||||
|
Loading…
Reference in New Issue
Block a user