mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
Merge branch 'master' into feature-3.6.0
This commit is contained in:
commit
f3545ccdc7
@ -15,6 +15,22 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.5.1
|
||||
|
||||
`2018-05-09`
|
||||
|
||||
- 🐞 Fixed broken style of Input.Group under Form. [#10371](https://github.com/ant-design/ant-design/issues/10371)
|
||||
- 🐞 Fixed overlay style of Select. [#10383](https://github.com/ant-design/ant-design/issues/10383)
|
||||
- 🐞 Remove focused style of Collapse.
|
||||
- 🐞 Remove unnecessary `z-index` of Input.Group and Checkbox. [#9840](https://github.com/ant-design/ant-design/issues/9840) [#10385](https://github.com/ant-design/ant-design/issues/10385)
|
||||
- 🐞 Fixed that monospaced font family can't be bold.
|
||||
- Table
|
||||
- 💄 Rewrited the editable table demo. [#10119](https://github.com/ant-design/ant-design/pull/10119)
|
||||
- 🐞 Fixed that table column overlay each other. [#9822](https://github.com/ant-design/ant-design/issues/9822)
|
||||
- TypeScript
|
||||
- 🐞 Fixed Breadcrumb.Item type. [#10372](https://github.com/ant-design/ant-design/pull/10372) [@karol-majewski](https://github.com/karol-majewski)
|
||||
- 🐞 Fixed Table `rowSelection` type。[#10374](https://github.com/ant-design/ant-design/issues/10374)
|
||||
|
||||
## 3.5.0
|
||||
|
||||
`2018-05-04`
|
||||
|
@ -15,6 +15,22 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.5.1
|
||||
|
||||
`2018-05-09`
|
||||
|
||||
- 🐞 修复 Input.Group 在 Form 下样式错位的问题。[#10371](https://github.com/ant-design/ant-design/issues/10371)
|
||||
- 🐞 修复 Select 箭头和内容重叠的问题。[#10383](https://github.com/ant-design/ant-design/issues/10383)
|
||||
- 🐞 移除 Collapse 点击时的 focus 样式。
|
||||
- 🐞 移除 Input.Group 和 Checkbox 不必要的 `z-index`。[#9840](https://github.com/ant-design/ant-design/issues/9840) [#10385](https://github.com/ant-design/ant-design/issues/10385)
|
||||
- 🐞 修复一个数字等宽字体没有加粗的问题。
|
||||
- Table
|
||||
- 💄 重写了可编辑表格的演示。[#10119](https://github.com/ant-design/ant-design/pull/10119)
|
||||
- 🐞 修复一个表格列内容互相重叠的问题。[#9822](https://github.com/ant-design/ant-design/issues/9822)
|
||||
- TypeScript
|
||||
- 🐞 调整 Breadcrumb.Item 的类型。[#10372](https://github.com/ant-design/ant-design/pull/10372) [@karol-majewski](https://github.com/karol-majewski)
|
||||
- 🐞 修复 Table 的 `rowSelection` 的类型。[#10374](https://github.com/ant-design/ant-design/issues/10374)
|
||||
|
||||
## 3.5.0
|
||||
|
||||
`2018-05-04`
|
||||
|
@ -39,7 +39,7 @@ export type ButtonType = 'default' | 'primary' | 'ghost' | 'dashed' | 'danger';
|
||||
export type ButtonShape = 'circle' | 'circle-outline';
|
||||
export type ButtonSize = 'small' | 'default' | 'large';
|
||||
|
||||
export interface BaseButtonProps<T> extends Omit<React.HTMLProps<T>, 'size'> {
|
||||
export interface BaseButtonProps<T> extends Omit<React.HTMLProps<T>, 'ref' | 'size'> {
|
||||
type?: ButtonType;
|
||||
htmlType?: string;
|
||||
icon?: string;
|
||||
|
@ -14,6 +14,7 @@
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
display: block;
|
||||
position: static;
|
||||
}
|
||||
|
||||
&-picker {
|
||||
|
@ -35,11 +35,11 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-dropdown-trigger ant-btn-default"
|
||||
class="ant-btn ant-dropdown-trigger ant-btn-default ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-down"
|
||||
class="anticon anticon-ellipsis"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
@ -57,12 +57,12 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-dropdown-trigger ant-btn-default"
|
||||
class="ant-btn ant-dropdown-trigger ant-btn-default ant-btn-icon-only"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-down"
|
||||
class="anticon anticon-ellipsis"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import Button from '../button';
|
||||
import { ButtonGroupProps } from '../button/button-group';
|
||||
import Icon from '../icon';
|
||||
import Dropdown, { DropDownProps } from './dropdown';
|
||||
import classNames from 'classnames';
|
||||
const ButtonGroup = Button.Group;
|
||||
@ -54,9 +53,7 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
|
||||
{children}
|
||||
</Button>
|
||||
<Dropdown {...dropdownProps}>
|
||||
<Button type={type}>
|
||||
<Icon type="down" />
|
||||
</Button>
|
||||
<Button type={type} icon="ellipsis" />
|
||||
</Dropdown>
|
||||
</ButtonGroup>
|
||||
);
|
||||
|
@ -208,6 +208,9 @@
|
||||
.@{iconfont-css-prefix}-down {
|
||||
.iconfont-size-under-12px(10px);
|
||||
}
|
||||
.@{iconfont-css-prefix}-ellipsis {
|
||||
text-shadow: 0 0 currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
.@{dropdown-prefix-cls}-button {
|
||||
|
@ -56,7 +56,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
|
||||
context: FormItemContext;
|
||||
|
||||
state = { helpShow: false };
|
||||
helpShow = false;
|
||||
|
||||
componentDidMount() {
|
||||
warning(
|
||||
@ -130,7 +130,10 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
}
|
||||
|
||||
onHelpAnimEnd = (_key: string, helpShow: boolean) => {
|
||||
this.setState({ helpShow });
|
||||
this.helpShow = helpShow;
|
||||
if (!helpShow) {
|
||||
this.setState({});
|
||||
}
|
||||
}
|
||||
|
||||
renderHelp() {
|
||||
@ -141,6 +144,9 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
{help}
|
||||
</div>
|
||||
) : null;
|
||||
if (children) {
|
||||
this.helpShow = !!children;
|
||||
}
|
||||
return (
|
||||
<Animate
|
||||
transitionName="show-help"
|
||||
@ -312,11 +318,10 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
const style = props.style;
|
||||
const itemClassName = {
|
||||
[`${prefixCls}-item`]: true,
|
||||
[`${prefixCls}-item-with-help`]: !!this.getHelpMessage() || this.state.helpShow,
|
||||
[`${prefixCls}-item-with-help`]: this.helpShow,
|
||||
[`${prefixCls}-item-no-colon`]: !props.colon,
|
||||
[`${props.className}`]: !!props.className,
|
||||
};
|
||||
|
||||
return (
|
||||
<Row className={classNames(itemClassName)} style={style}>
|
||||
{children}
|
||||
|
@ -132,8 +132,9 @@ input[type="checkbox"] {
|
||||
.@{form-prefix-cls}-extra {
|
||||
color: @text-color-secondary;
|
||||
line-height: @line-height-base;
|
||||
transition: color .15s @ease-out;
|
||||
transition: color .3s @ease-out; // sync input color transition
|
||||
margin-top: @form-help-margin-top;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.@{form-prefix-cls}-extra {
|
||||
@ -576,7 +577,7 @@ form {
|
||||
}
|
||||
}
|
||||
|
||||
.show-help-motion(show-help, antShowHelp, 0.15s);
|
||||
.show-help-motion(show-help, antShowHelp, 0.3s);
|
||||
|
||||
@keyframes antShowHelpIn {
|
||||
0% {
|
||||
|
@ -180,9 +180,11 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
} = this.props;
|
||||
const divProps = omit(others, ['collapsed',
|
||||
'defaultCollapsed', 'onCollapse', 'breakpoint']);
|
||||
const siderWidth = this.state.collapsed ? collapsedWidth : width;
|
||||
const rawWidth = this.state.collapsed ? collapsedWidth : width;
|
||||
// use "px" as fallback unit for width
|
||||
const siderWidth = typeof rawWidth === 'number' ? `${rawWidth}px` : String(rawWidth || 0);
|
||||
// special trigger when collapsedWidth == 0
|
||||
const zeroWidthTrigger = collapsedWidth === 0 || collapsedWidth === '0' || collapsedWidth === '0px' ? (
|
||||
const zeroWidthTrigger = parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
||||
<span onClick={this.toggle} className={`${prefixCls}-zero-width-trigger`}>
|
||||
<Icon type="bars" />
|
||||
</span>
|
||||
@ -201,21 +203,18 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
</div>
|
||||
) : null
|
||||
);
|
||||
// For collapsedWidth="40px"
|
||||
// https://github.com/ant-design/ant-design/issues/10140
|
||||
const siderWidthNumber = (siderWidth || 0).toString().replace(/px$/, '');
|
||||
const divStyle = {
|
||||
...style,
|
||||
flex: `0 0 ${siderWidthNumber}px`,
|
||||
maxWidth: `${siderWidthNumber}px`, // Fix width transition bug in IE11
|
||||
minWidth: `${siderWidthNumber}px`, // https://github.com/ant-design/ant-design/issues/6349
|
||||
width: `${siderWidthNumber}px`,
|
||||
flex: `0 0 ${siderWidth}`,
|
||||
maxWidth: siderWidth, // Fix width transition bug in IE11
|
||||
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
||||
width: siderWidth,
|
||||
};
|
||||
const siderCls = classNames(className, prefixCls, {
|
||||
[`${prefixCls}-collapsed`]: !!this.state.collapsed,
|
||||
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
||||
[`${prefixCls}-below`]: !!this.state.below,
|
||||
[`${prefixCls}-zero-width`]: siderWidth === 0 || siderWidth === '0' || siderWidth === '0px',
|
||||
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
|
||||
});
|
||||
return (
|
||||
<div className={siderCls} {...divProps} style={divStyle}>
|
||||
|
@ -34,4 +34,25 @@ describe('Layout', () => {
|
||||
);
|
||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-has-trigger')).toBe(true);
|
||||
});
|
||||
|
||||
it('should have 50% width of sidebar', async () => {
|
||||
const wrapper = mount(
|
||||
<Layout>
|
||||
<div><Sider width="50%">Sider</Sider></div>
|
||||
<Content>Content</Content>
|
||||
</Layout>
|
||||
);
|
||||
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').width).toBe('50%');
|
||||
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').flex).toBe('0 0 50%');
|
||||
});
|
||||
|
||||
it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => {
|
||||
const wrapper = mount(
|
||||
<Layout>
|
||||
<div><Sider width="0%">Sider</Sider></div>
|
||||
<Content>Content</Content>
|
||||
</Layout>
|
||||
);
|
||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-zero-width')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -18,13 +18,15 @@ class MenuItem extends React.Component<any, any> {
|
||||
render() {
|
||||
const { inlineCollapsed } = this.context;
|
||||
const props = this.props;
|
||||
return <Tooltip
|
||||
title={inlineCollapsed && props.level === 1 ? props.children : ''}
|
||||
placement="right"
|
||||
overlayClassName={`${props.rootPrefixCls}-inline-collapsed-tooltip`}
|
||||
>
|
||||
<Item {...props} ref={this.saveMenuItem} />
|
||||
</Tooltip>;
|
||||
return (
|
||||
<Tooltip
|
||||
title={inlineCollapsed && props.level === 1 ? props.children : ''}
|
||||
placement="right"
|
||||
overlayClassName={`${props.rootPrefixCls}-inline-collapsed-tooltip`}
|
||||
>
|
||||
<Item {...props} ref={this.saveMenuItem} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,5 +48,5 @@ message.config({
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| duration | time before auto-dismiss, in seconds | number | 1.5 |
|
||||
| getContainer | Return the mount node for Message | () => HTMLElement | () => document.body |
|
||||
| top | distance from top | number | 24px |
|
||||
| top | distance from top | number | 24 |
|
||||
| maxCount | max message show, drop oldest if exceed limit | number | - |
|
||||
|
@ -40,7 +40,7 @@ function notice(
|
||||
type: NoticeType,
|
||||
onClose?: () => void,
|
||||
) {
|
||||
let iconType = ({
|
||||
const iconType = ({
|
||||
info: 'info-circle',
|
||||
success: 'check-circle',
|
||||
error: 'cross-circle',
|
||||
|
@ -49,5 +49,5 @@ message.config({
|
||||
| --- | --- | --- | --- |
|
||||
| duration | 默认自动关闭延时,单位秒 | number | 3 |
|
||||
| getContainer | 配置渲染节点的输出位置 | () => HTMLElement | () => document.body |
|
||||
| top | 消息距离顶部的位置 | number | 24px |
|
||||
| top | 消息距离顶部的位置 | number | 24 |
|
||||
| maxCount | 最大显示数, 超过限制时,最早的消息会被自动关闭 | number | - |
|
||||
|
@ -14,6 +14,13 @@
|
||||
unicode-range: U+30-39;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Monospaced Number";
|
||||
font-weight: bold;
|
||||
src: local("Tahoma-Bold");
|
||||
unicode-range: U+30-39;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Chinese Quote";
|
||||
src: local("PingFang SC"), local("SimSun");
|
||||
|
@ -2954,23 +2954,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 0
|
||||
</div>
|
||||
Edrward 0
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 0
|
||||
</div>
|
||||
London Park no. 0
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -2994,23 +2988,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 1
|
||||
</div>
|
||||
Edrward 1
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 1
|
||||
</div>
|
||||
London Park no. 1
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3034,23 +3022,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 2
|
||||
</div>
|
||||
Edrward 2
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 2
|
||||
</div>
|
||||
London Park no. 2
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3074,23 +3056,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 3
|
||||
</div>
|
||||
Edrward 3
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 3
|
||||
</div>
|
||||
London Park no. 3
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3114,23 +3090,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 4
|
||||
</div>
|
||||
Edrward 4
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 4
|
||||
</div>
|
||||
London Park no. 4
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3154,23 +3124,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 5
|
||||
</div>
|
||||
Edrward 5
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 5
|
||||
</div>
|
||||
London Park no. 5
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3194,23 +3158,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 6
|
||||
</div>
|
||||
Edrward 6
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 6
|
||||
</div>
|
||||
London Park no. 6
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3234,23 +3192,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 7
|
||||
</div>
|
||||
Edrward 7
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 7
|
||||
</div>
|
||||
London Park no. 7
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3274,23 +3226,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 8
|
||||
</div>
|
||||
Edrward 8
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 8
|
||||
</div>
|
||||
London Park no. 8
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
@ -3314,23 +3260,17 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div>
|
||||
Edrward 9
|
||||
</div>
|
||||
Edrward 9
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
32
|
||||
</div>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
London Park no. 9
|
||||
</div>
|
||||
London Park no. 9
|
||||
</td>
|
||||
<td
|
||||
class=""
|
||||
|
@ -1,3 +1,5 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('table');
|
||||
demoTest('table', {
|
||||
skip: process.env.REACT === '15' ? ['edit-row'] : [],
|
||||
});
|
||||
|
@ -13,8 +13,8 @@ title:
|
||||
|
||||
Table with editable rows.
|
||||
|
||||
````jsx
|
||||
import { Table, Input, Popconfirm } from 'antd';
|
||||
```jsx
|
||||
import { Table, Input, InputNumber, Popconfirm, Form } from 'antd';
|
||||
|
||||
const data = [];
|
||||
for (let i = 0; i < 100; i++) {
|
||||
@ -25,111 +25,190 @@ for (let i = 0; i < 100; i++) {
|
||||
address: `London Park no. ${i}`,
|
||||
});
|
||||
}
|
||||
const FormItem = Form.Item;
|
||||
const EditableContext = React.createContext();
|
||||
|
||||
const EditableCell = ({ editable, value, onChange }) => (
|
||||
<div>
|
||||
{editable
|
||||
? <Input style={{ margin: '-5px 0' }} value={value} onChange={e => onChange(e.target.value)} />
|
||||
: value
|
||||
}
|
||||
</div>
|
||||
const EditableRow = ({ form, index, ...props }) => (
|
||||
<EditableContext.Provider value={form}>
|
||||
<tr {...props} />
|
||||
</EditableContext.Provider>
|
||||
);
|
||||
|
||||
const EditableFormRow = Form.create()(EditableRow);
|
||||
|
||||
class EditableCell extends React.Component {
|
||||
getInput = () => {
|
||||
if (this.props.inputType === 'number') {
|
||||
return <InputNumber size="small" />;
|
||||
}
|
||||
return <Input size="small" />;
|
||||
};
|
||||
render() {
|
||||
const {
|
||||
editing,
|
||||
dataIndex,
|
||||
title,
|
||||
inputType,
|
||||
record,
|
||||
index,
|
||||
...restProps
|
||||
} = this.props;
|
||||
return (
|
||||
<EditableContext.Consumer>
|
||||
{(form) => {
|
||||
const { getFieldDecorator } = form;
|
||||
return (
|
||||
<td {...restProps}>
|
||||
{editing ? (
|
||||
<FormItem>
|
||||
{getFieldDecorator(dataIndex, {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: `Please Input ${title}!`,
|
||||
},
|
||||
],
|
||||
initialValue: record[dataIndex],
|
||||
})(this.getInput())}
|
||||
</FormItem>
|
||||
) : (
|
||||
restProps.children
|
||||
)}
|
||||
</td>
|
||||
);
|
||||
}}
|
||||
</EditableContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EditableTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.columns = [{
|
||||
title: 'name',
|
||||
dataIndex: 'name',
|
||||
width: '25%',
|
||||
render: (text, record) => this.renderColumns(text, record, 'name'),
|
||||
}, {
|
||||
title: 'age',
|
||||
dataIndex: 'age',
|
||||
width: '15%',
|
||||
render: (text, record) => this.renderColumns(text, record, 'age'),
|
||||
}, {
|
||||
title: 'address',
|
||||
dataIndex: 'address',
|
||||
width: '40%',
|
||||
render: (text, record) => this.renderColumns(text, record, 'address'),
|
||||
}, {
|
||||
title: 'operation',
|
||||
dataIndex: 'operation',
|
||||
render: (text, record) => {
|
||||
const { editable } = record;
|
||||
return (
|
||||
<div className="editable-row-operations">
|
||||
{
|
||||
editable ?
|
||||
this.state = { data, editingKey: '' };
|
||||
this.columns = [
|
||||
{
|
||||
title: 'name',
|
||||
dataIndex: 'name',
|
||||
width: '25%',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: 'age',
|
||||
dataIndex: 'age',
|
||||
width: '15%',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: 'address',
|
||||
dataIndex: 'address',
|
||||
width: '40%',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: 'operation',
|
||||
dataIndex: 'operation',
|
||||
render: (text, record) => {
|
||||
const editable = this.isEditing(record);
|
||||
return (
|
||||
<div className="editable-row-operations">
|
||||
{editable ? (
|
||||
<span>
|
||||
<a onClick={() => this.save(record.key)}>Save</a>
|
||||
<Popconfirm title="Sure to cancel?" onConfirm={() => this.cancel(record.key)}>
|
||||
<EditableContext.Consumer>
|
||||
{form => (
|
||||
<a
|
||||
href="javascript:;"
|
||||
onClick={() => this.save(form, record.key)}
|
||||
>
|
||||
Save
|
||||
</a>
|
||||
)}
|
||||
</EditableContext.Consumer>
|
||||
<Popconfirm
|
||||
title="Sure to cancel?"
|
||||
onConfirm={() => this.cancel(record.key)}
|
||||
>
|
||||
<a>Cancel</a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
: <a onClick={() => this.edit(record.key)}>Edit</a>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
) : (
|
||||
<a onClick={() => this.edit(record.key)}>Edit</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
}];
|
||||
this.state = { data };
|
||||
this.cacheData = data.map(item => ({ ...item }));
|
||||
];
|
||||
}
|
||||
renderColumns(text, record, column) {
|
||||
isEditing = (record) => {
|
||||
return record.key === this.state.editingKey;
|
||||
};
|
||||
edit(key) {
|
||||
this.setState({ editingKey: key });
|
||||
}
|
||||
save(from, key) {
|
||||
from.validateFields((error, row) => {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
const newData = [...this.state.data];
|
||||
const index = newData.findIndex(item => key === item.key);
|
||||
if (index > -1) {
|
||||
const item = newData[index];
|
||||
newData.splice(index, 1, {
|
||||
...item,
|
||||
...row,
|
||||
});
|
||||
this.setState({ data: newData, editingKey: '' });
|
||||
} else {
|
||||
newData.push(data);
|
||||
this.setState({ data: newData, editingKey: '' });
|
||||
}
|
||||
});
|
||||
}
|
||||
cancel = () => {
|
||||
this.setState({ editingKey: '' });
|
||||
};
|
||||
render() {
|
||||
const components = {
|
||||
body: {
|
||||
row: EditableFormRow,
|
||||
cell: EditableCell,
|
||||
},
|
||||
};
|
||||
|
||||
const columns = this.columns.map((col) => {
|
||||
if (!col.editable) {
|
||||
return col;
|
||||
}
|
||||
return {
|
||||
...col,
|
||||
onCell: record => ({
|
||||
record,
|
||||
inputType: col.dataIndex === 'age' ? 'number' : 'text',
|
||||
dataIndex: col.dataIndex,
|
||||
title: col.title,
|
||||
editing: this.isEditing(record),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<EditableCell
|
||||
editable={record.editable}
|
||||
value={text}
|
||||
onChange={value => this.handleChange(value, record.key, column)}
|
||||
<Table
|
||||
components={components}
|
||||
bordered
|
||||
dataSource={this.state.data}
|
||||
columns={columns}
|
||||
/>
|
||||
);
|
||||
}
|
||||
handleChange(value, key, column) {
|
||||
const newData = [...this.state.data];
|
||||
const target = newData.filter(item => key === item.key)[0];
|
||||
if (target) {
|
||||
target[column] = value;
|
||||
this.setState({ data: newData });
|
||||
}
|
||||
}
|
||||
edit(key) {
|
||||
const newData = [...this.state.data];
|
||||
const target = newData.filter(item => key === item.key)[0];
|
||||
if (target) {
|
||||
target.editable = true;
|
||||
this.setState({ data: newData });
|
||||
}
|
||||
}
|
||||
save(key) {
|
||||
const newData = [...this.state.data];
|
||||
const target = newData.filter(item => key === item.key)[0];
|
||||
if (target) {
|
||||
delete target.editable;
|
||||
this.setState({ data: newData });
|
||||
this.cacheData = newData.map(item => ({ ...item }));
|
||||
}
|
||||
}
|
||||
cancel(key) {
|
||||
const newData = [...this.state.data];
|
||||
const target = newData.filter(item => key === item.key)[0];
|
||||
if (target) {
|
||||
Object.assign(target, this.cacheData.filter(item => key === item.key)[0]);
|
||||
delete target.editable;
|
||||
this.setState({ data: newData });
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return <Table bordered dataSource={this.state.data} columns={this.columns} />;
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<EditableTable />, mountNode);
|
||||
````
|
||||
```
|
||||
|
||||
````css
|
||||
```css
|
||||
.editable-row-operations a {
|
||||
margin-right: 8px;
|
||||
}
|
||||
````
|
||||
```
|
||||
|
@ -115,12 +115,11 @@ export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, F
|
||||
|
||||
renderMenuItem(item: ColumnFilterItem) {
|
||||
const { column } = this.props;
|
||||
const { selectedKeys } = this.state;
|
||||
const multiple = ('filterMultiple' in column) ? column.filterMultiple : true;
|
||||
const input = multiple ? (
|
||||
<Checkbox checked={this.state.selectedKeys.indexOf(item.value.toString()) >= 0} />
|
||||
) : (
|
||||
<Radio checked={this.state.selectedKeys.indexOf(item.value.toString()) >= 0} />
|
||||
);
|
||||
const input = multiple
|
||||
? <Checkbox checked={selectedKeys.indexOf(item.value.toString()) >= 0} />
|
||||
: <Radio checked={selectedKeys.indexOf(item.value.toString()) >= 0} />;
|
||||
|
||||
return (
|
||||
<MenuItem key={item.value}>
|
||||
|
@ -362,6 +362,10 @@
|
||||
border-radius: @border-radius-base;
|
||||
box-shadow: @box-shadow-base;
|
||||
|
||||
.@{ant-prefix}-checkbox-input {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.@{ant-prefix}-dropdown-menu {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
@ -505,6 +509,7 @@
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
table {
|
||||
width: auto;
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -63,4 +63,4 @@ Note: This way will load the styles of all components, regardless of your demand
|
||||
- [How to Customize Ant Design with React & Webpack… the Missing Guide](https://medium.com/@GeoffMiller/how-to-customize-ant-design-with-react-webpack-the-missing-guide-c6430f2db10f)
|
||||
- [Theming Ant Design with Sass and Webpack](https://gist.github.com/Kruemelkatze/057f01b8e15216ae707dc7e6c9061ef7)
|
||||
- [Using Sass/Scss with React App (create-react-app)](https://medium.com/@mzohaib.qc/using-sass-scss-with-react-app-create-react-app-d03072083ef8)
|
||||
- [Dynamic Theminig in Browser using Ant Design](https://medium.com/@mzohaib.qc/ant-design-dynamic-runtime-theme-1f9a1a030ba0)
|
||||
- [Dynamic Theming in Browser using Ant Design](https://medium.com/@mzohaib.qc/ant-design-dynamic-runtime-theme-1f9a1a030ba0)
|
||||
|
@ -66,4 +66,4 @@ antd 的样式使用了 [Less](http://lesscss.org/) 作为开发语言,并定
|
||||
- [How to Customize Ant Design with React & Webpack… the Missing Guide](https://medium.com/@GeoffMiller/how-to-customize-ant-design-with-react-webpack-the-missing-guide-c6430f2db10f)
|
||||
- [Theming Ant Design with Sass and Webpack](https://gist.github.com/Kruemelkatze/057f01b8e15216ae707dc7e6c9061ef7)
|
||||
- [Using Sass/Scss with React App (create-react-app)](https://medium.com/@mzohaib.qc/using-sass-scss-with-react-app-create-react-app-d03072083ef8)
|
||||
- [Dynamic Theminig in Browser using Ant Design](https://medium.com/@mzohaib.qc/ant-design-dynamic-runtime-theme-1f9a1a030ba0)
|
||||
- [Dynamic Theming in Browser using Ant Design](https://medium.com/@mzohaib.qc/ant-design-dynamic-runtime-theme-1f9a1a030ba0)
|
||||
|
@ -32,6 +32,7 @@ We supply a series of design principles, practical patterns and high quality des
|
||||
- <div class="outside-link"><a href="https://github.com/priornix/antizer" target="_blank">antizer (ClojureScript)</a></div>
|
||||
- <div class="outside-link"><a href="https://github.com/idcos/antd-ember" target="_blank">antd-ember</a></div>
|
||||
- <div class="outside-link"><a href="https://github.com/zzuu666/antue" target="_blank">antue (vue)</a></div>
|
||||
- <div class="outside-link"><a href="https://github.com/vueComponent/ant-design" target="_blank">vue-antd-ui - Ant Design of Vue.js 2.5.0+</a></div>
|
||||
|
||||
## Who's using Ant Design
|
||||
|
||||
|
@ -32,6 +32,7 @@ title: 介绍
|
||||
- <div class="outside-link"><a href="https://github.com/priornix/antizer" target="_blank">antizer (ClojureScript)</a></div>
|
||||
- <div class="outside-link"><a href="https://github.com/idcos/antd-ember" target="_blank">antd-ember</a></div>
|
||||
- <div class="outside-link"><a href="https://github.com/zzuu666/antue" target="_blank">antue (vue)</a></div>
|
||||
- <div class="outside-link"><a href="https://github.com/vueComponent/ant-design" target="_blank">vue-antd-ui - Ant Design of Vue.js 2.5.0+</a></div>
|
||||
|
||||
## 谁在使用
|
||||
|
||||
|
@ -32,6 +32,7 @@ ReactDOM.render(
|
||||
- 爱 🐱。
|
||||
- 岗位职责:
|
||||
- 参与金融云、数据服务、人工智能以及金融核心等业务领域的设计工作;
|
||||
- 参与[语雀](https://yuque.com/)、[云凤蝶](http://www.yunfengdie.com/intro)等创新产品的设计工作;
|
||||
- 参与 Ant Design 的打磨,将其建设成全球卓越的设计体系。
|
||||
|
||||
## 前端工程师
|
||||
|
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.1",
|
||||
"title": "Ant Design",
|
||||
"description": "An enterprise-class UI design language and React-based implementation",
|
||||
"homepage": "http://ant.design/",
|
||||
@ -66,7 +66,7 @@
|
||||
"rc-pagination": "~1.16.1",
|
||||
"rc-progress": "~2.2.2",
|
||||
"rc-rate": "~2.4.0",
|
||||
"rc-select": "~8.0.1",
|
||||
"rc-select": "~8.0.7",
|
||||
"rc-slider": "~8.6.0",
|
||||
"rc-steps": "~3.1.0",
|
||||
"rc-switch": "~1.6.0",
|
||||
@ -141,13 +141,13 @@
|
||||
"rc-queue-anim": "^1.4.1",
|
||||
"rc-scroll-anim": "^2.2.1",
|
||||
"rc-tween-one": "^1.7.2",
|
||||
"react": "^16.0.0",
|
||||
"react": "^16.3.2",
|
||||
"react-color": "^2.11.7",
|
||||
"react-copy-to-clipboard": "^5.0.0",
|
||||
"react-dnd": "^2.5.4",
|
||||
"react-dnd-html5-backend": "^2.5.4",
|
||||
"react-document-title": "^2.0.1",
|
||||
"react-dom": "^16.0.0",
|
||||
"react-dom": "^16.3.2",
|
||||
"react-github-button": "^0.1.1",
|
||||
"react-infinite-scroller": "^1.0.15",
|
||||
"react-intl": "^2.0.1",
|
||||
@ -163,7 +163,7 @@
|
||||
"stylelint": "9.2.0",
|
||||
"stylelint-config-standard": "^18.0.0",
|
||||
"typescript": "~2.8.1",
|
||||
"unified": "^6.1.5",
|
||||
"unified": "^7.0.0",
|
||||
"values.js": "^1.0.3",
|
||||
"xhr2": "^0.1.3"
|
||||
},
|
||||
@ -194,7 +194,7 @@
|
||||
"pre-publish": "npm run test-all && node ./scripts/prepub",
|
||||
"authors": "git log --format='%aN <%aE>' | sort -u | grep -v 'users.noreply.github.com' | grep -v 'gitter.im' | grep -v '.local>' | grep -v 'alibaba-inc.com' | grep -v 'alipay.com' | grep -v 'taobao.com' > AUTHORS.txt",
|
||||
"lint-staged": "lint-staged",
|
||||
"lint-staged:ts": "tsc && node node_modules/tslint/bin/tslint -c node_modules/antd-tools/lib/tslint.json",
|
||||
"lint-staged:ts": "tsc && node node_modules/tslint/bin/tslint",
|
||||
"lint-staged:es": "eslint ./.eslintrc.js ./webpack.config.js",
|
||||
"lint-staged:demo": "cross-env RUN_ENV=DEMO eslint --ext '.md'"
|
||||
},
|
||||
|
@ -27,7 +27,6 @@ function getStyle() {
|
||||
#header #logo {
|
||||
padding: 0;
|
||||
}
|
||||
#header .ant-row > div:last-child .ant-select,
|
||||
#header .ant-row > div:last-child .ant-menu,
|
||||
#header .nav-phone-icon {
|
||||
display: none;
|
||||
|
5
tslint.json
Normal file
5
tslint.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": [
|
||||
"./node_modules/antd-tools/lib/tslint.json"
|
||||
]
|
||||
}
|
6
typings/custom-typings.d.ts
vendored
6
typings/custom-typings.d.ts
vendored
@ -92,10 +92,10 @@ declare module "*.json" {
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module "prop-types"
|
||||
declare module "prop-types";
|
||||
|
||||
declare module "lodash/debounce"
|
||||
declare module "lodash/debounce";
|
||||
|
||||
declare module "lodash/uniqBy"
|
||||
|
||||
declare module 'intersperse';
|
||||
declare module 'intersperse';
|
||||
|
Loading…
Reference in New Issue
Block a user