zy-react-library 1.2.3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ import{useState as e,useCallback as t}from"react";import{message as i,Modal as l,Space as n,Button as o,Row as d,Col as r}from"antd";import{CopyOutlined as a,ExportOutlined as s,Html5Outlined as c,ClearOutlined as p}from"@ant-design/icons";import{DndContext as b}from"../../node_modules/@dnd-kit/core/dist/core.esm";import{arrayMove as h}from"../../node_modules/@dnd-kit/sortable/dist/sortable.esm";import m from"./FieldLibrary.js";import f from"./DropZone.js";import g from"./FieldConfigEditor.js";import u from"./TablePreview.js";import"../../src/components/DragTableBuilder/DragTableBuilder.less";import{jsxs as x,jsx as y}from"react/jsx-runtime";const w=[{type:"text",label:"文本",icon:"T"},{type:"number",label:"数字",icon:"#"},{type:"date",label:"日期",icon:"📅"},{type:"datetime",label:"日期时间",icon:"🕐"},{type:"select",label:"下拉选择",icon:"▼"},{type:"boolean",label:"布尔值",icon:"☑"},{type:"email",label:"邮箱",icon:"✉"},{type:"url",label:"链接",icon:"🔗"},{type:"image",label:"图片",icon:"🖼"},{type:"tag",label:"标签",icon:"🏷"},{type:"progress",label:"进度条",icon:"▓"},{type:"rate",label:"评分",icon:"★"}],v=v=>{const{fieldTypes:k=w,initialFields:C=[],onChange:T,onExport:L,showPreview:$=!0,showLibrary:E=!0,showConfigEditor:j=!0}=v,[I,D]=e(C),[M,R]=e(null),[_,F]=e(!1),H=t(()=>`field_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,[]),O=t(e=>{const{active:t,over:i}=e;if(i&&t.id!==i.id){const e=I.findIndex(e=>e.id===t.id),l=I.findIndex(e=>e.id===i.id),n=h(I,e,l);D(n),T&&T(n)}},[I,T]),U=t(e=>{const t=I.filter(t=>t.id!==e);D(t),T&&T(t)},[I,T]),B=t(e=>{R(e),F(!0)},[]),N=t(e=>{const t=I.map(t=>t.id===e.id?e:t);D(t),F(!1),R(null),T&&T(t),i.success("字段配置已保存")},[I,T]),S=t(()=>{F(!1),R(null)},[]),P=t(()=>{l.confirm({title:"确认清空",content:"确定要清空所有字段吗?",onOk:()=>{D([]),T&&T([]),i.success("已清空所有字段")}})},[T]),z=t(()=>{const e=I.map(e=>({title:e.title,dataIndex:e.dataIndex,width:e.width,align:e.align,fixed:e.fixed,ellipsis:e.ellipsis,sorter:!1!==e.sortable})),t=JSON.stringify(e,null,2);navigator.clipboard.writeText(t).then(()=>{i.success("配置已复制到剪贴板")}).catch(()=>{i.error("复制失败")})},[I]),J=t(()=>{const e=I.map(e=>({title:e.title,dataIndex:e.dataIndex,width:e.width,align:e.align,fixed:e.fixed,ellipsis:e.ellipsis,sorter:!1!==e.sortable}));L?L(e):(console.log("导出的表格配置:",e),i.success("配置已导出到控制台"))},[I,L]),Z=t(()=>{let e=`<table style="width: ${I.reduce((e,t)=>e+(t.width||150),0)}px; border-collapse: collapse; font-size: 13px;">\n`;return e+=" <thead>\n",e+=" <tr>\n",I.forEach(t=>{const i=t.align||"center";e+=` <th style="width: ${t.width||150}px; text-align: ${i}; padding: 8px 12px; border: 1px solid #f0f0f0; background: #fafafa; font-weight: 600;">${t.title||t.label}</th>\n`}),e+=" </tr>\n",e+=" </thead>\n",e+=" <tbody>\n",e+=" <tr>\n",I.forEach(t=>{const i=t.align||"center";e+=` <td style="width: ${t.width||150}px; text-align: ${i}; padding: 8px 12px; border: 1px solid #f0f0f0;">数据示例</td>\n`}),e+=" </tr>\n",e+=" </tbody>\n",e+="</table>",e},[I]),q=t(()=>{const e=Z();navigator.clipboard.writeText(e).then(()=>{i.success("HTML代码已复制到剪贴板")}).catch(()=>{i.error("复制失败")})},[Z]),A=t(()=>{const e=Z(),t=new Blob([e],{type:"text/html"}),l=URL.createObjectURL(t),n=document.createElement("a");n.href=l,n.download="table.html",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(l),i.success("HTML文件已导出")},[Z]),G=t(e=>{const t={id:H(),type:e.type,label:e.label,title:e.label,dataIndex:`field_${I.length+1}`,width:150,align:"center",ellipsis:!0,sortable:!0},l=[...I,t];D(l),T&&T(l),i.success(`已添加${e.label}字段`)},[I,H,T]);return x("div",{className:"drag-table-builder",children:[y("div",{className:"builder-header",children:x(n,{wrap:!0,children:[y(o,{icon:y(a,{}),onClick:z,disabled:0===I.length,children:"复制配置"}),y(o,{icon:y(s,{}),onClick:J,disabled:0===I.length,children:"导出配置"}),y(o,{icon:y(c,{}),onClick:q,disabled:0===I.length,children:"复制HTML"}),y(o,{icon:y(c,{}),onClick:A,disabled:0===I.length,children:"导出HTML"}),y(o,{icon:y(p,{}),onClick:P,disabled:0===I.length,danger:!0,children:"清空"})]})}),y(b,{onDragEnd:O,children:x(d,{gutter:16,children:[E&&y(r,{span:6,children:y(m,{fields:k,onFieldClick:G})}),x(r,{span:E?18:24,children:[y(f,{fields:I,onRemove:U,onEdit:B}),$&&y("div",{style:{marginTop:16},children:y(u,{fields:I})})]})]})}),j&&y(g,{visible:_,field:M,onSave:N,onCancel:S})]})};export{v as default};
@@ -0,0 +1,8 @@
1
+ .drag-table-builder {
2
+ .builder-header {
3
+ margin-bottom: 16px;
4
+ padding: 12px;
5
+ background: #f5f5f5;
6
+ border-radius: 6px;
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ import{DeleteOutlined as e}from"@ant-design/icons";import{SortableContext as i,verticalListSortingStrategy as t,useSortable as n}from"../../node_modules/@dnd-kit/sortable/dist/sortable.esm";import{CSS as s}from"../../node_modules/@dnd-kit/utilities/dist/utilities.esm";import{Card as a,Empty as d}from"antd";import"../../src/components/DragTableBuilder/DropZone.less";import{jsx as o,jsxs as l}from"react/jsx-runtime";const r=({field:i,onRemove:t,onEdit:a})=>{const{attributes:d,listeners:r,setNodeRef:c,transform:m,transition:p,isDragging:f}=n({id:i.id}),h={transform:s.Transform.toString(m),transition:p,opacity:f?.5:1};return o("div",{ref:c,style:h,...d,...r,className:"sortable-field",children:l("div",{className:"field-content",children:[o("span",{className:"drag-handle",children:"⋮⋮"}),o("span",{className:"field-title",children:i.title||i.label}),o("span",{className:"field-dataindex",children:i.dataIndex||"未设置"}),l("div",{className:"field-actions",children:[o("span",{className:"action-btn edit-btn",onClick:e=>{e.stopPropagation(),a(i)},children:"编辑"}),o("span",{className:"action-btn delete-btn",onClick:e=>{e.stopPropagation(),t(i.id)},children:o(e,{})})]})]})})},c=({fields:e,onRemove:n,onEdit:s,children:l})=>o("div",{className:"drop-zone",children:o(a,{title:"表格字段",size:"small",className:"drop-zone-card",children:0===e.length?o(d,{description:"从左侧点击字段添加到此处",image:d.PRESENTED_IMAGE_SIMPLE}):o(i,{items:e.map(e=>e.id),strategy:t,children:o("div",{className:"field-list",children:e.map(e=>o(r,{field:e,onRemove:n,onEdit:s},e.id))})})})});export{c as default};
@@ -0,0 +1,80 @@
1
+ .drop-zone {
2
+ .drop-zone-card {
3
+ min-height: 400px;
4
+
5
+ .field-list {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 8px;
9
+ }
10
+ }
11
+
12
+ .sortable-field {
13
+ cursor: move;
14
+ transition: all 0.3s;
15
+ border: 1px solid #d9d9d9;
16
+ border-radius: 4px;
17
+ padding: 8px 12px;
18
+ background: #fff;
19
+
20
+ &:hover {
21
+ border-color: #1890ff;
22
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
23
+ }
24
+
25
+ .field-content {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: 12px;
29
+
30
+ .drag-handle {
31
+ cursor: move;
32
+ color: #999;
33
+ font-size: 12px;
34
+ letter-spacing: -2px;
35
+ }
36
+
37
+ .field-title {
38
+ flex: 1;
39
+ font-weight: 500;
40
+ color: #333;
41
+ }
42
+
43
+ .field-dataindex {
44
+ color: #999;
45
+ font-size: 12px;
46
+ font-family: monospace;
47
+ }
48
+
49
+ .field-actions {
50
+ display: flex;
51
+ gap: 8px;
52
+ margin-left: auto;
53
+
54
+ .action-btn {
55
+ cursor: pointer;
56
+ font-size: 12px;
57
+ padding: 2px 8px;
58
+ border-radius: 3px;
59
+ transition: all 0.3s;
60
+
61
+ &.edit-btn {
62
+ color: #1890ff;
63
+
64
+ &:hover {
65
+ background: #e6f7ff;
66
+ }
67
+ }
68
+
69
+ &.delete-btn {
70
+ color: #ff4d4f;
71
+
72
+ &:hover {
73
+ background: #fff1f0;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
@@ -0,0 +1 @@
1
+ import{Select as e,Input as l,Form as i,Modal as a,Space as t,InputNumber as r,Switch as d}from"antd";import{useEffect as n}from"react";import"../../src/components/DragTableBuilder/FieldConfigEditor.less";import{jsx as s,jsxs as o}from"react/jsx-runtime";const{Option:c}=e,{TextArea:h}=l,m=({visible:m,field:u,onSave:p,onCancel:x})=>{const[b]=i.useForm();return n(()=>{m&&u&&b.setFieldsValue({title:u.title||u.label||"",dataIndex:u.dataIndex||"",width:u.width||150,align:u.align||"center",fixed:u.fixed||void 0,ellipsis:void 0===u.ellipsis||u.ellipsis,sortable:void 0===u.sortable||u.sortable,render:u.render||""})},[m,u,b]),s(a,{title:"编辑字段配置",open:m,onOk:()=>{b.validateFields().then(e=>{const l={...u,title:e.title,dataIndex:e.dataIndex,width:e.width,align:e.align,fixed:e.fixed||void 0,ellipsis:e.ellipsis,sortable:e.sortable,render:e.render};p(l)})},onCancel:x,width:600,okText:"保存",cancelText:"取消",children:o(i,{form:b,layout:"vertical",className:"field-config-form",children:[s(i.Item,{label:"列标题",name:"title",rules:[{required:!0,message:"请输入列标题"}],children:s(l,{placeholder:"请输入列标题"})}),s(i.Item,{label:"数据字段名",name:"dataIndex",rules:[{required:!0,message:"请输入数据字段名"}],children:s(l,{placeholder:"请输入数据字段名(如:name, age等)"})}),o(t,{style:{width:"100%"},size:"large",children:[s(i.Item,{label:"列宽度",name:"width",initialValue:150,children:s(r,{min:50,max:1e3,style:{width:120}})}),s(i.Item,{label:"对齐方式",name:"align",initialValue:"center",children:o(e,{style:{width:120},children:[s(c,{value:"left",children:"左对齐"}),s(c,{value:"center",children:"居中"}),s(c,{value:"right",children:"右对齐"})]})})]}),o(t,{style:{width:"100%"},size:"large",children:[s(i.Item,{label:"固定列",name:"fixed",children:o(e,{placeholder:"不固定",style:{width:120},allowClear:!0,children:[s(c,{value:"left",children:"左侧固定"}),s(c,{value:"right",children:"右侧固定"})]})}),s(i.Item,{label:"超长省略",name:"ellipsis",valuePropName:"checked",initialValue:!0,children:s(d,{})}),s(i.Item,{label:"可排序",name:"sortable",valuePropName:"checked",initialValue:!0,children:s(d,{})})]}),s(i.Item,{label:"自定义渲染函数(可选)",name:"render",extra:"请输入函数体,如:return text + '元'",children:s(h,{rows:3,placeholder:"可选:输入自定义渲染函数的函数体"})})]})})};export{m as default};
@@ -0,0 +1,5 @@
1
+ .field-config-form {
2
+ .ant-form-item {
3
+ margin-bottom: 16px;
4
+ }
5
+ }
@@ -0,0 +1 @@
1
+ import{Card as l,Tag as e}from"antd";import"../../src/components/DragTableBuilder/FieldLibrary.less";import{jsx as i,jsxs as a}from"react/jsx-runtime";const c=({field:l,onClick:c})=>i("div",{className:"clickable-field",onClick:()=>c(l),children:a(e,{color:"blue",className:"field-tag",children:[l.icon&&i("span",{className:"field-icon",children:l.icon}),i("span",{className:"field-label",children:l.label})]})}),s=({fields:e,onFieldClick:a})=>i("div",{className:"field-library",children:i(l,{title:"字段库",size:"small",className:"field-library-card",children:i("div",{className:"field-list",children:e.map(l=>i(c,{field:l,onClick:a},l.type))})})});export{s as default};
@@ -0,0 +1,37 @@
1
+ .field-library {
2
+ .field-library-card {
3
+ min-height: 400px;
4
+
5
+ .field-list {
6
+ display: flex;
7
+ flex-wrap: wrap;
8
+ gap: 8px;
9
+ }
10
+ }
11
+
12
+ .clickable-field {
13
+ cursor: pointer;
14
+ transition: all 0.3s;
15
+
16
+ &:hover {
17
+ transform: translateY(-2px);
18
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
19
+ }
20
+
21
+ .field-tag {
22
+ margin: 0;
23
+ padding: 4px 12px;
24
+ font-size: 14px;
25
+ cursor: pointer;
26
+ user-select: none;
27
+
28
+ .field-icon {
29
+ margin-right: 4px;
30
+ }
31
+
32
+ .field-label {
33
+ font-weight: 500;
34
+ }
35
+ }
36
+ }
37
+ }
@@ -0,0 +1 @@
1
+ import{Card as e,Empty as t}from"antd";import"../../src/components/DragTableBuilder/TablePreview.less";import{jsx as r,jsxs as i}from"react/jsx-runtime";const a=({fields:a,dataSource:l})=>{const n=l||(0===a.length?[]:Array.from({length:3},(e,t)=>{const r={};return a.forEach(e=>{const i=e.dataIndex;if(i)switch(e.type){case"text":r[i]=`示例文本${t+1}`;break;case"number":r[i]=Math.floor(1e3*Math.random());break;case"date":r[i]="2024-01-01";break;case"datetime":r[i]="2024-01-01 12:00:00";break;case"select":r[i]=t%2==0?"选项1":"选项2";break;case"boolean":r[i]=t%2==0?"是":"否";break;case"email":r[i]=`example${t}@test.com`;break;case"url":r[i]=`https://example.com/${t}`;break;default:r[i]=`数据${t+1}`}}),r})),s=a.reduce((e,t)=>e+(t.width||150),0);return r("div",{className:"table-preview",children:r(e,{title:"表格预览",size:"small",className:"preview-card",children:0===a.length?r(t,{description:"暂无数据,请先添加字段",image:t.PRESENTED_IMAGE_SIMPLE}):r("div",{className:"native-table-container",children:i("table",{className:"native-table",style:{width:s},children:[r("thead",{children:r("tr",{children:a.map(e=>r("th",{style:{width:e.width||150,textAlign:e.align||"center",position:e.fixed?"sticky":"static",left:"left"===e.fixed?0:"auto",right:"right"===e.fixed?0:"auto",zIndex:e.fixed?2:1},children:e.title||e.label},e.id))})}),r("tbody",{children:n.map((e,t)=>r("tr",{children:a.map(i=>{const a=e[i.dataIndex],l=((e,t,r,i)=>{if(e.render)try{return new Function("text","record","index",e.render)(t,r,i)}catch(e){return console.error("渲染函数执行错误:",e),t}return t})(i,a,e,t);return r("td",{style:{width:i.width||150,textAlign:i.align||"center",overflow:!1!==i.ellipsis?"hidden":"visible",textOverflow:!1!==i.ellipsis?"ellipsis":"clip",whiteSpace:!1!==i.ellipsis?"nowrap":"normal"},title:!1!==i.ellipsis?a:void 0,children:l},i.id)})},t))})]})})})})};export{a as default};
@@ -0,0 +1,69 @@
1
+ .table-preview {
2
+ .preview-card {
3
+ .native-table-container {
4
+ overflow-x: auto;
5
+ overflow-y: auto;
6
+ max-height: 300px;
7
+ border: 1px solid #f0f0f0;
8
+ border-radius: 4px;
9
+ }
10
+
11
+ .native-table {
12
+ width: 100%;
13
+ border-collapse: collapse;
14
+ font-size: 13px;
15
+ background: #fff;
16
+
17
+ thead {
18
+ position: sticky;
19
+ top: 0;
20
+ z-index: 10;
21
+ background: #fafafa;
22
+ }
23
+
24
+ th {
25
+ padding: 8px 12px;
26
+ font-weight: 600;
27
+ color: rgba(0, 0, 0, 0.88);
28
+ background: #fafafa;
29
+ border: 1px solid #f0f0f0;
30
+ white-space: nowrap;
31
+
32
+ &[style*="position: sticky"] {
33
+ background: #fafafa;
34
+ z-index: 2;
35
+ }
36
+ }
37
+
38
+ tbody {
39
+ tr {
40
+ transition: background 0.3s;
41
+
42
+ &:hover {
43
+ background: #fafafa;
44
+ }
45
+
46
+ &:nth-child(even) {
47
+ background: #fafafa;
48
+ }
49
+
50
+ &:hover:nth-child(even) {
51
+ background: #f0f0f0;
52
+ }
53
+ }
54
+ }
55
+
56
+ td {
57
+ padding: 8px 12px;
58
+ color: rgba(0, 0, 0, 0.88);
59
+ border: 1px solid #f0f0f0;
60
+ background: #fff;
61
+
62
+ &[style*="position: sticky"] {
63
+ background: #fff;
64
+ z-index: 1;
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,71 @@
1
+ import type { FC, ReactNode } from "react";
2
+ import type { ColumnsType } from "antd/es/table";
3
+
4
+ /**
5
+ * 字段类型定义
6
+ */
7
+ export interface FieldType {
8
+ /** 字段类型标识 */
9
+ type: string;
10
+ /** 字段显示名称 */
11
+ label: string;
12
+ /** 字段图标 */
13
+ icon?: string;
14
+ }
15
+
16
+ /**
17
+ * 表格字段配置
18
+ */
19
+ export interface TableField {
20
+ /** 字段唯一标识 */
21
+ id: string;
22
+ /** 字段类型 */
23
+ type: string;
24
+ /** 字段标签 */
25
+ label: string;
26
+ /** 列标题 */
27
+ title: string;
28
+ /** 数据字段名 */
29
+ dataIndex: string;
30
+ /** 列宽度 */
31
+ width?: number;
32
+ /** 对齐方式 */
33
+ align?: "left" | "center" | "right";
34
+ /** 固定列 */
35
+ fixed?: "left" | "right";
36
+ /** 超长省略 */
37
+ ellipsis?: boolean;
38
+ /** 可排序 */
39
+ sortable?: boolean;
40
+ /** 自定义渲染函数 */
41
+ render?: string;
42
+ }
43
+
44
+ /**
45
+ * DragTableBuilder 组件属性
46
+ */
47
+ export interface DragTableBuilderProps {
48
+ /** 可用字段类型列表 */
49
+ fieldTypes?: FieldType[];
50
+ /** 初始字段列表 */
51
+ initialFields?: TableField[];
52
+ /** 字段列表变化回调 */
53
+ onChange?: (fields: TableField[]) => void;
54
+ /** 导出配置回调 */
55
+ onExport?: (config: ColumnsType<any>) => void;
56
+ /** 是否显示预览区域 */
57
+ showPreview?: boolean;
58
+ /** 是否显示字段库 */
59
+ showLibrary?: boolean;
60
+ /** 是否显示配置编辑器 */
61
+ showConfigEditor?: boolean;
62
+ /** 自定义预览数据 */
63
+ dataSource?: any[];
64
+ }
65
+
66
+ /**
67
+ * 拖拽式表格构建器组件
68
+ */
69
+ declare const DragTableBuilder: FC<DragTableBuilderProps>;
70
+
71
+ export default DragTableBuilder;
@@ -0,0 +1 @@
1
+ import r from"./DragTableBuilder.js";export{r as default};
@@ -1,5 +1,4 @@
1
1
  import type { FormInstance, FormProps } from "antd/es/form";
2
- import type { useForm, useWatch } from "antd/es/form/Form";
3
2
  import type { Gutter } from "antd/es/grid/row";
4
3
  import type { FC, ReactNode } from "react";
5
4
  import type { FormOption, FormValues } from "./FormItemsRenderer";
@@ -42,8 +41,8 @@ export interface FormBuilderProps extends Omit<FormProps, "form"> {
42
41
  * 表单构建器组件
43
42
  */
44
43
  declare const FormBuilder: FC<FormBuilderProps> & {
45
- useForm: typeof useForm;
46
- useWatch: typeof useWatch;
44
+ useForm: typeof import("antd").Form.useForm;
45
+ useWatch: typeof import("antd").Form.useWatch;
47
46
  };
48
47
 
49
48
  export default FormBuilder;
@@ -2,12 +2,14 @@ import type { ColProps } from "antd/es/col";
2
2
  import type { FormItemProps, Rule } from "antd/es/form";
3
3
  import type { FormListFieldData } from "antd/es/form/FormList";
4
4
  import type { Gutter } from "antd/es/grid/row";
5
- import type { NamePath } from "rc-field-form/lib/interface";
6
5
  import type { FC, ReactNode } from "react";
7
6
  import type { FORM_ITEM_RENDER_TYPE_MAP } from "../../enum/formItemRender";
8
7
 
8
+ /** 表单项 name */
9
+ export type FormFieldName = string | number | (string | number)[];
10
+
9
11
  /**
10
- * 选项项数据类型
12
+ * 选择项数据类型
11
13
  */
12
14
  export interface OptionItem {
13
15
  /** ID字段 */
@@ -22,7 +24,7 @@ export interface OptionItem {
22
24
  /**
23
25
  * 字段键配置
24
26
  */
25
- export interface itemsFieldConfig {
27
+ export interface ItemsFieldConfig {
26
28
  /** 值字段的键名,默认 'bianma' */
27
29
  valueKey?: string;
28
30
  /** 标签字段的键名,默认 'name' */
@@ -71,17 +73,15 @@ export interface FormListUniqueProps {
71
73
  }
72
74
 
73
75
  /**
74
- * 表单配置项
76
+ * 表单配置项公共字段
75
77
  */
76
- export interface FormOption<T extends keyof FORM_ITEM_RENDER_TYPE_MAP = keyof FORM_ITEM_RENDER_TYPE_MAP> {
78
+ export interface FormOptionBase {
77
79
  /** React 需要的 key,如果传递了唯一的 name,则不需要 */
78
80
  key?: string;
79
81
  /** 表单项字段名 */
80
- name?: string | string[];
82
+ name?: FormFieldName;
81
83
  /** 表单项标签 */
82
84
  label?: ReactNode;
83
- /** 渲染类型 */
84
- render?: T | ReactNode;
85
85
  /** 占据栅格列数,默认 12 */
86
86
  span?: number | string;
87
87
  /** 是否必填,默认 true,支持函数动态计算 */
@@ -101,11 +101,9 @@ export interface FormOption<T extends keyof FORM_ITEM_RENDER_TYPE_MAP = keyof FO
101
101
  /** 选项数据(用于 select、radio、checkbox) */
102
102
  items?: OptionItem[];
103
103
  /** 字段键配置 */
104
- itemsField?: itemsFieldConfig;
104
+ itemsField?: ItemsFieldConfig;
105
105
  /** checkbox 的栅格数量,如果不传入不使用栅格,传入才使用 */
106
106
  checkboxCol?: number;
107
- /** 传递给表单控件的属性,支持函数动态计算 */
108
- componentProps?: FORM_ITEM_RENDER_TYPE_MAP[T] | ((formValues: FormValues) => FORM_ITEM_RENDER_TYPE_MAP[T]);
109
107
  /** 传递给 Form.Item 的属性,支持函数动态计算 */
110
108
  formItemProps?: FormItemProps | ((formValues: FormValues) => FormItemProps);
111
109
  /** label 栅格配置,默认直接使用外层的 labelCol,如果 span 等于 24,是外层的 labelCol.span 一半 */
@@ -115,13 +113,48 @@ export interface FormOption<T extends keyof FORM_ITEM_RENDER_TYPE_MAP = keyof FO
115
113
  /** 是否应该更新(用于表单联动) */
116
114
  shouldUpdate?: boolean | ((prevValues: FormValues, nextValues: FormValues, info: { source?: string }) => boolean);
117
115
  /** 依赖字段(用于表单联动) */
118
- dependencies?: NamePath[];
116
+ dependencies?: FormFieldName[];
119
117
  /** 是否仅用于保存标签,不渲染到页面上,只在表单中保存数据,默认 false */
120
118
  onlyForLabel?: boolean;
121
119
  /** Form.List 独有的属性 */
122
120
  formListUniqueProps?: FormListUniqueProps | ((formValues: FormValues) => FormListUniqueProps);
123
121
  }
124
122
 
123
+ /**
124
+ * 按 render 类型区分的表单项
125
+ */
126
+ export type FormOptionByRender<K extends keyof FORM_ITEM_RENDER_TYPE_MAP> = FormOptionBase & {
127
+ /** 渲染类型(写字面量时 componentProps 会按该类型推导) */
128
+ render: K;
129
+ /** 传递给表单控件的属性,类型由 render 决定 */
130
+ componentProps?: FORM_ITEM_RENDER_TYPE_MAP[K] | ((formValues: FormValues) => FORM_ITEM_RENDER_TYPE_MAP[K]);
131
+ };
132
+
133
+ /**
134
+ * 不写 render 或 render 为 input 时的表单项(默认按输入框)
135
+ */
136
+ export type FormOptionDefault = FormOptionBase & {
137
+ render?: "input" | undefined;
138
+ /** 传递给 Input 的属性 */
139
+ componentProps?: FORM_ITEM_RENDER_TYPE_MAP["input"] | ((formValues: FormValues) => FORM_ITEM_RENDER_TYPE_MAP["input"]);
140
+ };
141
+
142
+ /**
143
+ * 自定义渲染时的表单项(render 为 ReactNode 时使用)
144
+ */
145
+ export type FormOptionCustomRender = FormOptionBase & {
146
+ render?: ReactNode;
147
+ componentProps?: Record<string, any> | ((formValues: FormValues) => Record<string, any>);
148
+ };
149
+
150
+ /**
151
+ * 表单配置项
152
+ */
153
+ export type FormOption
154
+ = | FormOptionDefault
155
+ | { [K in keyof FORM_ITEM_RENDER_TYPE_MAP]: FormOptionByRender<K> }[keyof FORM_ITEM_RENDER_TYPE_MAP]
156
+ | FormOptionCustomRender;
157
+
125
158
  /**
126
159
  * FormItemsRenderer 组件属性
127
160
  */
@@ -1,5 +1,4 @@
1
1
  import type { FormInstance, FormProps } from "antd/es/form";
2
- import type { useForm, useWatch } from "antd/es/form/Form";
3
2
  import type { FC, ReactNode } from "react";
4
3
  import type { FormOption } from "../FormBuilder/FormItemsRenderer";
5
4
 
@@ -38,8 +37,8 @@ export interface SearchProps extends Omit<FormProps, "form" | "onFinish"> {
38
37
  * 支持自动展开/收起功能,当表单项超过4个时显示展开/收起按钮
39
38
  */
40
39
  declare const Search: FC<SearchProps> & {
41
- useForm: typeof useForm;
42
- useWatch: typeof useWatch;
40
+ useForm: typeof import("antd").Form.useForm;
41
+ useWatch: typeof import("antd").Form.useWatch;
43
42
  };
44
43
 
45
44
  export default Search;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zy-react-library",
3
3
  "private": false,
4
- "version": "1.2.3",
4
+ "version": "1.2.4",
5
5
  "type": "module",
6
6
  "description": "",
7
7
  "author": "LiuJiaNan",