import { Checkbox, ColProps, FormItemProps, FormProps, Input, InputNumber, Radio, RowProps, Slider, Switch, Table, TimePicker, TreeSelect, Upload } from 'antd'; import { NamePath } from 'antd/es/form/interface'; import React, { ComponentProps, HTMLAttributes, ReactNode } from 'react'; import SCascader from '../cascader'; import SCheckGroup from '../check-group'; import SDatePicker from '../date-picker'; import SDatePickerRange from '../date-picker-range'; import SInput from '../input'; import SRadioGroup from '../radio-group'; import SSelect from '../select'; import { RegKeyType } from "../../types/reg"; import { SButtonsItem } from '../button/types'; type RenderChildren = (values: Record, form: import('antd').FormInstance) => React.ReactNode; /** * 表单控件类型映射表 * * 定义了 SForm items 中 `type` 字段所有可选值及其对应组件。 * 使用时,`fieldProps` 的类型会根据 `type` 自动推导。 * * @example * ```tsx * const items: SFormItems[] = [ * { label: '姓名', name: 'name', type: 'input' }, * { label: '年龄', name: 'age', type: 'inputNumber' }, * { label: '性别', name: 'gender', type: 'select', fieldProps: { options: [...] } }, * { label: '日期', name: 'date', type: 'datePicker' }, * ]; * ``` */ export type FormFieldMapType = { /** 文本输入框 (SInput 增强版,支持 trim/onEnter) */ input: typeof SInput; /** 数字输入框 */ inputNumber: typeof InputNumber; /** 密码输入框 */ password: typeof Input.Password; /** 多行文本输入 */ textarea: typeof Input.TextArea; /** 下拉选择器 (SSelect 增强版) */ select: typeof SSelect; /** 滑动输入条 */ slider: typeof Slider; /** 单选按钮 */ radio: typeof Radio; /** 单选按钮组 (SRadioGroup) */ radioGroup: typeof SRadioGroup; /** 开关 */ switch: typeof Switch; /** 树选择 */ treeSelect: typeof TreeSelect; /** 文件上传 */ upload: typeof Upload; /** 增强日期选择器 (SDatePicker),onChange 直接返回字符串 */ datePicker: typeof SDatePicker; /** @deprecated 请使用 'datePicker',此别名将在未来版本移除 */ SDatePicker: typeof SDatePicker; /** 增强日期范围选择器 (SDatePickerRange),支持 rangeKeys 拆分 */ datePickerRange: typeof SDatePickerRange; /** @deprecated 请使用 'datePickerRange',此别名将在未来版本移除 */ SDatePickerRange: typeof SDatePickerRange; /** 时间选择器 */ timePicker: typeof TimePicker; /** 时间范围选择器 */ timePickerRange: typeof TimePicker.RangePicker; /** 复选框 */ checkbox: typeof Checkbox; /** 复选框组 (SCheckGroup) */ checkGroup: typeof SCheckGroup; /** 增强级联选择器 (SCascader) */ cascader: typeof SCascader; /** @deprecated 请使用 'cascader',此别名将在未来版本移除 */ SCascader: typeof SCascader; /** 嵌套表格 */ table: typeof Table; }; /** * 表单控件类型 * * 可选值: `'input'` | `'inputNumber'` | `'password'` | `'textarea'` | `'select'` | `'slider'` | * `'radio'` | `'radioGroup'` | `'switch'` | `'treeSelect'` | `'upload'` | `'datePicker'` | * `'datePickerRange'` | `'timePicker'` | `'timePickerRange'` | `'checkbox'` | `'checkGroup'` | * `'cascader'` | `'table'` * * 已废弃别名(仍可用,建议迁移): `'SDatePicker'` → `'datePicker'` | `'SDatePickerRange'` → `'datePickerRange'` | `'SCascader'` → `'cascader'` */ export type FormComType = keyof FormFieldMapType; export type FormComPropsType = Omit, 'onChange' | 'onFocus' | 'onBlur'> & ComponentProps; export type FormItemType = FormComType | 'placeholder'; /** * 表单项配置 * * 用于 SForm 的 `items` 数组中,每一项描述一个表单控件。 * `type` 决定渲染哪种控件,`fieldProps` 类型会根据 `type` 自动推导。 * * @example * ```tsx * const item: ItemsProps = { * label: '用户名', * name: 'username', * type: 'input', * required: '请输入用户名', * fieldProps: { placeholder: '请输入' }, * }; * ``` */ export interface ItemsProps extends Omit { /** 表单项标签 */ label?: ReactNode; /** 表单项字段名,支持嵌套路径如 ['user', 'name'] */ name?: NamePath; style?: React.CSSProperties; /** * 控件类型,决定渲染哪种表单组件 * @default 'input' */ type?: T; /** * 控件属性,类型根据 type 自动推导 * * 例如 type='select' 时,fieldProps 支持 options/mode 等 Select 属性 */ fieldProps?: T extends keyof FormFieldMapType ? Omit, 'onChange' | 'onFocus' | 'onBlur'> & ComponentProps : undefined; /** 自定义组件,替代 type 内置组件 */ customCom?: ReactNode | RenderChildren; /** 内置校验规则 key,如 'phone'、'percentage' 等 */ regKey?: RegKeyType; /** * 是否必填 * - true: 使用默认提示 * - string: 使用自定义提示文字 */ required?: string | boolean; /** 是否禁用 */ disabled?: boolean; /** 只读模式,展示文本而非控件 */ readonly?: boolean; /** 嵌套表单的字段前缀,用于数据结构嵌套 */ formName?: string; children?: ReactNode; } /** * SForm 表单项配置(带布局) * * 在 ItemsProps 基础上增加了栅格布局和显隐控制。 */ export interface SFormItems extends ItemsProps { /** 栅格布局配置,控制单个表单项占据的列宽 */ colProps?: ColProps; /** 是否隐藏该表单项(隐藏后仍参与表单提交) */ hidden?: boolean; /** CSS Grid 列跨度,仅 SForm.Search 组件生效 */ gridColumn?: number | string; } /** * SForm 表单组件 Props * * 继承 antd Form 全部属性,扩展了配置化表单能力。 * 通过 `items` 数组声明式定义表单,无需手动写 Form.Item。 * * @example * ```tsx * console.log(values)} * /> * ``` */ export interface SFormProps extends FormProps { /** 行布局配置 */ rowProps?: RowProps; children?: ReactNode; /** 表单项配置数组,核心属性 */ items?: Array>; /** * 列数,表单项自动等分排列 * @default 1 */ columns?: number; /** * 全局必填设置 * - true: 所有项必填 * - string: 所有项必填且使用该提示 */ required?: string | boolean; /** 表单提交回调 */ onFinish?: (e?: any) => void; /** 表单重置回调 */ onReset?: (e?: any) => void; /** 只读模式 */ readonly?: boolean; /** 嵌套表单的字段前缀 */ formName?: string; /** * 统一 label 宽度,解决 label 长短不一导致控件错位的问题 * - number: px 值(如 100 → 100px) * - string: 直接作为 CSS 值(如 '6em'、'120px') * @example labelWidth={100} */ labelWidth?: number | string; } /** * 分组表单项配置 * * 用于 SForm.Group 的 groupItems,将表单分成多个带标题的区块。 */ export type GroupItemsType = { /** 自定义分组容器组件 */ container?: React.ComponentType; /** 该分组的列数 */ columns?: number; /** 分组标题 */ title?: ReactNode; /** 该分组的表单项 */ items?: Array>; rowProps?: RowProps; /** 嵌套表单的字段前缀 */ formName?: string; }; /** * SForm.Group 分组表单 Props * * 将表单分为多个带标题的分组区块展示。 * * @example * ```tsx * * ``` */ export interface SFormGroupProps extends FormProps { /** 分组配置数组 */ groupItems?: GroupItemsType[]; onFinish?: (e: any) => void; onReset?: (e: any) => void; /** 自定义容器组件 */ container?: React.ComponentType; /** 嵌套表单的字段前缀 */ formName?: string; children?: ReactNode; /** 只读模式 */ readonly?: boolean; } /** * SForm.Search 搜索表单 Props * * 继承 SFormProps,增加了展开/收起、操作按钮等搜索场景功能。 * 通常与 STable/useSearchTable 配合使用。 * * @example * ```tsx * * ``` */ export interface SearchProps extends SFormProps { /** * 是否默认展开所有搜索项 * @default false */ defaultExpand?: boolean; /** 是否显示展开/收起按钮 */ showExpand?: boolean; /** 展开/收起回调 */ onExpand?: (expand: boolean) => void; /** * 收起时最大显示行数 * @default 1 */ maxRows?: number; /** 搜索栏右侧自定义操作节点 */ actionNode?: ReactNode; /** 自定义组件容器 */ container?: React.ComponentType; /** 是否包裹在卡片中 */ isCard?: boolean; /** * 行列间距,number 统一间距,[rowGap, columnGap] 分别设置 * @default [16, 24] */ gap?: number | [number, number]; /** 额外操作按钮,渲染在查询/重置旁 */ extraButtons?: SButtonsItem[]; /** 自定义操作区域样式 */ actionStyleRender?: (props: { expanded: boolean; actionSpan: number; }) => React.CSSProperties; /** * 统一 label 宽度,解决 label 长短不一导致控件错位的问题 * @example labelWidth={80} */ labelWidth?: number | string; } export {};