precision, addonBefore and addonAfter for InputNumber

This commit is contained in:
chenos 2021-08-05 23:09:17 +08:00
parent 1ceb8b6006
commit b9b41139c9
4 changed files with 178 additions and 11 deletions

View File

@ -18,6 +18,7 @@ export const percent: ISchema = {
'x-component-props': {
stringMode: true,
step: '0',
addonAfter: '%',
},
'x-decorator': 'FormItem',
'x-designable-bar': 'InputNumber.DesignableBar',

View File

@ -86,8 +86,7 @@ const schema = {
'x-component': 'InputNumber',
'x-component-props': {
placeholder: 'please enter',
formatter: value => `${value}%`,
parser: value => value.replace('%', ''),
addonAfter: '%',
},
'x-reactions': {
target: 'read',
@ -106,8 +105,89 @@ const schema = {
'x-component': 'InputNumber',
'x-component-props': {
placeholder: 'please enter',
formatter: value => `${value}%`,
parser: value => value.replace('%', ''),
addonAfter: '%',
},
},
}
};
export default () => {
return (
<SchemaRenderer schema={schema} />
);
};
```
### 精度
```tsx
/**
* title: 精度
*/
import React from 'react';
import { SchemaRenderer } from '../';
const schema = {
type: 'object',
properties: {
input: {
type: 'number',
title: `编辑模式`,
'x-decorator': 'FormItem',
'x-component': 'InputNumber',
'x-component-props': {
placeholder: 'please enter',
stringMode: true,
step: '0.001',
},
'x-reactions': {
target: 'read',
fulfill: {
state: {
value: '{{$self.value}}',
},
},
},
},
read: {
type: 'number',
title: `阅读模式`,
'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-component': 'InputNumber',
'x-component-props': {
placeholder: 'please enter',
stringMode: true,
step: '0.001',
},
},
}
};
export default () => {
return (
<SchemaRenderer schema={schema} />
);
};
```
### addonBefore 和 addonAfter 支持
```tsx
import React from 'react';
import { SchemaRenderer } from '../';
const schema = {
type: 'object',
properties: {
input: {
type: 'number',
title: `数字`,
'x-component': 'InputNumber',
'x-component-props': {
placeholder: 'please enter',
addonBefore: '前缀',
addonAfter: '后缀',
},
},
}

View File

@ -1,10 +1,69 @@
import { connect, mapReadPretty } from '@formily/react'
import { InputNumber as AntdNumber } from 'antd'
import { Display } from '../display'
import React from 'react';
import { connect, mapReadPretty } from '@formily/react';
import { InputNumber as AntdNumber, Input, Button } from 'antd';
import { Display } from '../display';
import getMiniDecimal, { toFixed } from 'rc-input-number/lib/utils/MiniDecimal';
import { getNumberPrecision } from 'rc-input-number/lib/utils/numberUtil';
import { isValid } from '@formily/shared';
import cls from 'classnames';
import './style.less';
export const InputNumber = connect(
export const InputNumber: any = connect(
(props) => {
const { addonBefore, addonAfter, ...others } = props;
const content = <AntdNumber {...others} />;
if (!addonBefore && !addonAfter) {
return content;
}
return (
<div
className={cls('nb-input-number', {
'has-addon-before': !!addonBefore,
'has-addon-after': !!addonAfter,
})}
>
{addonBefore && (
<div className="ant-input-group-addon">{addonBefore}</div>
)}
{content}
{addonAfter && (
<div className="ant-input-group-addon">{addonAfter}</div>
)}
</div>
);
},
mapReadPretty((props: any) => {
const { step, value, addonBefore, addonAfter } = props;
if (!isValid(value)) {
return null;
}
const precision = Math.max(
getNumberPrecision(String(value)),
getNumberPrecision(step),
);
return (
<div>
{addonBefore}
{toFixed(String(value), '.', precision)}
{addonAfter}
</div>
);
}),
);
InputNumber.Percent = connect(
AntdNumber,
mapReadPretty(Display.InputNumber)
)
mapReadPretty((props: any) => {
const { step, value } = props;
if (!isValid(value)) {
return null;
}
return toFixed(
String(value),
'.',
Math.max(getNumberPrecision(String(value)), getNumberPrecision(step)),
);
}),
);
export default InputNumber
export default InputNumber;

View File

@ -0,0 +1,27 @@
.nb-input-number {
display: table;
width: 100%;
line-height: 32px;
.ant-input-number {
width: 100%;
}
.ant-input-number,
.ant-input-group-addon {
display: table-cell;
}
.ant-input-group-addon {
vertical-align: middle;
}
&.has-addon-before {
.ant-input-number {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
&.has-addon-after {
.ant-input-number {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
}