merge feature into master-to-merge-feature

This commit is contained in:
afc163 2020-08-05 14:49:10 +08:00
commit 45cbbd6034
33 changed files with 936 additions and 29 deletions

View File

@ -2211,6 +2211,349 @@ exports[`renders ./components/badge/demo/ribbon-debug.md correctly 1`] = `
</div>
`;
exports[`renders ./components/badge/demo/size.md correctly 1`] = `
Array [
<span
class="ant-badge"
>
<a
class="head-example"
href="#"
/>
<sup
class="ant-scroll-number ant-badge-count"
data-show="true"
title="5"
>
<span
class="ant-scroll-number-only"
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit current"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
</span>
</sup>
</span>,
<span
class="ant-badge"
>
<a
class="head-example"
href="#"
/>
<sup
class="ant-scroll-number ant-badge-count ant-badge-count-sm"
data-show="true"
title="5"
>
<span
class="ant-scroll-number-only"
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit current"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
</span>
</sup>
</span>,
]
`;
exports[`renders ./components/badge/demo/status.md correctly 1`] = `
<div>
<span

View File

@ -65,6 +65,343 @@ exports[`Badge badge should support float number 2`] = `
</Badge>
`;
exports[`Badge render Badge size when contains children 1`] = `
Array [
<span
class="ant-badge"
>
<a />
<sup
class="ant-scroll-number ant-badge-count"
data-show="true"
title="5"
>
<span
class="ant-scroll-number-only"
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit current"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
</span>
</sup>
</span>,
<span
class="ant-badge"
>
<a />
<sup
class="ant-scroll-number ant-badge-count ant-badge-count-sm"
data-show="true"
title="5"
>
<span
class="ant-scroll-number-only"
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit current"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
<p
class="ant-scroll-number-only-unit"
>
0
</p>
<p
class="ant-scroll-number-only-unit"
>
1
</p>
<p
class="ant-scroll-number-only-unit"
>
2
</p>
<p
class="ant-scroll-number-only-unit"
>
3
</p>
<p
class="ant-scroll-number-only-unit"
>
4
</p>
<p
class="ant-scroll-number-only-unit"
>
5
</p>
<p
class="ant-scroll-number-only-unit"
>
6
</p>
<p
class="ant-scroll-number-only-unit"
>
7
</p>
<p
class="ant-scroll-number-only-unit"
>
8
</p>
<p
class="ant-scroll-number-only-unit"
>
9
</p>
</span>
</sup>
</span>,
]
`;
exports[`Badge render Badge status/color when contains children 1`] = `
Array [
<span

View File

@ -140,6 +140,20 @@ describe('Badge', () => {
);
expect(wrapper).toMatchSnapshot();
});
it('render Badge size when contains children', () => {
const wrapper = render(
<>
<Badge size="default" count={5}>
<a />
</Badge>
<Badge size="small" count={5}>
<a />
</Badge>
</>,
);
expect(wrapper).toMatchSnapshot();
});
});
describe('Ribbon', () => {

View File

@ -0,0 +1,30 @@
---
order: 9
title:
zh-CN: 大小
en-US: Size
---
## zh-CN
可以设置有数字徽标的大小。
## en-US
Set size of numeral Badge.
```jsx
import { Badge } from 'antd';
ReactDOM.render(
<>
<Badge size="default" count={5}>
<a href="#" className="head-example" />
</Badge>
<Badge size="small" count={5}>
<a href="#" className="head-example" />
</Badge>
</>,
mountNode,
);
```

View File

@ -24,6 +24,7 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
| overflowCount | Max count to show | number | 99 | |
| showZero | Whether to show badge when `count` is zero | boolean | false | |
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| size | If `count` is set, `size` sets the size of badge | `default` \| `small` | - | 4.6.0 |
| text | If `status` is set, `text` sets the display text of the status `dot` | ReactNode | - | |
| title | Text to show when hovering over the badge | string | - | |

View File

@ -30,6 +30,7 @@ export interface BadgeProps {
status?: PresetStatusColorType;
color?: LiteralUnion<PresetColorType, string>;
text?: React.ReactNode;
size?: 'default' | 'small';
offset?: [number | string, number | string];
title?: string;
}
@ -44,6 +45,7 @@ const Badge: CompoundedComponent = ({
count = null,
overflowCount = 99,
dot = false,
size = 'default',
title,
offset,
style,
@ -140,6 +142,7 @@ const Badge: CompoundedComponent = ({
const scrollNumberCls = classNames({
[`${prefixCls}-dot`]: bDot,
[`${prefixCls}-count`]: !bDot,
[`${prefixCls}-count-sm`]: size === 'small',
[`${prefixCls}-multiple-words`]:
!bDot && count && count.toString && count.toString().length > 1,
[`${prefixCls}-status-${status}`]: !!status,

View File

@ -25,6 +25,7 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/6%26GF9WHwvY/Badge.svg
| overflowCount | 展示封顶的数字值 | number | 99 | |
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false | |
| status | 设置 Badge 为状态点 | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| size | 在设置了 `count` 的前提下有效,设置小圆点的大小 | `default` \| `small` | - | 4.6.0 |
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | ReactNode | - | |
| title | 设置鼠标放在状态点上时显示的文字 | string | - | |

View File

@ -32,6 +32,15 @@
}
}
&-count-sm {
min-width: @badge-height-sm;
height: @badge-height-sm;
padding: 0;
font-size: @badge-font-size-sm;
line-height: @badge-height-sm;
border-radius: @badge-height-sm / 2;
}
&-multiple-words {
padding: 0 8px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -12,7 +12,7 @@ import SizeContext, { SizeType, SizeContextProvider } from '../config-provider/S
export type FormLayout = 'horizontal' | 'inline' | 'vertical';
export interface FormProps extends Omit<RcFormProps, 'form'> {
export interface FormProps<Values = any> extends Omit<RcFormProps<Values>, 'form'> {
prefixCls?: string;
hideRequiredMark?: boolean;
colon?: boolean;
@ -21,7 +21,7 @@ export interface FormProps extends Omit<RcFormProps, 'form'> {
labelAlign?: FormLabelAlign;
labelCol?: ColProps;
wrapperCol?: ColProps;
form?: FormInstance;
form?: FormInstance<Values>;
size?: SizeType;
scrollToFirstError?: boolean;
}
@ -105,7 +105,9 @@ const InternalForm: React.ForwardRefRenderFunction<unknown, FormProps> = (props,
);
};
const Form = React.forwardRef<FormInstance, FormProps>(InternalForm);
const Form = React.forwardRef<FormInstance, FormProps>(InternalForm) as <Values = any>(
props: React.PropsWithChildren<FormProps<Values>> & { ref?: React.Ref<FormInstance<Values>> },
) => React.ReactElement;
export { useForm, List, FormInstance };

View File

@ -1,7 +1,12 @@
import * as React from 'react';
import Form from '..';
import Form, { FormInstance } from '..';
import Input from '../../input';
interface FormValues {
username?: string;
path1?: { path2?: number };
}
describe('Form.typescript', () => {
it('Form.Item', () => {
const form = (
@ -14,4 +19,52 @@ describe('Form.typescript', () => {
expect(form).toBeTruthy();
});
describe('generic', () => {
it('hooks', () => {
const Demo = () => {
const [form] = Form.useForm<FormValues>();
form.setFieldsValue({ path1: { path2: 2333 } });
return (
<Form
form={form}
onFinish={values => {
expect(values).toBeTruthy();
expect(values.username).toBeTruthy();
expect(values.path1?.path2).toBeTruthy();
}}
/>
);
};
expect(Demo).toBeTruthy();
});
it('ref', () => {
class Demo extends React.Component {
formRef = React.createRef<FormInstance<FormValues>>();
componentDidMount() {
this.formRef.current?.setFieldsValue({ path1: { path2: 233 } });
}
render() {
return (
<Form
ref={this.formRef}
onFinish={values => {
expect(values).toBeTruthy();
expect(values.username).toBeTruthy();
expect(values.path1?.path2).toBeTruthy();
}}
/>
);
}
}
expect(Demo).toBeTruthy();
});
});
});

View File

@ -4,7 +4,7 @@ import scrollIntoView from 'scroll-into-view-if-needed';
import { ScrollOptions, NamePath, InternalNamePath } from '../interface';
import { toArray, getFieldId } from '../util';
export interface FormInstance extends RcFormInstance {
export interface FormInstance<Values = any> extends RcFormInstance<Values> {
scrollToField: (name: NamePath, options?: ScrollOptions) => void;
/** This is an internal usage. Do not use in your prod */
__INTERNAL__: {
@ -21,11 +21,11 @@ function toNamePathStr(name: NamePath) {
return namePath.join('_');
}
export default function useForm(form?: FormInstance): [FormInstance] {
export default function useForm<Values = any>(form?: FormInstance<Values>): [FormInstance<Values>] {
const [rcForm] = useRcForm();
const itemsRef = useRef<Record<string, React.ReactElement>>({});
const wrapForm: FormInstance = useMemo(
const wrapForm: FormInstance<Values> = useMemo(
() =>
form || {
...rcForm,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -18,6 +18,7 @@ When a numeric value needs to be provided.
| autoFocus | If get focus when component mounted | boolean | false |
| defaultValue | The initial value | number | - |
| disabled | If disable the input | boolean | false |
| readOnly | If readonly the input | boolean | false |
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - |
| max | The max value | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) |
| min | The min value | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) |

View File

@ -22,6 +22,7 @@ export interface InputNumberProps
tabIndex?: number;
onChange?: (value: number | string | undefined) => void;
disabled?: boolean;
readOnly?: boolean;
size?: SizeType;
formatter?: (value: number | string | undefined) => string;
parser?: (displayValue: string | undefined) => number | string;
@ -37,7 +38,13 @@ export interface InputNumberProps
const InputNumber = React.forwardRef<unknown, InputNumberProps>((props, ref) => {
const renderInputNumber = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { className, size: customizeSize, prefixCls: customizePrefixCls, ...others } = props;
const {
className,
size: customizeSize,
prefixCls: customizePrefixCls,
readOnly,
...others
} = props;
const prefixCls = getPrefixCls('input-number', customizePrefixCls);
const upIcon = <UpOutlined className={`${prefixCls}-handler-up-inner`} />;
const downIcon = <DownOutlined className={`${prefixCls}-handler-down-inner`} />;
@ -51,6 +58,7 @@ const InputNumber = React.forwardRef<unknown, InputNumberProps>((props, ref) =>
[`${prefixCls}-lg`]: mergeSize === 'large',
[`${prefixCls}-sm`]: mergeSize === 'small',
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-readonly`]: readOnly,
},
className,
);
@ -62,6 +70,7 @@ const InputNumber = React.forwardRef<unknown, InputNumberProps>((props, ref) =>
upHandler={upIcon}
downHandler={downIcon}
prefixCls={prefixCls}
readOnly={readOnly}
{...others}
/>
);

View File

@ -21,6 +21,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
| autoFocus | 自动获取焦点 | boolean | false |
| defaultValue | 初始值 | number | - |
| disabled | 禁用 | boolean | false |
| readOnly | 只读 | boolean | false |
| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - |
| max | 最大值 | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) |
| min | 最小值 | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) |

View File

@ -72,6 +72,12 @@
}
}
&-readonly {
.@{input-number-prefix-cls}-handler-wrap {
display: none;
}
}
&-input {
width: 100%;
height: @input-height-base - 2px;

View File

@ -60,6 +60,7 @@ Select component to select value from options.
| virtual | Disable virtual scroll when set to false | boolean | true | 4.1.0 |
| onBlur | Called when blur | function | - | |
| onChange | Called when select an option or input value change | function(value, option:Option \| Array&lt;Option>) | - | |
| onClear | Called when clear | function | - | 4.6.0 |
| onDeselect | Called when a option is deselected, param is the selected option's value. Only called for multiple or tags, effective in multiple or tags mode only | function(string \| number \| LabeledValue) | - | |
| onFocus | Called when focus | function | - | |
| onInputKeyDown | Called when key pressed | function | - | |

View File

@ -61,6 +61,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
| virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |
| onBlur | 失去焦点时回调 | function | - | |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value, option:Option \| Array&lt;Option>) | - | |
| onClear | 清除内容时回调 | function | - | 4.6.0 |
| onDeselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(string \| number \| LabeledValue) | - | |
| onFocus | 获得焦点时回调 | function | - | |
| onInputKeyDown | 按键按下时回调 | function | - | |

View File

@ -47,3 +47,12 @@
@typography-title-margin-bottom
);
}
.typography-title-5() {
.typography-title(
@heading-5-size,
@typography-title-font-weight,
1.5,
@heading-color,
@typography-title-margin-bottom
);
}

View File

@ -164,7 +164,7 @@
@body-background: @black;
@component-background: #141414;
@text-color: fade(@white, 65%);
@text-color: fade(@white, 85%);
@text-color-secondary: fade(@white, 45%);
@text-color-inverse: @white;
@icon-color-hover: fade(@white, 75%);

View File

@ -50,7 +50,7 @@
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
@code-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
@text-color: fade(@black, 65%);
@text-color: fade(@black, 85%);
@text-color-secondary: fade(@black, 45%);
@text-color-inverse: @white;
@icon-color: inherit;
@ -69,6 +69,7 @@
@heading-2-size: ceil(@font-size-base * 2.14);
@heading-3-size: ceil(@font-size-base * 1.71);
@heading-4-size: ceil(@font-size-base * 1.42);
@heading-5-size: ceil(@font-size-base * 1.14);
// https://github.com/ant-design/ant-design/issues/20210
@line-height-base: 1.5715;
@border-radius-base: 2px;
@ -651,8 +652,10 @@
// Badge
// ---
@badge-height: 20px;
@badge-height-sm: 14px;
@badge-dot-size: 6px;
@badge-font-size: @font-size-sm;
@badge-font-size-sm: @font-size-sm;
@badge-font-weight: normal;
@badge-status-size: 6px;
@badge-text-color: @component-background;

View File

@ -8,6 +8,7 @@ import EditOutlined from '@ant-design/icons/EditOutlined';
import CheckOutlined from '@ant-design/icons/CheckOutlined';
import CopyOutlined from '@ant-design/icons/CopyOutlined';
import ResizeObserver from 'rc-resize-observer';
import { AutoSizeType } from 'rc-textarea/lib/ResizableTextArea';
import { ConfigConsumerProps, configConsumerProps, ConfigContext } from '../config-provider';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import devWarning from '../_util/devWarning';
@ -35,6 +36,8 @@ interface EditConfig {
editing?: boolean;
onStart?: () => void;
onChange?: (value: string) => void;
maxLength?: number;
autoSize?: boolean | AutoSizeType;
}
interface EllipsisConfig {
@ -402,6 +405,7 @@ class Base extends React.Component<InternalBlockProps, BaseState> {
renderEditInput() {
const { children, className, style } = this.props;
const { direction } = this.context;
const { maxLength, autoSize } = this.getEditable();
return (
<Editable
value={typeof children === 'string' ? children : ''}
@ -411,6 +415,8 @@ class Base extends React.Component<InternalBlockProps, BaseState> {
className={className}
style={style}
direction={direction}
maxLength={maxLength}
autoSize={autoSize}
/>
);
}

View File

@ -2,6 +2,7 @@ import * as React from 'react';
import classNames from 'classnames';
import KeyCode from 'rc-util/lib/KeyCode';
import EnterOutlined from '@ant-design/icons/EnterOutlined';
import { AutoSizeType } from 'rc-textarea/lib/ResizableTextArea';
import TextArea from '../input/TextArea';
interface EditableProps {
@ -13,6 +14,8 @@ interface EditableProps {
className?: string;
style?: React.CSSProperties;
direction?: 'ltr' | 'rtl';
maxLength?: number;
autoSize?: boolean | AutoSizeType;
}
interface EditableState {
@ -115,8 +118,15 @@ class Editable extends React.Component<EditableProps, EditableState> {
render() {
const { current } = this.state;
const { prefixCls, 'aria-label': ariaLabel, className, style, direction } = this.props;
const {
prefixCls,
'aria-label': ariaLabel,
className,
style,
direction,
maxLength,
autoSize,
} = this.props;
const textAreaClassName = classNames(prefixCls, className, `${prefixCls}-edit-content`, {
[`${prefixCls}-rtl`]: direction === 'rtl',
});
@ -124,6 +134,7 @@ class Editable extends React.Component<EditableProps, EditableState> {
<div className={textAreaClassName} style={style}>
<TextArea
ref={this.setTextarea}
maxLength={maxLength}
value={current}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
@ -132,7 +143,7 @@ class Editable extends React.Component<EditableProps, EditableState> {
onCompositionEnd={this.onCompositionEnd}
onBlur={this.onBlur}
aria-label={ariaLabel}
autoSize
autoSize={autoSize === undefined || autoSize}
/>
<EnterOutlined className={`${prefixCls}-edit-content-confirm`} />
</div>

View File

@ -3,7 +3,7 @@ import devWarning from '../_util/devWarning';
import Base, { BlockProps } from './Base';
import { tupleNum, Omit } from '../_util/type';
const TITLE_ELE_LIST = tupleNum(1, 2, 3, 4);
const TITLE_ELE_LIST = tupleNum(1, 2, 3, 4, 5);
export type TitleProps = Omit<BlockProps & { level?: typeof TITLE_ELE_LIST[number] }, 'strong'>;
@ -14,7 +14,11 @@ const Title: React.FC<TitleProps> = props => {
if (TITLE_ELE_LIST.indexOf(level) !== -1) {
component = `h${level}`;
} else {
devWarning(false, 'Typography.Title', 'Title only accept `1 | 2 | 3 | 4` as `level` value.');
devWarning(
false,
'Typography.Title',
'Title only accept `1 | 2 | 3 | 4 | 5` as `level` value. And `5` need 4.6.0+ version.',
);
component = 'h1';
}

View File

@ -361,6 +361,40 @@ Array [
</div>,
<div
class="ant-typography"
>
This is an editable text with limited length.
<div
aria-label="Edit"
class="ant-typography-edit"
role="button"
style="border:0;background:transparent;padding:0;line-height:inherit;display:inline-block"
tabindex="0"
>
<span
aria-label="edit"
class="anticon anticon-edit"
role="button"
>
<svg
aria-hidden="true"
class=""
data-icon="edit"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z"
/>
</svg>
</span>
</div>
</span>,
<br />,
<span
class="ant-typography"
>
This is a copyable text.
<div
@ -896,5 +930,10 @@ Array [
>
h4. Ant Design
</h4>,
<h5
class="ant-typography"
>
h5. Ant Design
</h5>,
]
`;

View File

@ -65,7 +65,7 @@ describe('Typography', () => {
mount(<Title level={false} />);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Typography.Title] Title only accept `1 | 2 | 3 | 4` as `level` value.',
'Warning: [antd: Typography.Title] Title only accept `1 | 2 | 3 | 4 | 5` as `level` value. And `5` need 4.6.0+ version.',
);
});
});

View File

@ -22,6 +22,7 @@ const { Paragraph } = Typography;
class Demo extends React.Component {
state = {
str: 'This is an editable text.',
lengthLimitedStr: 'This is an editable text with limited length.',
};
onChange = str => {
@ -29,10 +30,24 @@ class Demo extends React.Component {
this.setState({ str });
};
onLengthLimitedStrChange = lengthLimitedStr => {
this.setState({ lengthLimitedStr });
};
render() {
const { lengthLimitedStr } = this.state;
return (
<>
<Paragraph editable={{ onChange: this.onChange }}>{this.state.str}</Paragraph>
<Paragraph
editable={{
onChange: this.onLengthLimitedStrChange,
maxLength: 50,
autoSize: { maxRows: 5, minRows: 3 },
}}
>
{lengthLimitedStr}
</Paragraph>
<Paragraph copyable>This is a copyable text.</Paragraph>
<Paragraph copyable={{ text: 'Hello, Ant Design!' }}>Replace copy text.</Paragraph>
<Paragraph copyable={{ icon: <SmileOutlined /> }}>Custom icon.</Paragraph>

View File

@ -24,6 +24,7 @@ ReactDOM.render(
<Title level={2}>h2. Ant Design</Title>
<Title level={3}>h3. Ant Design</Title>
<Title level={4}>h4. Ant Design</Title>
<Title level={5}>h5. Ant Design</Title>
</>,
mountNode,
);

View File

@ -23,7 +23,7 @@ Basic text writing, including headings, body text, lists, and more.
| copyable | Whether to be copyable, customize it via setting an object | boolean \| { text: string, onCopy: function, icon: ReactNode, tooltips: \[ReactNode, ReactNode\] } | false | icon and tooltips: 4.4.0 |
| delete | Deleted line style | boolean | false | |
| disabled | Disabled content | boolean | false | |
| editable | If editable. Can control edit state when is object | boolean \| { editing: boolean, onStart: function, onChange: function(string) } | false | |
| editable | If editable. Can control edit state when is object | boolean \| { editing: boolean, maxLength: number, autoSize: true \| false \| { minRows: number, maxRows: number }, onStart: function, onChange: function(string) } | false | maxLength and autoSize: 4.6.0 |
| ellipsis | Display ellipsis when text overflows. Should set width when ellipsis needed | boolean | false | |
| mark | Marked style | boolean | false | |
| keyboard | Keyboard style | boolean | false | 4.3.0 |
@ -40,9 +40,9 @@ Basic text writing, including headings, body text, lists, and more.
| copyable | Whether to be copyable, customize it via setting an object | boolean \| { text: string, onCopy: function, icon: ReactNode, tooltips: \[ReactNode, ReactNode\] } | false | icon and tooltips: 4.4.0 |
| delete | Deleted line style | boolean | false | |
| disabled | Disabled content | boolean | false | |
| editable | If editable. Can control edit state when is object | boolean \| { editing: boolean, onStart: function, onChange: function(string) } | false | |
| editable | If editable. Can control edit state when is object | boolean \| { editing: boolean, maxLength: number, autoSize: true \| false \| { minRows: number, maxRows: number }, onStart: function, onChange: function(string) } | false | maxLength and autoSize: 4.6.0 |
| ellipsis | Display ellipsis when text overflows. Can configure rows and expandable by using object | boolean \| { rows: number, expandable: boolean, onExpand: function(event), onEllipsis: function(ellipsis) } | false | onEllipsis: 4.2.0 |
| level | Set content importance. Match with `h1`, `h2`, `h3`, `h4` | number: 1, 2, 3, 4 | 1 | |
| level | Set content importance. Match with `h1`, `h2`, `h3`, `h4`, `h5` | number: 1, 2, 3, 4, 5 | 1 | 5: 4.6.0 |
| mark | Marked style | boolean | false | |
| underline | Underlined style | boolean | false | |
| onChange | Trigger when user edits the content | function(string) | - | |
@ -56,7 +56,7 @@ Basic text writing, including headings, body text, lists, and more.
| copyable | Whether to be copyable, customize it via setting an object | boolean \| { text: string, onCopy: function, icon: ReactNode, tooltips: \[ReactNode, ReactNode\] } | false | icon and tooltips: 4.4.0 |
| delete | Deleted line style | boolean | false | |
| disabled | Disabled content | boolean | false | |
| editable | If editable. Can control edit state when is object | boolean \| { editing: boolean, onStart: function, onChange: function(string) } | false | |
| editable | If editable. Can control edit state when is object | boolean \| { editing: boolean, maxLength: number, autoSize: true \| false \| { minRows: number, maxRows: number }, onStart: function, onChange: function(string) } | false | maxLength and autoSize: 4.6.0 |
| ellipsis | Display ellipsis when text overflows. Can configure rows expandable and suffix by using object | boolean \| { rows: number, expandable: boolean, suffix: string, symbol: React.ReactNode, onExpand: function(event), onEllipsis: function(ellipsis) } | false | onEllipsis: 4.2.0 |
| mark | Marked style | boolean | false | |
| underline | Underlined style | boolean | false | |

View File

@ -24,7 +24,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
| copyable | 是否可拷贝,为对象时可进行各种自定义 | boolean \| { text: string, onCopy: function, icon: ReactNode, tooltips: \[ReactNode, ReactNode\] } | false | `icon``tooltips``4.4.0` 支持 |
| delete | 添加删除线样式 | boolean | false | |
| disabled | 禁用文本 | boolean | false | |
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, onStart: function, onChange: function(string) } | false | |
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, maxLength: number, autoSize: true \| false \| { minRows: number, maxRows: number }, onStart: function, onChange: function(string) } | false | maxLength and autoSize: 4.6.0 |
| ellipsis | 设置自动溢出省略,需要设置元素宽度 | boolean | false | |
| mark | 添加标记样式 | boolean | false | |
| keyboard | 添加键盘样式 | boolean | false | 4.3.0 |
@ -40,9 +40,9 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
| copyable | 是否可拷贝,为对象时可进行各种自定义 | boolean \| { text: string, onCopy: function, icon: ReactNode, tooltips: \[ReactNode, ReactNode\] } | false | `icon``tooltips``4.4.0` 支持 |
| delete | 添加删除线样式 | boolean | false | |
| disabled | 禁用文本 | boolean | false | |
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, onStart: function, onChange: function(string) } | false | |
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, maxLength: number, autoSize: true \| false \| { minRows: number, maxRows: number }, onStart: function, onChange: function(string) } | false | maxLength and autoSize: 4.6.0 |
| ellipsis | 自动溢出省略,为对象时可设置省略行数与是否可展开等 | boolean \| { rows: number, expandable: boolean, onExpand: function(event), onEllipsis: function(ellipsis) } | false | onEllipsis: 4.2.0 |
| level | 重要程度,相当于 `h1`、`h2`、`h3`、`h4` | number: 1, 2, 3, 4 | 1 | |
| level | 重要程度,相当于 `h1`、`h2`、`h3`、`h4`、`h5` | number: 1, 2, 3, 4, 5 | 1 | 5: 4.6.0 |
| mark | 添加标记样式 | boolean | false | |
| underline | 添加下划线样式 | boolean | false | |
| onChange | 当用户提交编辑内容时触发 | function(string) | - | |
@ -56,7 +56,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
| copyable | 是否可拷贝,为对象时可进行各种自定义 | boolean \| { text: string, onCopy: function, icon: ReactNode, tooltips: \[ReactNode, ReactNode\] } | false | `icon``tooltips``4.4.0` 支持 |
| delete | 添加删除线样式 | boolean | false | |
| disabled | 禁用文本 | boolean | false | |
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, onStart: function, onChange: function(string) } | false | |
| editable | 是否可编辑,为对象时可对编辑进行控制 | boolean \| { editing: boolean, maxLength: number, autoSize: true \| false \| { minRows: number, maxRows: number }, onStart: function, onChange: function(string) } | false | maxLength and autoSize: 4.6.0 |
| ellipsis | 自动溢出省略,为对象时可设置省略行数、是否可展开、添加后缀等 | boolean \| { rows: number, expandable: boolean, suffix: string, symbol: React.ReactNode, onExpand: function(event), onEllipsis: function(ellipsis) } | false | onEllipsis: 4.2.0 |
| mark | 添加标记样式 | boolean | false | |
| underline | 添加下划线样式 | boolean | false | |

View File

@ -48,11 +48,16 @@
h4 {
.typography-title-4();
}
h5&,
h5 {
.typography-title-5();
}
h1&,
h2&,
h3&,
h4& {
h4&,
h5& {
.@{typography-prefix-cls} + & {
margin-top: @typography-title-margin-top;
}
@ -65,11 +70,13 @@
h1,
h2,
h3,
h4 {
h4,
h5 {
+ h1,
+ h2,
+ h3,
+ h4 {
+ h4,
+ h5 {
margin-top: @typography-title-margin-top;
}
}

View File

@ -123,7 +123,7 @@
"rc-dialog": "~8.1.0",
"rc-drawer": "~4.1.0",
"rc-dropdown": "~3.1.2",
"rc-field-form": "~1.8.0",
"rc-field-form": "~1.9.2",
"rc-input-number": "~6.0.0",
"rc-mentions": "~1.4.0",
"rc-menu": "~8.5.0",
@ -133,7 +133,7 @@
"rc-progress": "~3.0.0",
"rc-rate": "~2.8.2",
"rc-resize-observer": "^0.2.3",
"rc-select": "~11.0.10",
"rc-select": "~11.1.0",
"rc-slider": "~9.3.0",
"rc-steps": "~4.1.0",
"rc-switch": "~3.2.0",