2024 / 1 / 3 日更新
// todo 组件只用于渲染 Form.Item 层 | 不包含 Form
// 调用示例
/*
label="项目名称"
name="projectName"
type="Input"
input_disabled={modalStateText === "edit"}
input_maxLength={64}
style={{ width: 240 }}
rules={[{ required: true, message: "请输入项目名称!" }]}
/>; */
import {
AutoComplete,
Button,
Cascader,
Checkbox,
DatePicker,
Form,
Input,
InputNumber,
InputRef,
QRCode,
Radio,
Select,
Slider,
Upload,
} from "antd";
import { Rule } from "antd/es/form";
import { SelectValue } from "antd/es/select";
import { RcFile } from "antd/es/upload";
import { Dayjs } from "dayjs";
import { ChangeEvent, KeyboardEvent } from "react";
const { RangePicker } = DatePicker;
type FormItemComponentType =
| "Upload"
| "Radio"
| "Input"
| "QRCode"
| "Slider"
| "Selector"
| "Cascader"
| "Checkbox"
| "DatePicker"
| "InputNumber"
| "RangePicker"
| "AutoComplete";
type CascaderOptionType = {
label: React.ReactNode;
value: string;
disabled?: boolean;
children?: Array;
};
type UploadType = {
file: RcFile;
data: any;
filename: string;
withCredentials: boolean;
action: string;
headers: { [key: string]: any };
method: string;
onSuccess: (response: any, file: RcFile) => void;
onError: (error: Error, response: any, file: RcFile) => void;
onProgress: (event: { percent: number }, file: RcFile) => void;
};
type GenericFormItemProps = {
type: FormItemComponentType;
label: string;
name: keyof T & string;
rules: Array;
style?: React.CSSProperties;
selector_showSearch?: boolean;
selector_placeholder?: string;
selector_options?: Array<{ value: string; label: string }>;
selector_allowClear?: boolean;
selector_disabled?: boolean;
select_onChange?: (
value: SelectValue,
option:
| { value: string; label: string }
| { value: string; label: string }[],
) => void;
input_ref?: React.RefObject;
input_value?: string;
input_border?: boolean;
input_disabled?: boolean;
input_maxLength?: number;
input_showCount?: boolean;
input_addonAfter?: string;
input_placeholder?: string;
input_defaultValue?: string;
input_prefix?: React.ReactNode;
input_suffix?: React.ReactNode;
input_onChange?: (e: ChangeEvent) => void;
input_onPressEnter?: (e: KeyboardEvent) => void;
date_placeholder?: string;
date_picker?: "time" | "date" | "week" | "month" | "quarter" | "year";
date_allowClear?: boolean;
date_autoFocus?: boolean;
date_bordered?: boolean;
date_disabled?: boolean;
date_showToday?: boolean;
date_value?: Dayjs;
date_defaultValue?: Dayjs;
date_disabledDate?: (currentDate: Dayjs) => boolean;
date_pickerOnChange?: (date: Dayjs | null, dateString: string) => void;
inputNumber_min?: number;
inputNumber_max?: number;
inputNumber_disabled?: boolean;
inputNumber_size?: "large" | "middle" | "small";
radio_options?: Array<{ value: string; label: string }>;
radio_value?: number;
radio_disabled?: boolean;
slider_min?: number;
slider_max?: number;
slider_disabled?: boolean;
slider_tooltip?: boolean;
autoComplete_placeholder?: string;
autoComplete_disabled?: boolean;
autoComplete_options?: Array>;
autoComplete_maxlength?: number;
cascader_options?: Array;
cascader_disabled?: boolean;
checkbox_options?: Array<{ value: string; label: string }>;
checkbox_disabled?: boolean;
QRCode_value?: string;
upload_accept?: string;
upload_fileList?: Array;
upload_button_title?: string;
upload_button_disabled?: boolean;
upload_showUploadList?: boolean;
upload_button_icon?: React.ReactNode;
upload_button_loading?: boolean;
upload_button_type?: "link" | "text" | "default" | "primary" | "dashed";
upload_customRequest?: (options: UploadType) => void;
};
const filterOption = (
input: string,
option?: { label: string; value: string | number },
): boolean => (option?.label ?? "").toLowerCase().includes(input.toLowerCase());
const FormItem = >(
PropsInfo: GenericFormItemProps,
) => {
// 基础信息
const { type, label, name, rules, style } = PropsInfo;
// 下拉框信息
const {
selector_options,
selector_disabled,
selector_allowClear,
selector_showSearch,
selector_placeholder,
select_onChange,
} = PropsInfo;
// 输入框信息
const {
input_ref,
input_value,
input_border,
input_prefix,
input_suffix,
input_disabled,
input_maxLength,
input_showCount,
input_addonAfter,
input_placeholder,
input_defaultValue,
input_onChange,
input_onPressEnter,
} = PropsInfo;
// 日期选择器信息
const {
date_value,
date_picker,
date_disabled,
date_bordered,
date_showToday,
date_autoFocus,
date_allowClear,
date_placeholder,
date_defaultValue,
date_disabledDate,
date_pickerOnChange,
} = PropsInfo;
// 数字输入框信息
const {
inputNumber_min,
inputNumber_max,
inputNumber_size,
inputNumber_disabled,
} = PropsInfo;
// 单选框 Radio 信息
const { radio_options, radio_value, radio_disabled } = PropsInfo;
// 移动数字滑块 信息
const { slider_disabled, slider_min, slider_max, slider_tooltip } = PropsInfo;
// 级联选择器信息
const { cascader_options, cascader_disabled } = PropsInfo;
// 输入框自动完成信息
const {
autoComplete_placeholder,
autoComplete_options,
autoComplete_disabled,
autoComplete_maxlength,
} = PropsInfo;
// 复选框信息
const { checkbox_options, checkbox_disabled } = PropsInfo;
// 二维码信息
const { QRCode_value } = PropsInfo;
// upload 上传文件信息
const {
upload_accept,
upload_fileList,
upload_button_disabled,
upload_button_icon,
upload_button_type,
upload_button_title,
upload_showUploadList,
upload_button_loading,
upload_customRequest,
} = PropsInfo;
const renderItem = (): React.ReactNode => {
switch (type) {
case "Selector":
return (
时小记,终有成。