优化FormItemsRenderer

master
LiuJiaNan 2025-12-18 16:29:53 +08:00
parent c8547b6125
commit 47fd256ac8
3 changed files with 39 additions and 14 deletions

View File

@ -4,14 +4,7 @@ import type { FormListFieldData } from "antd/es/form/FormList";
import type { Gutter } from "antd/es/grid/row"; import type { Gutter } from "antd/es/grid/row";
import type { NamePath } from "rc-field-form/lib/interface"; import type { NamePath } from "rc-field-form/lib/interface";
import type { FC, ReactNode } from "react"; import type { FC, ReactNode } from "react";
import type { FORM_ITEM_RENDER_ENUM } from "../../enum/formItemRender"; import type { FORM_ITEM_RENDER_TYPE_MAP } from "../../enum/formItemRender";
/**
*
*/
export type FormItemRenderType
= | (typeof FORM_ITEM_RENDER_ENUM)[keyof typeof FORM_ITEM_RENDER_ENUM]
| ReactNode;
/** /**
* *
@ -62,7 +55,7 @@ export interface FormListUniqueProps {
/** /**
* *
*/ */
export interface FormOption { export interface FormOption<T extends keyof FORM_ITEM_RENDER_TYPE_MAP = keyof FORM_ITEM_RENDER_TYPE_MAP> {
/** React 需要的 key如果传递了唯一的 name则不需要 */ /** React 需要的 key如果传递了唯一的 name则不需要 */
key?: string; key?: string;
/** 表单项字段名 */ /** 表单项字段名 */
@ -70,7 +63,7 @@ export interface FormOption {
/** 表单项标签 */ /** 表单项标签 */
label?: ReactNode; label?: ReactNode;
/** 渲染类型 */ /** 渲染类型 */
render?: FormItemRenderType; render?: T | ReactNode;
/** 占据栅格列数,默认 12 */ /** 占据栅格列数,默认 12 */
span?: number | string; span?: number | string;
/** 是否必填,默认 true支持函数动态计算 */ /** 是否必填,默认 true支持函数动态计算 */
@ -92,7 +85,7 @@ export interface FormOption {
/** 字段键配置 */ /** 字段键配置 */
itemsField?: itemsFieldConfig; itemsField?: itemsFieldConfig;
/** 传递给表单控件的属性,支持函数动态计算 */ /** 传递给表单控件的属性,支持函数动态计算 */
componentProps?: Record<string, any> | ((formValues: FormValues) => Record<string, any>); componentProps?: FORM_ITEM_RENDER_TYPE_MAP[T] | ((formValues: FormValues) => FORM_ITEM_RENDER_TYPE_MAP[T]);
/** 传递给 Form.Item 的属性,支持函数动态计算 */ /** 传递给 Form.Item 的属性,支持函数动态计算 */
formItemProps?: FormItemProps | ((formValues: FormValues) => FormItemProps); formItemProps?: FormItemProps | ((formValues: FormValues) => FormItemProps);
/** label 栅格配置,默认直接使用外层的 labelCol如果 span 等于 24是外层的 labelCol.span 一半 */ /** label 栅格配置,默认直接使用外层的 labelCol如果 span 等于 24是外层的 labelCol.span 一半 */

View File

@ -408,6 +408,8 @@ const FormItemsRenderer = ({
// 渲染特殊类型的表单项 // 渲染特殊类型的表单项
const renderOtherTypeItem = ({ option, style, col, index }) => { const renderOtherTypeItem = ({ option, style, col, index }) => {
const componentProps = getComponentProps(option);
// 如果是 customizeRender 类型,完全交给外部控制渲染 // 如果是 customizeRender 类型,完全交给外部控制渲染
if (option.customizeRender) { if (option.customizeRender) {
return ( return (
@ -435,7 +437,7 @@ const FormItemsRenderer = ({
if (option.render === FORM_ITEM_RENDER_ENUM.DIVIDER) { if (option.render === FORM_ITEM_RENDER_ENUM.DIVIDER) {
return ( return (
<Col key={getKey(option) || index} span={col.span} style={style}> <Col key={getKey(option) || index} span={col.span} style={style}>
<Divider orientation="left">{option.label}</Divider> <Divider orientation="left" {...componentProps}>{option.label}</Divider>
</Col> </Col>
); );
} }
@ -446,9 +448,11 @@ const FormItemsRenderer = ({
// 渲染 Form.List // 渲染 Form.List
const renderFormList = (option, index, col, style) => { const renderFormList = (option, index, col, style) => {
const formListUniqueProps = getFormListUniqueProps(option); const formListUniqueProps = getFormListUniqueProps(option);
const componentProps = getComponentProps(option);
return ( return (
<Col key={getKey(option) || index} span={col.span} style={style}> <Col key={getKey(option) || index} span={col.span} style={style}>
<Form.List name={option.name}> <Form.List name={option.name} {...componentProps}>
{(fields, { add, remove }) => ( {(fields, { add, remove }) => (
<> <>
{fields.map((field, fieldIndex) => { {fields.map((field, fieldIndex) => {

View File

@ -1,3 +1,12 @@
import type { CheckboxProps } from "antd/es/checkbox";
import type { DatePickerProps } from "antd/es/date-picker";
import type { DividerProps } from "antd/es/divider";
import type { FormListProps } from "antd/es/form";
import type { InputProps, TextAreaProps } from "antd/es/input";
import type { InputNumberProps } from "antd/es/input-number";
import type { RadioProps } from "antd/es/radio";
import type { SelectProps } from "antd/es/select";
/** /**
* *
*/ */
@ -33,5 +42,24 @@ export declare const FORM_ITEM_RENDER_ENUM: {
/** 映射为 antd Divider */ /** 映射为 antd Divider */
DIVIDER: "divider"; DIVIDER: "divider";
/** 映射为 antd FormList */ /** 映射为 antd FormList */
FORM_LIST: "formList", FORM_LIST: "formList";
}; };
export interface FORM_ITEM_RENDER_TYPE_MAP {
input: InputProps;
textarea: TextAreaProps;
inputNumber: InputNumberProps;
number: InputNumberProps;
select: SelectProps;
radio: RadioProps;
checkbox: CheckboxProps;
date: DatePickerProps;
dateMonth: DatePickerProps;
dateYear: DatePickerProps;
dateWeek: DatePickerProps;
dateRange: DatePickerProps;
datetime: DatePickerProps;
datetimeRange: DatePickerProps;
divider: DividerProps;
formList: FormListProps;
}