选择器组件,文档如下: 组件封装代码如下:
import React, { FC, useMemo, createRef, useEffect, useState, useCallback, memo } from 'react';
import { DownOutlined, LoadingOutlined, CloseOutlined } from '@ant-design/icons';
import style from './index.module.less';
interface Options {
label: String | number;
value: String | number;
disabled?: Boolean;
}
interface SelectProps {
option: Array<Options>;
width?: Number;
placeholder?: String;
disabled?: Boolean;
loading?: Boolean;
showSearch?: Boolean;
clearable?: Boolean;
handleSelectCallback?: Function;
handleTextChange?: Function;
}
const Select: FC<SelectProps> = (props) => {
const {
option,
width,
placeholder,
disabled,
loading,
showSearch,
clearable,
handleSelectCallback,
handleTextChange,
} = props;
const [selected, setSelected] = useState<string | number | any>('');
const optionRef = createRef() as any;
useEffect(() => {
optionRef.current.style.height = `0px`;
}, []);
const ownsWidth = useMemo(() => {
if (width) {
return {
width: `${width}px`,
};
}
return {};
}, [width]);
const disabledStyle = useMemo(() => {
if (disabled) {
return {
cursor: 'not-allowed',
background: 'rgb(238, 238, 238)',
};
}
}, [disabled]);
const toggleOptions = (e: any) => {
e.stopPropagation();
if (disabled) return;
if (optionRef.current.style.height === '0px') {
if (showSearch) {
optionRef.current.style.height = `${inputFilterOtpions.length * 100}%`;
} else {
optionRef.current.style.height = `${option.length * 100}%`;
}
} else {
optionRef.current.style.height = '0px';
}
};
const changeOptions = (v: Options, e: any) => {
e.stopPropagation();
if (v.disabled) return;
optionRef.current.style.height = '0px';
setSelected(v.label);
if (handleSelectCallback) {
handleSelectCallback(v.value);
}
};
const inputFilterOtpions = useMemo(() => {
return option.filter((item) => {
return (item.label as string).includes(selected);
});
}, [option, selected]);
const handleInputChange = useCallback(
(e: any) => {
setSelected(e.target.value);
optionRef.current.style.height =
option.filter((item) => {
return (item.label as string).includes(e.target.value);
}).length *
100 +
'%';
if (handleTextChange) {
handleTextChange(e.target.value);
}
},
[selected],
);
return showSearch ? (
<>
<div className={style.select} style={{ ...ownsWidth, ...disabledStyle }}>
<div className={style.selected}>
<input
type="text"
className={style.selected}
value={selected}
placeholder={placeholder as string}
onClick={toggleOptions}
onChange={(e) => handleInputChange(e)}
/>
{clearable ? (
<CloseOutlined onClick={() => setSelected('')} />
) : (
<DownOutlined onClick={toggleOptions} />
)}
</div>
<div className={style.selectOptions} style={ownsWidth} ref={optionRef}>
{inputFilterOtpions.map((s) => {
return (
<div
key={s.label as any}
className={style.option}
style={
s.disabled ? { cursor: 'not-allowed', background: 'rgb(238, 238, 238)' } : {}
}
onClick={(e) => changeOptions(s as Options, e)}
>
{s.label}
</div>
);
})}
</div>
</div>
</>
) : (
<div className={style.select} style={{ ...ownsWidth, ...disabledStyle }}>
<div className={style.selected} onClick={toggleOptions}>
{selected ? (
<div className={style.size}>{selected}</div>
) : (
(placeholder && <div className={style.placeholder}>{placeholder}</div>) || <div />
)}
{loading ? <LoadingOutlined /> : <DownOutlined />}
</div>
<div className={style.selectOptions} style={ownsWidth} ref={optionRef}>
{option.map((s) => {
return (
<div
key={s.label as any}
className={style.option}
style={s.disabled ? { cursor: 'not-allowed', background: 'rgb(238, 238, 238)' } : {}}
onClick={(e) => changeOptions(s as Options, e)}
>
{s.label}
</div>
);
})}
</div>
</div>
);
};
export default memo(Select);
组件库线上地址:https://fengxinhhh.github.io/React-View-UI-fs/#/common/select 接下来会记录每一个组件…并且更新线上文档
|