@dmitryvim/form-builder 0.1.42 → 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.
- package/README.md +244 -22
- package/dist/browser/formbuilder.min.js +179 -0
- package/dist/browser/formbuilder.v0.2.0.min.js +179 -0
- package/dist/cjs/index.cjs +3582 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/esm/index.js +3534 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/form-builder.js +152 -3372
- package/dist/types/components/container.d.ts +15 -0
- package/dist/types/components/file.d.ts +26 -0
- package/dist/types/components/group.d.ts +24 -0
- package/dist/types/components/index.d.ts +11 -0
- package/dist/types/components/number.d.ts +11 -0
- package/dist/types/components/registry.d.ts +15 -0
- package/dist/types/components/select.d.ts +11 -0
- package/dist/types/components/text.d.ts +11 -0
- package/dist/types/components/textarea.d.ts +11 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/instance/FormBuilderInstance.d.ts +134 -0
- package/dist/types/instance/state.d.ts +13 -0
- package/dist/types/styles/theme.d.ts +63 -0
- package/dist/types/types/component-operations.d.ts +45 -0
- package/dist/types/types/config.d.ts +44 -0
- package/dist/types/types/index.d.ts +4 -0
- package/dist/types/types/schema.d.ts +115 -0
- package/dist/types/types/state.d.ts +11 -0
- package/dist/types/utils/helpers.d.ts +4 -0
- package/dist/types/utils/styles.d.ts +21 -0
- package/dist/types/utils/translation.d.ts +8 -0
- package/dist/types/utils/validation.d.ts +2 -0
- package/package.json +32 -15
- package/dist/demo.js +0 -861
- package/dist/elements.html +0 -1130
- package/dist/elements.js +0 -488
- package/dist/index.html +0 -315
package/README.md
CHANGED
|
@@ -48,6 +48,16 @@ npm install @dmitryvim/form-builder
|
|
|
48
48
|
- **🔧 Framework agnostic**: Works with any web stack (React, Vue, Angular, vanilla JS)
|
|
49
49
|
- **📦 Zero dependencies**: Self-contained HTML/CSS/JavaScript
|
|
50
50
|
- **📱 Responsive design**: Mobile-friendly with Tailwind CSS styling
|
|
51
|
+
- **🏗️ Instance-based architecture**: Multiple independent forms with isolated state
|
|
52
|
+
|
|
53
|
+
### New in v0.2.0
|
|
54
|
+
|
|
55
|
+
- **🔄 onChange Events**: Real-time change notifications with debouncing (eliminates polling)
|
|
56
|
+
- **🎨 CSS Theming**: 43 configurable theme properties (no `!important` overrides)
|
|
57
|
+
- **📝 Partial Updates**: Update fields without re-rendering (`setFormData`, `updateField`)
|
|
58
|
+
- **⚡ Async Thumbnails**: Dynamic thumbnail loading with async-only `getThumbnail`
|
|
59
|
+
|
|
60
|
+
**Impact**: Eliminates ~280+ lines of workaround code for Klein integration
|
|
51
61
|
|
|
52
62
|
## Quick Examples
|
|
53
63
|
|
|
@@ -144,24 +154,52 @@ npm install @dmitryvim/form-builder
|
|
|
144
154
|
|
|
145
155
|
```javascript
|
|
146
156
|
// ES6 imports
|
|
147
|
-
import
|
|
148
|
-
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
import { createFormBuilder } from "@dmitryvim/form-builder";
|
|
158
|
+
|
|
159
|
+
// Create form instance with v0.3.0 features
|
|
160
|
+
const formBuilder = createFormBuilder({
|
|
161
|
+
uploadFile: async (file) => {
|
|
162
|
+
// Your upload logic - return resource ID
|
|
163
|
+
return "resource-123";
|
|
164
|
+
},
|
|
165
|
+
downloadFile: (resourceId, fileName) => {
|
|
166
|
+
// Handle file download
|
|
167
|
+
window.open(`/api/files/${resourceId}`, '_blank');
|
|
168
|
+
},
|
|
169
|
+
getThumbnail: async (resourceId) => {
|
|
170
|
+
// v0.2.0: Async-only thumbnail loading
|
|
171
|
+
const url = await fetchThumbnailUrl(resourceId);
|
|
172
|
+
return url;
|
|
173
|
+
},
|
|
174
|
+
actionHandler: (value, key, field) => {
|
|
175
|
+
// Handle action button clicks
|
|
176
|
+
console.log("Action clicked:", { value, key, field });
|
|
177
|
+
},
|
|
178
|
+
// v0.2.0: Real-time change events
|
|
179
|
+
onChange: (formData) => {
|
|
180
|
+
console.log("Form changed:", formData);
|
|
181
|
+
if (formData.valid) autoSave(formData.data);
|
|
182
|
+
},
|
|
183
|
+
// v0.2.0: CSS theming
|
|
184
|
+
theme: {
|
|
185
|
+
primaryColor: '#0066cc',
|
|
186
|
+
borderRadius: '4px',
|
|
162
187
|
}
|
|
163
188
|
});
|
|
164
|
-
|
|
189
|
+
|
|
190
|
+
// Render form
|
|
191
|
+
const rootElement = document.getElementById("form-container");
|
|
192
|
+
formBuilder.renderForm(rootElement, schema, prefillData);
|
|
193
|
+
|
|
194
|
+
// Get form data
|
|
195
|
+
const result = formBuilder.getFormData();
|
|
196
|
+
if (result.valid) {
|
|
197
|
+
console.log("Form data:", result.data);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// v0.2.0: Update fields without re-rendering
|
|
201
|
+
formBuilder.updateField('email', 'newemail@example.com');
|
|
202
|
+
formBuilder.setFormData({ name: 'John', email: 'john@example.com' });
|
|
165
203
|
```
|
|
166
204
|
|
|
167
205
|
### 2. CDN Integration
|
|
@@ -170,7 +208,15 @@ FormBuilder.renderForm(schema, prefillData);
|
|
|
170
208
|
<!-- Direct script include (npm CDN) -->
|
|
171
209
|
<script src="https://cdn.jsdelivr.net/npm/@dmitryvim/form-builder@latest/dist/form-builder.js"></script>
|
|
172
210
|
<script>
|
|
173
|
-
window.FormBuilder
|
|
211
|
+
const { createFormBuilder } = window.FormBuilder;
|
|
212
|
+
|
|
213
|
+
const formBuilder = createFormBuilder({
|
|
214
|
+
uploadFile: async (file) => "resource-id",
|
|
215
|
+
downloadFile: (resourceId) => { /* download */ }
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const rootElement = document.getElementById("form-container");
|
|
219
|
+
formBuilder.renderForm(rootElement, schema);
|
|
174
220
|
</script>
|
|
175
221
|
|
|
176
222
|
<!-- Or use our S3 CDN -->
|
|
@@ -222,12 +268,188 @@ See [Integration Guide](docs/integration.md) for detailed setup instructions.
|
|
|
222
268
|
- **Read-only mode**: Display data without editing
|
|
223
269
|
- **Action buttons**: Custom buttons in readonly mode with configurable handlers
|
|
224
270
|
|
|
271
|
+
## API Reference
|
|
272
|
+
|
|
273
|
+
### Core Methods
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { createFormBuilder } from '@dmitryvim/form-builder';
|
|
277
|
+
|
|
278
|
+
// Create form instance
|
|
279
|
+
const form = createFormBuilder({
|
|
280
|
+
// Required handlers
|
|
281
|
+
uploadFile: async (file: File) => string, // Upload file, return resource ID
|
|
282
|
+
downloadFile: (resourceId: string, fileName: string) => void,
|
|
283
|
+
|
|
284
|
+
// Optional handlers
|
|
285
|
+
getThumbnail?: async (resourceId: string) => string | null, // v0.2.0: Async-only, for preview thumbnails
|
|
286
|
+
getDownloadUrl?: (resourceId: string) => string | null, // Optional: URL for downloading full file
|
|
287
|
+
actionHandler?: (value: any, key: string, field: any) => void,
|
|
288
|
+
|
|
289
|
+
// v0.2.0: onChange events
|
|
290
|
+
onChange?: (formData: FormResult) => void,
|
|
291
|
+
onFieldChange?: (fieldPath: string, value: any, formData: FormResult) => void,
|
|
292
|
+
debounceMs?: number, // Default: 300ms
|
|
293
|
+
|
|
294
|
+
// v0.2.0: CSS theming
|
|
295
|
+
theme?: {
|
|
296
|
+
primaryColor?: string,
|
|
297
|
+
borderRadius?: string,
|
|
298
|
+
fontSize?: string,
|
|
299
|
+
fontFamily?: string,
|
|
300
|
+
// ... 39 more theme properties
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Render form
|
|
305
|
+
form.renderForm(rootElement, schema, prefillData);
|
|
306
|
+
|
|
307
|
+
// Get form data
|
|
308
|
+
const result = form.getFormData(); // { valid, errors, data }
|
|
309
|
+
|
|
310
|
+
// v0.2.0: Update data without re-rendering
|
|
311
|
+
form.setFormData({ name: 'John', email: 'john@example.com' });
|
|
312
|
+
form.updateField('email', 'newemail@example.com');
|
|
313
|
+
form.updateField('address.city', 'New York'); // Nested paths
|
|
314
|
+
|
|
315
|
+
// Switch modes
|
|
316
|
+
form.setMode('readonly'); // or 'edit'
|
|
317
|
+
|
|
318
|
+
// Cleanup
|
|
319
|
+
form.destroy();
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Migration from v0.1.x
|
|
323
|
+
|
|
324
|
+
**Breaking Changes in v0.2.0:**
|
|
325
|
+
|
|
326
|
+
1. **Instance-Only API** - Global static methods removed
|
|
327
|
+
```typescript
|
|
328
|
+
// OLD (v0.1.x)
|
|
329
|
+
FormBuilder.configure({ uploadFile: async (file) => "id" });
|
|
330
|
+
FormBuilder.renderForm(root, schema);
|
|
331
|
+
|
|
332
|
+
// NEW (v0.2.0)
|
|
333
|
+
const form = createFormBuilder({ uploadFile: async (file) => "id" });
|
|
334
|
+
form.renderForm(root, schema);
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
2. **Async getThumbnail** - Must return Promise
|
|
338
|
+
```typescript
|
|
339
|
+
// OLD (v0.1.x)
|
|
340
|
+
getThumbnail: (resourceId) => `/thumbs/${resourceId}.jpg`
|
|
341
|
+
|
|
342
|
+
// NEW (v0.2.0)
|
|
343
|
+
getThumbnail: async (resourceId) => `/thumbs/${resourceId}.jpg`
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
See [CHANGELOG.md](CHANGELOG.md) for complete migration details.
|
|
347
|
+
|
|
348
|
+
### Theming
|
|
349
|
+
|
|
350
|
+
Customize appearance with 43 theme properties:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
const form = createFormBuilder({
|
|
354
|
+
theme: {
|
|
355
|
+
// Colors
|
|
356
|
+
primaryColor: '#0066cc',
|
|
357
|
+
borderColor: '#e0e0e0',
|
|
358
|
+
errorColor: '#d32f2f',
|
|
359
|
+
|
|
360
|
+
// Typography
|
|
361
|
+
fontSize: '16px',
|
|
362
|
+
fontFamily: '"Roboto", sans-serif',
|
|
363
|
+
|
|
364
|
+
// Spacing
|
|
365
|
+
borderRadius: '4px',
|
|
366
|
+
inputPaddingX: '12px',
|
|
367
|
+
|
|
368
|
+
// Buttons
|
|
369
|
+
buttonBgColor: '#0066cc',
|
|
370
|
+
buttonTextColor: '#ffffff',
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**Most Common Properties:**
|
|
376
|
+
- `primaryColor` - Primary brand color
|
|
377
|
+
- `borderRadius` - Border radius for inputs/buttons
|
|
378
|
+
- `fontSize` - Base font size
|
|
379
|
+
- `fontFamily` - Font family
|
|
380
|
+
- `borderColor` - Input border color
|
|
381
|
+
|
|
382
|
+
No `!important` overrides needed. See [CHANGELOG.md](CHANGELOG.md) for all 43 properties.
|
|
383
|
+
|
|
384
|
+
### File Handling
|
|
385
|
+
|
|
386
|
+
The form builder provides flexible file handling with separate hooks for uploads, downloads, and previews:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
const form = createFormBuilder({
|
|
390
|
+
// Required: Upload handler
|
|
391
|
+
uploadFile: async (file) => {
|
|
392
|
+
const formData = new FormData();
|
|
393
|
+
formData.append('file', file);
|
|
394
|
+
const response = await fetch('/api/upload', {
|
|
395
|
+
method: 'POST',
|
|
396
|
+
body: formData
|
|
397
|
+
});
|
|
398
|
+
const data = await response.json();
|
|
399
|
+
return data.resourceId; // Return unique resource ID
|
|
400
|
+
},
|
|
401
|
+
|
|
402
|
+
// Required: Download handler
|
|
403
|
+
downloadFile: (resourceId, fileName) => {
|
|
404
|
+
// Option 1: Direct download
|
|
405
|
+
window.open(`/api/files/${resourceId}/download`, '_blank');
|
|
406
|
+
|
|
407
|
+
// Option 2: Programmatic download
|
|
408
|
+
fetch(`/api/files/${resourceId}/download`)
|
|
409
|
+
.then(response => response.blob())
|
|
410
|
+
.then(blob => {
|
|
411
|
+
const url = URL.createObjectURL(blob);
|
|
412
|
+
const a = document.createElement('a');
|
|
413
|
+
a.href = url;
|
|
414
|
+
a.download = fileName;
|
|
415
|
+
a.click();
|
|
416
|
+
URL.revokeObjectURL(url);
|
|
417
|
+
});
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
// Optional: Thumbnail URLs for preview (async-only in v0.2.0)
|
|
421
|
+
getThumbnail: async (resourceId) => {
|
|
422
|
+
const response = await fetch(`/api/files/${resourceId}/thumbnail`);
|
|
423
|
+
const data = await response.json();
|
|
424
|
+
return data.thumbnailUrl; // Return URL or null
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
// Optional: Full file download URL (used instead of getThumbnail for downloads)
|
|
428
|
+
getDownloadUrl: (resourceId) => {
|
|
429
|
+
return `/api/files/${resourceId}/download`;
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Handler Priority for Downloads:**
|
|
435
|
+
|
|
436
|
+
When a user clicks the download button in readonly mode, the form builder uses this priority:
|
|
437
|
+
|
|
438
|
+
1. **`getDownloadUrl`** - If provided, this URL is used for downloads
|
|
439
|
+
2. **`getThumbnail`** - If `getDownloadUrl` is not provided, falls back to thumbnail URL
|
|
440
|
+
3. **`downloadFile`** - If neither URL hook is provided, calls the download handler
|
|
441
|
+
|
|
442
|
+
**Use Cases:**
|
|
443
|
+
|
|
444
|
+
- **Separate thumbnail and download URLs**: Provide both `getThumbnail` (for optimized previews) and `getDownloadUrl` (for full files)
|
|
445
|
+
- **Same URL for both**: Provide only `getThumbnail` if thumbnail URL is also the download URL
|
|
446
|
+
- **Programmatic download**: Provide only `downloadFile` for custom download logic
|
|
447
|
+
|
|
225
448
|
## Documentation
|
|
226
449
|
|
|
227
|
-
-
|
|
228
|
-
- [
|
|
229
|
-
- [
|
|
230
|
-
- [Development Guide](CLAUDE.md) - Architecture and development workflow
|
|
450
|
+
- **API Reference** - See above for core methods and theming
|
|
451
|
+
- **Development Guide** - [CLAUDE.md](CLAUDE.md) for architecture and workflow
|
|
452
|
+
- **Changelog** - [CHANGELOG.md](CHANGELOG.md) for version history and migration
|
|
231
453
|
|
|
232
454
|
## Live Demo
|
|
233
455
|
|
|
@@ -246,7 +468,7 @@ Features a 3-column interface:
|
|
|
246
468
|
- **GitHub**: [picazru/form-builder](https://github.com/picazru/form-builder)
|
|
247
469
|
- **NPM Package**: [@dmitryvim/form-builder](https://www.npmjs.com/package/@dmitryvim/form-builder)
|
|
248
470
|
- **CDN**: [picaz-form-builder.website.yandexcloud.net](https://picaz-form-builder.website.yandexcloud.net/)
|
|
249
|
-
- **Version**: 0.
|
|
471
|
+
- **Version**: 0.2.0 (Unreleased - Breaking Changes + New Features)
|
|
250
472
|
- **License**: MIT - see [LICENSE](LICENSE) file
|
|
251
473
|
|
|
252
474
|
Built with ❤️ for the web development community.
|