@dmitryvim/form-builder 0.1.41 → 0.2.0

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 (35) hide show
  1. package/README.md +244 -22
  2. package/dist/browser/formbuilder.min.js +179 -0
  3. package/dist/browser/formbuilder.v0.2.0.min.js +179 -0
  4. package/dist/cjs/index.cjs +3582 -0
  5. package/dist/cjs/index.cjs.map +1 -0
  6. package/dist/esm/index.js +3534 -0
  7. package/dist/esm/index.js.map +1 -0
  8. package/dist/form-builder.js +152 -3372
  9. package/dist/types/components/container.d.ts +15 -0
  10. package/dist/types/components/file.d.ts +26 -0
  11. package/dist/types/components/group.d.ts +24 -0
  12. package/dist/types/components/index.d.ts +11 -0
  13. package/dist/types/components/number.d.ts +11 -0
  14. package/dist/types/components/registry.d.ts +15 -0
  15. package/dist/types/components/select.d.ts +11 -0
  16. package/dist/types/components/text.d.ts +11 -0
  17. package/dist/types/components/textarea.d.ts +11 -0
  18. package/dist/types/index.d.ts +33 -0
  19. package/dist/types/instance/FormBuilderInstance.d.ts +134 -0
  20. package/dist/types/instance/state.d.ts +13 -0
  21. package/dist/types/styles/theme.d.ts +63 -0
  22. package/dist/types/types/component-operations.d.ts +45 -0
  23. package/dist/types/types/config.d.ts +44 -0
  24. package/dist/types/types/index.d.ts +4 -0
  25. package/dist/types/types/schema.d.ts +115 -0
  26. package/dist/types/types/state.d.ts +11 -0
  27. package/dist/types/utils/helpers.d.ts +4 -0
  28. package/dist/types/utils/styles.d.ts +21 -0
  29. package/dist/types/utils/translation.d.ts +8 -0
  30. package/dist/types/utils/validation.d.ts +2 -0
  31. package/package.json +35 -15
  32. package/dist/demo.js +0 -861
  33. package/dist/elements.html +0 -1130
  34. package/dist/elements.js +0 -488
  35. package/dist/index.html +0 -315
