import cns from 'classnames' import React, { ComponentType, createElement, CSSProperties, FormEvent, FormHTMLAttributes, ReactNode, Ref, useCallback, useMemo, useState } from 'react' import { ComponentSize, useLangData, usePrefix } from '../ConfigProvider' import { concat } from '../utils' import { isPromise } from '../utils/promise' import Button, { ButtonType, ButtonProps } from '../Button' import { sizeCtx, layoutCtx, Layout, LayoutType, footerCtx, useFooterCtx, FooterAlign, useFormLayout, useFormSize, LabelOptions, useFormLabelOptions, labelOptionsCtx, defaultLabelWidth, defaultLabelGapForHorizontal, useFormVerticalGap, verticalGapCtx } from './defs' import { useIsMounted, useRefs } from '../utils/hooks' import { WithRef } from '../utils/type' export interface Props extends LabelOptions { /** * 提交行为的回调函数 * Form 组件会对原生的 submit envent 进行 preventDefault 操作后再触发该回调 */ onSubmit?: () => void | Promise /** 取消行为的回调函数 */ onCancel?: () => void /** 表单内容尺寸 */ size?: ComponentSize /** 表单内容布局 */ layout?: LayoutType | Layout /** * `FormItem`、`Footer` 等内容间的垂直间距 * @default "24px" */ verticalGap?: string /** * 表单的尾部内容,一般是提交 & 取消按钮等, * 若不传(或传 `undefined`)则使用默认尾部,若传 `null` 则尾部不会渲染; * 对于 `layout: inline` 的表单,尾部内容会被展示到右侧 */ footer?: ReactNode /** * 获取 form 引用 * * @deprecated use formProps.ref instead */ formRef?: Ref /** 需要传给 `form` 元素的属性 */ formProps?: WithRef, T> /** 自定义样式名 */ className?: string /** 自定义样式 */ style?: CSSProperties /** 表单内容 */ children?: ReactNode /** 指定组件实现替换 HTML form */ as?: ComponentType, T>> } export default function Form({ onSubmit, onCancel, size: sizeFromProps, layout: layoutFromProps, verticalGap: verticalGapFromProps, footer =