@dmitryvim/form-builder 0.1.22 → 0.1.25
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 +13 -6
- package/dist/demo.js +488 -473
- package/dist/form-builder.js +1433 -1291
- package/dist/index.html +270 -142
- package/docs/13_form_builder.html +1217 -543
- package/docs/REQUIREMENTS.md +46 -14
- package/docs/integration.md +241 -206
- package/docs/schema.md +37 -31
- package/package.json +14 -2
package/dist/index.html
CHANGED
|
@@ -1,174 +1,302 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
<head>
|
|
3
|
+
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<title>Form Builder - JSON Schema to Dynamic Forms</title>
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
7
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
8
|
<script>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
+
};
|
|
19
28
|
</script>
|
|
20
29
|
<style>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
+
}
|
|
43
52
|
</style>
|
|
44
|
-
</head>
|
|
45
|
-
<body class="bg-gray-50">
|
|
53
|
+
</head>
|
|
54
|
+
<body class="bg-gray-50">
|
|
46
55
|
<!-- Header -->
|
|
47
56
|
<div class="bg-white border-b border-gray-200 px-6 py-4">
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
</
|
|
58
|
-
|
|
59
|
-
<strong>💡 URL Schema:</strong> Add <code class="bg-blue-100 px-1 py-0.5 rounded font-mono">?schema=BASE64</code>
|
|
60
|
-
</div>
|
|
57
|
+
<div class="flex items-center justify-between">
|
|
58
|
+
<div class="flex items-center space-x-3">
|
|
59
|
+
<div
|
|
60
|
+
class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center"
|
|
61
|
+
>
|
|
62
|
+
<span class="text-white font-bold text-sm">FB</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div>
|
|
65
|
+
<h1 class="text-lg font-bold text-gray-800">Form Builder</h1>
|
|
66
|
+
<p class="text-xs text-gray-500">JSON Schema → Dynamic Forms</p>
|
|
67
|
+
</div>
|
|
61
68
|
</div>
|
|
69
|
+
<div
|
|
70
|
+
class="hidden bg-blue-50 border border-blue-200 rounded-lg p-2 text-xs text-blue-800"
|
|
71
|
+
id="urlInfo"
|
|
72
|
+
>
|
|
73
|
+
<strong>💡 URL Schema:</strong> Add
|
|
74
|
+
<code class="bg-blue-100 px-1 py-0.5 rounded font-mono"
|
|
75
|
+
>?schema=BASE64</code
|
|
76
|
+
>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
62
79
|
</div>
|
|
63
80
|
|
|
64
81
|
<!-- Main Content -->
|
|
65
82
|
<div class="p-4">
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
<!-- Two Column Layout -->
|
|
84
|
+
<div class="flex gap-4 h-full">
|
|
85
|
+
<!-- Left Column: Schema & Form -->
|
|
86
|
+
<div class="flex-1 space-y-4">
|
|
87
|
+
<!-- Schema Input Card -->
|
|
88
|
+
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
|
89
|
+
<div class="p-4 border-b border-gray-200">
|
|
90
|
+
<h3 class="text-lg font-semibold text-gray-900">JSON Schema</h3>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="p-4 space-y-4">
|
|
93
|
+
<div class="space-y-2">
|
|
94
|
+
<div class="flex gap-2 flex-wrap">
|
|
95
|
+
<button
|
|
96
|
+
class="bg-blue-600 text-white px-3 py-2 rounded-lg hover:bg-blue-700 transition-colors text-sm"
|
|
97
|
+
id="applySchemaBtn"
|
|
98
|
+
>
|
|
99
|
+
Apply Schema
|
|
100
|
+
</button>
|
|
101
|
+
<button
|
|
102
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
103
|
+
id="resetSchemaBtn"
|
|
104
|
+
>
|
|
105
|
+
Reset Example
|
|
106
|
+
</button>
|
|
107
|
+
<button
|
|
108
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
109
|
+
id="prettySchemaBtn"
|
|
110
|
+
>
|
|
111
|
+
Format
|
|
112
|
+
</button>
|
|
113
|
+
<button
|
|
114
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
115
|
+
id="downloadSchemaBtn"
|
|
116
|
+
>
|
|
117
|
+
Download
|
|
118
|
+
</button>
|
|
87
119
|
</div>
|
|
120
|
+
<textarea
|
|
121
|
+
id="schemaInput"
|
|
122
|
+
class="w-full 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 resize-y min-h-[300px]"
|
|
123
|
+
spellcheck="false"
|
|
124
|
+
placeholder="Paste your JSON schema here..."
|
|
125
|
+
></textarea>
|
|
126
|
+
<div
|
|
127
|
+
id="schemaErrors"
|
|
128
|
+
class="hidden text-red-600 text-sm bg-red-50 border border-red-200 rounded-lg p-3"
|
|
129
|
+
></div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
88
133
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<div class="flex gap-2 flex-wrap pt-4 border-t border-gray-200">
|
|
101
|
-
<button class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors" id="submitBtn">Submit Form</button>
|
|
102
|
-
<button class="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition-colors" id="saveDraftBtn">Save Draft</button>
|
|
103
|
-
<button class="border border-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-50 transition-colors" id="clearFormBtn">Clear Values</button>
|
|
104
|
-
</div>
|
|
105
|
-
<div id="formErrors" class="hidden text-red-600 text-sm bg-red-50 border border-red-200 rounded-lg p-3"></div>
|
|
106
|
-
</div>
|
|
134
|
+
<!-- Generated Form Card -->
|
|
135
|
+
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
|
136
|
+
<div class="p-4 border-b border-gray-200">
|
|
137
|
+
<h3 class="text-lg font-semibold text-gray-900">
|
|
138
|
+
Generated Form
|
|
139
|
+
</h3>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="p-4 space-y-4">
|
|
142
|
+
<div id="formContainer" class="min-h-[200px]">
|
|
143
|
+
<div class="text-center text-gray-500 py-8">
|
|
144
|
+
Apply a schema to generate the form
|
|
107
145
|
</div>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="flex gap-2 flex-wrap pt-4 border-t border-gray-200">
|
|
148
|
+
<button
|
|
149
|
+
class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
|
|
150
|
+
id="submitBtn"
|
|
151
|
+
>
|
|
152
|
+
Submit Form
|
|
153
|
+
</button>
|
|
154
|
+
<button
|
|
155
|
+
class="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition-colors"
|
|
156
|
+
id="saveDraftBtn"
|
|
157
|
+
>
|
|
158
|
+
Save Draft
|
|
159
|
+
</button>
|
|
160
|
+
<button
|
|
161
|
+
class="border border-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-50 transition-colors"
|
|
162
|
+
id="clearFormBtn"
|
|
163
|
+
>
|
|
164
|
+
Clear Values
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
<div
|
|
168
|
+
id="formErrors"
|
|
169
|
+
class="hidden text-red-600 text-sm bg-red-50 border border-red-200 rounded-lg p-3"
|
|
170
|
+
></div>
|
|
108
171
|
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
109
174
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
175
|
+
<!-- Right Column: Output & Prefill -->
|
|
176
|
+
<div class="flex-1 space-y-4">
|
|
177
|
+
<!-- Form Output Card -->
|
|
178
|
+
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
|
179
|
+
<div class="p-4 border-b border-gray-200">
|
|
180
|
+
<h3 class="text-lg font-semibold text-gray-900">Form Output</h3>
|
|
181
|
+
</div>
|
|
182
|
+
<div class="p-4 space-y-4">
|
|
183
|
+
<div class="space-y-2">
|
|
184
|
+
<div class="flex gap-2 flex-wrap">
|
|
185
|
+
<button
|
|
186
|
+
class="bg-gray-600 text-white px-3 py-2 rounded-lg hover:bg-gray-700 transition-colors text-sm"
|
|
187
|
+
id="copyOutputBtn"
|
|
188
|
+
>
|
|
189
|
+
Copy JSON
|
|
190
|
+
</button>
|
|
191
|
+
<button
|
|
192
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
193
|
+
id="downloadOutputBtn"
|
|
194
|
+
>
|
|
195
|
+
Download
|
|
196
|
+
</button>
|
|
197
|
+
<button
|
|
198
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
199
|
+
id="shareUrlBtn"
|
|
200
|
+
>
|
|
201
|
+
Share URL
|
|
202
|
+
</button>
|
|
127
203
|
</div>
|
|
204
|
+
<textarea
|
|
205
|
+
id="outputJson"
|
|
206
|
+
class="w-full 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 resize-y min-h-[300px]"
|
|
207
|
+
readonly
|
|
208
|
+
placeholder="Submit the form to see the output JSON here..."
|
|
209
|
+
></textarea>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
128
213
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
214
|
+
<!-- Prefill Data Card -->
|
|
215
|
+
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
|
216
|
+
<div class="p-4 border-b border-gray-200">
|
|
217
|
+
<h3 class="text-lg font-semibold text-gray-900">Prefill Data</h3>
|
|
218
|
+
</div>
|
|
219
|
+
<div class="p-4 space-y-4">
|
|
220
|
+
<div class="space-y-2">
|
|
221
|
+
<div class="flex gap-2 flex-wrap">
|
|
222
|
+
<button
|
|
223
|
+
class="bg-gray-600 text-white px-3 py-2 rounded-lg hover:bg-gray-700 transition-colors text-sm"
|
|
224
|
+
id="loadPrefillBtn"
|
|
225
|
+
>
|
|
226
|
+
Load Prefill
|
|
227
|
+
</button>
|
|
228
|
+
<button
|
|
229
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
230
|
+
id="copyTemplateBtn"
|
|
231
|
+
>
|
|
232
|
+
Generate Template
|
|
233
|
+
</button>
|
|
144
234
|
</div>
|
|
235
|
+
<textarea
|
|
236
|
+
id="prefillInput"
|
|
237
|
+
class="w-full 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 resize-y min-h-[200px]"
|
|
238
|
+
spellcheck="false"
|
|
239
|
+
placeholder='{"field1": "value1", "field2": "value2", ...}'
|
|
240
|
+
></textarea>
|
|
241
|
+
<div
|
|
242
|
+
id="prefillErrors"
|
|
243
|
+
class="hidden text-red-600 text-sm bg-red-50 border border-red-200 rounded-lg p-3"
|
|
244
|
+
></div>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
145
248
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
249
|
+
<!-- Read-only Demo Card -->
|
|
250
|
+
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
|
|
251
|
+
<div class="p-4 border-b border-gray-200">
|
|
252
|
+
<h3 class="text-lg font-semibold text-gray-900">
|
|
253
|
+
Read-only Demo
|
|
254
|
+
</h3>
|
|
255
|
+
<p class="text-sm text-gray-600 mt-1">
|
|
256
|
+
FormBuilder в readonly режиме
|
|
257
|
+
</p>
|
|
258
|
+
</div>
|
|
259
|
+
<div class="p-4 space-y-4">
|
|
260
|
+
<div class="space-y-2">
|
|
261
|
+
<div class="flex gap-2 flex-wrap">
|
|
262
|
+
<button
|
|
263
|
+
class="bg-blue-600 text-white px-3 py-2 rounded-lg hover:bg-blue-700 transition-colors text-sm"
|
|
264
|
+
id="applyReadonlyBtn"
|
|
265
|
+
>
|
|
266
|
+
Apply Readonly
|
|
267
|
+
</button>
|
|
268
|
+
<button
|
|
269
|
+
class="border border-gray-300 text-gray-700 px-3 py-2 rounded-lg hover:bg-gray-50 transition-colors text-sm"
|
|
270
|
+
id="clearReadonlyBtn"
|
|
271
|
+
>
|
|
272
|
+
Clear
|
|
273
|
+
</button>
|
|
274
|
+
</div>
|
|
275
|
+
<textarea
|
|
276
|
+
id="readonlySchemaInput"
|
|
277
|
+
class="w-full 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 resize-y min-h-[150px]"
|
|
278
|
+
spellcheck="false"
|
|
279
|
+
placeholder='{"version": "0.3", "title": "Results", "elements": [...]}'
|
|
280
|
+
></textarea>
|
|
281
|
+
<div
|
|
282
|
+
id="readonlyErrors"
|
|
283
|
+
class="hidden text-red-600 text-sm bg-red-50 border border-red-200 rounded-lg p-3"
|
|
284
|
+
></div>
|
|
285
|
+
</div>
|
|
286
|
+
<div
|
|
287
|
+
id="readonlyDemoContainer"
|
|
288
|
+
class="min-h-[200px] border border-gray-200 rounded-lg p-4"
|
|
289
|
+
>
|
|
290
|
+
<div class="text-center text-gray-500 py-8">
|
|
291
|
+
Apply a schema to see readonly mode
|
|
167
292
|
</div>
|
|
293
|
+
</div>
|
|
168
294
|
</div>
|
|
295
|
+
</div>
|
|
169
296
|
</div>
|
|
297
|
+
</div>
|
|
170
298
|
</div>
|
|
171
299
|
<script src="./form-builder.js"></script>
|
|
172
300
|
<script src="./demo.js"></script>
|
|
173
|
-
</body>
|
|
174
|
-
</html>
|
|
301
|
+
</body>
|
|
302
|
+
</html>
|