Group API

Group API 包含分组表单的配置(GroupSchema)和容器组件(Group),用于将表单字段分组显示。

导入

import { Form } from '@schema-formx/react';
import type { GroupSchema } from '@schema-formx/react';

注意Group 组件是内部组件,不从 @schema-formx/react 导出。如果你需要自定义分组容器,请通过 components.DefaultGroup 注册自定义组件,或在 GroupSchema.component 中指定。


Schema 格式说明

Schema FormX 支持两种 schema 格式:

FieldSchema[] 格式

直接使用字段数组,所有字段会自动包裹在一个默认分组中:

// FieldSchema[] 格式
const schema = [
  { type: 'string', name: 'name', label: '姓名' },
  { type: 'string', name: 'email', label: '邮箱' }
];

// 内部自动转换为:
const groupSchema = [
  {
    key: 'group',  // 默认 key
    fields: schema
  }
];

自动包裹机制:当使用 FieldSchema[] 格式时,Form 组件会自动将所有字段包裹在一个默认分组中:

// 原始 schema
const schema = [
  { type: 'string', name: 'name', label: '姓名' },
  { type: 'number', name: 'age', label: '年龄' }
];

// 内部自动转换为:
// [
//   { key: 'group', fields: [{ type: 'string', name: 'name', label: '姓名' }, { type: 'number', name: 'age', label: '年龄' }] }
// ]
// 所有字段放在同一个 Group 中,key 固定为 'group'

说明:如果你需要为每个字段独立设置分组样式,请使用 GroupSchema[] 格式手动分组。

GroupSchema[] 格式

使用分组数组,可以显式定义多个分组:

// GroupSchema[] 格式
const schema: GroupSchema[] = [
  {
    key: 'basic',
    props: { title: '基本信息' },
    fields: [
      { type: 'string', name: 'name', label: '姓名' }
    ]
  },
  {
    key: 'contact',
    props: { title: '联系方式' },
    fields: [
      { type: 'string', name: 'email', label: '邮箱' }
    ]
  }
];

选择建议

场景推荐格式
简单表单,无需分组FieldSchema[]
需要分组显示GroupSchema[]
需要自定义分组容器GroupSchema[]
需要分组级布局配置GroupSchema[]

注意:两种格式不能混合使用,一个表单只能使用一种格式。


GroupSchema 类型

分组配置类型,用于定义分组表单的配置。

type GroupSchema = {
  key: string;
  fields: FieldSchema[];
  component?: string;
  props?: Record<string, unknown>;
};

说明GroupSchema 没有内置的 label 属性。如果需要显示分组标题,可以通过 props 传递给自定义分组容器组件,或在自定义 DefaultGroup 中自行处理。

key

分组的唯一标识,用于区分不同的分组。

类型string

必填:是

示例

{
  key: 'basic',
  fields: [...]
}

使用场景

  • 分组的唯一标识
  • layout.groups 中的索引 key
  • 自定义分组容器的 key 属性

fields

分组内包含的字段配置数组。

类型FieldSchema[]

必填:是

示例

{
  key: 'basic',
  fields: [
    { type: 'string', name: 'name', label: '姓名', required: true },
    { type: 'string', name: 'email', label: '邮箱', required: true }
  ]
}

注意事项

  • 字段的 name 在整个表单中必须唯一,即使在不同的分组中
  • 字段按照数组顺序渲染

component

指定分组使用的容器组件。

类型string

必填:否

默认值:使用 components.DefaultGroup 或内置 Group 组件

示例

{
  key: 'basic',
  component: 'CardGroup',  // 使用注册的 CardGroup 组件
  fields: [...]
}

组件查找顺序

  1. 如果指定了 component,从 components 对象中查找对应名称的组件
  2. 如果未指定,从 components 中查找 DefaultGroup
  3. 如果都未找到,使用内置 Group 组件

props

传递给分组容器组件的额外属性。

类型Record<string, unknown>

