【antd design 5 Form.itme 封装】 持续更新......

 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 (
          
        );

      case "DatePicker":
        return (
          
              document.getElementById("filterWrapper")
            }
            style={style}
            value={date_value}
            picker={date_picker}
            disabled={date_disabled}
            bordered={date_bordered}
            showToday={date_showToday ?? false}
            autoFocus={date_autoFocus}
            allowClear={date_allowClear ?? true}
            placeholder={date_placeholder ?? ""}
            defaultValue={date_defaultValue}
            onChange={date_pickerOnChange}
            disabledDate={date_disabledDate}
          />
        );

      case "AutoComplete":
        return (
          
              document.getElementById("filterWrapper")
            }
            maxLength={autoComplete_maxlength}
            style={style}
            disabled={autoComplete_disabled ?? false}
            options={autoComplete_options}
            placeholder={autoComplete_placeholder ?? ""}
            filterOption={(input_value, option) =>
              String(option!.value)
                .toUpperCase()
                .indexOf(input_value.toUpperCase()) !== -1
            }
          />
        );

      case "Upload":
        return (
          
            
          
        );

      case "RangePicker":
        return ;

      case "Radio":
        return (
          
            {radio_options?.map((item) => (
              
                {item.label}
              
            ))}
          
        );

      case "InputNumber":
        return (
          
        );

      case "Slider":
        return (
          
        );

      case "Cascader":
        return (
          
              document.getElementById("filterWrapper")
            }
            disabled={cascader_disabled ?? false}
            options={cascader_options}
            expandTrigger="hover"
          />
        );

      case "Checkbox":
        return (
          
        );

      case "QRCode":
        return ;

      default:
        return 
传入的 type 不存在,请检查
; } }; return ( {renderItem()} ); }; export default FormItem;

时小记,终有成。

你可能感兴趣的:(前端,react.js,javascript,前端)