@speykye/vue-form-engine 0.1.0 → 0.1.1

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 (2) hide show
  1. package/README.md +308 -0
  2. package/package.json +4 -3
package/README.md ADDED
@@ -0,0 +1,308 @@
1
+ # @speykye/vue-form-engine
2
+
3
+ A lightweight UI-agnostic schema-driven form engine for Vue 3.
4
+
5
+ > Status: Experimental / 0.x. The API may change before 1.0.
6
+
7
+ Vue Form Engine is designed for complex business forms that involve conditional fields, custom business blocks, array fields, async validation, hidden payload strategies, and UI adapter requirements.
8
+
9
+ Use native UI form components for simple forms. Use Vue Form Engine when your forms need a reusable runtime protocol and schema-driven behavior.
10
+
11
+ ## Why
12
+
13
+ Vue has many excellent UI form components, such as Ant Design Vue, Element Plus, Vant, Naive UI, and others.
14
+
15
+ However, complex business forms often need more than UI components:
16
+
17
+ - Conditional field visibility
18
+ - Conditional disabled state
19
+ - Hidden field payload strategy
20
+ - Async validation with debounce
21
+ - Custom field registration
22
+ - Custom business block registration
23
+ - Array fields
24
+ - UI-library-independent schema
25
+ - Reusable form behavior across projects
26
+
27
+ Vue Form Engine provides a small runtime layer between your schema and your UI library.
28
+
29
+ ```text
30
+ Schema
31
+
32
+ Core Runtime
33
+
34
+ Vue Renderer
35
+
36
+ UI Adapter
37
+
38
+ Ant Design Vue / Custom Components
39
+ ```
40
+
41
+ ## Install
42
+
43
+ With Ant Design Vue adapter:
44
+
45
+ ```bash
46
+ pnpm add @speykye/vue-form-engine @speykye/vue-form-engine-adapter-antdv ant-design-vue
47
+ ```
48
+
49
+ Or with npm:
50
+
51
+ ```bash
52
+ npm install @speykye/vue-form-engine @speykye/vue-form-engine-adapter-antdv ant-design-vue
53
+ ```
54
+
55
+ ## Basic setup
56
+
57
+ ```ts
58
+ import { createApp } from 'vue';
59
+ import Antd from 'ant-design-vue';
60
+ import 'ant-design-vue/dist/reset.css';
61
+
62
+ import App from './App.vue';
63
+ import { createVueFormEngine } from '@speykye/vue-form-engine';
64
+ import { antdvAdapter } from '@speykye/vue-form-engine-adapter-antdv';
65
+
66
+ const app = createApp(App);
67
+
68
+ app.use(Antd);
69
+
70
+ app.use(
71
+ createVueFormEngine({
72
+ plugins: [antdvAdapter()]
73
+ })
74
+ );
75
+
76
+ app.mount('#app');
77
+ ```
78
+
79
+ ## Basic usage
80
+
81
+ ```vue
82
+ <script setup lang="ts">
83
+ import { ref } from 'vue';
84
+ import type { FormSchema } from '@speykye/vue-form-engine';
85
+
86
+ const model = ref({});
87
+
88
+ const schema: FormSchema = {
89
+ sections: [
90
+ {
91
+ title: 'Account',
92
+ items: [
93
+ {
94
+ key: 'username',
95
+ type: 'input',
96
+ label: 'Username',
97
+ placeholder: 'Please enter username',
98
+ rules: [
99
+ { required: true, message: 'Username is required' }
100
+ ]
101
+ },
102
+ {
103
+ key: 'userType',
104
+ type: 'select',
105
+ label: 'User Type',
106
+ options: [
107
+ { label: 'Normal', value: 'normal' },
108
+ { label: 'Enterprise', value: 'enterprise' }
109
+ ]
110
+ },
111
+ {
112
+ key: 'companyName',
113
+ type: 'input',
114
+ label: 'Company Name',
115
+ visibleWhen: {
116
+ deps: ['userType'],
117
+ predicate: model => model.userType === 'enterprise'
118
+ }
119
+ }
120
+ ]
121
+ }
122
+ ],
123
+ hiddenValueStrategy: 'submitVisibleOnly'
124
+ };
125
+
126
+ function handleSubmit(values: Record<string, any>) {
127
+ console.log('submit values:', values);
128
+ }
129
+ </script>
130
+
131
+ <template>
132
+ <DynamicFormEngine
133
+ v-model="model"
134
+ :schema="schema"
135
+ @submit="handleSubmit"
136
+ />
137
+ </template>
138
+ ```
139
+
140
+ ## Features
141
+
142
+ - UI-agnostic form runtime
143
+ - Schema-driven rendering
144
+ - Core / renderer / adapter architecture
145
+ - Field registry
146
+ - Block registry
147
+ - Custom field support
148
+ - Custom business block support
149
+ - Conditional visibility
150
+ - Conditional disabled state
151
+ - Hidden value strategy
152
+ - Array field support
153
+ - Async validation debounce
154
+ - Ant Design Vue adapter
155
+ - TypeScript support
156
+
157
+ ## Hidden value strategy
158
+
159
+ Complex forms often hide fields based on user choices.
160
+
161
+ For example, when `userType` changes from `enterprise` to `normal`, the `companyName` field may become hidden. Without a payload strategy, the hidden value may still be submitted.
162
+
163
+ Vue Form Engine supports:
164
+
165
+ ```ts
166
+ hiddenValueStrategy: 'keep' | 'clear' | 'submitVisibleOnly'
167
+ ```
168
+
169
+ Recommended default for business forms:
170
+
171
+ ```ts
172
+ hiddenValueStrategy: 'submitVisibleOnly'
173
+ ```
174
+
175
+ This keeps values in the local model but excludes hidden fields from the submitted payload.
176
+
177
+ ## Custom fields
178
+
179
+ You can register custom field components through the form engine.
180
+
181
+ ```ts
182
+ formEngine.registerField('captcha', CaptchaField);
183
+ ```
184
+
185
+ Then use it in schema:
186
+
187
+ ```ts
188
+ {
189
+ key: 'captcha',
190
+ type: 'captcha',
191
+ label: 'Captcha'
192
+ }
193
+ ```
194
+
195
+ A field component should follow the standard field component protocol:
196
+
197
+ - Props: `field`, `modelValue`, `model`, `disabled`, `readonly`, `errorMessage`
198
+ - Emits: `update:modelValue`, `change`, `blur`
199
+
200
+ ## Custom blocks
201
+
202
+ Use custom blocks for business components that control multiple model keys.
203
+
204
+ ```ts
205
+ formEngine.registerBlock('invitationCode', InvitationCodeBlock);
206
+ ```
207
+
208
+ Schema example:
209
+
210
+ ```ts
211
+ {
212
+ kind: 'block',
213
+ key: 'invitationCodeBlock',
214
+ type: 'invitationCode',
215
+ props: {
216
+ invitationCodeKey: 'invitationCode',
217
+ confirmedInvitationCodeKey: 'confirmedInvitationCode',
218
+ invitationVerifiedKey: 'invitationVerified'
219
+ }
220
+ }
221
+ ```
222
+
223
+ Blocks are useful for scenarios such as:
224
+
225
+ - Invitation code verification
226
+ - Captcha groups
227
+ - Address picker with coordinate output
228
+ - Upload widgets
229
+ - Complex business-specific form sections
230
+
231
+ ## Array fields
232
+
233
+ Array fields are useful for repeated object groups.
234
+
235
+ ```ts
236
+ {
237
+ kind: 'array',
238
+ key: 'contacts',
239
+ type: 'array',
240
+ label: 'Contacts',
241
+ minItems: 1,
242
+ maxItems: 5,
243
+ itemFields: [
244
+ {
245
+ key: 'name',
246
+ type: 'input',
247
+ label: 'Name'
248
+ },
249
+ {
250
+ key: 'phone',
251
+ type: 'input',
252
+ label: 'Phone'
253
+ }
254
+ ]
255
+ }
256
+ ```
257
+
258
+ Submitted model:
259
+
260
+ ```ts
261
+ {
262
+ contacts: [
263
+ {
264
+ name: 'Alice',
265
+ phone: '123456'
266
+ }
267
+ ]
268
+ }
269
+ ```
270
+
271
+ ## When should you use this?
272
+
273
+ Use Vue Form Engine when your form has:
274
+
275
+ - Complex conditional logic
276
+ - Many reusable business fields
277
+ - Custom widgets or blocks
278
+ - Dynamic array fields
279
+ - Async validation
280
+ - Hidden value cleanup requirements
281
+ - Multiple UI library targets
282
+ - Internal platform or SaaS form requirements
283
+
284
+ ## When should you not use this?
285
+
286
+ Do not use this engine for very simple forms.
287
+
288
+ For example, if your form only has a few static fields, native UI library forms are usually simpler and better:
289
+
290
+ ```vue
291
+ <el-form>
292
+ <el-input />
293
+ </el-form>
294
+ ```
295
+
296
+ ## Packages
297
+
298
+ - `@speykye/vue-form-engine-core` — core protocol and runtime utilities
299
+ - `@speykye/vue-form-engine` — Vue renderer and plugin
300
+ - `@speykye/vue-form-engine-adapter-antdv` — Ant Design Vue adapter
301
+
302
+ ## Links
303
+
304
+ - GitHub: https://github.com/speykye/vue-form-engine
305
+
306
+ ## License
307
+
308
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speykye/vue-form-engine",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -13,13 +13,14 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "README.md"
17
18
  ],
18
19
  "peerDependencies": {
19
20
  "vue": "^3.5.0"
20
21
  },
21
22
  "dependencies": {
22
- "@speykye/vue-form-engine-core": "^0.1.0"
23
+ "@speykye/vue-form-engine-core": "^0.1.1"
23
24
  },
24
25
  "scripts": {
25
26
  "build": "vue-tsc --declaration --emitDeclarationOnly --outDir dist && vite build",