@@ -1,1130 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <title>Form Builder - Element Types Documentation</title>
6
- <meta name="viewport" content="width=device-width, initial-scale=1" />
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <script>
9
- tailwind.config = {
10
- darkMode: "media",
11
- theme: {
12
- extend: {
13
- fontFamily: {
14
- mono: [
15
- "ui-monospace",
16
- "SFMono-Regular",
17
- "Menlo",
18
- "Monaco",
19
- "Consolas",
20
- '"Liberation Mono"',
21
- '"Courier New"',
22
- "monospace",
23
- ],
24
- },
25
- },
26
- },
27
- };
28
- </script>
29
- <style>
30
- /* Custom styles for form validation states */
31
- .invalid {
32
- @apply border-red-500 !important;
33
- }
34
- .field-hint {
35
- @apply text-gray-500 text-xs mt-1;
36
- }
37
- .error-message {
38
- @apply text-red-500 text-xs mt-1;
39
- }
40
- .file-preview-container {
41
- @apply mb-3 p-3 border border-dashed border-gray-300 rounded-lg min-h-[60px] flex items-center justify-center bg-blue-50;
42
- }
43
- .dark .file-preview-container {
44
- @apply bg-blue-900/20 border-gray-600;
45
- }
46
- .resource-pill {
47
- @apply inline-flex items-center gap-1.5 bg-blue-50 border border-gray-300 rounded-full px-2.5 py-1 font-mono text-xs m-0.5;
48
- }
49
- .dark .resource-pill {
50
- @apply bg-blue-900/20 border-gray-600;
51
- }
52
-
53
- /* Toggle switch styles */
54
- .toggle-switch {
55
- position: relative;
56
- display: inline-block;
57
- width: 60px;
58
- height: 34px;
59
- }
60
-
61
- .toggle-switch input {
62
- opacity: 0;
63
- width: 0;
64
- height: 0;
65
- }
66
-
67
- .toggle-slider {
68
- position: absolute;
69
- cursor: pointer;
70
- top: 0;
71
- left: 0;
72
- right: 0;
73
- bottom: 0;
74
- background-color: #ccc;
75
- transition: 0.4s;
76
- border-radius: 34px;
77
- }
78
-
79
- .toggle-slider:before {
80
- position: absolute;
81
- content: "";
82
- height: 26px;
83
- width: 26px;
84
- left: 4px;
85
- bottom: 4px;
86
- background-color: white;
87
- transition: 0.4s;
88
- border-radius: 50%;
89
- }
90
-
91
- input:checked + .toggle-slider {
92
- background-color: #2563eb;
93
- }
94
-
95
- input:checked + .toggle-slider:before {
96
- transform: translateX(26px);
97
- }
98
-
99
- /* Navigation styles */
100
- .nav-item {
101
- @apply block px-3 py-2 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-gray-900 transition-colors;
102
- }
103
- .nav-item.active {
104
- @apply bg-blue-100 text-blue-900;
105
- }
106
- </style>
107
- </head>
108
- <body class="bg-gray-50">
109
- <!-- Header -->
110
- <div class="bg-white border-b border-gray-200 px-6 py-4">
111
- <div class="flex items-center justify-between">
112
- <div class="flex items-center space-x-3">
113
- <div
114
- class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center"
115
- >
116
- <span class="text-white font-bold text-sm">FB</span>
117
- </div>
118
- <div>
119
- <h1 class="text-lg font-bold text-gray-800">
120
- Form Builder - Element Types
121
- </h1>
122
- <p class="text-xs text-gray-500">
123
- Complete documentation for all form field types
124
- </p>
125
- </div>
126
- </div>
127
- <div class="flex items-center space-x-4">
128
- <a
129
- href="./index.html"
130
- class="text-sm text-blue-600 hover:text-blue-800"
131
- >← Back to Demo</a
132
- >
133
- </div>
134
- </div>
135
- </div>
136
-
137
- <!-- Main Content -->
138
- <div class="flex">
139
- <!-- Left Navigation -->
140
- <div class="w-64 bg-white border-r border-gray-200 min-h-screen">
141
- <div class="p-4">
142
- <h3 class="text-sm font-semibold text-gray-900 mb-3">
143
- Element Types
144
- </h3>
145
- <nav class="space-y-1">
146
- <a href="#text" class="nav-item" data-element="text">Text Input</a>
147
- <a
148
- href="#text-multiple"
149
- class="nav-item"
150
- data-element="text-multiple"
151
- >Text Input (Multiple)</a
152
- >
153
- <a href="#textarea" class="nav-item" data-element="textarea"
154
- >Textarea</a
155
- >
156
- <a
157
- href="#textarea-multiple"
158
- class="nav-item"
159
- data-element="textarea-multiple"
160
- >Textarea (Multiple)</a
161
- >
162
- <a href="#number" class="nav-item" data-element="number"
163
- >Number Input</a
164
- >
165
- <a
166
- href="#number-multiple"
167
- class="nav-item"
168
- data-element="number-multiple"
169
- >Number Input (Multiple)</a
170
- >
171
- <a href="#select" class="nav-item" data-element="select"
172
- >Select Dropdown</a
173
- >
174
- <a
175
- href="#select-multiple"
176
- class="nav-item"
177
- data-element="select-multiple"
178
- >Select Dropdown (Multiple)</a
179
- >
180
- <a href="#file" class="nav-item" data-element="file">File Upload</a>
181
- <a href="#files" class="nav-item" data-element="files"
182
- >Multiple Files (Legacy)</a
183
- >
184
- <a href="#container" class="nav-item" data-element="container"
185
- >Container</a
186
- >
187
- <a href="#group" class="nav-item" data-element="group"
188
- >Group (Legacy)</a
189
- >
190
- </nav>
191
- </div>
192
- </div>
193
-
194
- <!-- Main Content Area -->
195
- <div class="flex-1 p-6">
196
- <!-- Text Element -->
197
- <div id="text" class="element-section mb-16">
198
- <h2 class="text-2xl font-bold text-gray-900 mb-4">Text Input</h2>
199
- <p class="text-gray-700 mb-4">
200
- Single line text input with pattern validation and length
201
- constraints.
202
- </p>
203
- <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
204
- <p class="text-sm text-blue-800">
205
- <strong>Hidden Fields:</strong> Set <code>hidden: true</code> to
206
- hide the field from display while including its value in form
207
- data. Hidden fields use their <code>default</code> value and are
208
- not rendered in the form.
209
- </p>
210
- </div>
211
-
212
- <div class="grid grid-cols-2 gap-6">
213
- <!-- Schema Editor -->
214
- <div>
215
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
216
- Schema Definition
217
- </h3>
218
- <textarea
219
- id="text-schema"
220
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
221
- spellcheck="false"
222
- >
223
- {
224
- "type": "text",
225
- "key": "username",
226
- "label": "Username",
227
- "placeholder": "Enter your username",
228
- "required": true,
229
- "minLength": 3,
230
- "maxLength": 20,
231
- "pattern": "^[a-zA-Z0-9_]+$",
232
- "description": "Username must be 3-20 characters, alphanumeric and underscore only",
233
- "default": "",
234
- "actions": [
235
- {
236
- "value": "check_availability",
237
- "label": "Check Availability"
238
- }
239
- ],
240
- "hidden": false
241
- }</textarea
242
- >
243
- </div>
244
-
245
- <!-- Live Preview -->
246
- <div>
247
- <div class="flex items-center justify-between mb-3">
248
- <h3 class="text-lg font-semibold text-gray-900">
249
- Live Preview
250
- </h3>
251
- <div class="flex items-center space-x-3">
252
- <span class="text-sm font-medium text-gray-700"
253
- >Read Only</span
254
- >
255
- <label class="toggle-switch">
256
- <input
257
- type="checkbox"
258
- class="readonly-toggle"
259
- data-element="text"
260
- />
261
- <span class="toggle-slider"></span>
262
- </label>
263
- </div>
264
- </div>
265
- <div
266
- id="text-preview"
267
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
268
- ></div>
269
- </div>
270
- </div>
271
-
272
- <div class="mt-6">
273
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
274
- Available Properties
275
- </h3>
276
- <div class="bg-gray-50 rounded-lg p-4">
277
- <ul class="space-y-2 text-sm">
278
- <li><strong>type:</strong> "text" (required)</li>
279
- <li><strong>key:</strong> Field identifier (required)</li>
280
- <li><strong>label:</strong> Display label for the field</li>
281
- <li><strong>placeholder:</strong> Placeholder text</li>
282
- <li>
283
- <strong>required:</strong> Whether field is required (boolean)
284
- </li>
285
- <li>
286
- <strong>minLength:</strong> Minimum character length (number)
287
- </li>
288
- <li>
289
- <strong>maxLength:</strong> Maximum character length (number)
290
- </li>
291
- <li>
292
- <strong>pattern:</strong> Regular expression for validation
293
- </li>
294
- <li><strong>default:</strong> Default value</li>
295
- <li>
296
- <strong>description:</strong> Field description (shows in
297
- tooltip)
298
- </li>
299
- <li>
300
- <strong>hint:</strong> Additional hint text (shows in tooltip)
301
- </li>
302
- <li>
303
- <strong>actions:</strong> Array of action buttons for readonly
304
- mode
305
- </li>
306
- <li>
307
- <strong>hidden:</strong> Hide field from form display but
308
- include in data (boolean)
309
- </li>
310
- </ul>
311
- </div>
312
- </div>
313
- </div>
314
-
315
- <!-- Textarea Element -->
316
- <div id="textarea" class="element-section mb-16">
317
- <h2 class="text-2xl font-bold text-gray-900 mb-4">Textarea</h2>
318
- <p class="text-gray-700 mb-6">
319
- Multi-line text input with configurable row height.
320
- </p>
321
-
322
- <div class="grid grid-cols-2 gap-6">
323
- <div>
324
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
325
- Schema Definition
326
- </h3>
327
- <textarea
328
- id="textarea-schema"
329
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
330
- spellcheck="false"
331
- >
332
- {
333
- "type": "textarea",
334
- "key": "description",
335
- "label": "Description",
336
- "placeholder": "Enter detailed description...",
337
- "rows": 6,
338
- "required": false,
339
- "minLength": 10,
340
- "maxLength": 500,
341
- "description": "Provide a detailed description of your project"
342
- }</textarea
343
- >
344
- </div>
345
-
346
- <div>
347
- <div class="flex items-center justify-between mb-3">
348
- <h3 class="text-lg font-semibold text-gray-900">
349
- Live Preview
350
- </h3>
351
- <div class="flex items-center space-x-3">
352
- <span class="text-sm font-medium text-gray-700"
353
- >Read Only</span
354
- >
355
- <label class="toggle-switch">
356
- <input
357
- type="checkbox"
358
- class="readonly-toggle"
359
- data-element="textarea"
360
- />
361
- <span class="toggle-slider"></span>
362
- </label>
363
- </div>
364
- </div>
365
- <div
366
- id="textarea-preview"
367
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
368
- ></div>
369
- </div>
370
- </div>
371
-
372
- <div class="mt-6">
373
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
374
- Available Properties
375
- </h3>
376
- <div class="bg-gray-50 rounded-lg p-4">
377
- <ul class="space-y-2 text-sm">
378
- <li><strong>type:</strong> "textarea" (required)</li>
379
- <li><strong>key:</strong> Field identifier (required)</li>
380
- <li><strong>label:</strong> Display label for the field</li>
381
- <li><strong>placeholder:</strong> Placeholder text</li>
382
- <li>
383
- <strong>rows:</strong> Number of visible rows (default: 4)
384
- </li>
385
- <li>
386
- <strong>required:</strong> Whether field is required (boolean)
387
- </li>
388
- <li>
389
- <strong>minLength:</strong> Minimum character length (number)
390
- </li>
391
- <li>
392
- <strong>maxLength:</strong> Maximum character length (number)
393
- </li>
394
- <li><strong>default:</strong> Default value</li>
395
- <li>
396
- <strong>description:</strong> Field description (shows in
397
- tooltip)
398
- </li>
399
- <li>
400
- <strong>hint:</strong> Additional hint text (shows in tooltip)
401
- </li>
402
- <li>
403
- <strong>actions:</strong> Array of action buttons for readonly
404
- mode
405
- </li>
406
- <li>
407
- <strong>hidden:</strong> Hide field from form display but
408
- include in data (boolean)
409
- </li>
410
- </ul>
411
- </div>
412
- </div>
413
- </div>
414
-
415
- <!-- Number Element -->
416
- <div id="number" class="element-section mb-16">
417
- <h2 class="text-2xl font-bold text-gray-900 mb-4">Number Input</h2>
418
- <p class="text-gray-700 mb-6">
419
- Numeric input with min/max/step validation.
420
- </p>
421
-
422
- <div class="grid grid-cols-2 gap-6">
423
- <div>
424
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
425
- Schema Definition
426
- </h3>
427
- <textarea
428
- id="number-schema"
429
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
430
- spellcheck="false"
431
- >
432
- {
433
- "type": "number",
434
- "key": "price",
435
- "label": "Price (USD)",
436
- "placeholder": "0.00",
437
- "required": true,
438
- "min": 0,
439
- "max": 10000,
440
- "step": 0.01,
441
- "default": 99.99,
442
- "description": "Product price in US dollars"
443
- }</textarea
444
- >
445
- </div>
446
-
447
- <div>
448
- <div class="flex items-center justify-between mb-3">
449
- <h3 class="text-lg font-semibold text-gray-900">
450
- Live Preview
451
- </h3>
452
- <div class="flex items-center space-x-3">
453
- <span class="text-sm font-medium text-gray-700"
454
- >Read Only</span
455
- >
456
- <label class="toggle-switch">
457
- <input
458
- type="checkbox"
459
- class="readonly-toggle"
460
- data-element="number"
461
- />
462
- <span class="toggle-slider"></span>
463
- </label>
464
- </div>
465
- </div>
466
- <div
467
- id="number-preview"
468
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
469
- ></div>
470
- </div>
471
- </div>
472
-
473
- <div class="mt-6">
474
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
475
- Available Properties
476
- </h3>
477
- <div class="bg-gray-50 rounded-lg p-4">
478
- <ul class="space-y-2 text-sm">
479
- <li><strong>type:</strong> "number" (required)</li>
480
- <li><strong>key:</strong> Field identifier (required)</li>
481
- <li><strong>label:</strong> Display label for the field</li>
482
- <li><strong>placeholder:</strong> Placeholder text</li>
483
- <li>
484
- <strong>required:</strong> Whether field is required (boolean)
485
- </li>
486
- <li><strong>min:</strong> Minimum value (number)</li>
487
- <li><strong>max:</strong> Maximum value (number)</li>
488
- <li>
489
- <strong>step:</strong> Step increment for input controls
490
- </li>
491
- <li><strong>default:</strong> Default value</li>
492
- <li>
493
- <strong>description:</strong> Field description (shows in
494
- tooltip)
495
- </li>
496
- <li>
497
- <strong>hint:</strong> Additional hint text (shows in tooltip)
498
- </li>
499
- <li>
500
- <strong>actions:</strong> Array of action buttons for readonly
501
- mode
502
- </li>
503
- <li>
504
- <strong>hidden:</strong> Hide field from form display but
505
- include in data (boolean)
506
- </li>
507
- </ul>
508
- </div>
509
- </div>
510
- </div>
511
-
512
- <!-- Select Element -->
513
- <div id="select" class="element-section mb-16">
514
- <h2 class="text-2xl font-bold text-gray-900 mb-4">Select Dropdown</h2>
515
- <p class="text-gray-700 mb-6">
516
- Dropdown selection with predefined options.
517
- </p>
518
-
519
- <div class="grid grid-cols-2 gap-6">
520
- <div>
521
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
522
- Schema Definition
523
- </h3>
524
- <textarea
525
- id="select-schema"
526
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
527
- spellcheck="false"
528
- >
529
- {
530
- "type": "select",
531
- "key": "category",
532
- "label": "Product Category",
533
- "required": true,
534
- "options": [
535
- {"value": "electronics", "label": "Electronics"},
536
- {"value": "clothing", "label": "Clothing & Apparel"},
537
- {"value": "books", "label": "Books & Media"},
538
- {"value": "home", "label": "Home & Garden"},
539
- {"value": "sports", "label": "Sports & Recreation"}
540
- ],
541
- "default": "electronics",
542
- "description": "Select the primary category for your product"
543
- }</textarea
544
- >
545
- </div>
546
-
547
- <div>
548
- <div class="flex items-center justify-between mb-3">
549
- <h3 class="text-lg font-semibold text-gray-900">
550
- Live Preview
551
- </h3>
552
- <div class="flex items-center space-x-3">
553
- <span class="text-sm font-medium text-gray-700"
554
- >Read Only</span
555
- >
556
- <label class="toggle-switch">
557
- <input
558
- type="checkbox"
559
- class="readonly-toggle"
560
- data-element="select"
561
- />
562
- <span class="toggle-slider"></span>
563
- </label>
564
- </div>
565
- </div>
566
- <div
567
- id="select-preview"
568
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
569
- ></div>
570
- </div>
571
- </div>
572
-
573
- <div class="mt-6">
574
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
575
- Available Properties
576
- </h3>
577
- <div class="bg-gray-50 rounded-lg p-4">
578
- <ul class="space-y-2 text-sm">
579
- <li><strong>type:</strong> "select" (required)</li>
580
- <li><strong>key:</strong> Field identifier (required)</li>
581
- <li><strong>label:</strong> Display label for the field</li>
582
- <li>
583
- <strong>required:</strong> Whether field is required (boolean)
584
- </li>
585
- <li>
586
- <strong>options:</strong> Array of {value, label} option
587
- objects (required)
588
- </li>
589
- <li>
590
- <strong>default:</strong> Default selected value (must match
591
- an option value)
592
- </li>
593
- <li>
594
- <strong>description:</strong> Field description (shows in
595
- tooltip)
596
- </li>
597
- <li>
598
- <strong>hint:</strong> Additional hint text (shows in tooltip)
599
- </li>
600
- <li>
601
- <strong>actions:</strong> Array of action buttons for readonly
602
- mode
603
- </li>
604
- <li>
605
- <strong>hidden:</strong> Hide field from form display but
606
- include in data (boolean)
607
- </li>
608
- </ul>
609
- </div>
610
- </div>
611
- </div>
612
-
613
- <!-- File Element -->
614
- <div id="file" class="element-section mb-16">
615
- <h2 class="text-2xl font-bold text-gray-900 mb-4">File Upload</h2>
616
- <p class="text-gray-700 mb-4">
617
- File upload with preview, drag-and-drop, and file type restrictions.
618
- Supports both single and multiple files.
619
- </p>
620
- <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
621
- <p class="text-sm text-blue-800">
622
- <strong>Multiple Files:</strong> Set
623
- <code>multiple: true</code> to allow multiple file selection. Use
624
- <code>min</code> and <code>max</code> properties to control file
625
- count limits.
626
- </p>
627
- </div>
628
-
629
- <div class="grid grid-cols-2 gap-6">
630
- <div>
631
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
632
- Schema Definition
633
- </h3>
634
- <textarea
635
- id="file-schema"
636
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
637
- spellcheck="false"
638
- >
639
- {
640
- "type": "file",
641
- "key": "avatar",
642
- "label": "Profile Picture",
643
- "required": false,
644
- "accept": {
645
- "extensions": ["jpg", "jpeg", "png", "gif", "webp"],
646
- "maxSize": 5242880
647
- },
648
- "description": "Upload your profile picture (max 5MB, images only)"
649
- }</textarea
650
- >
651
- </div>
652
-
653
- <div>
654
- <div class="flex items-center justify-between mb-3">
655
- <h3 class="text-lg font-semibold text-gray-900">
656
- Live Preview
657
- </h3>
658
- <div class="flex items-center space-x-3">
659
- <span class="text-sm font-medium text-gray-700"
660
- >Read Only</span
661
- >
662
- <label class="toggle-switch">
663
- <input
664
- type="checkbox"
665
- class="readonly-toggle"
666
- data-element="file"
667
- />
668
- <span class="toggle-slider"></span>
669
- </label>
670
- </div>
671
- </div>
672
- <div
673
- id="file-preview"
674
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
675
- ></div>
676
- </div>
677
- </div>
678
-
679
- <div class="mt-6">
680
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
681
- Available Properties
682
- </h3>
683
- <div class="bg-gray-50 rounded-lg p-4">
684
- <ul class="space-y-2 text-sm">
685
- <li><strong>type:</strong> "file" (required)</li>
686
- <li><strong>key:</strong> Field identifier (required)</li>
687
- <li><strong>label:</strong> Display label for the field</li>
688
- <li>
689
- <strong>required:</strong> Whether field is required (boolean)
690
- </li>
691
- <li><strong>accept:</strong> Object with file restrictions</li>
692
- <li>
693
- <strong>accept.extensions:</strong> Array of allowed file
694
- extensions
695
- </li>
696
- <li>
697
- <strong>accept.maxSize:</strong> Maximum file size in bytes
698
- </li>
699
- <li>
700
- <strong>multiple:</strong> Allow multiple file selection
701
- (boolean)
702
- </li>
703
- <li>
704
- <strong>minCount:</strong> Minimum number of files (when
705
- multiple is true)
706
- </li>
707
- <li>
708
- <strong>maxCount:</strong> Maximum number of files (when
709
- multiple is true)
710
- </li>
711
- <li>
712
- <strong>default:</strong> Default file resource ID or array
713
- for multiple
714
- </li>
715
- <li>
716
- <strong>description:</strong> Field description (shows in
717
- tooltip)
718
- </li>
719
- <li>
720
- <strong>hint:</strong> Additional hint text (shows in tooltip)
721
- </li>
722
- <li>
723
- <strong>actions:</strong> Array of action buttons for readonly
724
- mode
725
- </li>
726
- <li>
727
- <strong>hidden:</strong> Hide field from form display but
728
- include in data (boolean)
729
- </li>
730
- </ul>
731
- </div>
732
- </div>
733
- </div>
734
-
735
- <!-- Files Element -->
736
- <div id="files" class="element-section mb-16">
737
- <h2 class="text-2xl font-bold text-gray-900 mb-4">
738
- Multiple Files (Legacy)
739
- </h2>
740
- <p class="text-gray-700 mb-4">
741
- Multiple file uploads with grid preview, count limits, and
742
- drag-and-drop.
743
- </p>
744
- <div
745
- class="bg-orange-50 border border-orange-200 rounded-lg p-4 mb-6"
746
- >
747
- <p class="text-sm text-orange-800">
748
- <strong>⚠️ Deprecated:</strong> The <code>files</code> type is
749
- deprecated. Use <code>file</code> with
750
- <code>multiple: true</code> instead for consistent API design.
751
- </p>
752
- </div>
753
-
754
- <div class="grid grid-cols-2 gap-6">
755
- <div>
756
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
757
- Schema Definition
758
- </h3>
759
- <textarea
760
- id="files-schema"
761
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
762
- spellcheck="false"
763
- >
764
- {
765
- "type": "files",
766
- "key": "attachments",
767
- "label": "Project Attachments",
768
- "required": false,
769
- "min": 1,
770
- "max": 10,
771
- "accept": {
772
- "extensions": ["jpg", "png", "pdf", "doc", "docx", "mp4"],
773
- "maxSize": 10485760
774
- },
775
- "description": "Upload project files (max 10MB each, 1-10 files)"
776
- }</textarea
777
- >
778
- </div>
779
-
780
- <div>
781
- <div class="flex items-center justify-between mb-3">
782
- <h3 class="text-lg font-semibold text-gray-900">
783
- Live Preview
784
- </h3>
785
- <div class="flex items-center space-x-3">
786
- <span class="text-sm font-medium text-gray-700"
787
- >Read Only</span
788
- >
789
- <label class="toggle-switch">
790
- <input
791
- type="checkbox"
792
- class="readonly-toggle"
793
- data-element="files"
794
- />
795
- <span class="toggle-slider"></span>
796
- </label>
797
- </div>
798
- </div>
799
- <div
800
- id="files-preview"
801
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
802
- ></div>
803
- </div>
804
- </div>
805
-
806
- <div class="mt-6">
807
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
808
- Available Properties
809
- </h3>
810
- <div class="bg-gray-50 rounded-lg p-4">
811
- <ul class="space-y-2 text-sm">
812
- <li><strong>type:</strong> "files" (required)</li>
813
- <li><strong>key:</strong> Field identifier (required)</li>
814
- <li><strong>label:</strong> Display label for the field</li>
815
- <li>
816
- <strong>required:</strong> Whether field is required (boolean)
817
- </li>
818
- <li><strong>min:</strong> Minimum number of files (number)</li>
819
- <li><strong>max:</strong> Maximum number of files (number)</li>
820
- <li><strong>accept:</strong> Object with file restrictions</li>
821
- <li>
822
- <strong>accept.extensions:</strong> Array of allowed file
823
- extensions
824
- </li>
825
- <li>
826
- <strong>accept.maxSize:</strong> Maximum file size in bytes
827
- </li>
828
- <li>
829
- <strong>default:</strong> Array of default file resource IDs
830
- </li>
831
- <li>
832
- <strong>description:</strong> Field description (shows in
833
- tooltip)
834
- </li>
835
- <li>
836
- <strong>hint:</strong> Additional hint text (shows in tooltip)
837
- </li>
838
- <li>
839
- <strong>actions:</strong> Array of action buttons for readonly
840
- mode
841
- </li>
842
- <li>
843
- <strong>hidden:</strong> Hide field from form display but
844
- include in data (boolean)
845
- </li>
846
- </ul>
847
- </div>
848
- </div>
849
- </div>
850
-
851
- <!-- Container Element -->
852
- <div id="container" class="element-section mb-16">
853
- <h2 class="text-2xl font-bold text-gray-900 mb-4">Container</h2>
854
- <p class="text-gray-700 mb-4">
855
- Nested object container with support for both single objects and
856
- repeatable arrays.
857
- </p>
858
- <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
859
- <p class="text-sm text-blue-800">
860
- <strong>Multiple Containers:</strong> Set
861
- <code>multiple: true</code> to create repeatable container arrays.
862
- Use <code>minCount</code> and <code>maxCount</code> to control
863
- item limits.
864
- </p>
865
- </div>
866
-
867
- <div class="grid grid-cols-2 gap-6">
868
- <!-- Schema Editor -->
869
- <div>
870
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
871
- Schema Definition
872
- </h3>
873
- <textarea
874
- id="container-schema"
875
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
876
- spellcheck="false"
877
- >
878
- {
879
- "type": "container",
880
- "key": "contacts",
881
- "label": "Contact Information",
882
- "multiple": true,
883
- "minCount": 1,
884
- "maxCount": 5,
885
- "elements": [
886
- {
887
- "type": "text",
888
- "key": "name",
889
- "label": "Contact Name",
890
- "required": true
891
- },
892
- {
893
- "type": "text",
894
- "key": "email",
895
- "label": "Email Address",
896
- "required": true,
897
- "pattern": "^[^@]+@[^@]+\\.[^@]+$"
898
- },
899
- {
900
- "type": "select",
901
- "key": "role",
902
- "label": "Role",
903
- "options": [
904
- {"value": "primary", "label": "Primary Contact"},
905
- {"value": "secondary", "label": "Secondary Contact"},
906
- {"value": "technical", "label": "Technical Contact"}
907
- ],
908
- "default": "primary"
909
- }
910
- ],
911
- "description": "Add contact information for your project"
912
- }</textarea
913
- >
914
- </div>
915
-
916
- <!-- Live Preview -->
917
- <div>
918
- <div class="flex items-center justify-between mb-3">
919
- <h3 class="text-lg font-semibold text-gray-900">
920
- Live Preview
921
- </h3>
922
- <div class="flex items-center space-x-3">
923
- <span class="text-sm font-medium text-gray-700"
924
- >Read Only</span
925
- >
926
- <label class="toggle-switch">
927
- <input
928
- type="checkbox"
929
- class="readonly-toggle"
930
- data-element="container"
931
- />
932
- <span class="toggle-slider"></span>
933
- </label>
934
- </div>
935
- </div>
936
- <div
937
- id="container-preview"
938
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
939
- ></div>
940
- </div>
941
- </div>
942
-
943
- <div class="mt-6">
944
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
945
- Available Properties
946
- </h3>
947
- <div class="bg-gray-50 rounded-lg p-4">
948
- <ul class="space-y-2 text-sm">
949
- <li><strong>type:</strong> "container" (required)</li>
950
- <li><strong>key:</strong> Field identifier (required)</li>
951
- <li><strong>label:</strong> Display label for the container</li>
952
- <li>
953
- <strong>elements:</strong> Array of nested form elements
954
- (required)
955
- </li>
956
- <li>
957
- <strong>multiple:</strong> Make container repeatable (boolean)
958
- </li>
959
- <li>
960
- <strong>minCount:</strong> Minimum number of container
961
- instances (when multiple is true)
962
- </li>
963
- <li>
964
- <strong>maxCount:</strong> Maximum number of container
965
- instances (when multiple is true)
966
- </li>
967
- <li>
968
- <strong>description:</strong> Container description (shows in
969
- tooltip)
970
- </li>
971
- <li>
972
- <strong>hint:</strong> Additional hint text (shows in tooltip)
973
- </li>
974
- <li>
975
- <strong>actions:</strong> Array of action buttons for readonly
976
- mode
977
- </li>
978
- <li>
979
- <strong>hidden:</strong> Hide field from form display but
980
- include in data (boolean)
981
- </li>
982
- </ul>
983
- </div>
984
- </div>
985
- </div>
986
-
987
- <!-- Group Element -->
988
- <div id="group" class="element-section mb-16">
989
- <h2 class="text-2xl font-bold text-gray-900 mb-4">
990
- Group Container (Legacy)
991
- </h2>
992
- <p class="text-gray-700 mb-4">
993
- Nested object container with optional repeatable arrays (min/max
994
- items).
995
- </p>
996
- <div
997
- class="bg-orange-50 border border-orange-200 rounded-lg p-4 mb-6"
998
- >
999
- <p class="text-sm text-orange-800">
1000
- <strong>⚠️ Deprecated:</strong> The <code>group</code> type is
1001
- deprecated. Use <code>container</code> with
1002
- <code>multiple: true</code> instead. Groups use
1003
- <code>repeat: {min, max}</code> syntax which is being replaced by
1004
- <code>minCount</code> and <code>maxCount</code> properties.
1005
- </p>
1006
- </div>
1007
-
1008
- <div class="grid grid-cols-2 gap-6">
1009
- <div>
1010
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
1011
- Schema Definition
1012
- </h3>
1013
- <textarea
1014
- id="group-schema"
1015
- class="w-full h-80 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
1016
- spellcheck="false"
1017
- >
1018
- {
1019
- "type": "group",
1020
- "key": "contacts",
1021
- "label": "Contact Information",
1022
- "repeat": {
1023
- "min": 1,
1024
- "max": 5
1025
- },
1026
- "elements": [
1027
- {
1028
- "type": "text",
1029
- "key": "name",
1030
- "label": "Contact Name",
1031
- "required": true
1032
- },
1033
- {
1034
- "type": "text",
1035
- "key": "email",
1036
- "label": "Email Address",
1037
- "required": true,
1038
- "pattern": "^[^@]+@[^@]+\\.[^@]+$"
1039
- },
1040
- {
1041
- "type": "select",
1042
- "key": "role",
1043
- "label": "Role",
1044
- "options": [
1045
- {"value": "primary", "label": "Primary Contact"},
1046
- {"value": "secondary", "label": "Secondary Contact"},
1047
- {"value": "technical", "label": "Technical Contact"}
1048
- ],
1049
- "default": "primary"
1050
- }
1051
- ],
1052
- "description": "Add contact information for your project"
1053
- }</textarea
1054
- >
1055
- </div>
1056
-
1057
- <div>
1058
- <div class="flex items-center justify-between mb-3">
1059
- <h3 class="text-lg font-semibold text-gray-900">
1060
- Live Preview
1061
- </h3>
1062
- <div class="flex items-center space-x-3">
1063
- <span class="text-sm font-medium text-gray-700"
1064
- >Read Only</span
1065
- >
1066
- <label class="toggle-switch">
1067
- <input
1068
- type="checkbox"
1069
- class="readonly-toggle"
1070
- data-element="group"
1071
- />
1072
- <span class="toggle-slider"></span>
1073
- </label>
1074
- </div>
1075
- </div>
1076
- <div
1077
- id="group-preview"
1078
- class="border border-gray-300 rounded-lg p-4 bg-white min-h-80"
1079
- ></div>
1080
- </div>
1081
- </div>
1082
-
1083
- <div class="mt-6">
1084
- <h3 class="text-lg font-semibold text-gray-900 mb-3">
1085
- Available Properties
1086
- </h3>
1087
- <div class="bg-gray-50 rounded-lg p-4">
1088
- <ul class="space-y-2 text-sm">
1089
- <li><strong>type:</strong> "group" (required)</li>
1090
- <li><strong>key:</strong> Field identifier (required)</li>
1091
- <li><strong>label:</strong> Display label for the group</li>
1092
- <li>
1093
- <strong>elements:</strong> Array of nested form elements
1094
- (required)
1095
- </li>
1096
- <li>
1097
- <strong>repeat:</strong> Object to make group repeatable
1098
- </li>
1099
- <li>
1100
- <strong>repeat.min:</strong> Minimum number of group instances
1101
- </li>
1102
- <li>
1103
- <strong>repeat.max:</strong> Maximum number of group instances
1104
- </li>
1105
- <li>
1106
- <strong>description:</strong> Group description (shows in
1107
- tooltip)
1108
- </li>
1109
- <li>
1110
- <strong>hint:</strong> Additional hint text (shows in tooltip)
1111
- </li>
1112
- <li>
1113
- <strong>actions:</strong> Array of action buttons for readonly
1114
- mode
1115
- </li>
1116
- <li>
1117
- <strong>hidden:</strong> Hide field from form display but
1118
- include in data (boolean)
1119
- </li>
1120
- </ul>
1121
- </div>
1122
- </div>
1123
- </div>
1124
- </div>
1125
- </div>
1126
-
1127
- <script type="module" src="./form-builder.js"></script>
1128
- <script type="module" src="./elements.js"></script>
1129
- </body>
1130
- </html>