Skip to content

Commit

Permalink
feat(Input): 增加数字输入框增量设置和超出警告功能 (#748)
Browse files Browse the repository at this point in the history
  • Loading branch information
nullptr-z committed Apr 7, 2022
1 parent b8cf088 commit 8fd6ce7
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 23 deletions.
66 changes: 52 additions & 14 deletions packages/react-input/README.md
Expand Up @@ -35,16 +35,48 @@ ReactDOM.render(<Demo />, _mount_);
import ReactDOM from 'react-dom';
import { InputNumber } from 'uiw';

const Demo = () => (
<div>
<InputNumber
placeholder="请输入内容"
style={{ maxWidth: 200 }}
min={1}
max={10}
/>
</div>
);
const Demo = () => {

return(
<div>
<Row gutter={10}>
<Col fixed>
<InputNumber
placeholder="请输入内容"
style={{ width: 200 }}
/>
</Col>
<Col fixed>限制大小</Col>
<Col fixed>
<InputNumber
placeholder="请输入内容"
style={{ width: 200 }}
min={1}
max={10}
/>
</Col>
<Col fixed>超出限界警告</Col>
<Col fixed>
<InputNumber
placeholder="请输入内容"
style={{ width: 200 }}
min={1}
max={10}
overLimitColor={'red'}
/>
</Col>
<Col fixed>设置步涨值</Col>
<Col fixed>
<InputNumber
placeholder="请输入内容"
style={{ width: 200 }}
step={5}
/>
</Col>
</Row>
</div>
)
};
ReactDOM.render(<Demo />, _mount_);
```

Expand Down Expand Up @@ -410,17 +442,23 @@ ReactDOM.render(<Demo />, _mount_);

## Input

| 参数 | 说明 | 类型 | 默认值 |
|--------- |-------- |--------- |-------- |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|--------- |-------- |--------- |-------- |-------- |
| value | 绑定值 | String | - |
| disabled | 禁用输入框 | Boolean | `false` |
| preIcon | 输入框``面放置图标 | String/ReactNode | - |
| addonAfter | 带标签的 input,设置后置标签 | String/ReactNode | - |
| size | 指定输入框的尺寸,除了默认的大小外,还提供了 `large``small``default` 三种尺寸。 | String | - |
| inputStyle | 传递给input的样式,在需要动态设置样式场景下使用 | Object | - | v4.18.2 |

## InputNumber
在v4.18.2中增加

| 参数 | 说明 | 类型 | 默认值 | 版本 |
|--------- |-------- |--------- |-------- |-------- |
| min | 最小值 | Number | - | v4.18.2 |
| max | 最大值 | Number | - | v4.18.2 |
| min | 最小值 | Number | - |
| max | 最大值 | Number | - |
| step | 设置步长值 | Number | - |
| overLimitColor | 允许超出`min`,`max`限制, 使用该警告色显示 | String | - |

更多属性文档请参考 Input。
52 changes: 44 additions & 8 deletions packages/react-input/src/InputNumber.tsx
@@ -1,25 +1,61 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useMemo } from 'react';
import Input, { InputProps } from './';

interface InputNumberProps extends InputProps {
min?: number;
max?: number;
step?: number;
overLimitColor?: string;
formatter?: (value: number) => string;
parser?: (value: number) => number;
keyboard?: boolean;
}

export default React.forwardRef<HTMLInputElement, InputNumberProps>((props, ref) => {
const { min, max, ...inputProps } = props;
const {
className,
min,
max,
step,
overLimitColor,
keyboard = false,
formatter,
prefixCls = 'w-input-number',
...otherProps
} = props;

const [value, valueSet] = useState(props.value || 0);
const value = useMemo(() => Number.parseFloat((props.value || 0)?.toString()), [props.value]);
const [isOverLimit, isOverLimitSet] = useState(overLimitComp(value));

function overLimitComp(value: number) {
if (typeof min === 'number' && value < min) return true;
if (typeof max === 'number' && value > max) return true;
return false;
}

const onChange = (v: React.ChangeEvent<HTMLInputElement>) => {
const parseValue = Number.parseInt(v.target.value);
if (typeof min === 'number' && parseValue < min) return;
if (typeof max === 'number' && parseValue > max) return;
const isOverLimit = overLimitComp(Number.parseFloat(v.target.value));
isOverLimitSet(isOverLimit);

valueSet(v.target.value);
props.onChange?.(v);
};

return <Input {...inputProps} value={value} onChange={onChange} type="number" />;
const overLimitProps = useMemo(() => {
if (!overLimitColor) return { min, max };
}, []);

const cls = [prefixCls, className].filter(Boolean).join(' ').trim();
const inputStyle = useMemo(() => (isOverLimit ? { color: overLimitColor?.toString() } : undefined), [isOverLimit]);

return (
<Input
{...otherProps}
className={cls}
type="number"
inputStyle={inputStyle}
onChange={onChange}
step={step}
{...overLimitProps}
/>
);
});
11 changes: 10 additions & 1 deletion packages/react-input/src/index.tsx
Expand Up @@ -9,6 +9,7 @@ export interface InputProps extends IProps, Omit<HTMLInputProps, 'size'> {
preIcon?: IconProps['type'];
addonAfter?: React.ReactNode;
size?: 'large' | 'default' | 'small';
inputStyle?: React.CSSProperties;
}

export default React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
Expand All @@ -20,6 +21,7 @@ export default React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
type = 'text',
preIcon = null,
addonAfter,
inputStyle,
...otherProps
} = props;
const inputRef = React.useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -51,7 +53,14 @@ export default React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
return (
<div className={cls} style={style}>
<Icon type={preIcon} />
<input ref={inputRef} type={type} autoComplete="off" {...otherProps} className={`${prefixCls}-inner`} />
<input
ref={inputRef}
type={type}
autoComplete="off"
{...otherProps}
style={inputStyle}
className={`${prefixCls}-inner`}
/>
{addonAfter && (
<span className={`${prefixCls}-addon-after`} ref={addonRef}>
{addonAfter}
Expand Down

0 comments on commit 8fd6ce7

Please sign in to comment.