npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kne/form-info

v0.1.27

Published

构建一个更加美观的form表单组件

Readme

form-info

描述

构建一个更加美观的form表单组件

安装

npm i --save @kne/form-info

概述

这是一个基于 React 和 Ant Design 的高颜值表单组件库,专为现代化 Web 应用设计。该组件库通过优雅的视觉设计和丰富的交互功能,为开发者提供了一套完整的表单解决方案。

核心特点

美观优雅的界面设计 - 采用现代化的视觉风格,配合精心设计的间距、色彩和排版,让表单界面更加专业美观。

多样化的表单组件 - 提供 FormInfo、FormModal、FormSteps、FormStepsModal、List、TableList、MultiField 等丰富的表单组件,满足各种复杂的业务场景需求。

灵活的布局系统 - 支持响应式网格布局和 Flexbox 布局,可以轻松实现单列、多列以及自定义复杂布局。

强大的列表功能 - 内置 List、TableList 等列表组件,支持动态添加/删除、嵌套列表等高级功能。

多步骤表单支持 - 提供 FormSteps 和 FormStepsModal 组件,轻松实现向导式表单流程,提升用户体验。

国际化支持 - 内置中英文语言包,支持自定义国际化文本,便于多语言应用开发。

完整的事件系统 - 提供丰富的回调函数和事件钩子,支持表单验证、数据处理、状态管理等完整生命周期控制。

高度可定制 - 组件设计充分考虑扩展性,支持自定义样式、图标、按钮文本等,满足个性化需求。

该组件库特别适合企业级应用、管理系统、数据录入平台等需要大量表单交互的场景,能够显著提升开发效率和用户体验。

示例(全屏)

示例样式

@use '~@kne/responsive-utils/scss' as resp;

// 手机预览下给示例内容留白,便于观察层级与间距
@include resp.mobile-container {
  .example-driver-runner {
    padding: 12px 16px 24px;
    box-sizing: border-box;
  }
}

示例代码

  • 基础表单示例
  • 展示FormInfo、List、TableList、MultiField等基础组件的组合使用,包含普通字段、隐藏字段、多字段、列表、表格列表等多种表单元素的完整示例
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const {default: FormInfo, List, TableList, MultiField, Form, Input, TextArea, SubmitButton, ResetButton} = _FormInfo;
const {Flex, message, Divider, Switch, Space} = antd;
const {useState} = React;

