react-form-dto 0.0.8 β†’ 1.0.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 CHANGED
@@ -1,31 +1,43 @@
1
1
  # React Form DTO
2
2
 
3
- **Schema-first, DTO-driven form builder for React and Material UI (MUI v7)**
3
+ ![npm](https://img.shields.io/npm/v/react-form-dto)
4
+ ![license](https://img.shields.io/npm/l/react-form-dto)
5
+ ![typescript](https://img.shields.io/badge/TypeScript-Strict-blue)
6
+ ![mui](https://img.shields.io/badge/MUI-v7-blue)
4
7
 
5
- React Form DTO helps you build complex, responsive, and accessible forms using declarative JSON/TypeScript DTOs instead of verbose JSX. It is designed for enterprise-grade applications, internal tools, admin panels, and workflows where forms are dynamic, configurable, and data-driven.
8
+ **Schema-first, DTO-driven form framework for React and Material UI (MUI v7)**
9
+
10
+ React Form DTO is a **high-level form framework** for building complex, dynamic, and enterprise-scale forms using declarative JSON or TypeScript DTOsβ€”rather than verbose, repetitive JSX.
11
+
12
+ It is designed for **schema-driven UIs**, backend-configured workflows, admin panels, and internal tools where forms must be **configurable, scalable, and predictable**.
6
13
 
7
14
  ---
8
15
 
9
16
  ## Why React Form DTO?
10
17
 
11
- Most form libraries focus on low-level state management. React Form DTO operates at a **higher abstraction level**.
18
+ Most form libraries solve **state management**.
19
+ React Form DTO solves **form architecture**.
20
+
21
+ It operates at a higher abstraction level where **layout, validation, rendering, and behavior** are defined in a single schema.
12
22
 
13
- **Use this library when:**
23
+ ### Use this library when:
14
24
 
15
- - Your forms are generated from backend schemas or configurations
16
- - You want to avoid duplicating UI logic across applications
17
- - You need imperative control over form state (wizards, modals, async flows)
18
- - Your project is built on Material UI
25
+ - Forms are generated from backend schemas or configuration APIs
26
+ - UI logic must be reused across multiple applications
27
+ - Forms are large, dynamic, or conditional
28
+ - You need imperative control (wizards, modals, async flows)
29
+ - Your design system is based on Material UI
19
30
 
20
- **Key advantages:**
31
+ ### Key Advantages
21
32
 
22
33
  - πŸ“„ **DTO-first design** – define forms entirely in JSON or TypeScript
23
- - 🎨 **Material UI v7 native** – consistent design & accessibility
24
- - 🧱 **Composable architecture** – Form β†’ Section β†’ Field
25
- - 🎯 **Imperative API** – programmatic access via refs
26
- - πŸ”€ **Conditional rendering** – show/hide fields dynamically
27
- - 🧩 **Custom renderers** – plug in your own components
28
- - πŸ›‘οΈ **Strong TypeScript typing** – predictable, safe APIs
34
+ - 🎨 **Material UI v7 native** – accessibility and consistency by default
35
+ - 🧱 **Composable structure** – Form β†’ Section β†’ Field
36
+ - 🎯 **Imperative API** – programmatic control via refs
37
+ - πŸ”€ **Conditional rendering** – dynamic visibility and logic
38
+ - 🧩 **Extensible renderers** – plug in custom components
39
+ - πŸ›‘οΈ **Strong TypeScript typing** – safe, predictable APIs
40
+ - πŸš€ **Enterprise-ready** – optimized for large, config-driven forms
29
41
 
30
42
  ---
31
43
 
@@ -33,22 +45,43 @@ Most form libraries focus on low-level state management. React Form DTO operates
33
45
 
34
46
  | Feature | React Form DTO | React Hook Form | Formik |
35
47
  |------|---------------|----------------|--------|
36
- | Schema/DTO driven | βœ… Native | ❌ Manual | ❌ Manual |
48
+ | Schema / DTO driven | βœ… Native | ❌ Manual | ❌ Manual |
37
49
  | MUI-first | βœ… Yes | ⚠️ Partial | ⚠️ Partial |
38
50
  | Imperative API | βœ… First-class | ⚠️ Limited | ⚠️ Limited |
39
51
  | Large dynamic forms | βœ… Excellent | ⚠️ Medium | ❌ Poor |
40
52
  | Boilerplate | βœ… Minimal | ❌ High | ❌ High |
41
53
 
42
- > React Form DTO is **not a replacement** for React Hook Form. It is a higher-level abstraction for schema-driven UI generation.
54
+ > **Note:** React Form DTO is **not a replacement** for React Hook Form.
55
+ > It is a **higher-level abstraction** for schema-driven UI generation.
56
+
57
+ ---
58
+
59
+ ## What This Library Is Not
60
+
61
+ - ❌ A low-level form state library
62
+ - ❌ A visual form builder
63
+ - ❌ A replacement for small hand-crafted forms
64
+ - ❌ A design system
65
+
66
+ React Form DTO excels when **forms are data, not components**.
67
+
68
+ ---
69
+
70
+ ## Documentation & Demo
71
+
72
+ - πŸ“˜ **Documentation:** See full DTO reference, APIs, and advanced examples [Documentation](https://shakir-afridi.github.io/react-form-dto/docs)
73
+ - πŸ“— **Storybook:** Interactive component playground and live demos [Live Demo](https://shakir-afridi.github.io/react-form-dto/storybook)
43
74
 
44
75
  ---
45
76
 
46
77
  ## Installation
47
78
 
48
79
  ```bash
49
- git clone https://github.com/Shakir-Afridi/react-form-dto.git
50
- cd react-form-dto
51
- npm install
80
+ npm install react-form-dto
81
+ # or
82
+ yarn add react-form-dto
83
+ # or
84
+ pnpm add react-form-dto
52
85
  ```
53
86
 
54
87
  ### Requirements
@@ -59,7 +92,25 @@ npm install
59
92
 
60
93
  ---
61
94
 
62
- ## Minimal Example
95
+ ## Core Concepts
96
+
97
+ ### DTO as Source of Truth
98
+
99
+ All structure, layout, validation, and behavior live in a single schema.
100
+
101
+ ### Stateless Rendering
102
+
103
+ The UI is derived entirely from the DTO and internal state.
104
+
105
+ ### Imperative Escape Hatch
106
+
107
+ Refs enable workflows that declarative-only approaches struggle with.
108
+
109
+ ### Renderer Isolation
110
+
111
+ Field logic is decoupled from presentation, enabling customization.
112
+
113
+ ## Quick Start
63
114
 
64
115
  ```tsx
65
116
  import { FormBuilder, type FormBuilderHandle } from 'react-form-dto';
@@ -201,12 +252,14 @@ const profileForm: FormDTO = {
201
252
  - `date`
202
253
  - `email`
203
254
  - `password`
255
+ - `textarea`
204
256
 
205
257
  ### Selection Inputs
206
258
 
207
259
  - `select`
208
260
  - `autocomplete`
209
261
  - `multi-autocomplete`
262
+ - `radio`
210
263
 
211
264
  ### Boolean Inputs
212
265
 
@@ -214,6 +267,143 @@ const profileForm: FormDTO = {
214
267
 
215
268
  ---
216
269
 
270
+ ## 🌍 Internationalization (I18n)
271
+
272
+ React Form DTO has built-in support for multi-language forms through `I18String` and `I18nOption` types.
273
+
274
+ ### Using I18String
275
+
276
+ Any text property (`label`, `placeholder`, `title`, `description`, validation messages) can be either a plain string or a locale map:
277
+
278
+ ```tsx
279
+ // Simple string (single language)
280
+ {
281
+ label: "First Name"
282
+ }
283
+
284
+ // Multi-language support
285
+ {
286
+ label: {
287
+ en: "First Name",
288
+ fr: "PrΓ©nom",
289
+ es: "Nombre",
290
+ de: "Vorname"
291
+ }
292
+ }
293
+ ```
294
+
295
+ ### Using I18nOption for Selections
296
+
297
+ For select, autocomplete, and multi-autocomplete fields, you can use `I18nOption` objects to provide translatable labels while maintaining stable values:
298
+
299
+ ```tsx
300
+ {
301
+ id: "country",
302
+ type: "select",
303
+ label: { en: "Country", fr: "Pays" },
304
+ options: [
305
+ {
306
+ value: "us",
307
+ label: { en: "United States", fr: "Γ‰tats-Unis" }
308
+ },
309
+ {
310
+ value: "fr",
311
+ label: { en: "France", fr: "France" }
312
+ },
313
+ {
314
+ value: "de",
315
+ label: { en: "Germany", fr: "Allemagne" }
316
+ }
317
+ ]
318
+ }
319
+ ```
320
+
321
+ **Backward Compatibility:** Simple string arrays still work:
322
+
323
+ ```tsx
324
+ options: ["USA", "France", "Germany"] // Still supported
325
+ ```
326
+
327
+ ### I18n Validation Messages
328
+
329
+ Validation messages also support I18n:
330
+
331
+ ```tsx
332
+ validations: {
333
+ required: {
334
+ en: "This field is required",
335
+ fr: "Ce champ est obligatoire",
336
+ es: "Este campo es obligatorio"
337
+ },
338
+ validate: (value) => value.length < 2
339
+ ? {
340
+ en: "Minimum 2 characters",
341
+ fr: "Minimum 2 caractères"
342
+ }
343
+ : null
344
+ }
345
+ ```
346
+
347
+ ### Complete I18n Example
348
+
349
+ ```tsx
350
+ const multilingualForm: FormDTO = {
351
+ title: {
352
+ en: "User Registration",
353
+ fr: "Inscription de l'utilisateur",
354
+ es: "Registro de Usuario"
355
+ },
356
+ description: {
357
+ en: "Please fill in your details",
358
+ fr: "Veuillez remplir vos coordonnΓ©es",
359
+ es: "Por favor complete sus datos"
360
+ },
361
+ sections: [
362
+ {
363
+ id: "personal",
364
+ heading: {
365
+ en: "Personal Information",
366
+ fr: "Informations personnelles",
367
+ es: "InformaciΓ³n Personal"
368
+ },
369
+ fields: [
370
+ {
371
+ id: "title",
372
+ type: "select",
373
+ label: { en: "Title", fr: "Titre", es: "TΓ­tulo" },
374
+ options: [
375
+ { value: "mr", label: { en: "Mr", fr: "M.", es: "Sr." } },
376
+ { value: "ms", label: { en: "Ms", fr: "Mme", es: "Sra." } },
377
+ { value: "dr", label: { en: "Dr", fr: "Dr", es: "Dr." } }
378
+ ]
379
+ },
380
+ {
381
+ id: "firstName",
382
+ type: "text",
383
+ label: { en: "First Name", fr: "PrΓ©nom", es: "Nombre" },
384
+ placeholder: {
385
+ en: "Enter your first name",
386
+ fr: "Entrez votre prΓ©nom",
387
+ es: "Ingrese su nombre"
388
+ },
389
+ validations: {
390
+ required: {
391
+ en: "First name is required",
392
+ fr: "Le prΓ©nom est obligatoire",
393
+ es: "El nombre es obligatorio"
394
+ }
395
+ }
396
+ }
397
+ ]
398
+ }
399
+ ]
400
+ };
401
+ ```
402
+
403
+ > **Note:** The library provides the I18n structure. You'll need to implement locale selection and text resolution in your application layer.
404
+
405
+ ---
406
+
217
407
  ## Custom Field Renderers
218
408
 
219
409
  Override any default renderer by supplying your own component:
@@ -258,14 +448,23 @@ validations: {
258
448
 
259
449
  ---
260
450
 
261
- ## Documentation & Demo
451
+ ## Real-World Enterprise Usage
262
452
 
263
- - πŸ“˜ **Documentation:** See full DTO reference, APIs, and advanced examples [Documentation](https://shakir-afridi.github.io/react-form-dto/docs)
264
- - πŸ“— **Storybook:** Interactive component playground and live demos [Live Demo](https://shakir-afridi.github.io/react-form-dto/storybook)
453
+ ```text
454
+ Backend β†’ returns FormDTO
455
+ Frontend β†’ renders form dynamically
456
+ Backend updates β†’ UI changes without redeploy
457
+ ```
458
+
459
+ This enables:
460
+
461
+ - Backend-driven workflows
462
+ - Feature flags via schemas
463
+ - Faster iteration without frontend releases
265
464
 
266
465
  ---
267
466
 
268
- ## Ideal Use Cases
467
+ ## Other Use Cases
269
468
 
270
469
  - Admin dashboards
271
470
  - Internal enterprise tools
@@ -275,6 +474,23 @@ validations: {
275
474
 
276
475
  ---
277
476
 
477
+ ## Performance Characteristics
478
+
479
+ - Independent field rendering
480
+ - Section-level isolation
481
+ - Optimized for 100+ field forms
482
+ - No unnecessary re-renders across sections
483
+
484
+ ---
485
+
486
+ ## Incremental Adoption Strategy
487
+
488
+ - Use React Form DTO for large dynamic forms
489
+ - Keep React Hook Form for small custom forms
490
+ - Share validation logic between both
491
+
492
+ ---
493
+
278
494
  ## Roadmap (Suggested)
279
495
 
280
496
  - Field registry API (`registerFieldType`)
@@ -286,11 +502,18 @@ validations: {
286
502
 
287
503
  ## 🀝 Contributing
288
504
 
289
- - Fork the repo
290
- - Create a feature branch (`git checkout -b feature/my-feature`)
291
- - Commit changes (`git commit -m "Add my feature"`)
292
- - Push to branch (`git push origin feature/my-feature`)
293
- - Open a Pull Request
505
+ Contributions are welcome and encouraged.
506
+
507
+ 1. Fork the repository
508
+ 2. Create a feature branch
509
+ `git checkout -b feature/my-feature`
510
+ 3. Commit your changes
511
+ `git commit -m "Add my feature"`
512
+ 4. Push to the branch
513
+ `git push origin feature/my-feature`
514
+ 5. Open a Pull Request
515
+
516
+ Please keep changes focused and well-documented.
294
517
 
295
518
  ---
296
519
 
@@ -300,4 +523,4 @@ MIT
300
523
 
301
524
  ---
302
525
 
303
- **React Form DTO β€” Schema-first forms for Material UI**
526
+ **React Form DTO β€” Schema-first forms for Material UI**
@@ -11,6 +11,7 @@ export interface FieldRendererProps {
11
11
  /** Callback function to update the field value */
12
12
  onChange: (val: any) => void;
13
13
  error?: string | null;
14
+ locale: string;
14
15
  }
15
16
  /**
16
17
  * Props for the Field component.
@@ -23,6 +23,8 @@ type FormBuilderProps = {
23
23
  dto: FormDTO;
24
24
  /** Optional custom renderers for specific field types */
25
25
  renderers?: Record<string, React.ComponentType<any>>;
26
+ /** Current locale for i18n string resolution (default: 'en') */
27
+ locale?: string;
26
28
  };
27
29
  /**
28
30
  * FormBuilder component that dynamically renders a form based on a FormDTO definition.
@@ -13,6 +13,8 @@ type SectionProps = {
13
13
  /** Optional custom renderers for specific field types */
14
14
  renderers?: Record<string, React.ComponentType<any>>;
15
15
  validateField: (id: string) => string[];
16
+ /** Current locale for i18n string resolution (default: 'en') */
17
+ locale?: string;
16
18
  };
17
19
  /**
18
20
  * Section component that renders a form section with its heading, description, and fields.
@@ -5,6 +5,7 @@ type AutoCompleteFieldProps = {
5
5
  value: any;
6
6
  onChange: (val: any) => void;
7
7
  error?: string | null;
8
+ locale?: string;
8
9
  };
9
10
  export declare const AutoCompleteField: React.FC<AutoCompleteFieldProps>;
10
11
  export {};
@@ -13,4 +13,4 @@ import { FieldRendererProps } from '../../components/Field';
13
13
  * onChange={handleChange}
14
14
  * />
15
15
  */
16
- export declare function CheckBoxInput({ field, value, onChange, error, }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare function CheckBoxInput({ field, value, onChange, error, locale, }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
@@ -5,6 +5,7 @@ type MultiAutoCompleteFieldProps = {
5
5
  value: any[];
6
6
  onChange: (val: any) => void;
7
7
  error?: string | null;
8
+ locale?: string;
8
9
  };
9
10
  export declare const MultiAutoCompleteField: React.FC<MultiAutoCompleteFieldProps>;
10
11
  export {};
@@ -5,6 +5,7 @@ type RadioInputProps = {
5
5
  value: any;
6
6
  onChange: (val: any) => void;
7
7
  error?: string | null;
8
+ locale?: string;
8
9
  };
9
10
  export declare const RadioInput: React.FC<RadioInputProps>;
10
11
  export {};
@@ -13,4 +13,4 @@ import { FieldRendererProps } from '../../components/Field';
13
13
  * onChange={handleChange}
14
14
  * />
15
15
  */
16
- export declare function SelectInput({ field, value, onChange, error, }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare function SelectInput({ field, value, onChange, error, locale, }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
@@ -13,4 +13,4 @@ import { FieldRendererProps } from '../../components/Field';
13
13
  * onChange={handleChange}
14
14
  * />
15
15
  */
16
- export declare function TextInput({ field, value, onChange, error, }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare function TextInput({ field, value, onChange, error, locale, }: FieldRendererProps): import("react/jsx-runtime").JSX.Element;
@@ -5,6 +5,7 @@ type TextAreaInputProps = {
5
5
  value: any;
6
6
  onChange: (val: any) => void;
7
7
  error?: string | null;
8
+ locale?: string;
8
9
  };
9
10
  export declare const TextAreaInput: React.FC<TextAreaInputProps>;
10
11
  export {};
@@ -1,2 +1,3 @@
1
1
  import { FormDTO } from '../types';
2
2
  export declare const profileForm: FormDTO;
3
+ export declare const profileFormI18n: FormDTO;
@@ -12,7 +12,7 @@ type Errors = Record<string, string | null>;
12
12
  * form.handleChange('email', 'user@example.com');
13
13
  * const errors = form.validateAll();
14
14
  */
15
- export declare function useFormBuilder(dto: FormDTO): {
15
+ export declare function useFormBuilder(dto: FormDTO, locale?: string): {
16
16
  /** Current form values for all fields */
17
17
  values: Record<string, any>;
18
18
  /** Function to update a field value */