必填:否

示例

{
  key: 'basic',
  component: 'CardGroup',
  props: {
    title: '基本信息',
    bordered: true,
    collapsible: true
  },
  fields: [...]
}

注意事项

  • classNamestylelayout 由内部自动注入
  • 可以通过 props 传递额外的自定义属性

Group 组件

内置的分组容器组件,用于渲染分组。

注意Group 组件是内部组件,不从 @schema-formx/react 导出。如果你需要自定义分组容器,请通过 components.DefaultGroup 注册自定义组件,或在 GroupSchema.component 中指定。

属性

layout

布局配置,控制分组的样式和布局。

类型Layout

必填:是

示例

<Group layout={layout}>
  {/* 分组内容 */}
</Group>

className

分组容器的 CSS 类名。

类型string

必填:否

示例

<Group className="custom-group">
  {/* 分组内容 */}
</Group>

style

分组容器的内联样式。

类型CSSProperties

必填:否

示例

<Group style={{ marginBottom: '20px', padding: '16px' }}>
  {/* 分组内容 */}
</Group>

children

分组内的内容,通常是表单字段。

类型ReactNode

必填:是

示例

<Group layout={layout}>
  <div>字段 1</div>
  <div>字段 2</div>
</Group>

自定义分组容器

GroupProps 接口

自定义分组容器组件需要实现以下接口:

type GroupProps = {
  layout: Layout;           // 布局配置
  className?: string;       // 布局容器的样式类
  style?: CSSProperties;    // 布局容器的样式
  children: ReactNode;      // 分组内容
  [key: string]: unknown;   // 其他自定义属性(来自 props)
}

基础示例

const CustomGroup = ({ className, style, layout, children, title, ...rest }) => (
  <div className={className} style={style}>
    <h3>{title}</h3>
    {children}
  </div>
);

注册自定义分组容器

const components = {
  DefaultControl: MyInput,
  DefaultGroup: CustomGroup  // 全局默认分组容器
};

<Form components={components} schema={schema} />

为特定分组指定容器

const schema: GroupSchema[] = [
  {
    key: 'basic',
    component: 'CardGroup',  // 使用 CardGroup 组件
    props: { title: '基本信息' },
    fields: [...]
  }
];

## 使用示例

### 基础分组用法

```tsx
import { Form } from '@schema-formx/react';
import type { GroupSchema } from '@schema-formx/react';

const schema: GroupSchema[] = [
  {
    key: 'basic',
    props: { title: '基本信息' },
    fields: [
      { type: 'string', name: 'name', label: '姓名', required: true },
      { type: 'string', name: 'email', label: '邮箱', required: true }
    ]
  },
  {
    key: 'address',
    props: { title: '地址信息' },
    fields: [
      { type: 'string', name: 'province', label: '省份' },
      { type: 'string', name: 'city', label: '城市' }
    ]
  }
];

function MyForm() {
  return <Form schema={schema} layout={{}} components={{ DefaultControl: MyInput }} />;
}

自定义分组容器

import { Form } from '@schema-formx/react';

// 自定义分组组件
const CardGroup = ({ title, children, className, style }) => (
  <div className={className} style={{ ...style, border: '1px solid #d9d9d9', borderRadius: '8px' }}>
    <div style={{ padding: '12px 16px', borderBottom: '1px solid #d9d9d9', backgroundColor: '#fafafa' }}>
      <h3 style={{ margin: 0 }}>{title}</h3>
    </div>
    <div style={{ padding: '16px' }}>
      {children}
    </div>
  </div>
);

const components = {
  DefaultControl: MyInput,
  CardGroup  // 注册自定义分组组件
};

const schema: GroupSchema[] = [
  {
    key: 'basic',
    component: 'CardGroup',
    props: { title: '基本信息' },
    fields: [...]
  }
];

function MyForm() {
  return <Form components={components} schema={schema} layout={{}} />;
}

相关 API