@dmitryvim/form-builder 0.2.25 → 0.2.27

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 CHANGED
@@ -54,7 +54,7 @@ This package ships with complete TypeScript definitions. Ensure your `tsconfig.j
54
54
  ## Core Features
55
55
 
56
56
  - **🎯 Schema-driven forms**: JSON Schema v0.3 → Interactive forms with live preview
57
- - **📁 Advanced file handling**: Images, videos, documents with drag-and-drop and grid preview
57
+ - **📁 Advanced file handling**: Images, videos, documents with drag-and-drop, tile preview, and per-file upload progress
58
58
  - **✅ Real-time validation**: Client-side validation with visual feedback and error display
59
59
  - **🌍 Internationalization**: Built-in English/Russian support with extensible translation system
60
60
  - **🎨 Rich field types**: Text, textarea, number, select, file, files, and nested groups
@@ -92,12 +92,20 @@ The root schema now supports container-like properties:
92
92
  "title": "Contact Form",
93
93
  "columns": 2,
94
94
  "prefillHints": [
95
- {"label": "Work", "values": {"email": "work@company.com"}, "icon": "💼"},
96
- {"label": "Personal", "values": {"email": "personal@email.com"}, "icon": "🏠"}
95
+ {
96
+ "label": "Work",
97
+ "values": { "email": "work@company.com" },
98
+ "icon": "💼"
99
+ },
100
+ {
101
+ "label": "Personal",
102
+ "values": { "email": "personal@email.com" },
103
+ "icon": "🏠"
104
+ }
97
105
  ],
98
106
  "elements": [
99
- {"type": "text", "key": "name", "label": "Name"},
100
- {"type": "text", "key": "email", "label": "Email"}
107
+ { "type": "text", "key": "name", "label": "Name" },
108
+ { "type": "text", "key": "email", "label": "Email" }
101
109
  ]
102
110
  }
103
111
  ```
@@ -293,8 +301,8 @@ See [Integration Guide](docs/integration.md) for detailed setup instructions.
293
301
  - **Colour**: Colour picker with hex values (single or palette)
294
302
  - **Slider**: Range slider with linear/exponential scales (v0.2.7+)
295
303
  - **Table**: 2D editable grid with cell merging, keyboard navigation, readonly mode
296
- - **File**: Single file upload with preview and type restrictions
297
- - **Files**: Multiple file upload with grid layout and drag-and-drop
304
+ - **File**: Single file upload with compact dropzone, tile preview, and type restrictions
305
+ - **Files**: Multiple file upload with 80px tile grid, per-file upload progress, and drag-and-drop
298
306
  - **Container**: Nested containers with repeatable array support
299
307
 
300
308
  ### File Handling
@@ -618,6 +626,54 @@ interface EnableCondition {
618
626
  - Works in both edit and readonly modes
619
627
  - Safe handling of undefined/null values
620
628
 
629
+ ### Per-Field Readonly
630
+
631
+ Set `readonly: true` on any individual field to lock it while keeping the rest of the form editable.
632
+
633
+ ```json
634
+ {
635
+ "elements": [
636
+ {
637
+ "type": "file",
638
+ "key": "avatar",
639
+ "label": "Avatar",
640
+ "readonly": true
641
+ },
642
+ {
643
+ "type": "text",
644
+ "key": "name",
645
+ "label": "Name",
646
+ "required": true
647
+ }
648
+ ]
649
+ }
650
+ ```
651
+
652
+ In this example, the prefilled avatar image shows as a preview (no upload/delete UI) while the `name` field remains fully editable.
653
+
654
+ **Behavior:**
655
+
656
+ - Effective readonly for a field = `element.readonly === true` OR form-wide `setMode('readonly')`
657
+ - Readonly file fields show preview + download only; no upload or delete controls
658
+ - Readonly multi-value fields (`multiple: true`) render items without add/remove buttons
659
+ - `readonly: true` on a container propagates to **all descendants** recursively — child `readonly: false` does not override an ancestor's readonly (matches `<fieldset disabled>` semantics)
660
+ - Orthogonal to `enableIf`: hidden fields stay hidden; visible readonly fields render readonly
661
+
662
+ **Container readonly example** — all children render readonly even though they have no `readonly` flag of their own:
663
+
664
+ ```json
665
+ {
666
+ "type": "container",
667
+ "key": "locked_section",
668
+ "label": "Locked Section",
669
+ "readonly": true,
670
+ "elements": [
671
+ { "type": "text", "key": "ref_code", "label": "Reference Code" },
672
+ { "type": "number", "key": "amount", "label": "Amount" }
673
+ ]
674
+ }
675
+ ```
676
+
621
677
  **Path Resolution:**
622
678
 
623
679
  - **Dot notation**: `user.profile.name`, `settings.theme.primaryColor`
@@ -680,9 +736,7 @@ An editable 2D grid with plain-text cells, cell merging, and full keyboard navig
680
736
  ["Widget A", "100", "120", "140"],
681
737
  ["Widget B", "80", "90", "95"]
682
738
  ],
683
- "merges": [
684
- { "row": 0, "col": 0, "rowspan": 1, "colspan": 2 }
685
- ]
739
+ "merges": [{ "row": 0, "col": 0, "rowspan": 1, "colspan": 2 }]
686
740
  }
687
741
  ```
688
742
 
@@ -697,10 +751,10 @@ An editable 2D grid with plain-text cells, cell merging, and full keyboard navig
697
751
 
698
752
  **Properties:**
699
753
 
700
- | Property | Type | Default | Description |
701
- |----------|------|---------|-------------|
702
- | `columns` | `number` | `3` | Initial column count |
703
- | `rows` | `number` | `3` | Initial row count |
754
+ | Property | Type | Default | Description |
755
+ | --------- | -------- | ------- | -------------------- |
756
+ | `columns` | `number` | `3` | Initial column count |
757
+ | `rows` | `number` | `3` | Initial row count |
704
758
 
705
759
  **Features:**
706
760