@dmitryvim/form-builder 0.1.37 → 0.1.39
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.
- package/README.md +10 -5
- package/dist/demo.js +77 -74
- package/dist/form-builder.js +216 -85
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/docs/13_form_builder.html +0 -1337
- package/docs/REQUIREMENTS.md +0 -313
- package/docs/integration.md +0 -480
- package/docs/schema.md +0 -433
package/docs/schema.md
DELETED
|
@@ -1,433 +0,0 @@
|
|
|
1
|
-
# Schema Reference
|
|
2
|
-
|
|
3
|
-
Complete reference for Form Builder JSON Schema v0.3 format.
|
|
4
|
-
|
|
5
|
-
## Schema Structure
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
interface FormSchema {
|
|
9
|
-
version: "0.3"; // Required: Schema version
|
|
10
|
-
title: string; // Form title
|
|
11
|
-
elements: FormElement[]; // Array of form elements
|
|
12
|
-
}
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Field Types
|
|
16
|
-
|
|
17
|
-
### Text Field
|
|
18
|
-
|
|
19
|
-
Single line text input with validation.
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"type": "text",
|
|
24
|
-
"key": "name",
|
|
25
|
-
"label": "Full Name",
|
|
26
|
-
"required": true,
|
|
27
|
-
"minLength": 2,
|
|
28
|
-
"maxLength": 50,
|
|
29
|
-
"pattern": "^[A-Za-z ]+$",
|
|
30
|
-
"default": ""
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**Properties:**
|
|
35
|
-
|
|
36
|
-
- `minLength` - Minimum character count
|
|
37
|
-
- `maxLength` - Maximum character count
|
|
38
|
-
- `pattern` - Regular expression for validation
|
|
39
|
-
- `default` - Default value
|
|
40
|
-
|
|
41
|
-
### Textarea Field
|
|
42
|
-
|
|
43
|
-
Multi-line text input.
|
|
44
|
-
|
|
45
|
-
```json
|
|
46
|
-
{
|
|
47
|
-
"type": "textarea",
|
|
48
|
-
"key": "description",
|
|
49
|
-
"label": "Description",
|
|
50
|
-
"required": false,
|
|
51
|
-
"minLength": 0,
|
|
52
|
-
"maxLength": 1000,
|
|
53
|
-
"default": ""
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Properties:** Same as text field
|
|
58
|
-
|
|
59
|
-
### Number Field
|
|
60
|
-
|
|
61
|
-
Numeric input with constraints.
|
|
62
|
-
|
|
63
|
-
```json
|
|
64
|
-
{
|
|
65
|
-
"type": "number",
|
|
66
|
-
"key": "age",
|
|
67
|
-
"label": "Age",
|
|
68
|
-
"required": true,
|
|
69
|
-
"min": 0,
|
|
70
|
-
"max": 120,
|
|
71
|
-
"decimals": 0,
|
|
72
|
-
"step": 1,
|
|
73
|
-
"default": 0
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Properties:**
|
|
78
|
-
|
|
79
|
-
- `min` - Minimum value
|
|
80
|
-
- `max` - Maximum value
|
|
81
|
-
- `decimals` - Number of decimal places (0-8)
|
|
82
|
-
- `step` - Step increment for input
|
|
83
|
-
|
|
84
|
-
### Select Field
|
|
85
|
-
|
|
86
|
-
Dropdown selection with predefined options.
|
|
87
|
-
|
|
88
|
-
```json
|
|
89
|
-
{
|
|
90
|
-
"type": "select",
|
|
91
|
-
"key": "country",
|
|
92
|
-
"label": "Country",
|
|
93
|
-
"required": true,
|
|
94
|
-
"options": [
|
|
95
|
-
{ "value": "us", "label": "United States" },
|
|
96
|
-
{ "value": "ca", "label": "Canada" },
|
|
97
|
-
{ "value": "uk", "label": "United Kingdom" }
|
|
98
|
-
],
|
|
99
|
-
"default": "us"
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**Properties:**
|
|
104
|
-
|
|
105
|
-
- `options` - Array of value/label pairs
|
|
106
|
-
|
|
107
|
-
### File Field
|
|
108
|
-
|
|
109
|
-
Single file upload with preview.
|
|
110
|
-
|
|
111
|
-
```json
|
|
112
|
-
{
|
|
113
|
-
"type": "file",
|
|
114
|
-
"key": "avatar",
|
|
115
|
-
"label": "Profile Picture",
|
|
116
|
-
"required": true,
|
|
117
|
-
"accept": {
|
|
118
|
-
"extensions": ["jpg", "jpeg", "png"],
|
|
119
|
-
"mime": ["image/jpeg", "image/png"]
|
|
120
|
-
},
|
|
121
|
-
"maxSizeMB": 5
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
**Properties:**
|
|
126
|
-
|
|
127
|
-
- `accept.extensions` - Allowed file extensions
|
|
128
|
-
- `accept.mime` - Allowed MIME types
|
|
129
|
-
- `maxSizeMB` - Maximum file size in megabytes
|
|
130
|
-
|
|
131
|
-
### Files Field
|
|
132
|
-
|
|
133
|
-
Multiple file upload with count limits.
|
|
134
|
-
|
|
135
|
-
```json
|
|
136
|
-
{
|
|
137
|
-
"type": "files",
|
|
138
|
-
"key": "documents",
|
|
139
|
-
"label": "Documents",
|
|
140
|
-
"required": false,
|
|
141
|
-
"accept": {
|
|
142
|
-
"extensions": ["pdf", "doc", "docx"],
|
|
143
|
-
"mime": ["application/pdf"]
|
|
144
|
-
},
|
|
145
|
-
"minCount": 0,
|
|
146
|
-
"maxCount": 5,
|
|
147
|
-
"maxSizeMB": 10
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**Properties:**
|
|
152
|
-
|
|
153
|
-
- `minCount` - Minimum number of files
|
|
154
|
-
- `maxCount` - Maximum number of files
|
|
155
|
-
- All `file` type properties
|
|
156
|
-
|
|
157
|
-
### Group Field
|
|
158
|
-
|
|
159
|
-
Nested object structure with optional repetition.
|
|
160
|
-
|
|
161
|
-
```json
|
|
162
|
-
{
|
|
163
|
-
"type": "group",
|
|
164
|
-
"key": "address",
|
|
165
|
-
"label": "Address",
|
|
166
|
-
"elements": [
|
|
167
|
-
{
|
|
168
|
-
"type": "text",
|
|
169
|
-
"key": "street",
|
|
170
|
-
"label": "Street Address",
|
|
171
|
-
"required": true
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
"type": "text",
|
|
175
|
-
"key": "city",
|
|
176
|
-
"label": "City",
|
|
177
|
-
"required": true
|
|
178
|
-
}
|
|
179
|
-
]
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
**With Repetition and Custom Element Titles:**
|
|
184
|
-
|
|
185
|
-
```json
|
|
186
|
-
{
|
|
187
|
-
"type": "group",
|
|
188
|
-
"key": "slides",
|
|
189
|
-
"label": "Video Slides",
|
|
190
|
-
"element_label": "Slide $index",
|
|
191
|
-
"repeat": {
|
|
192
|
-
"min": 1,
|
|
193
|
-
"max": 5
|
|
194
|
-
},
|
|
195
|
-
"elements": [
|
|
196
|
-
{
|
|
197
|
-
"type": "file",
|
|
198
|
-
"key": "image",
|
|
199
|
-
"label": "Slide Image",
|
|
200
|
-
"required": true
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
"type": "text",
|
|
204
|
-
"key": "title",
|
|
205
|
-
"label": "Slide Title",
|
|
206
|
-
"required": true
|
|
207
|
-
}
|
|
208
|
-
]
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**Properties:**
|
|
213
|
-
|
|
214
|
-
- `elements` - Array of nested form elements
|
|
215
|
-
- `element_label` - Optional custom title for each group item (supports `$index` placeholder)
|
|
216
|
-
- `repeat.min` - Minimum number of repetitions
|
|
217
|
-
- `repeat.max` - Maximum number of repetitions
|
|
218
|
-
|
|
219
|
-
## Common Properties
|
|
220
|
-
|
|
221
|
-
All field types support these properties:
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
interface BaseElement {
|
|
225
|
-
type: string; // Field type
|
|
226
|
-
key: string; // Unique identifier
|
|
227
|
-
label: string; // Display label
|
|
228
|
-
required?: boolean; // Required validation (default: false)
|
|
229
|
-
default?: any; // Default value (not allowed for file types)
|
|
230
|
-
}
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## Complete Example
|
|
234
|
-
|
|
235
|
-
Based on the sample from `docs/13_form_builder.html`:
|
|
236
|
-
|
|
237
|
-
```json
|
|
238
|
-
{
|
|
239
|
-
"version": "0.3",
|
|
240
|
-
"title": "Asset Uploader with Slides",
|
|
241
|
-
"elements": [
|
|
242
|
-
{
|
|
243
|
-
"type": "file",
|
|
244
|
-
"key": "cover",
|
|
245
|
-
"label": "Cover image",
|
|
246
|
-
"required": true,
|
|
247
|
-
"accept": {
|
|
248
|
-
"extensions": ["png", "jpg", "jpeg"],
|
|
249
|
-
"mime": ["image/png", "image/jpeg"]
|
|
250
|
-
},
|
|
251
|
-
"maxSizeMB": 25
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
"type": "files",
|
|
255
|
-
"key": "assets",
|
|
256
|
-
"label": "Additional images",
|
|
257
|
-
"required": false,
|
|
258
|
-
"accept": {
|
|
259
|
-
"extensions": ["png", "jpg"],
|
|
260
|
-
"mime": ["image/png", "image/jpeg"]
|
|
261
|
-
},
|
|
262
|
-
"minCount": 0,
|
|
263
|
-
"maxCount": 10,
|
|
264
|
-
"maxSizeMB": 25
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
"type": "text",
|
|
268
|
-
"key": "title",
|
|
269
|
-
"label": "Project title",
|
|
270
|
-
"required": true,
|
|
271
|
-
"minLength": 1,
|
|
272
|
-
"maxLength": 120,
|
|
273
|
-
"pattern": "^[A-Za-z0-9 _-]+$",
|
|
274
|
-
"default": "My Project"
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
"type": "textarea",
|
|
278
|
-
"key": "description",
|
|
279
|
-
"label": "Description",
|
|
280
|
-
"required": false,
|
|
281
|
-
"minLength": 0,
|
|
282
|
-
"maxLength": 2000,
|
|
283
|
-
"default": ""
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
"type": "select",
|
|
287
|
-
"key": "theme",
|
|
288
|
-
"label": "Theme",
|
|
289
|
-
"required": true,
|
|
290
|
-
"options": [
|
|
291
|
-
{ "value": "light", "label": "Light" },
|
|
292
|
-
{ "value": "dark", "label": "Dark" }
|
|
293
|
-
],
|
|
294
|
-
"default": "dark"
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
"type": "number",
|
|
298
|
-
"key": "opacity",
|
|
299
|
-
"label": "Opacity",
|
|
300
|
-
"required": true,
|
|
301
|
-
"min": 0,
|
|
302
|
-
"max": 1,
|
|
303
|
-
"decimals": 2,
|
|
304
|
-
"step": 0.01,
|
|
305
|
-
"default": 0.85
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
"type": "group",
|
|
309
|
-
"key": "slides",
|
|
310
|
-
"label": "Slides",
|
|
311
|
-
"repeat": {
|
|
312
|
-
"min": 1,
|
|
313
|
-
"max": 5
|
|
314
|
-
},
|
|
315
|
-
"elements": [
|
|
316
|
-
{
|
|
317
|
-
"type": "text",
|
|
318
|
-
"key": "title",
|
|
319
|
-
"label": "Slide title",
|
|
320
|
-
"required": true,
|
|
321
|
-
"minLength": 1,
|
|
322
|
-
"maxLength": 80,
|
|
323
|
-
"default": ""
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
"type": "textarea",
|
|
327
|
-
"key": "body",
|
|
328
|
-
"label": "Slide text",
|
|
329
|
-
"required": true,
|
|
330
|
-
"minLength": 1,
|
|
331
|
-
"maxLength": 1000,
|
|
332
|
-
"default": ""
|
|
333
|
-
}
|
|
334
|
-
]
|
|
335
|
-
}
|
|
336
|
-
]
|
|
337
|
-
}
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
## Output Format
|
|
341
|
-
|
|
342
|
-
Form submission produces structured JSON data:
|
|
343
|
-
|
|
344
|
-
```json
|
|
345
|
-
{
|
|
346
|
-
"cover": "res_abc123def456",
|
|
347
|
-
"assets": ["res_def456ghi789", "res_ghi789jkl012"],
|
|
348
|
-
"title": "My Amazing Project",
|
|
349
|
-
"description": "A detailed description of the project...",
|
|
350
|
-
"theme": "dark",
|
|
351
|
-
"opacity": 0.85,
|
|
352
|
-
"slides": [
|
|
353
|
-
{
|
|
354
|
-
"title": "Introduction",
|
|
355
|
-
"body": "Welcome to our presentation..."
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
"title": "Features",
|
|
359
|
-
"body": "Here are the key features..."
|
|
360
|
-
}
|
|
361
|
-
]
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
**Key Points:**
|
|
366
|
-
|
|
367
|
-
- File fields return resource IDs (e.g., `res_abc123def456`)
|
|
368
|
-
- Files fields return arrays of resource IDs
|
|
369
|
-
- Group fields return objects or arrays of objects
|
|
370
|
-
- All other fields return their literal values
|
|
371
|
-
|
|
372
|
-
## Validation Rules
|
|
373
|
-
|
|
374
|
-
### Schema Validation
|
|
375
|
-
|
|
376
|
-
The form builder validates schemas before rendering:
|
|
377
|
-
|
|
378
|
-
- `version` must be `"0.3"`
|
|
379
|
-
- `elements` must be an array
|
|
380
|
-
- Each element must have `type` and `key`
|
|
381
|
-
- No duplicate keys within the same scope
|
|
382
|
-
- File fields cannot have `default` values
|
|
383
|
-
- Select fields' `default` must be in `options`
|
|
384
|
-
- Numeric constraints must be logical (min ≤ max)
|
|
385
|
-
|
|
386
|
-
### Field Validation
|
|
387
|
-
|
|
388
|
-
During form interaction:
|
|
389
|
-
|
|
390
|
-
- **Required fields**: Must have values
|
|
391
|
-
- **Text/Textarea**: Length constraints and pattern matching
|
|
392
|
-
- **Number**: Range constraints and decimal places
|
|
393
|
-
- **File/Files**: Type restrictions, size limits, count limits
|
|
394
|
-
- **Select**: Value must be in options list
|
|
395
|
-
|
|
396
|
-
### Custom Validation
|
|
397
|
-
|
|
398
|
-
For advanced validation, handle the `formSubmit` event:
|
|
399
|
-
|
|
400
|
-
```javascript
|
|
401
|
-
window.addEventListener("message", (event) => {
|
|
402
|
-
if (event.data.type === "formSubmit") {
|
|
403
|
-
const { data, schema } = event.data;
|
|
404
|
-
|
|
405
|
-
// Custom validation logic
|
|
406
|
-
if (data.email && !isValidEmail(data.email)) {
|
|
407
|
-
// Handle validation error
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Process valid submission
|
|
412
|
-
handleFormSubmission(data);
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
## Schema Evolution
|
|
418
|
-
|
|
419
|
-
### Version History
|
|
420
|
-
|
|
421
|
-
- **v0.3**: Current version with file upload support
|
|
422
|
-
- Future versions will maintain backwards compatibility within the same major version
|
|
423
|
-
|
|
424
|
-
### Migration Guidelines
|
|
425
|
-
|
|
426
|
-
When updating schemas:
|
|
427
|
-
|
|
428
|
-
1. Always specify the correct version
|
|
429
|
-
2. Test with the form builder before deployment
|
|
430
|
-
3. Use schema validation to catch errors early
|
|
431
|
-
4. Provide migration paths for breaking changes
|
|
432
|
-
|
|
433
|
-
This schema reference provides complete documentation for creating effective forms with the Form Builder library.
|