@xbeeant/form-engine-designer 0.0.3 → 0.0.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.
Files changed (131) hide show
  1. package/dist/es/Canvas.js +42 -47
  2. package/dist/es/Canvas.js.map +1 -1
  3. package/dist/es/Designer.js +121 -98
  4. package/dist/es/Designer.js.map +1 -1
  5. package/dist/es/DesignerContext.js +86 -73
  6. package/dist/es/DesignerContext.js.map +1 -1
  7. package/dist/es/Palette.js +3 -3
  8. package/dist/es/Palette.js.map +1 -1
  9. package/dist/es/PropertyPanel.js +99 -100
  10. package/dist/es/PropertyPanel.js.map +1 -1
  11. package/dist/es/catalog.js +17 -10
  12. package/dist/es/catalog.js.map +1 -1
  13. package/dist/es/designer-context.js +110 -0
  14. package/dist/es/designer-context.js.map +1 -0
  15. package/dist/es/history.js +73 -0
  16. package/dist/es/history.js.map +1 -0
  17. package/dist/es/index.css +1 -1
  18. package/dist/es/index.js +3 -3
  19. package/dist/es/property/basic-property.js +6 -0
  20. package/dist/es/property/basic-property.js.map +1 -1
  21. package/dist/es/property-panel.js +294 -0
  22. package/dist/es/property-panel.js.map +1 -0
  23. package/dist/es/resizable-panel.js +103 -0
  24. package/dist/es/resizable-panel.js.map +1 -0
  25. package/dist/es/schema-utils.js +286 -0
  26. package/dist/es/schema-utils.js.map +1 -0
  27. package/dist/es/widgets/BindEditor.js +60 -49
  28. package/dist/es/widgets/BindEditor.js.map +1 -1
  29. package/dist/es/widgets/CodeEditor.js +41 -49
  30. package/dist/es/widgets/CodeEditor.js.map +1 -1
  31. package/dist/es/widgets/DefaultEditor.js +25 -30
  32. package/dist/es/widgets/DefaultEditor.js.map +1 -1
  33. package/dist/es/widgets/DependenciesEditor.js +21 -21
  34. package/dist/es/widgets/DependenciesEditor.js.map +1 -1
  35. package/dist/es/widgets/EnumEditor.js +25 -31
  36. package/dist/es/widgets/EnumEditor.js.map +1 -1
  37. package/dist/es/widgets/ExpressionSwitch.js +32 -30
  38. package/dist/es/widgets/ExpressionSwitch.js.map +1 -1
  39. package/dist/es/widgets/ReactionsEditor.js +103 -103
  40. package/dist/es/widgets/ReactionsEditor.js.map +1 -1
  41. package/dist/es/widgets/RemoteDataEditor.js +63 -63
  42. package/dist/es/widgets/RemoteDataEditor.js.map +1 -1
  43. package/dist/es/widgets/ValidateEditor.js +49 -49
  44. package/dist/es/widgets/ValidateEditor.js.map +1 -1
  45. package/dist/es/widgets/bind-editor.js +78 -0
  46. package/dist/es/widgets/bind-editor.js.map +1 -0
  47. package/dist/es/widgets/code-editor.js +76 -0
  48. package/dist/es/widgets/code-editor.js.map +1 -0
  49. package/dist/es/widgets/default-editor.js +50 -0
  50. package/dist/es/widgets/default-editor.js.map +1 -0
  51. package/dist/es/widgets/dependencies-editor.js +36 -0
  52. package/dist/es/widgets/dependencies-editor.js.map +1 -0
  53. package/dist/es/widgets/enum-editor.js +43 -0
  54. package/dist/es/widgets/enum-editor.js.map +1 -0
  55. package/dist/es/widgets/expression-builder.js +367 -0
  56. package/dist/es/widgets/expression-builder.js.map +1 -0
  57. package/dist/es/widgets/expression-model.js +340 -0
  58. package/dist/es/widgets/expression-model.js.map +1 -0
  59. package/dist/es/widgets/expression-switch.js +49 -0
  60. package/dist/es/widgets/expression-switch.js.map +1 -0
  61. package/dist/es/widgets/index.js +13 -13
  62. package/dist/es/widgets/index.js.map +1 -1
  63. package/dist/es/widgets/options-editor.js +102 -0
  64. package/dist/es/widgets/options-editor.js.map +1 -0
  65. package/dist/es/widgets/reactions-editor.js +401 -0
  66. package/dist/es/widgets/reactions-editor.js.map +1 -0
  67. package/dist/es/widgets/reactions-model.js +107 -0
  68. package/dist/es/widgets/reactions-model.js.map +1 -0
  69. package/dist/es/widgets/remote-data-editor.js +314 -0
  70. package/dist/es/widgets/remote-data-editor.js.map +1 -0
  71. package/dist/es/widgets/use-form-data-fields.js +16 -0
  72. package/dist/es/widgets/use-form-data-fields.js.map +1 -0
  73. package/dist/es/widgets/validate-editor.js +118 -0
  74. package/dist/es/widgets/validate-editor.js.map +1 -0
  75. package/package.json +4 -5
  76. package/dist/es/react/src/components/FormController.js +0 -160
  77. package/dist/es/react/src/components/FormController.js.map +0 -1
  78. package/dist/es/react/src/components/NexusField.js +0 -98
  79. package/dist/es/react/src/components/NexusField.js.map +0 -1
  80. package/dist/es/react/src/components/NexusForm.js +0 -128
  81. package/dist/es/react/src/components/NexusForm.js.map +0 -1
  82. package/dist/es/react/src/components/NexusFormProvider.js +0 -19
  83. package/dist/es/react/src/components/NexusFormProvider.js.map +0 -1
  84. package/dist/es/react/src/components/NexusLayout.js +0 -49
  85. package/dist/es/react/src/components/NexusLayout.js.map +0 -1
  86. package/dist/es/react/src/components/NexusObject.js +0 -65
  87. package/dist/es/react/src/components/NexusObject.js.map +0 -1
  88. package/dist/es/react/src/contexts/FieldInheritContext.js +0 -6
  89. package/dist/es/react/src/contexts/FieldInheritContext.js.map +0 -1
  90. package/dist/es/react/src/contexts/GridContext.js +0 -6
  91. package/dist/es/react/src/contexts/GridContext.js.map +0 -1
  92. package/dist/es/react/src/contexts/LayoutConfigContext.js +0 -6
  93. package/dist/es/react/src/contexts/LayoutConfigContext.js.map +0 -1
  94. package/dist/es/react/src/contexts/NexusContext.js +0 -13
  95. package/dist/es/react/src/contexts/NexusContext.js.map +0 -1
  96. package/dist/es/react/src/hooks/useForm.js +0 -13
  97. package/dist/es/react/src/hooks/useForm.js.map +0 -1
  98. package/dist/es/react/src/utils/renderTreeNode.js +0 -18
  99. package/dist/es/react/src/utils/renderTreeNode.js.map +0 -1
  100. package/dist/es/react/src/utils/resolveColSpan.js +0 -10
  101. package/dist/es/react/src/utils/resolveColSpan.js.map +0 -1
  102. package/src/Canvas.tsx +0 -1111
  103. package/src/Designer.css +0 -206
  104. package/src/Designer.tsx +0 -254
  105. package/src/DesignerContext.tsx +0 -192
  106. package/src/Palette.tsx +0 -261
  107. package/src/PropertyPanel.tsx +0 -486
  108. package/src/ResizablePanel.tsx +0 -210
  109. package/src/catalog.ts +0 -527
  110. package/src/index.ts +0 -25
  111. package/src/property/basic-property.ts +0 -126
  112. package/src/schemaUtils.test.ts +0 -261
  113. package/src/schemaUtils.ts +0 -627
  114. package/src/types.ts +0 -38
  115. package/src/vite-env.d.ts +0 -1
  116. package/src/widgets/BindEditor.tsx +0 -105
  117. package/src/widgets/CodeEditor.tsx +0 -114
  118. package/src/widgets/DefaultEditor.tsx +0 -73
  119. package/src/widgets/DependenciesEditor.tsx +0 -56
  120. package/src/widgets/EnumEditor.tsx +0 -66
  121. package/src/widgets/ExpressionBuilder.tsx +0 -509
  122. package/src/widgets/ExpressionSwitch.tsx +0 -62
  123. package/src/widgets/OptionsEditor.tsx +0 -141
  124. package/src/widgets/ReactionsEditor.tsx +0 -532
  125. package/src/widgets/RemoteDataEditor.tsx +0 -382
  126. package/src/widgets/ValidateEditor.tsx +0 -162
  127. package/src/widgets/expressionModel.test.ts +0 -262
  128. package/src/widgets/expressionModel.ts +0 -573
  129. package/src/widgets/index.ts +0 -45
  130. package/src/widgets/reactionsModel.ts +0 -190
  131. package/src/widgets/useFormDataFields.ts +0 -21
