diff --git a/packages/client/src/schemas/database-field/interfaces/percent.ts b/packages/client/src/schemas/database-field/interfaces/percent.ts index 1fd1b07225..d535bb4b66 100644 --- a/packages/client/src/schemas/database-field/interfaces/percent.ts +++ b/packages/client/src/schemas/database-field/interfaces/percent.ts @@ -18,6 +18,7 @@ export const percent: ISchema = { 'x-component-props': { stringMode: true, step: '0', + addonAfter: '%', }, 'x-decorator': 'FormItem', 'x-designable-bar': 'InputNumber.DesignableBar', diff --git a/packages/client/src/schemas/input-number/index.md b/packages/client/src/schemas/input-number/index.md index c97b861b43..26238f0cad 100644 --- a/packages/client/src/schemas/input-number/index.md +++ b/packages/client/src/schemas/input-number/index.md @@ -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 ( + + ); +}; +``` + +### 精度 + +```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 ( + + ); +}; +``` + +### 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: '后缀', }, }, } diff --git a/packages/client/src/schemas/input-number/index.tsx b/packages/client/src/schemas/input-number/index.tsx index ab23fa4f93..e5e8998d84 100644 --- a/packages/client/src/schemas/input-number/index.tsx +++ b/packages/client/src/schemas/input-number/index.tsx @@ -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 = ; + if (!addonBefore && !addonAfter) { + return content; + } + return ( +
+ {addonBefore && ( +
{addonBefore}
+ )} + {content} + {addonAfter && ( +
{addonAfter}
+ )} +
+ ); + }, + mapReadPretty((props: any) => { + const { step, value, addonBefore, addonAfter } = props; + if (!isValid(value)) { + return null; + } + const precision = Math.max( + getNumberPrecision(String(value)), + getNumberPrecision(step), + ); + return ( +
+ {addonBefore} + {toFixed(String(value), '.', precision)} + {addonAfter} +
+ ); + }), +); + +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; diff --git a/packages/client/src/schemas/input-number/style.less b/packages/client/src/schemas/input-number/style.less new file mode 100644 index 0000000000..6ba9db9f2c --- /dev/null +++ b/packages/client/src/schemas/input-number/style.less @@ -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; + } + } +} \ No newline at end of file