@dynamicforms/vue-forms 0.1.4 → 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/dist/index.d.ts CHANGED
@@ -1,14 +1,16 @@
1
1
  import { ComputedRef } from 'vue';
2
+ import { Ref } from 'vue';
2
3
 
3
4
  export declare class AbortEventHandlingException extends Error {
4
5
  }
5
6
 
6
7
  export declare class Action extends FieldBase {
7
8
  private readonly _value;
8
- protected constructor(params?: Partial<IField<ActionValue>>);
9
+ protected constructor(params?: Partial<IFieldConstructorParams<ActionValue>>);
9
10
  static create(params?: Partial<IField<ActionValue>>): Action;
10
11
  get value(): ActionValue;
11
12
  set value(newValue: ActionValue);
13
+ setValue(newValue: ActionValue): Promise<void>;
12
14
  get icon(): string | undefined;
13
15
  set icon(newValue: string | undefined);
14
16
  get label(): string | undefined;
@@ -20,8 +22,13 @@ export declare class Action extends FieldBase {
20
22
  declare type ActionExecutor = (field: IField, supr: FieldActionExecute, ...params: any[]) => Promise<any>;
21
23
 
22
24
  export declare class ActionsMap extends Map<symbol, FieldActionExecute> {
25
+ private readonly eagerActions;
23
26
  register(action: FieldActionBase): void;
24
- trigger<T extends FieldActionBase>(ActionClass: new (...args: any[]) => T, field: IField, ...params: any[]): any;
27
+ trigger<T extends FieldActionBase>(ActionClass: {
28
+ new (...args: any[]): T;
29
+ classIdentifier: symbol;
30
+ }, field: IField, ...params: any[]): Promise<any>;
31
+ triggerEager(field: IField, ...params: any[]): Promise<any>;
25
32
  }
26
33
 
27
34
  export declare interface ActionValue {
@@ -29,6 +36,39 @@ export declare interface ActionValue {
29
36
  icon?: string;
30
37
  }
31
38
 
39
+ export declare function buildErrorMessage(mdErrorString: string): string | MdString;
40
+
41
+ export declare class ConditionalEnabledAction extends ConditionalStatementAction {
42
+ constructor(statement: Statement);
43
+ }
44
+
45
+ declare type ConditionalExecutorFn = (field: IField, currentResult: boolean, previousResult: boolean | undefined) => Promise<void>;
46
+
47
+ export declare class ConditionalStatementAction extends ValueChangedAction {
48
+ private lastResult;
49
+ private readonly boundFields;
50
+ constructor(statement: Statement, executorFn: ConditionalExecutorFn);
51
+ static get classIdentifier(): symbol;
52
+ get eager(): boolean;
53
+ boundToField(field: IField): void;
54
+ }
55
+
56
+ export declare class ConditionalValueAction<T> extends ConditionalStatementAction {
57
+ constructor(statement: Statement, trueValue: T);
58
+ }
59
+
60
+ export declare class ConditionalVisibilityAction extends ConditionalStatementAction {
61
+ constructor(statement: Statement);
62
+ }
63
+
64
+ /**
65
+ * Interface for custom component content definition
66
+ */
67
+ export declare interface CustomModalContentComponentDef {
68
+ componentName: string;
69
+ componentProps: Record<any, any>;
70
+ }
71
+
32
72
  /**
33
73
  * DisplayMode enum provides an enumeration for supported ways of rendering a particular object in the DOM
34
74
  */
@@ -49,43 +89,53 @@ export declare const EmptyField: Field<string>;
49
89
 
50
90
  export declare class EnabledChangedAction extends FieldActionBase {
51
91
  constructor(executorFn: (field: IField, supr: FieldActionExecute, newValue: boolean, oldValue: boolean) => Promise<void>);
52
- get classIdentifier(): symbol;
92
+ static get classIdentifier(): symbol;
53
93
  execute(field: IField, supr: FieldActionExecute, newValue: boolean, oldValue: boolean): Promise<void>;
54
94
  }
55
95
 
56
96
  export declare class EnabledChangingAction extends FieldActionBase {
57
97
  constructor(executorFn: (field: IField, supr: FieldActionExecute, newValue: boolean, oldValue: boolean) => Promise<boolean>);
58
- get classIdentifier(): symbol;
98
+ static get classIdentifier(): symbol;
59
99
  execute(field: IField, supr: FieldActionExecute, newValue: boolean, oldValue: boolean): Promise<boolean>;
60
100
  }
61
101
 
62
102
  export declare class ExecuteAction extends FieldActionBase {
63
103
  constructor(executorFn: (field: IField, supr: FieldActionExecute, params: any) => Promise<any>);
64
- get classIdentifier(): symbol;
104
+ static get classIdentifier(): symbol;
65
105
  execute(field: IField, supr: FieldActionExecute, params: any): Promise<any>;
66
106
  }
67
107
 
68
108
  export declare class Field<T = any> extends FieldBase {
69
109
  private _value;
70
- protected constructor(params?: Partial<IField<T>>);
71
- static create<T = any>(params?: Partial<IField<T>>): Field<T>;
110
+ protected constructor(params?: Partial<IFieldConstructorParams<T>>);
111
+ /**
112
+ * Creates a new reactive Field instance.
113
+ * @param params Initial field parameters
114
+ * @returns Reactive Field instance
115
+ */
116
+ static create<T = any>(params?: Partial<IFieldConstructorParams<T>>): Field<T>;
72
117
  get value(): T;
73
118
  set value(newValue: T);
119
+ setValue(newValue: T): Promise<void>;
74
120
  clone(overrides?: Partial<IField<T>>): Field<T>;
75
121
  }
76
122
 
77
123
  export declare abstract class FieldActionBase implements IFieldAction {
78
- abstract get classIdentifier(): symbol;
124
+ static get classIdentifier(): symbol;
125
+ get classIdentifier(): symbol;
79
126
  private readonly executorFn;
80
127
  constructor(executorFn: ActionExecutor);
81
128
  execute(field: IField, supr: IFieldAction['execute'], ...params: any[]): Promise<any>;
129
+ get eager(): boolean;
130
+ boundToField(field: IField): void;
82
131
  }
83
132
 
84
133
  export declare type FieldActionExecute<T = any> = (field: IField<T>, ...params: any[]) => Promise<any>;
85
134
 
86
- declare abstract class FieldBase<T = any> implements IField<T> {
135
+ export declare abstract class FieldBase<T = any> implements IField<T> {
87
136
  abstract get value(): T;
88
137
  abstract set value(newValue: T);
138
+ abstract setValue(newValue: T): Promise<void>;
89
139
  readonly reactiveValue: ComputedRef<T>;
90
140
  abstract clone(overrides?: Partial<IField<T>>): IField<T>;
91
141
  originalValue: T;
@@ -112,8 +162,6 @@ declare abstract class FieldBase<T = any> implements IField<T> {
112
162
  declare namespace Form {
113
163
  export {
114
164
  DisplayMode,
115
- ValidationError,
116
- ValidationErrorText,
117
165
  FieldActionBase,
118
166
  ActionsMap,
119
167
  EnabledChangedAction,
@@ -125,6 +173,13 @@ declare namespace Form {
125
173
  ValueChangedAction,
126
174
  ListItemAddedAction,
127
175
  ListItemRemovedAction,
176
+ Operator,
177
+ ConditionalStatementAction,
178
+ ConditionalVisibilityAction,
179
+ ConditionalEnabledAction,
180
+ ConditionalValueAction,
181
+ OperandType,
182
+ Statement,
128
183
  ActionValue,
129
184
  Action,
130
185
  NullableAction,
@@ -132,33 +187,57 @@ declare namespace Form {
132
187
  NullableField,
133
188
  EmptyField,
134
189
  IField,
190
+ IFieldConstructorActionsList,
191
+ IFieldConstructorParams,
135
192
  AbortEventHandlingException,
136
193
  FieldActionExecute,
137
194
  IFieldAction,
195
+ FieldBase,
138
196
  GenericFieldsInterface,
139
197
  Group,
140
198
  NullableGroup,
141
199
  List,
142
- NullableList
200
+ NullableList,
201
+ Validators,
202
+ buildErrorMessage,
203
+ isCustomModalContentComponentDef,
204
+ MdString,
205
+ CustomModalContentComponentDef,
206
+ RenderContent,
207
+ RenderContentRef,
208
+ ValidationError,
209
+ ValidationErrorText,
210
+ ValidationErrorRenderContent,
211
+ ValidationFunction,
212
+ Validator
143
213
  }
144
214
  }
145
215
  export default Form;
146
216
 
217
+ export declare const forms: {
218
+ install(app: any, options?: Partial<FormsConfig>): void;
219
+ };
220
+
221
+ declare interface FormsConfig {
222
+ useMarkdownInValidators: boolean;
223
+ }
224
+
147
225
  export declare type GenericFieldsInterface = Record<string, IField>;
148
226
 
149
227
  export declare class Group<T extends GenericFieldsInterface = GenericFieldsInterface> extends FieldBase {
150
228
  private readonly _fields;
151
229
  private _value;
152
230
  private suppressNotifyValueChanged;
153
- constructor(fields: T, params?: Partial<IField>);
231
+ constructor(fields: T, params?: Partial<IFieldConstructorParams>);
154
232
  private static isValidFields;
155
233
  static createFromFormData(data: Record<string, any> | null): Group;
156
- field(fieldName: string): IField | null;
234
+ field<K extends keyof T>(fieldName: K): T[K] | null;
157
235
  get fields(): T;
158
236
  get value(): Record<string, any> | null;
159
237
  set value(newValue: Record<string, any> | null);
238
+ setValue(newValue: Record<string, any> | null): Promise<void>;
160
239
  get fullValue(): Record<string, any>;
161
- notifyValueChanged(): void;
240
+ notifyValueChanged(): Promise<void>;
162
241
  clone(overrides?: Partial<IField>): Group<T>;
163
242
  }
164
243
 
@@ -174,6 +253,9 @@ export declare interface IField<T = any> {
174
253
  parent?: any;
175
254
  fieldName?: string;
176
255
  clone(overrides?: Partial<IField<T>>): IField<T>;
256
+ setVisibility(newValue: DisplayMode): Promise<void>;
257
+ setEnabled(newValue: boolean): Promise<void>;
258
+ setValue(newValue: T): Promise<void>;
177
259
  registerAction(action: IFieldAction<T>): this;
178
260
  triggerAction<T2 extends IFieldAction<T>>(actionClass: abstract new (...args: any[]) => T2, ...params: any[]): any;
179
261
  validate(): void;
@@ -184,15 +266,38 @@ export declare interface IFieldAction<T = any> {
184
266
  execute(field: IField<T>, supr: FieldActionExecute<T>, ...params: any[]): any;
185
267
  }
186
268
 
269
+ export declare interface IFieldConstructorActionsList<T = any> {
270
+ actions?: IFieldAction<T>[];
271
+ validators?: IFieldAction<T>[];
272
+ }
273
+
274
+ export declare type IFieldConstructorParams<T = any> = IField<T> & IFieldConstructorActionsList<T>;
275
+
276
+ declare class InAllowedValues<T = any> extends Validator {
277
+ constructor(allowedValues: T[], message?: RenderContentRef);
278
+ }
279
+
280
+ /**
281
+ * Type guard to check if content is a custom component definition
282
+ * @param msg - Content to check
283
+ * @returns True if content is a custom component definition
284
+ */
285
+ export declare function isCustomModalContentComponentDef(msg?: RenderContentRef): msg is CustomModalContentComponentDef;
286
+
287
+ declare class LengthInRange<T = any> extends Validator {
288
+ constructor(minLength: number, maxLength: number, message?: RenderContentRef);
289
+ }
290
+
187
291
  export declare class List<T extends GenericFieldsInterface = GenericFieldsInterface> extends FieldBase {
188
292
  private _value;
189
293
  private _itemTemplate?;
190
294
  private _previousValue;
191
- constructor(itemTemplate?: Group<T>, params?: Partial<IField>);
295
+ constructor(itemTemplate?: Group<T>, params?: Partial<IFieldConstructorParams>);
192
296
  private processSetValueItem;
193
- private setValue;
297
+ private setValueInternal;
194
298
  get value(): Record<string, any>[] | null;
195
299
  set value(newValue: Record<string, any>[]);
300
+ setValue(newValue: Record<string, any>[]): Promise<void>;
196
301
  clone(overrides?: Partial<IField>): List<T>;
197
302
  notifyValueChanged(): void;
198
303
  get(index: number): Group<T> | undefined;
@@ -205,16 +310,38 @@ export declare class List<T extends GenericFieldsInterface = GenericFieldsInterf
205
310
 
206
311
  export declare class ListItemAddedAction extends FieldActionBase {
207
312
  constructor(executorFn: (field: IField, supr: FieldActionExecute, item: any, index: number) => Promise<void>);
208
- get classIdentifier(): symbol;
313
+ static get classIdentifier(): symbol;
209
314
  execute(field: IField, supr: FieldActionExecute, item: any, index: number): Promise<void>;
210
315
  }
211
316
 
212
317
  export declare class ListItemRemovedAction extends FieldActionBase {
213
318
  constructor(executorFn: (field: IField, supr: FieldActionExecute, item: any, index: number) => Promise<void>);
214
- get classIdentifier(): symbol;
319
+ static get classIdentifier(): symbol;
215
320
  execute(field: IField, supr: FieldActionExecute, item: any, index: number): Promise<void>;
216
321
  }
217
322
 
323
+ declare class MaxLength<T = any> extends Validator {
324
+ constructor(maxLength: number, message?: RenderContentRef);
325
+ }
326
+
327
+ declare class MaxValue<T = any> extends Validator {
328
+ constructor(maxValue: T, message?: RenderContentRef);
329
+ }
330
+
331
+ /**
332
+ * Marks content for markdown rendering
333
+ */
334
+ export declare class MdString extends String {
335
+ }
336
+
337
+ declare class MinLength<T = any> extends Validator {
338
+ constructor(minLength: number, message?: RenderContentRef);
339
+ }
340
+
341
+ declare class MinValue<T = any> extends Validator {
342
+ constructor(minValue: T, message?: RenderContentRef);
343
+ }
344
+
218
345
  export declare type NullableAction = Action | null;
219
346
 
220
347
  export declare type NullableField<T = any> = Field<T> | null;
@@ -223,41 +350,160 @@ export declare type NullableGroup = Group | null;
223
350
 
224
351
  export declare type NullableList = List | null;
225
352
 
353
+ export declare type OperandType = any | Statement | IField;
354
+
355
+ /**
356
+ * Operators provides us a functionality for backend to send us complex condition upon which we send
357
+ * dynamic visibility prop for form input fields
358
+ */
359
+ export declare enum Operator {
360
+ NOT = 0,
361
+ OR = 1,
362
+ AND = 2,
363
+ XOR = 3,
364
+ NAND = 4,
365
+ NOR = 5,
366
+ EQUALS = -1,
367
+ NOT_EQUALS = -2,
368
+ GT = -3,
369
+ LT = -4,
370
+ GE = -5,
371
+ LE = -6,
372
+ IN = -7,
373
+ NOT_IN = -8,
374
+ INCLUDES = -9,
375
+ NOT_INCLUDES = -10
376
+ }
377
+
378
+ export declare namespace Operator {
379
+ export function fromString(operator: string): Operator;
380
+ export function fromAny(mode: any): Operator;
381
+ export function isDefined(operator: number | string): boolean;
382
+ export function isLogicOperator(operator: Operator): boolean;
383
+ }
384
+
385
+ declare class Pattern<T = any> extends Validator {
386
+ constructor(pattern: RegExp, message?: RenderContentRef);
387
+ }
388
+
389
+ /**
390
+ * Type for different renderable content formats: plain string, markdown, or custom component
391
+ */
392
+ export declare type RenderContent = string | MdString | CustomModalContentComponentDef;
393
+
394
+ /**
395
+ * Type for different renderable content formats (supporting references): plain string, markdown, or custom component
396
+ */
397
+ export declare type RenderContentRef = RenderContent | Ref<RenderContent>;
398
+
399
+ declare class Required_2<T = any> extends Validator {
400
+ constructor(message?: RenderContentRef);
401
+ }
402
+
403
+ export declare class Statement {
404
+ private readonly operand1;
405
+ private readonly operator;
406
+ private readonly operand2;
407
+ constructor(operand1: OperandType, operator: Operator, operand2: OperandType);
408
+ get operand1Value(): any;
409
+ get operand2Value(): any;
410
+ evaluate(): boolean;
411
+ /**
412
+ * Recursively collects all fields used in this statement and its nested statements
413
+ * @returns A set of all fields used in this statement
414
+ */
415
+ collectFields(): Set<IField>;
416
+ }
417
+
418
+ /**
419
+ * Base validation error class with component rendering capabilities
420
+ */
226
421
  export declare class ValidationError {
227
422
  get componentName(): string;
228
423
  get componentBindings(): {};
424
+ get componentBody(): string;
425
+ }
426
+
427
+ /**
428
+ * Validation error that supports multiple content types (plain text, markdown, component)
429
+ */
430
+ export declare class ValidationErrorRenderContent extends ValidationError {
431
+ text: Ref<RenderContent>;
432
+ textType: ComputedRef<'string' | 'md' | 'component'>;
433
+ constructor(text: RenderContentRef);
434
+ get getTextType(): "string" | "md" | "component";
435
+ get componentName(): string;
436
+ get componentBindings(): Record<any, any>;
437
+ get componentBody(): string;
229
438
  }
230
439
 
440
+ /**
441
+ * Simple text-only ValidationError
442
+ */
231
443
  export declare class ValidationErrorText extends ValidationError {
232
444
  text: string;
233
445
  constructor(text: string);
234
446
  get componentName(): string;
235
- get componentBindings(): {
236
- class: string;
237
- };
447
+ get componentBody(): string;
448
+ }
449
+
450
+ export declare type ValidationFunction<T = any> = (newValue: T, oldValue: T, field: IField<T>) => ValidationError[] | null;
451
+
452
+ /**
453
+ * Validator is a specialized action that performs validation when a field's value changes.
454
+ * It automatically adds/removes validation errors from the field's errors array.
455
+ */
456
+ export declare class Validator<T = any> extends ValueChangedAction {
457
+ private readonly source;
458
+ /**
459
+ * Creates a new validator
460
+ * @param validationFn Function that validates the field value and returns errors or null
461
+ */
462
+ constructor(validationFn: ValidationFunction<T>);
463
+ static get classIdentifier(): symbol;
464
+ get eager(): boolean;
465
+ protected replacePlaceholders(text: RenderContentRef, replace: Record<string, any>): string | MdString | CustomModalContentComponentDef;
466
+ }
467
+
468
+ export declare namespace Validators {
469
+ export {
470
+ InAllowedValues,
471
+ Required_2 as Required,
472
+ Pattern,
473
+ MinValue,
474
+ MaxValue,
475
+ ValueInRange,
476
+ MinLength,
477
+ MaxLength,
478
+ LengthInRange
479
+ }
238
480
  }
239
481
 
240
482
  export declare class ValidChangedAction extends FieldActionBase {
241
483
  constructor(executorFn: (field: IField, supr: FieldActionExecute, newValue: boolean, oldValue: boolean) => Promise<void>);
242
- get classIdentifier(): symbol;
484
+ static get classIdentifier(): symbol;
243
485
  execute(field: IField, supr: FieldActionExecute, newValue: boolean, oldValue: boolean): Promise<void>;
244
486
  }
245
487
 
246
488
  export declare class ValueChangedAction<T = any> extends FieldActionBase {
247
489
  constructor(executorFn: (field: IField<T>, supr: FieldActionExecute<T>, newValue: T, oldValue: T) => Promise<void>);
248
- get classIdentifier(): symbol;
490
+ static get classIdentifier(): symbol;
249
491
  execute(field: IField<T>, supr: FieldActionExecute<T>, newValue: T, oldValue: T): Promise<void>;
250
492
  }
251
493
 
494
+ declare class ValueInRange<T = any> extends Validator {
495
+ constructor(minValue: T, maxValue: T, message?: RenderContentRef);
496
+ }
497
+
252
498
  export declare class VisibilityChangedAction extends FieldActionBase {
253
499
  constructor(executorFn: (field: IField, supr: FieldActionExecute, newValue: DisplayMode, oldValue: DisplayMode) => Promise<void>);
254
- get classIdentifier(): symbol;
500
+ static get classIdentifier(): symbol;
255
501
  execute(field: IField, supr: FieldActionExecute, newValue: DisplayMode, oldValue: DisplayMode): Promise<void>;
256
502
  }
257
503
 
258
504
  export declare class VisibilityChangingAction extends FieldActionBase {
259
505
  constructor(executorFn: (field: IField, supr: FieldActionExecute, newValue: DisplayMode, oldValue: DisplayMode) => Promise<DisplayMode>);
260
- get classIdentifier(): symbol;
506
+ static get classIdentifier(): symbol;
261
507
  execute(field: IField, supr: FieldActionExecute, newValue: DisplayMode, oldValue: DisplayMode): Promise<DisplayMode>;
262
508
  }
263
509
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dynamicforms/vue-forms",
3
3
  "private": false,
4
- "version": "0.1.4",
4
+ "version": "0.2.0",
5
5
  "type": "module",
6
6
  "description": "Data entry forms for vue - logic (no controls here)",
7
7
  "author": "Jure Erznožnik",
package/readme.md CHANGED
@@ -21,7 +21,9 @@ separates these concerns, allowing you to build forms that match your design sys
21
21
  - **TypeScript support**: Full type definitions for excellent developer experience
22
22
  - **Lightweight**: No dependencies besides Vue and lodash
23
23
  - **Field types**: Core field types (Field, Action, Group, List) to represent any data structure
24
- - **Validation**: Simple validation system with extensible error handling
24
+ - **Validation**: Comprehensive validation system with built-in validators and extensible error handling
25
+ - **Conditional logic**: Dynamic form behavior based on field values and conditions
26
+ - **Display modes**: Control field visibility with different display modes (Full, Hidden, Invisible, Suppress)
25
27
 
26
28
  ## Installation
27
29
 
@@ -88,6 +90,118 @@ const form = new Group({
88
90
  }));
89
91
  ```
90
92
 
93
+ ## Built-in Validators
94
+
95
+ The library provides several built-in validators for common validation scenarios:
96
+
97
+ ```typescript
98
+ import { Field, Group, Validators } from '@dynamicforms/vue-forms';
99
+
100
+ const validatedForm = new Group({
101
+ // Required field
102
+ username: Field.create({
103
+ validators: [new Validators.Required('Username is required')]
104
+ }),
105
+
106
+ // Email validation with pattern
107
+ email: Field.create({
108
+ validators: [
109
+ new Validators.Pattern(
110
+ /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
111
+ 'Please enter a valid email address'
112
+ )
113
+ ]
114
+ }),
115
+
116
+ // Numeric range validation
117
+ age: Field.create({
118
+ value: 25,
119
+ validators: [
120
+ new Validators.ValueInRange(18, 100, 'Age must be between 18 and 100')
121
+ ]
122
+ }),
123
+
124
+ // Allowed values validation
125
+ role: Field.create({
126
+ validators: [
127
+ new Validators.InAllowedValues(['admin', 'user', 'guest'])
128
+ ]
129
+ }),
130
+
131
+ // Text length validation
132
+ bio: Field.create({
133
+ validators: [
134
+ new Validators.LengthInRange(10, 200, 'Bio must be between 10 and 200 characters')
135
+ ]
136
+ })
137
+ });
138
+ ```
139
+
140
+ ## Conditional Form Behavior
141
+
142
+ Create dynamic forms with conditional logic using Statements and Operators:
143
+
144
+ ```typescript
145
+ import {
146
+ Field, Group, Statement, Operator,
147
+ ConditionalVisibilityAction, ConditionalEnabledAction
148
+ } from '@dynamicforms/vue-forms';
149
+
150
+ const form = new Group({
151
+ isCompany: Field.create({ value: false }),
152
+ companyName: Field.create(),
153
+ firstName: Field.create(),
154
+ lastName: Field.create()
155
+ });
156
+
157
+ // Show company name field only when isCompany is true
158
+ const showCompanyNameStatement = new Statement(form.fields.isCompany, Operator.EQUALS, true);
159
+ form.fields.companyName.registerAction(
160
+ new ConditionalVisibilityAction(showCompanyNameStatement)
161
+ );
162
+
163
+ // Show personal name fields only when isCompany is false
164
+ const showPersonalFieldsStatement = new Statement(form.fields.isCompany, Operator.EQUALS, false);
165
+ form.fields.firstName.registerAction(
166
+ new ConditionalVisibilityAction(showPersonalFieldsStatement)
167
+ );
168
+ form.fields.lastName.registerAction(
169
+ new ConditionalVisibilityAction(showPersonalFieldsStatement)
170
+ );
171
+ ```
172
+
173
+ ## Advanced Data Structures (Lists)
174
+
175
+ Work with array data using the List component:
176
+
177
+ ```typescript
178
+ import { Field, Group, List } from '@dynamicforms/vue-forms';
179
+
180
+ // Define a template for list items
181
+ const contactTemplate = new Group({
182
+ name: Field.create(),
183
+ email: Field.create(),
184
+ phone: Field.create()
185
+ });
186
+
187
+ // Create a list with the template
188
+ const contactsList = new List(contactTemplate);
189
+
190
+ // Add items to the list
191
+ contactsList.push({ name: 'John Doe', email: 'john@example.com', phone: '123-456-7890' });
192
+ contactsList.push({ name: 'Jane Doe', email: 'jane@example.com', phone: '987-654-3210' });
193
+
194
+ // Access list items
195
+ const firstContact = contactsList.get(0);
196
+ console.log(firstContact.fields.name.value); // 'John Doe'
197
+
198
+ // Modify items
199
+ firstContact.fields.email.value = 'john.doe@example.com';
200
+
201
+ // Remove items
202
+ contactsList.remove(1);
203
+ ```
204
+
91
205
  ## TypeScript Support
92
206
 
93
207
  The library is written in TypeScript and provides full type definitions:
@@ -95,39 +209,61 @@ The library is written in TypeScript and provides full type definitions:
95
209
  ```typescript
96
210
  import { Field, Group, IField } from '@dynamicforms/vue-forms';
97
211
 
212
+ // Define field types explicitly
213
+ const usernameField = Field.create<string>({ value: '' });
214
+ const emailField = Field.create<string>({ value: '' });
215
+ const ageField = Field.create<number>({ value: 25 });
216
+ const isActiveField = Field.create<boolean>({ value: true });
217
+
218
+ // Type inference also works with initial values
219
+ const implicitTypedField = Field.create({ value: 'string' }); // Type is inferred as string
220
+
98
221
  // Define your form structure with types
99
- interface UserFormData {
100
- username: Field;
101
- email: Field;
222
+ interface UserFormData extends GenericFieldsInterface {
223
+ username: Field<string>;
224
+ email: Field<string>;
225
+ age: Field<number>;
226
+ isActive: Field<boolean>;
102
227
  preferences: Group<{
103
- darkMode: Field;
104
- notifications: Field;
228
+ darkMode: Field<boolean>;
229
+ notifications: Field<boolean>;
105
230
  }>;
106
231
  }
107
232
 
108
233
  // Create the form with type checking
109
234
  const userForm = new Group<UserFormData>({
110
- username: Field.create({ value: '' }),
111
- email: Field.create({ value: '' }),
112
- preferences: new Group({
113
- darkMode: Field.create({ value: true }),
114
- notifications: Field.create({ value: true })
235
+ username: Field.create<string>({ value: '' }),
236
+ email: Field.create<string>({ value: '' }),
237
+ age: Field.create<number>({ value: 25 }),
238
+ isActive: Field.create<boolean>({ value: true }),
239
+ preferences: new Group<{
240
+ darkMode: Field<boolean>;
241
+ notifications: Field<boolean>;
242
+ }>({
243
+ darkMode: Field.create<boolean>({ value: true }),
244
+ notifications: Field.create<boolean>({ value: true })
115
245
  })
116
246
  });
117
247
 
118
- // TypeScript knows the structure
248
+ // TypeScript knows the structure and types
249
+ const email: string = userForm.fields.email.value;
250
+ const age: number = userForm.fields.age.value;
119
251
  const darkMode: boolean = userForm.fields.preferences.fields.darkMode.value;
252
+
253
+ // Type safety prevents errors
254
+ // userForm.fields.age.value = 'not a number'; // Error: Type 'string' is not assignable to type 'number'
120
255
  ```
121
256
 
257
+ ## Documentation
258
+
259
+ For more detailed documentation and examples, check out the documentation (currently only locally runnable).
260
+
122
261
  ## Conclusion
123
262
 
124
263
  `@dynamicforms/vue-forms` provides a clean, flexible approach to form management in Vue applications. By focusing on
125
264
  data structures and state management rather than UI components, it offers unparalleled flexibility while maintaining
126
265
  a simple, intuitive API.
127
266
 
128
- For more detailed documentation and examples, check out the [source code](https://github.com/velis74/dynamicforms-vue-forms) or reach out to the author
129
- for assistance.
130
-
131
267
  ## License
132
268
 
133
269
  MIT