@dmitryvim/form-builder 0.1.1 → 0.1.5

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