const BaseExample = () => {
    const [loading, setLoading] = useState(false);
    const [formData, setFormData] = useState({
        employeeId: 'EMP20240001',
        name: '张三',
        department: '技术研发部',
        position: '高级前端工程师'
    });

    // 模拟表单提交
    const handleSubmit = async (formData) => {
        setLoading(true);
        console.log('提交的表单数据:', formData);
        
        // 模拟API请求
        await new Promise(resolve => setTimeout(resolve, 1000));
        
        message.success('员工信息提交成功!');
        setLoading(false);
    };

    return <Form data={formData} onSubmit={handleSubmit}>
        <FormInfo 
            title="员工基本信息" 
            subtitle="请填写员工的基本个人信息" 
            column={2}
            gap={20}
            list={[
                <Input name="employeeId" label="工号" rule="REQ" disabled />,
                <Input name="name" label="姓名" rule="REQ" placeholder="请输入员工姓名" />,
                <Input name="department" label="所属部门" rule="REQ" placeholder="例如:技术研发部" />,
                <Input name="position" label="职位" rule="REQ" placeholder="例如:高级前端工程师" />,
                <Input name="phone" label="联系电话" rule="REQ TEL" placeholder="请输入11位手机号" />,
                <Input name="email" label="邮箱" rule="REQ EMAIL" placeholder="请输入企业邮箱" />,
                <Input name="idCard" label="身份证号" rule="REQ ID_CARD" placeholder="请输入18位身份证号" />,
                <TextArea name="skills" label="技能特长" placeholder="请描述员工的专业技能" block />,
                <MultiField 
                    name="certificates" 
                    label="职业证书" 
                    field={Input} 
                    block
                    addText="添加证书"
                    placeholder="例如:PMP项目管理认证"
                />,
                <TextArea name="remarks" label="备注信息" placeholder="其他需要说明的信息" block />
            ]}
        />
        
        <Divider />
        
        <List 
            title="工作经历" 
            name="workExperience"
            bordered
            itemTitle={({index, data}) => data?.companyName || &#96;工作经历 ${index + 1}&#96;}
            important
            maxLength={5}
            addText="添加工作经历"
            list={[
                <Input name="companyName" label="公司名称" rule="REQ" placeholder="例如:阿里巴巴集团" />,
                <Input name="jobTitle" label="职位名称" rule="REQ" placeholder="例如:高级开发工程师" />,
                <Input name="workYears" label="工作年限" rule="REQ" placeholder="例如:3年" />,
                <TextArea name="workDescription" label="工作描述" placeholder="请描述主要工作内容和成就" block />,
                <List 
                    title="项目经历" 
                    name="projects"
                    bordered
                    itemTitle={({index, data}) => data?.projectName || &#96;项目 ${index + 1}&#96;}
                    list={[
                        <Input name="projectName" label="项目名称" rule="REQ" placeholder="例如:双十一活动系统" />,
                        <Input name="projectRole" label="担任角色" rule="REQ" placeholder="例如:技术负责人" />,
                        <TextArea name="projectDescription" label="项目描述" placeholder="项目背景、职责和成果" block />
                    ]}
                    block
                />
            ]}
        />
        
        <Divider />
        
        <TableList 
            title="家庭成员信息" 
            name="familyMembers"
            itemTitle={({index}) => &#96;家庭成员 ${index + 1}&#96;}
            maxLength={10}
            addText="添加家庭成员"
            list={[
                <Input name="memberName" label="姓名" rule="REQ" placeholder="家庭成员姓名" />,
                <Input name="relationship" label="关系" rule="REQ" placeholder="例如:配偶、子女" />,
                <Input name="memberPhone" label="联系电话" rule="TEL" placeholder="联系电话" />,
                <Input name="workUnit" label="工作单位" placeholder="工作单位名称" />
            ]}
        />
        
        <Divider />
        
        <FormInfo 
            title="紧急联系人" 
            column={3}
            list={[
                <Input name="emergencyContact" label="姓名" rule="REQ" placeholder="紧急联系人姓名" />,
                <Input name="emergencyRelation" label="关系" rule="REQ" placeholder="与员工关系" />,
                <Input name="emergencyPhone" label="电话" rule="REQ TEL" placeholder="联系电话" />
            ]}
        />
        
        <Flex justify="center" gap={12} style={{marginTop: 24}}>
            <SubmitButton loading={loading}>提交信息</SubmitButton>
            <ResetButton>重置表单</ResetButton>
        </Flex>
    </Form>;
};

render(<BaseExample/>);
  • 混合场景(FormInfo / List / TableList / MultiField / Steps)
  • 对齐 form-creator 预览的五种模块同屏组合:验收 TableList 列最小宽度与操作列 sticky、Steps 标题随文字且连线最大 40px、List 默认无边框等
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const {
  default: FormInfo,
  List,
  TableList,
  MultiField,
  Form,
  Steps,
  Input,
  TextArea,
  Select,
  SubmitButton,
  ResetButton
} = _FormInfo;
const {Flex, message} = antd;
const {useState} = React;

/**
 * 混合场景:FormInfo / List / TableList / MultiField / Steps(嵌入父 Form)
 * 验收:TableList 列宽与 sticky、Steps 样式、下一步校验、提交失败跳步、重置回第一步。
 */
const MixedExample = () => {
  const [loading, setLoading] = useState(false);

  const handleSubmit = async data => {
    setLoading(true);
    console.log('混合表单提交:', data);
    await new Promise(resolve => setTimeout(resolve, 600));
    message.success('提交成功');
    setLoading(false);
  };

  return (
    <Form
      data={{
        name: '张三',
        mobile: '13800138000',
        workExperiences: [{company: '示例公司', title: '前端'}],
        educations: [{school: '示例大学', major: '计算机', degree: 'bachelor'}],
        backupContacts: ['']
      }}
      onSubmit={handleSubmit}
    >
      <FormInfo
        title="基本信息"
        subtitle="请先填写基础资料"
        column={2}
        list={[
          <Input name="name" label="姓名" rule="REQ" placeholder="请输入姓名" />,
          <Input name="mobile" label="手机号" rule="REQ TEL" placeholder="请输入手机号" />,
          <Select
            name="gender"
            label="性别"
            rule="REQ"
            placeholder="请选择"
            options={[
              {label: '男', value: 'male'},
              {label: '女', value: 'female'}
            ]}
          />,
          <TextArea name="remark" label="备注" block placeholder="补充说明" />
        ]}
      />

      <List
        title="工作经历"
        name="workExperiences"
        addText="添加工作经历"
        minLength={1}
        itemTitle={({index, data}) => data?.company || &#96;工作经历 ${index + 1}&#96;}
        list={[
          <Input name="company" label="公司" rule="REQ" placeholder="请输入公司名称" />,
          <Input name="title" label="职位" rule="REQ" placeholder="请输入职位" />,
          <Input name="startDate" label="入职时间" placeholder="例如:2020-01" />
        ]}
      />

      <TableList
        title="教育经历"
        name="educations"
        addText="添加教育经历"
        bordered
        list={[
          <Input name="school" label="学校" rule="REQ" placeholder="请输入学校" />,
          <Input name="major" label="专业" placeholder="请输入专业" />,
          <Select
            name="degree"
            label="学历"
            placeholder="请选择"
            options={[
              {label: '本科', value: 'bachelor'},
              {label: '硕士', value: 'master'},
              {label: '博士', value: 'doctor'}
            ]}
          />
        ]}
      />

      <FormInfo
        title="备用联系方式"
        column={1}
        list={[
          <MultiField
            name="backupContacts"
            label="联系方式"
            field={Input}
            block
            minLength={1}
            maxLength={3}
            placeholder="请输入联系方式"
          />
        ]}
      />

      <Steps
        title="入职补充信息"
        bordered
        items={[
          {
            title: '账号信息',
            column: 2,
            list: [
              <Input name="email" label="邮箱" rule="REQ EMAIL" placeholder="请输入邮箱" />,
              <Input name="employeeNo" label="工号" placeholder="选填" />
            ]
          },
          {
            title: '紧急联系人',
            column: 2,
            list: [
              <Input name="emergencyName" label="联系人" rule="REQ" placeholder="请输入姓名" />,
              <Input name="emergencyMobile" label="联系电话" rule="REQ TEL" placeholder="请输入手机号" />,
              <Select
                name="emergencyRelation"
                label="关系"
                placeholder="请选择"
                options={[
                  {label: '父母', value: 'parent'},
                  {label: '配偶', value: 'spouse'},
                  {label: '子女', value: 'child'},
                  {label: '其他', value: 'other'}
                ]}
              />
            ]
          },
          {
            title: '其他说明',
            column: 1,
            list: [
              <TextArea name="onboardNote" label="补充说明" block placeholder="如有特殊需求请填写" />
            ]
          }
        ]}
      />

      <Flex justify="center" gap={12} style={{marginTop: 24}}>
        <SubmitButton loading={loading}>提交</SubmitButton>
        <ResetButton>重置</ResetButton>
      </Flex>
    </Form>
  );
};

render(<MixedExample />);
  • 超多层列表嵌套
  • 第 1~4 级常规嵌套;第 5 级起同宽无缩进,仅第 5 级保留左侧色条;标签可展开/收起;子项 hover 高亮;可切换边框
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const { default: FormInfo, List, Form, Input, TextArea, SubmitButton, ResetButton } = _FormInfo;
const { Flex, message, Alert, Space, Switch } = antd;
const { useState } = React;

/**
 * 第 1~4 级:常规嵌套样式
 * 第 5 级起(子步骤…):nest-beyond 满宽同宽;仅第 5 级保留左侧色条
 */
const NestedDeepExample = () => {
  const [bordered, setBordered] = useState(true);

  const handleSubmit = data => {
    console.log('深层嵌套提交:', data);
    message.success('提交成功');
  };

  return (
    <Flex vertical gap={16}>
      <Alert
        type="info"
        showIcon
        message="超多层列表嵌套"
        description="第 1~4 级(部门→小组→成员→任务)为常规嵌套;从第 5 级「子步骤」起同宽无缩进,仅第 5 级保留左侧色条。第 5 级起标签可展开/收起(样式隐藏、不删 DOM),子项 hover 高亮当前范围。"
      />
      <Space>
        <span>边框模式:</span>
        <Switch checked={bordered} onChange={setBordered} />
      </Space>
      <Form
        key={bordered ? 'bordered' : 'plain'}
        data={{
          departments: [
            {
              name: '研发中心',
              teams: [
                {
                  name: '前端组',
                  members: [
                    {
                      name: '张三',
                      role: '工程师',
                      email: '[email protected]',
                      city: '上海',
                      tasks: [
                        {
                          title: '表单搭建',
                          note: '嵌套列表样式',
                          steps: [
                            {
                              name: '样式验收',
                              checks: [
                                {
                                  label: '满宽色条',
                                  remarks: [{ content: '第 5 层起不再靠缩进表示包含' }]
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }}
        onSubmit={handleSubmit}
      >
        <List
          title="组织架构(第 1 级)"
          name="departments"
          addText="添加部门"
          bordered={bordered}
          minLength={1}
          itemTitle={({ data, index }) => data?.name || &#96;部门 ${index + 1}&#96;}
          list={[
            <Input name="name" label="部门名称" rule="REQ" placeholder="例如:研发中心" />,
            <List
              title="下属小组(第 2 级)"
              name="teams"
              addText="添加小组"
              bordered={bordered}
              minLength={1}
              itemTitle={({ data, index }) => data?.name || &#96;小组 ${index + 1}&#96;}
              list={[
                <Input name="name" label="小组名称" rule="REQ" placeholder="例如:前端组" />,
                <List
                  title="小组成员(第 3 级)"
                  name="members"
                  addText="添加成员"
                  bordered={bordered}
                  minLength={1}
                  itemTitle={({ data, index }) => data?.name || &#96;成员 ${index + 1}&#96;}
                  list={[
                    <Input name="name" label="姓名" rule="REQ" placeholder="姓名" />,
                    <Input name="role" label="角色" placeholder="例如:工程师" />,
                    <FormInfo
                      title="联系资料"
                      column={2}
                      bordered={bordered}
                      list={[
                        <Input name="email" label="邮箱" placeholder="[email protected]" />,
                        <Input name="city" label="城市" placeholder="所在城市" />
                      ]}
                    />,
                    <List
                      title="任务明细(第 4 级)"
                      name="tasks"
                      addText="添加任务"
                      bordered={bordered}
                      list={[
                        <Input name="title" label="任务" rule="REQ" placeholder="任务名称" />,
                        <TextArea name="note" label="备注" block placeholder="补充说明" />,
                        <List
                          title="子步骤(第 5 级·满宽色条)"
                          name="steps"
                          addText="添加步骤"
                          bordered={bordered}
                          itemTitle={({ data, index }) => data?.name || &#96;步骤 ${index + 1}&#96;}
                          list={[
                            <Input name="name" label="步骤名" rule="REQ" placeholder="例如:样式验收" />,
                            <List
                              title="检查项(第 6 级)"
                              name="checks"
                              addText="添加检查项"
                              bordered={bordered}
                              itemTitle={({ data, index }) => data?.label || &#96;检查 ${index + 1}&#96;}
                              list={[
                                <Input name="label" label="检查点" rule="REQ" placeholder="例如:满宽色条" />,
                                <List
                                  title="备注条(第 7 级)"
                                  name="remarks"
                                  addText="添加备注"
                                  bordered={bordered}
                                  list={[
                                    <TextArea name="content" label="说明" block placeholder="更深层级仍保持内容区宽度" />
                                  ]}
                                />
                              ]}
                            />
                          ]}
                        />
                      ]}
                    />
                  ]}
                />
              ]}
            />
          ]}
        />
        <Flex justify="center" gap={16}>
          <SubmitButton>提交</SubmitButton>
          <ResetButton>重置</ResetButton>
        </Flex>
      </Form>
    </Flex>
  );
};

render(<NestedDeepExample />);
  • 模态框表单示例
  • 演示FormModal组件的使用,展示如何在弹窗中展示表单,支持表单数据初始化和提交后的自动关闭功能
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const {default: FormInfo, FormModal, List, Input, TextArea, SubmitButton} = _FormInfo;
const {useState} = React;
const {Button, Space, message, Divider, Switch} = antd;

const BaseExample = () => {
    const [open, onOpenChange] = useState(false);
    const [autoClose, setAutoClose] = useState(true);
    const [loading, setLoading] = useState(false);

    // 模拟编辑的员工数据
    const [employeeData, setEmployeeData] = useState({
        id: 'EMP20240001',
        name: '李四',
        employeeNo: 'EMP001',
        department: '产品部',
        position: '产品经理',
        phone: '13800138000',
        email: '[email protected]',
        entryDate: '2024-01-15',
        workExperience: [
            {
                companyName: '腾讯科技',
                jobTitle: '产品经理',
                workYears: '2年',
                workDescription: '负责社交产品的规划与设计'
            }
        ]
    });

    // 表单提交处理
    const handleSubmit = async (formData) => {
        setLoading(true);
        console.log('提交的员工数据:', formData);
        
        // 模拟API请求
        await new Promise(resolve => setTimeout(resolve, 1500));
        
        message.success('员工信息更新成功!');
        setLoading(false);
        
        // 如果autoClose为true,会自动关闭,否则需要手动关闭
        if (!autoClose) {
            // 可以在这里执行其他操作后再手动关闭
            setTimeout(() => onOpenChange(false), 500);
        }
    };

    // 自定义底部按钮
    const customFooter = (submitProps) => (
        <Space>
            <Button onClick={() => onOpenChange(false)}>取消</Button>
            <Button 
                type="primary" 
                loading={submitProps.loading}
                onClick={submitProps.onSubmit}
            >
                保存并继续编辑
            </Button>
            <Button 
                type="primary" 
                loading={submitProps.loading}
                onClick={() => {
                    submitProps.onSubmit();
                }}
            >
                保存并关闭
            </Button>
        </Space>
    );

    return <>
        <Space direction="vertical" size="middle">
            <div>
                <Space>
                    <span>自动关闭:</span>
                    <Switch checked={autoClose} onChange={setAutoClose} />
                </Space>
            </div>
            <Button type="primary" onClick={() => onOpenChange(true)}>
                编辑员工信息
            </Button>
        </Space>

        {/* 标准用法 */}
        <FormModal 
            title="编辑员工信息"
            open={open} 
            onCancel={() => onOpenChange(false)}
            formProps={{
                data: employeeData,
                onSubmit: handleSubmit
            }}
            autoClose={autoClose}
            okText="保存"
            cancelText="取消"
            okType="primary"
            width={800}
            okButtonProps={{
                loading: loading
            }}
        >
            <FormInfo bordered
                title="基本信息" 
                column={2}
                list={[
                    <Input name="employeeNo" label="工号" rule="REQ" disabled />,
                    <Input name="name" label="姓名" rule="REQ" placeholder="请输入员工姓名" />,
                    <Input name="department" label="部门" rule="REQ" placeholder="所属部门" />,
                    <Input name="position" label="职位" rule="REQ" placeholder="职位名称" />,
                    <Input name="phone" label="手机号" rule="REQ TEL" placeholder="11位手机号" />,
                    <Input name="email" label="邮箱" rule="EMAIL" placeholder="企业邮箱" />,
                    <Input name="entryDate" label="入职日期" placeholder="入职日期" />,
                    <TextArea name="remarks" label="备注" placeholder="备注信息" block />
                ]}
            />
            
            <Divider />
            
            <List
                title="工作经历" 
                name="workExperience"
                bordered
                itemTitle={({index, data}) => data?.companyName || &#96;工作经历 ${index + 1}&#96;}
                important
                maxLength={5}
                addText="添加工作经历"
                list={[
                    <Input name="companyName" label="公司名称" rule="REQ" placeholder="公司全称" />,
                    <Input name="jobTitle" label="职位" rule="REQ" placeholder="职位名称" />,
                    <Input name="workYears" label="工作年限" placeholder="例如:3年" />,
                    <TextArea name="workDescription" label="工作描述" placeholder="主要工作内容" block />
                ]}
            />
        </FormModal>
    </>;
};

render(<BaseExample/>);
  • 步骤表单示例
  • 展示FormSteps组件的水平布局和垂直布局两种使用方式,演示多步骤表单的流程控制和步骤管理
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const {default: FormInfo, FormSteps, List, Input, TextArea, SubmitButton, CancelButton} = _FormInfo;
const {Flex, Divider, message, Button, Space, Card, Switch, Alert} = antd;
const {useState} = React;

const BaseExample = () => {
    const [loading, setLoading] = useState(false);
    const [currentStep, setCurrentStep] = useState(0);
    const [autoStep, setAutoStep] = useState(true);

    // 员工入职办理流程数据
    const onboardingData = {
        // 第一步:个人信息
        employeeName: '王五',
        employeeId: 'EMP20240023',
        idCard: '110101199001011234',
        gender: '男',
        birthday: '1990-01-01',
        phone: '13900139000',
        email: '[email protected]',
        education: '本科',
        graduateSchool: '北京大学',
        major: '计算机科学与技术',
        
        // 第二步:岗位信息
        department: '技术研发部',
        position: '前端开发工程师',
        level: 'P6',
        entryDate: '2024-03-04',
        probationPeriod: '3个月',
        salary: '面议',
        workLocation: '北京总部',
        
        // 第三步:银行账户
        bankName: '中国工商银行',
        bankAccount: '6222021234567890123',
        bankBranch: '北京朝阳支行',
        
        // 第四步:紧急联系人
        emergencyContacts: [
            {
                name: '王母',
                relationship: '母亲',
                phone: '13800138001'
            }
        ]
    };

    // 步骤变更回调
    const handleStepChange = (current, formData) => {
        console.log(&#96;切换到第 ${current + 1} 步,表单数据:&#96;, formData);
        setCurrentStep(current);
    };

    // 流程完成回调
    const handleComplete = async (formData) => {
        setLoading(true);
        console.log('入职办理完成,最终数据:', formData);
        
        // 模拟API提交
        await new Promise(resolve => setTimeout(resolve, 2000));
        
        message.success('入职办理完成!欢迎加入公司!');
        setLoading(false);
    };

    return (
        <Flex vertical gap={24}>
            {/* 配置面板 */}
            <Card title="配置选项" size="small">
                <Space>
                    <span>自动切换步骤:</span>
                    <Switch checked={autoStep} onChange={setAutoStep} />
                    <Divider type="vertical" />
                    <span>当前步骤: 第 {currentStep + 1} 步</span>
                </Space>
            </Card>

            {/* 水平方向步骤表单 */}
            <Card title="员工入职办理流程(水平布局)">
                <FormSteps 
                    items={[{
                        title: '个人信息',
                        formProps: {
                            data: onboardingData
                        },
                        children: (
                            <>
                                <Alert 
                                    message="请填写员工基本个人信息" 
                                    type="info" 
                                    showIcon 
                                    style={{marginBottom: 16}}
                                />
                                <FormInfo 
                                    title="个人资料" 
                                    column={2}
                                    list={[
                                        <Input name="employeeName" label="姓名" rule="REQ" placeholder="员工姓名" />,
                                        <Input name="employeeId" label="工号" rule="REQ" disabled />,
                                        <Input name="idCard" label="身份证号" rule="REQ ID_CARD" placeholder="18位身份证号" />,
                                        <Input name="gender" label="性别" rule="REQ" placeholder="男/女" />,
                                        <Input name="birthday" label="出生日期" placeholder="例如:1990-01-01" />,
                                        <Input name="phone" label="手机号" rule="REQ TEL" placeholder="11位手机号" />,
                                        <Input name="email" label="邮箱" rule="EMAIL" placeholder="个人邮箱" />,
                                        <Input name="education" label="学历" rule="REQ" placeholder="例如:本科、硕士" />,
                                        <Input name="graduateSchool" label="毕业院校" placeholder="学校名称" />,
                                        <Input name="major" label="专业" placeholder="所学专业" />
                                    ]}
                                />
                                <Flex justify="center" gap={8} style={{marginTop: 16}}>
                                    <CancelButton>取消</CancelButton>
                                    <SubmitButton>下一步</SubmitButton>
                                </Flex>
                            </>
                        )
                    }, {
                        title: '岗位信息',
                        formProps: {
                            data: onboardingData
                        },
                        children: (
                            <>
                                <FormInfo 
                                    title="岗位配置" 
                                    column={2}
                                    list={[
                                        <Input name="department" label="所属部门" rule="REQ" placeholder="例如:技术研发部" />,
                                        <Input name="position" label="职位名称" rule="REQ" placeholder="职位名称" />,
                                        <Input name="level" label="职级" rule="REQ" placeholder="例如:P6、P7" />,
                                        <Input name="entryDate" label="入职日期" rule="REQ" placeholder="入职日期" />,
                                        <Input name="probationPeriod" label="试用期" placeholder="例如:3个月" />,
                                        <Input name="salary" label="薪资" placeholder="薪资信息" />,
                                        <Input name="workLocation" label="工作地点" placeholder="工作城市" />,
                                        <Input name="reportTo" label="汇报对象" placeholder="直属领导" />
                                    ]}
                                />
                                <Flex justify="center" gap={8} style={{marginTop: 16}}>
                                    <CancelButton>取消</CancelButton>
                                    <SubmitButton>下一步</SubmitButton>
                                </Flex>
                            </>
                        )
                    }, {
                        title: '银行账户',
                        formProps: {
                            data: onboardingData
                        },
                        children: (
                            <>
                                <Alert 
                                    message="银行账户信息用于工资发放,请仔细核对" 
                                    type="warning" 
                                    showIcon 
                                    style={{marginBottom: 16}}
                                />
                                <FormInfo 
                                    title="银行信息" 
                                    column={2}
                                    list={[
                                        <Input name="bankName" label="开户银行" rule="REQ" placeholder="例如:中国工商银行" />,
                                        <Input name="bankBranch" label="开户支行" rule="REQ" placeholder="支行名称" />,
                                        <Input name="bankAccount" label="银行账号" rule="REQ" placeholder="银行卡号" />,
                                        <Input name="accountName" label="账户名" rule="REQ" placeholder="持卡人姓名" />
                                    ]}
                                />
                                <Flex justify="center" gap={8} style={{marginTop: 16}}>
                                    <CancelButton>取消</CancelButton>
                                    <SubmitButton>下一步</SubmitButton>
                                </Flex>
                            </>
                        )
                    }, {
                        title: '紧急联系人',
                        formProps: {
                            data: onboardingData
                        },
                        children: (
                            <>
                                <List 
                                    title="紧急联系人列表" 
                                    name="emergencyContacts"
                                    bordered
                                    itemTitle={({index, data}) => data?.name || &#96;联系人 ${index + 1}&#96;}
                                    important
                                    maxLength={3}
                                    addText="添加联系人"
                                    list={[
                                        <Input name="name" label="姓名" rule="REQ" placeholder="联系人姓名" />,
                                        <Input name="relationship" label="关系" rule="REQ" placeholder="与员工关系" />,
                                        <Input name="phone" label="联系电话" rule="REQ TEL" placeholder="联系电话" />,
                                        <Input name="address" label="联系地址" placeholder="联系地址" />
                                    ]}
                                />
                                <Flex justify="center" gap={8} style={{marginTop: 16}}>
                                    <CancelButton>取消</CancelButton>
                                    <SubmitButton loading={loading}>完成办理</SubmitButton>
                                </Flex>
                            </>
                        )
                    }]}
                    autoStep={autoStep}
                    onChange={handleStepChange}
                    onComplete={handleComplete}
                    stepsClassName="custom-steps"
                />
            </Card>

            <Divider />

            {/* 垂直方向步骤表单 */}
            <Card title="员工入职办理流程(垂直布局)">
                <FormSteps 
                    orientation="vertical"
                    items={[{
                        title: '个人信息',
                        formProps: {
                            data: onboardingData
                        },
                        children: (
                            <>
                                <FormInfo 
                                    title="个人资料" 
                                    column={2}
                                    list={[
                                        <Input name="employeeName" label="姓名" rule="REQ" />,
                                        <Input name="employeeId" label="工号" rule="REQ" disabled />,
                                        <Input name="idCard" label="身份证号" rule="REQ ID_CARD" />,
                                        <Input name="phone" label="手机号" rule="REQ TEL" />
                                    ]}
                                />
                                <Flex justify="center" gap={8} style={{marginTop: 16}}>
                                    <CancelButton>取消</CancelButton>
                                    <SubmitButton>下一步</SubmitButton>
                                </Flex>
                            </>
                        )
                    }, {
                        title: '岗位信息',
                        formProps: {
                            data: onboardingData
                        },
                        children: (
                            <>
                                <FormInfo 
                                    title="岗位配置" 
                                    column={2}
                                    list={[
                                        <Input name="department" label="部门" rule="REQ" />,
                                        <Input name="position" label="职位" rule="REQ" />,
                                        <Input name="entryDate" label="入职日期" rule="REQ" />
                                    ]}
                                />
                                <Flex justify="center" gap={8} style={{marginTop: 16}}>
                                    <CancelButton>取消</CancelButton>
                                    <SubmitButton>完成</SubmitButton>
                                </Flex>
                            </>
                        )
                    }]}
                    autoStep={true}
                    onComplete={handleComplete}
                />
            </Card>
        </Flex>
    );
};

render(<BaseExample/>);
  • 模态框步骤表单示例
  • 演示FormStepsModal组件的使用,结合模态框和步骤表单功能,展示在弹窗中实现复杂多步骤表单流程的完整解决方案
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const { default: FormInfo, FormStepsModal, List, Input, TextArea, Select, DatePicker } = _FormInfo;
const { Flex, Button, Space, message, Divider, Result } = antd;
const { useState } = React;

const BaseExample = () => {
  const [open, onOpenChange] = useState(false);
  const [loading, setLoading] = useState(false);
  const [currentStep, setCurrentStep] = useState(0);

  // 模拟项目申请的初始数据
  const projectData = {
    // 第一步:项目基本信息
    projectName: '智能客服系统',
    projectType: 'internal',
    department: '技术研发中心',
    priority: 'high',
    startDate: '2024-03-01',
    endDate: '2024-08-31',
    budget: '500000',

    // 第二步:项目团队
    teamMembers: [
      {
        name: '张三',
        role: '技术负责人',
        email: '[email protected]',
        phone: '13800138000'
      }
    ],

    // 第三步:项目详情
    background: '现有客服系统效率低下,需要引入AI技术提升服务质量',
    objectives: &#96;1. 响应时间缩短50%\n2. 客户满意度提升30%\n3. 人力成本降低40%&#96;,
    deliverables: '智能客服系统一套,包含前端界面、后台管理、AI对话引擎'
  };

  // 步骤完成回调
  const handleComplete = async (formData) => {
    setLoading(true);
    console.log('提交的项目申请数据:', formData);
    
    // 模拟API提交
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    message.success('项目申请提交成功!');
    setLoading(false);
    onOpenChange(false);
    
    // 可以在这里执行提交后的操作,如跳转到列表页
  };

  // 步骤变更回调
  const handleStepChange = (current, data) => {
    console.log(&#96;切换到第 ${current + 1} 步,当前数据:&#96;, data);
    setCurrentStep(current);
  };

  return (
    <Space direction="vertical" size="middle">
      <Button 
        type="primary" 
        size="large"
        onClick={() => {
          setCurrentStep(0);
          onOpenChange(true);
        }}
      >
        新建项目申请
      </Button>

      <FormStepsModal
        modalProps={{ 
          open, 
          title: '项目立项申请',
          onCancel: () => onOpenChange(false),
          width: 900,
          destroyOnClose: false
        }}
        items={[
          {
            title: '基本信息',
            formProps: {
              data: projectData
            },
            children: (
              <>
                <FormInfo 
                  title="项目基本信息" 
                  column={2}
                  list={[
                    <Input name="projectName" label="项目名称" rule="REQ" placeholder="请输入项目名称" />,
                    <Input name="projectType" label="项目类型" rule="REQ" placeholder="例如:内部项目、外部项目" />,
                    <Input name="department" label="所属部门" rule="REQ" placeholder="负责部门" />,
                    <Input name="priority" label="优先级" rule="REQ" placeholder="高、中、低" />,
                    <Input name="startDate" label="开始日期" rule="REQ" placeholder="计划开始时间" />,
                    <Input name="endDate" label="结束日期" rule="REQ" placeholder="计划结束时间" />,
                    <Input name="budget" label="预算金额" rule="REQ" placeholder="项目预算(元)" />,
                    <Input name="projectManager" label="项目经理" rule="REQ" placeholder="项目负责人" />
                  ]}
                />
                <Divider />
                <FormInfo 
                  title="项目背景" 
                  column={1}
                  list={[
                    <TextArea 
                      name="background" 
                      label="项目背景" 
                      rule="REQ" 
                      placeholder="请描述项目背景和必要性"
                      block
                      rows={4}
                    />
                  ]}
                />
              </>
            )
          },
          {
            title: '团队配置',
            formProps: {
              data: projectData
            },
            children: (
              <>
                <FormInfo 
                  title="核心成员" 
                  column={2}
                  list={[
                    <Input name="sponsor" label="项目发起人" rule="REQ" placeholder="发起人姓名" />,
                    <Input name="sponsorDept" label="发起人部门" rule="REQ" placeholder="所属部门" />
                  ]}
                />
                <Divider />
                <List 
                  title="项目团队成员" 
                  name="teamMembers"
                  bordered
                  itemTitle={({index, data}) => data?.name || &#96;成员 ${index + 1}&#96;}
                  important
                  maxLength={10}
                  addText="添加团队成员"
                  list={[
                    <Input name="name" label="姓名" rule="REQ" placeholder="成员姓名" />,
                    <Input name="role" label="角色" rule="REQ" placeholder="例如:开发、测试、产品" />,
                    <Input name="email" label="邮箱" rule="EMAIL" placeholder="企业邮箱" />,
                    <Input name="phone" label="手机号" rule="TEL" placeholder="联系电话" />,
                    <Input name="joinDate" label="参与时间" placeholder="加入项目时间" />,
                    <Input name="workload" label="投入比例" placeholder="例如:50%" />
                  ]}
                />
              </>
            )
          },
          {
            title: '项目详情',
            formProps: {
              data: projectData
            },
            children: (
              <>
                <FormInfo 
                  title="项目目标与交付物" 
                  column={1}
                  list={[
                    <TextArea 
                      name="objectives" 
                      label="项目目标" 
                      rule="REQ" 
                      placeholder="请列出项目的主要目标(每行一个)"
                      block
                      rows={4}
                    />,
                    <TextArea 
                      name="deliverables" 
                      label="交付物清单" 
                      rule="REQ" 
                      placeholder="项目需要交付的成果物"
                      block
                      rows={3}
                    />,
                    <TextArea 
                      name="risks" 
                      label="风险与应对" 
                      placeholder="可能存在的风险及应对措施"
                      block
                      rows={3}
                    />
                  ]}
                />
                <Divider />
                <List 
                  title="里程碑计划" 
                  name="milestones"
                  bordered
                  itemTitle={({index, data}) => data?.milestoneName || &#96;里程碑 ${index + 1}&#96;}
                  addText="添加里程碑"
                  list={[
                    <Input name="milestoneName" label="里程碑名称" rule="REQ" placeholder="例如:需求确认" />,
                    <Input name="plannedDate" label="计划日期" rule="REQ" placeholder="预计完成日期" />,
                    <Input name="deliverable" label="交付物" placeholder="该阶段的交付物" />,
                    <TextArea name="milestoneDesc" label="说明" placeholder="里程碑说明" block />
                  ]}
                />
              </>
            )
          }
        ]}
        autoStep={true}
        completeText="提交申请"
        nextText="下一步"
        onComplete={handleComplete}
        onChange={handleStepChange}
      />
    </Space>
  );
};

render(<BaseExample />);
  • 边框模式示例
  • 演示FormInfo、List、TableList组件的bordered属性,控制卡片是否显示边框,通过开关切换对比有边框与无边框效果
  • _FormInfo(@kne/current-lib_form-info),antd(antd),(@kne/current-lib_form-info/dist/index.css)
const {default: FormInfo, List, TableList, Form, Input, TextArea} = _FormInfo;
const {Flex, Switch, Space, Divider} = antd;
const {useState} = React;

const BorderedExample = () => {
    const [bordered, setBordered] = useState(true);

    return <Form data={{
        employeeId: 'EMP20240001',
        name: '张三',
        department: '技术研发部'
    }}>
        <Flex vertical gap={16}>
            <Space>
                <span>边框模式:</span>
                <Switch checked={bordered} onChange={setBordered} />
            </Space>

            <FormInfo
                title="员工基本信息"
                subtitle="bordered 控制卡片是否显示边框"
                bordered={bordered}
                column={2}
                gap={20}
                list={[
                    <Input name="employeeId" label="工号" rule="REQ" disabled />,
                    <Input name="name" label="姓名" rule="REQ" placeholder="请输入员工姓名" />,
                    <Input name="department" label="所属部门" rule="REQ" placeholder="例如:技术研发部" />,
                    <Input name="position" label="职位" rule="REQ" placeholder="例如:高级前端工程师" />
                ]}
            />

            <Divider />

            <List
                title="工作经历(important)"
                name="workExperience"
                bordered={bordered}
                itemTitle={({index, data}) => data?.companyName || &#96;工作经历 ${index + 1}&#96;}
                important
                addText="添加工作经历"
                list={[
                    <Input name="companyName" label="公司名称" rule="REQ" placeholder="例如:阿里巴巴集团" />,
                    <Input name="jobTitle" label="职位名称" rule="REQ" placeholder="例如:高级开发工程师" />,
                    <TextArea name="workDescription" label="工作描述" placeholder="请描述主要工作内容和成就" block />
                ]}
            />

            <List
                title="教育经历(非important)"
                name="educationHistory"
                bordered={bordered}
                itemTitle={({index, data}) => data?.schoolName || &#96;教育经历 ${index + 1}&#96;}
                addText="添加教育经历"
                list={[
                    <Input name="schoolName" label="学校名称" rule="REQ" placeholder="例如:北京大学" />,
                    <Input name="major" label="专业" rule="REQ" placeholder="例如:计算机科学与技术" />,
                    <Input name="degree" label="学历" rule="REQ" placeholder="例如:本科" />
                ]}
            />

            <Divider />

            <TableList
                title="家庭成员信息"
                name="familyMembers"
                bordered={bordered}
                addText="添加家庭成员"
                list={[
                    <Input name="memberName" label="姓名" rule="REQ" placeholder="家庭成员姓名" />,
                    <Input name="relationship" label="关系" rule="REQ" placeholder="例如:配偶、子女" />,
                    <Input name="memberPhone" label="联系电话" rule="TEL" placeholder="联系电话" />,
                    <Input name="memberCompany" label="工作单位" placeholder="工作单位名称" />,
                    <Input name="memberPosition" label="职位" placeholder="例如:工程师" />,
                    <Input name="memberIdCard" label="证件号码" placeholder="身份证号" />,
                    <Input name="memberAddress" label="居住地址" placeholder="省市区街道" />,
                    <Input name="memberEmail" label="电子邮箱" placeholder="[email protected]" />,
                    <Input name="memberEmergency" label="紧急联系" placeholder="是否紧急联系人" />
                ]}
            />
        </Flex>
    </Form>;
};

render(<BorderedExample />);

API

FormInfo

基础表单分区组件,用于结构化展示一组表单项。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | column | 列数;支持数字,或传给 @kne/flex-box 的配置对象 | number \| object | 2 | | list | 表单项列表。字段 key 由 @kne/react-form-plus FieldList 按 fieldKey / name(分组内 groupId:name)生成,不拼 list 下标 | ReactNode[] | [] | | gap | 字段间距 | number | 24 | | className | 自定义样式类名 | string | - | | title | 标题 | string \| ReactNode | - | | subtitle | 副标题 | string \| ReactNode | - | | extra | 标题栏右侧额外内容 | ReactNode | - | | bordered | 是否显示边框(透传 InfoPage.Part) | boolean | - |

Form

基础表单容器,封装 @kne/react-form-antd 的 Form。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | type | 表单类型 | string | inner | | className | 自定义样式类名 | string | - | | children | 子节点 | ReactNode | - | | onSubmit | 提交回调 | (data, ...args) => any | - |

其余属性透传给底层 Form。

FormModal

弹窗表单:在 Modal 中承载表单内容。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | open | 是否显示 | boolean | false | | title | 弹窗标题 | ReactNode | - | | onCancel | 关闭回调 | () => void | - | | formProps | 透传给内部 Form 的属性(含 data、onSubmit 等) | object | {} | | autoClose | 提交成功后自动关闭 | boolean | true | | okType | 确认按钮类型 | string | primary | | okText | 确认按钮文案 | string \| ReactNode | 提交 | | cancelText | 取消按钮文案 | string \| ReactNode | 取消 | | okButtonProps | 确认按钮属性 | object | - | | cancelButtonProps | 取消按钮属性 | object | - | | onOk | 自定义确认逻辑 | () => void \| Promise | - | | footer | 底部区域;可为函数 ({ defaultFooter, props }) => ReactNode | ReactNode \| function | - | | renderModal | 自定义整窗渲染。除 antd Modal 参数外,会传入 formProps、cancelText、saveText、autoClose;默认实现会剥掉这些字段再交给 antd Modal | (props) => ReactNode | - | | modalRender | 自定义内容渲染 ({ formChildren, defaultChildren, props }) | function | - | | width / centered / closable / maskClosable / destroyOnClose / className | 透传 antd Modal | - | - |

FormSteps

独立步骤向导:每一步自带 Form,适合多表单向导流程。导出上同时挂载 FormSteps.Embed(等同下方 Steps)。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | items | 步骤配置 | StepItem[] | [] | | current | 受控当前步骤 | number | - | | defaultCurrent | 默认步骤 | number | 0 | | autoStep | 提交成功后自动进入下一步 / 触发完成 | boolean | true | | direction / orientation | 步骤条方向。未指定时桌面横排、放不下自动竖排,移动端竖排;horizontal 强制横排;vertical 强制竖排 | string | - | | onChange | 步骤变化 | (current: number) => void | - | | onComplete | 最后一步完成回调,参数为各步缓存 | (stepCache) => void | - | | stepsClassName | 步骤条样式类名 | string | - | | className | 外层样式类名 | string | - | | children | 自定义包裹渲染;可为函数 | ReactNode \| function | - |

每个 items[] 项:

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | title | 步骤标题 | string \| ReactNode | - | | formProps | 该步 Form 属性(data、onSubmit 等) | object | - | | children | 步骤内容;可为函数,注入 isLastStep / currentStep / onStepChange / getStepCache | ReactNode \| function | - |

Steps(FormSteps.Embed)

嵌入父级 Form 的分步区域(不自建 Form)。字段始终挂载,随父表单一并提交。

行为约定:

  • 点击「下一步」:校验当前步字段
  • 父表单提交失败(form:submit:error / 提交未通过):跳到首个出错步骤
  • 父表单重置(form:reset):回到第 0 步

独立多 Form 向导请继续使用 FormSteps,二者互不影响。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | items | 步骤配置 | StepsItem[] | [] | | title | 分区标题 | string \| ReactNode | - | | subtitle | 副标题 | string \| ReactNode | - | | bordered | 是否显示边框 | boolean | - | | current | 受控当前步骤 | number | - | | defaultCurrent | 默认步骤 | number | 0 | | onChange | 步骤变化 | (current: number) => void | - | | direction / orientation | 步骤条方向。未指定时桌面横排、放不下自动竖排,移动端竖排;horizontal 强制横排;vertical 强制竖排 | string | - | | showActions | 是否显示上一步 / 下一步 | boolean | true | | prevText / nextText | 按钮文案 | string \| ReactNode | 上一步 / 下一步 | | prevIcon / nextIcon | 按钮图标 | ReactNode | - | | stepsClassName / className | 样式类名 | string | - |

每个 items[] 项:

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | title | 步骤标题 | string \| ReactNode | - | | list | 字段列表(同 FormInfo.list) | ReactNode[] | - | | column / gap | 传给内部 FormInfo | number \| object | - | | children | 自定义内容(与 list 二选一) | ReactNode | - | | fieldNames | 本步校验字段名;默认从 list 的 name 收集 | string[] | - | | key / id | 步骤标识 | string \| number | - |

另导出工具方法 validateFieldsByName(openApi, names?),按字段名触发校验。

FormStepsModal

弹窗版步骤向导(FormSteps + Modal)。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | items | 步骤配置(同 FormSteps) | StepItem[] | [] | | modalProps | 透传 FormModal / Modal(含 open、title、autoClose 等) | object | { autoClose: true } | | completeText | 完成按钮文案 | string \| ReactNode | 完成 | | nextText | 下一步按钮文案 | string \| ReactNode | 下一步 | | autoStep | 是否自动切步 | boolean | true | | onComplete | 完成回调 | (data) => void | - | | className | 样式类名 | string | - |

List

动态列表表单。子项卡片默认带边框;bordered 控制外层 Part。移动端边框由容器查询收起,不依赖 JS 开关。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | name | 字段名 | string | - | | title | 列表标题 | string \| ReactNode | - | | list | 每项内的表单项 | ReactNode[] | - | | important | 重要样式(子项头背景等) | boolean | false | | bordered | 外层 Part 是否边框 | boolean | - | | itemTitle | 子项标题;({ index, data }) => string | function | - | | addText / removeText | 添加 / 删除文案 | string \| ReactNode | 添加 / 删除 | | addIcon / removeIcon | 添加 / 删除图标 | ReactNode | PlusOutlined / DeleteOutlined | | empty | 空状态 | ReactNode | Empty | | itemClassName / className | 样式类名 | string | - | | block | 是否块级 | boolean | - |

SubList 与 List 为同一实现。

TableList

表格形态的动态列表。桌面端字段列等分对齐,列过多时可横向滚动,操作列在溢出时 sticky;移动端走 @kne/table-view 的 renderMobile 卡片布局。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | name | 字段名 | string | - | | title | 表格标题 | string \| ReactNode | - | | list | 列对应的表单项 | ReactNode[] | - | | bordered | 外层 Part 是否边框 | boolean | - | | renderMobile | 移动端渲染:true 默认卡片;function 自定义;string 走 table-view preset;false 关闭 | boolean \| string \| function | true | | addText / removeText | 添加 / 删除文案 | string \| ReactNode | 添加 / 删除 | | addIcon / removeIcon | 添加 / 删除图标 | ReactNode | PlusOutlined / DeleteOutlined | | empty | 空状态 | ReactNode | Empty | | itemTitle | 子项标题函数 | function | - | | className | 样式类名 | string | - |

MultiField

同一字段可动态增减多条(同类型控件)。

| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | name | 字段名 | string | - | | label | 字段标签 | string | - | | field | 字段组件 | ComponentType | - | | block | 是否块级 | boolean | false | | rule | 校验规则字符串 | string | - | | addText | 添加文案;可为 (label) => string | string \| function | 添加 | | removeText | 删除文案;可为函数;传 null 隐藏 | string \| function \| null | - | | addIcon / removeIcon | 图标 | ReactNode | PlusOutlined / DeleteOutlined | | empty | 空状态 | ReactNode | Empty | | className | 样式类名 | string | - |

国际化

内置文案键(zh-CN / en-US):

| 键名 | 中文 | 英文 | | --- | --- | --- | | submit | 提交 | Submit | | cancel | 取消 | Cancel | | complete | 完成 | Complete | | prev | 上一步 | Previous | | next | 下一步 | Next | | addText | 添加 | Add | | deleteText | 删除 | Delete | | untitledStep | 第{index}步 | Step {index} |

可通过 withLocale 或 @kne/react-intl 的 useIntl 覆盖。