Concis组件库封装——Input输入框
import React, { FC, useState, useMemo, memo } from 'react';
import { CloseOutlined, EyeOutlined, UpOutlined, DownOutlined } from '@ant-design/icons';
import style from './';
interface InputProps {
/**
* @description 自定义宽度
* @default 170px
*/
width?: string;
/**
* @description 自定义样式
* @default {}
*/
moreStyle?: object;
/**
* @description 输入框类型
* @default text
*/
type?: string;
/**
* @description 提示
* @default ''
*/
placeholder?: string;
/**
* @description 显示清空按钮
* @default false
*/
showClear?: boolean;
/**
* @description 显示密码切换按钮(需同时设置type="password")
* @default false
*/
showTogglePwd?: boolean;
/**
* @description 数字框最小值
* @default ''
*/
min?: number;
/**
* @description 数字框最大值
* @default ''
*/
max?: number;
/**
* @description 数字框递增/减值
* @default 1
*/
step?: number;
/**
* @description 输入框内容改变回调
*/
handleIptChange?: Function;
/**
* @description 数字框内容改变回调
*/
handleNumChange?: Function;
/**
* @description 默认内容
* @default ''
*/
defaultValue?: string;
}
const Input: FC<InputProps> = (props) => {
const {
width,
moreStyle,
type,
placeholder,
showClear,
showTogglePwd,
min,
max,
step,
handleIptChange,
handleNumChange,
defaultValue,
} = props;
const [iptValue, setIptValue] = useState<string | number>(defaultValue || '');
const [pwdIptState, setPwdIptState] = useState(true); //密码框切换状态
const changeIpt = (e: any) => {
//改变文本框
setIptValue(e.target.value);
if (handleIptChange) {
handleIptChange(e.target.value);
}
};
const blurIpt = (e: any) => {
//失去焦点
if (type === 'num' && Number(iptValue) == NaN) {
setIptValue('');
}
};
const addNum = () => {
//加
if (type === 'num' && Number(iptValue) == NaN) {
return setIptValue('');
}
const stepNum = step || 1;
if (step && max && Number(iptValue) + stepNum > max) {
handleNumChange && handleNumChange(max);
return setIptValue(max);
}
if (step && min && Number(iptValue) + stepNum < min) {
handleNumChange && handleNumChange(min);
return setIptValue(min);
}
handleNumChange && handleNumChange(Number(iptValue) + stepNum);
setIptValue(Number(iptValue) + stepNum);
};
const lowNum = () => {
//减
if (type === 'num' && Number(iptValue) == NaN) {
return setIptValue('');
}
const stepNum = step || 1;
if (step && min && Number(iptValue) - stepNum < min) {
handleNumChange && handleNumChange(min);
return setIptValue(min);
}
handleNumChange && handleNumChange(Number(iptValue) - stepNum);
setIptValue(Number(iptValue) - stepNum);
};
const iptType = useMemo(() => {
if (showTogglePwd && type === 'password') {
return pwdIptState ? 'password' : 'text';
}
return type || 'text';
}, [type, showTogglePwd, pwdIptState]);
const exticStyle = useMemo(() => {
let style = { width: '170px' };
if (width) {
style.width = width + 'px';
}
console.log({ ...style, ...moreStyle });
return { ...style, ...moreStyle };
}, [width, moreStyle]);
return (
<div className={style.box} style={{ width: width ? width + 'px' : '170px' }}>
<input
className={style.input}
style={exticStyle}
type={iptType}
placeholder={placeholder}
value={iptValue}
onChange={changeIpt}
onBlur={blurIpt}
/>
{
//可清除
(showClear && (
<CloseOutlined
style={{ position: 'absolute', right: '5px', fontSize: '12px', cursor: 'pointer' }}
onClick={() => setIptValue('')}
/>
)) ||
//密码框
(type === 'password' && showTogglePwd && (
<EyeOutlined
style={{ position: 'absolute', right: '5px', fontSize: '12px', cursor: 'pointer' }}
onClick={() => setPwdIptState(!pwdIptState)}
/>
)) ||
//数字框
(type === 'num' && (
<div className={style.numTags}>
<UpOutlined style={{ cursor: 'pointer', fontSize: '10px' }} onClick={addNum} />
<DownOutlined style={{ cursor: 'pointer', fontSize: '10px' }} onClick={lowNum} />
</div>
))
}
</div>
);
};
export default memo(Input);