package/src/Palette.tsx DELETED
@@ -1,261 +0,0 @@
1
- // ============================================================================
2
- // @xbeeant/form-engine-designer — 左侧组件目录面板
3
- // ============================================================================
4
-
5
- import type { SchemaNode } from '@xbeeant/form-engine';
6
- import { Collapse, Input } from 'antd';
7
- import type { DragEvent } from 'react';
8
- import { useCallback, useMemo, useState } from 'react';
9
- import { useDesigner } from './DesignerContext';
10
- import {
11
- generateKey,
12
- getNodeAtProperties,
13
- getPropertiesOf,
14
- } from './schemaUtils';
15
- import type { CatalogItem, FieldDef } from './types';
16
-
17
- // 拖拽负载:palette 组件目录项 or 外部字段定义
18
- export interface PaletteDragPayload {
19
- source: 'palette';
20
- catalogItem: CatalogItem;
21
- }
22
- export interface FieldDefDragPayload {
23
- source: 'fieldDef';
24
- fieldDef: FieldDef;
25
- }
26
- export type PaletteDragData = PaletteDragPayload | FieldDefDragPayload;
27
-
28
- // 面板类型 → 允许的唯一父容器类型(面板不能直接添加到根或普通容器)
29
- const PANE_PARENT_TYPE: Record<string, string> = {
30
- tabPane: 'tabs',
31
- collapsePanel: 'collapse',
32
- step: 'steps',
33
- };
34
-
35
- const isPaneItem = (item: CatalogItem): boolean =>
36
- item.category === 'layout' && !!PANE_PARENT_TYPE[item.layoutType ?? ''];
37
-
38
- function PaletteItem({
39
- item,
40
- onAdd,
41
- }: {
42
- item: CatalogItem;
43
- onAdd: (item: CatalogItem) => void;
44
- }) {
45
- const handleDragStart = (e: DragEvent<HTMLDivElement>) => {
46
- const payload: PaletteDragPayload = {
47
- source: 'palette',
48
- catalogItem: item,
49
- };
50
- e.dataTransfer.setData('application/json', JSON.stringify(payload));
51
- e.dataTransfer.effectAllowed = 'copy';
52
- };
53
-
54
- // 面板类组件只能放入对应容器,点击/拖拽提示差异化
55
- const paneParent = isPaneItem(item)
56
- ? PANE_PARENT_TYPE[item.layoutType ?? '']
57
- : undefined;
58
- const title = paneParent
59
- ? `拖拽「${item.label}」到「${paneParent}」容器中,或选中容器后点击`
60
- : `点击添加或拖拽「${item.label}」到画布`;
61
-
62
- return (
63
- <div
64
- className='group flex flex-col items-center gap-1 rounded-lg border border-[#f0f0f0] bg-white px-1 py-2 cursor-grab select-none transition-all hover:-translate-y-px hover:border-[#1677ff] hover:shadow-[0_2px_8px_rgba(22,119,255,0.12)] active:cursor-grabbing'
65
- draggable
66
- onDragStart={handleDragStart}
67
- onClick={() => onAdd(item)}
68
- title={title}
69
- >
70
- <span className='flex h-7 w-7 items-center justify-center rounded-md bg-[#f5f7fa] text-[15px] transition-colors group-hover:bg-[#e8f1ff]'>
71
- {item.icon}
72
- </span>
73
- <span className='w-full truncate text-center text-xs text-[#666] transition-colors group-hover:text-[#1677ff]'>
74
- {item.label}
75
- </span>
76
- </div>
77
- );
78
- }
79
-
80
- function FieldDefItem({ field }: { field: FieldDef }) {
81
- const handleDragStart = (e: DragEvent<HTMLDivElement>) => {
82
- const payload: FieldDefDragPayload = {
83
- source: 'fieldDef',
84
- fieldDef: field,
85
- };
86
- e.dataTransfer.setData('application/json', JSON.stringify(payload));
87
- e.dataTransfer.effectAllowed = 'copy';
88
- };
89
-
90
- return (
91
- <div
92
- className='flex items-center gap-2 rounded-lg border border-[#f0f0f0] bg-white px-2 py-1.5 cursor-grab select-none transition-all hover:-translate-y-px hover:border-[#1677ff] hover:shadow-[0_2px_8px_rgba(22,119,255,0.12)] active:cursor-grabbing'
93
- draggable
94
- onDragStart={handleDragStart}
95
- title={`id: ${field.id} · widget: ${field.widget}`}
96
- >
97
- <span className='flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-md bg-[#f5f7fa] text-[13px]'>
98
- 🔧
99
- </span>
100
- <span className='truncate text-xs text-[#666]'>{field.name}</span>
101
- </div>
102
- );
103
- }
104
-
105
- export function Palette() {
106
- const {
107
- schema,
108
- selectedPath,
109
- addNode,
110
- fields,
111
- widgetCatalog,
112
- layoutCatalog,
113
- } = useDesigner();
114
- const [keyword, setKeyword] = useState('');
115
-
116
- const handleAdd = useCallback(
117
- (item: CatalogItem) => {
118
- const base = item.widget || item.layoutType || 'field';
119
- // 面板类组件只能放入对应容器:点击时若已选中匹配容器则加入,否则忽略
120
- const paneParentType = isPaneItem(item)
121
- ? PANE_PARENT_TYPE[item.layoutType ?? '']
122
- : undefined;
123
- if (paneParentType) {
124
- if (!selectedPath || selectedPath.length === 0) {
125
- return;
126
- }
127
- const parent = getNodeAtProperties(schema.properties, selectedPath);
128
- if (!parent || parent.type !== paneParentType) {
129
- return;
130
- }
131
- const parentProps = getPropertiesOf(parent);
132
- if (!parentProps) {
133
- return;
134
- }
135
- const key = generateKey(parentProps, base);
136
- addNode(selectedPath, key, item.createNode() as unknown as SchemaNode);
137
- return;
138
- }
139
- const key = generateKey(schema.properties, base);
140
- const node = item.createNode() as unknown as SchemaNode;
141
- addNode([], key, node);
142
- },
143
- [schema, addNode, selectedPath],
144
- );
145
-
146
- const kw = keyword.trim().toLowerCase();
147
-
148
- const widgetItems = useMemo(
149
- () =>
150
- widgetCatalog
151
- .filter((item) => item.label.toLowerCase().includes(kw))
152
- .map((item) => (
153
- <PaletteItem key={item.widget} item={item} onAdd={handleAdd} />
154
- )),
155
- [widgetCatalog, kw, handleAdd],
156
- );
157
-
158
- const layoutItems = useMemo(
159
- () =>
160
- layoutCatalog
161
- .filter((item) => item.label.toLowerCase().includes(kw))
162
- .map((item) => (
163
- <PaletteItem key={item.layoutType} item={item} onAdd={handleAdd} />
164
- )),
165
- [layoutCatalog, kw, handleAdd],
166
- );
167
-
168
- const fieldItems = useMemo(
169
- () =>
170
- (fields ?? [])
171
- .filter((field) => field.name.toLowerCase().includes(kw))
172
- .map((field) => <FieldDefItem key={field.id} field={field} />),
173
- [fields, kw],
174
- );
175
-
176
- const sectionGrid = (items: React.ReactNode[], hasMore: boolean) =>
177
- items.length > 0 ? (
178
- <div className='grid grid-cols-2 gap-1.5 px-1 pb-2'>{items}</div>
179
- ) : (
180
- <div className='py-3 text-center text-xs text-[#c0c4cc]'>
181
- {hasMore ? '无匹配组件' : '暂无组件'}
182
- </div>
183
- );
184
-
185
- const collapseItems = [
186
- {
187
- key: 'widgets',
188
- label: (
189
- <span className='flex w-full items-center justify-between pr-1'>
190
- <span>表单组件</span>
191
- <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>
192
- {widgetItems.length}
193
- </span>
194
- </span>
195
- ),
196
- children: sectionGrid(widgetItems, true),
197
- },
198
- {
199
- key: 'layouts',
200
- label: (
201
- <span className='flex w-full items-center justify-between pr-1'>
202
- <span>布局组件</span>
203
- <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>
204
- {layoutItems.length}
205
- </span>
206
- </span>
207
- ),
208
- children: sectionGrid(layoutItems, true),
209
- },
210
- ];
211
-
212
- // 仅当传入 fields 时显示「字段列表」分组
213
- if (fields && fields.length > 0) {
214
- collapseItems.push({
215
- key: 'fieldList',
216
- label: (
217
- <span className='flex w-full items-center justify-between pr-1'>
218
- <span>字段列表</span>
219
- <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>
220
- {fieldItems.length}
221
- </span>
222
- </span>
223
- ),
224
- children: (
225
- <div className='flex flex-col gap-1.5 px-1 pb-2'>
226
- {fieldItems.length > 0 ? (
227
- fieldItems
228
- ) : (
229
- <div className='py-3 text-center text-xs text-[#c0c4cc]'>
230
- 无匹配字段
231
- </div>
232
- )}
233
- </div>
234
- ),
235
- });
236
- }
237
-
238
- return (
239
- <div className='flex h-full flex-col border-r border-[#f0f0f0] bg-[#f7f8fa]'>
240
- <div className='px-3 pb-2 pt-3'>
241
- <Input
242
- size='small'
243
- allowClear
244
- prefix={<span className='text-xs text-[#bbb]'>🔍</span>}
245
- placeholder='搜索组件…'
246
- value={keyword}
247
- onChange={(e) => setKeyword(e.target.value)}
248
- className='nexus-palette-search'
249
- />
250
- </div>
251
- <div className='flex-1 overflow-y-auto px-2 pb-3'>
252
- <Collapse
253
- className='nexus-palette-collapse'
254
- expandIconPlacement='end'
255
- defaultActiveKey={['widgets', 'layouts']}
256
- items={collapseItems}
257
- />
258
- </div>
259
- </div>
260
- );
261
- }