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