Skip to content

Commit

Permalink
Added property documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei15193 committed Oct 21, 2024
1 parent fa319b1 commit f9f59ad
Show file tree
Hide file tree
Showing 29 changed files with 451 additions and 92 deletions.
369 changes: 326 additions & 43 deletions docs.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-model-view-viewmodel",
"version": "3.0.0-forms.4",
"description": "A library for developing React applications using Model-View-ViewModel inspired by .NET",
"version": "3.0.0-rc.1",
"description": "A library for developing ReactJS applications using Model-View-ViewModel, inspired by .NET.",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"module": "./src/index.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class ReadOnlyObservableCollection<TItem> extends ViewModel implements IR

/**
* Gets or sets the number of items in the collection.
* @protected
* @see [Array.length](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/length)
*/
protected set length(value: number) {
Expand Down
81 changes: 77 additions & 4 deletions src/forms/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { FormCollection } from './FormCollection';
* Represents a form for which both fields and sections can be configured. Form sections are forms themselves making this a tree structure
* where fields represent leaves and sections are parent nodes.
*
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*
* ----
*
Expand Down Expand Up @@ -54,9 +54,82 @@ import { FormCollection } from './FormCollection';
*
* The configuration does not change the state, the form still looks more or less
* the same, but the way fields behave is different. Some fields become required
* or have different validaiton rules while other can become locked and are no
* or have different validation rules while other can become locked and are no
* longer editable.
*
*
* #### Form Structure and Change Propagation
*
* Forms have a hierarchical structure comprising of fields and sections which are
* forms themselves. This allows for both simple and complex form definitions
* through the same model.
*
* Any form contrains a collection of fields and a collection of sections, however
* propagation has an additional level of sections collections. Any form is a parent
* node while fields are leaves in the tree structure with propagation generally
* going bottom-up.
*
* * {@linkcode Form} - root or parent node
* * {@linkcode FormField} - leaf nodes, any changes to a field are propagated to the parent node, a {@linkcode Form}.
* * {@linkcode FormCollection} - a collection of {@linkcode Form} instances, any change to a form collection is propagated to the parent node, a {@linkcode Form}.
*
* Any changes to a {@linkcode Form} is propagated to the {@linkcode FormCollection}
* to which it was added. With this, extensions and validation can be added at any level,
* from fields, to forms and form collections themselves.
*
* For simple cases, defining a form is done by extending a {@linkcode Form} and
* adding fields using {@linkcode withFields}.
*
* In case of large forms it can be beneficial to group fields into sections,
* which are just different {@linkcode Form} composing a larger one. This can be
* done using {@linkcode withSections}.
*
* For more complex cases where there are collections of forms where items can
* be added and removed, and each item has its own set of editable fields, a
* {@linkcode FormCollection} must be used to allow for items to be added and
* removed. To conrol the interface for mutating the collection consider
* extending {@link ReadOnlyFormCollection} instead.
*
* To add your own form collections to a form use {@linkcode withSectionsCollection}
* as this will perform the same operation as {@linkcode withSections} only that
* you have control over the underlying form collection. Any changes to the
* collection are reflected on the form as well.
*
* All fields and sections that are added with any of the mentioned methods are
* available through the {@linkcode fields} and {@linkcode sections} properties.
*
* #### Validation
*
* Validation is one of the best examples for change propagation and is offered
* out of the box. Whenever a field becomes invalid, the entire form becomes
* invalid.
*
* This applies to form sections as well, whenever a section collection is
* invalid, the form (parent node) becomes invalid, and finally, when a form
* becomes invalid, the form collection it was added to also becomes invalid.
*
* With this, the propagation can be seen clearly as validity is determined
* completely by the status of each component of the entire form, from all levels.
* Any change in one of the nodes goes all the way up to the root node making it
* very easy to check if the entire form is valid or not, and later on checking
* which sections or fields are invalid.
*
* Multiple validators can be added and upon any change that is notified by the
* target invokes them until the first validator returns an error message. E.g.:
* if a field is required and has 2nd validator for checking the length of the
* content, the 2nd validator will only be invoked when the 1st one passes, when
* the field has an actual value.
*
* This allows for granular validation messages as well as reusing them across
* {@linkcode IValidatable} objects.
*
* For more complex cases when the validity of one field is dependent on the
* value of another field, such as the start date/end date pair, then validation
* triggers can be configured so that when either field changes the validators
* are invoked. This is similar in a way to how dependencies work on a ReactJS
* hook.
*
* All form components have a `validation` property where configuraiton can be
* made, check {@linkcode validation} for more information.
* ----
*
* @guidance Define a Form
Expand Down Expand Up @@ -214,7 +287,7 @@ import { FormCollection } from './FormCollection';
* By default, validation errors are represented using `string`s, however this
* can be changed through the {@linkcode TValidationError} generic parameter.
* The snippet below illustrates using a [literal type](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html)
* for validaiton results.
* for validation results.
*
* ```ts
* type ValidationError = 'Required' | 'GreaterThanZero';
Expand Down
2 changes: 1 addition & 1 deletion src/forms/FormCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ReadOnlyFormCollection } from './ReadOnlyFormCollection';
* form sections for cases where validation and other aspects are based on the state of an entity or the form itself.
*
* @template TForm The concrete type of the form.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export class FormCollection<TForm extends Form<TValidationError>, TValidationError = string> extends ReadOnlyFormCollection<TForm, TValidationError> implements IFormCollection<TForm, TValidationError> {
/**
Expand Down
4 changes: 2 additions & 2 deletions src/forms/FormField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Validatable, type IValidator, type ValidatorCallback, type IObjectValid
/**
* Represents the configuration of a field, this can be extended for custom fields to easily add more features.
* @template TValue The value of the field.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IFormFieldConfig<TValue, TValidationError = string> {
/**
Expand Down Expand Up @@ -33,7 +33,7 @@ export interface IFormFieldConfig<TValue, TValidationError = string> {
/**
* Represents a form field containing the minimum set of information required to describe a field in a form.
* @template TValue The value of the field.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*
* ----
*
Expand Down
6 changes: 3 additions & 3 deletions src/forms/IConfigurableFormCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import type { Form } from './Form';
* Represents a callback used to configure an individual form section within a collection.
*
* @template TSection The form section type to configure.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export type FormSetupCallback<TSection extends Form<TValidationError>, TValidationError = string> = (section: TSection) => void;

/**
* Represents collection of form sections that can be configured. This is useful for cases like having a list of editable items
* and neeeding to add validaiton for each based on the state of an entity or the form itself.
* and neeeding to add validation for each based on the state of an entity or the form itself.
*
* @template TSection The concrete type of the form section.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IConfigurableFormCollection<TSection extends Form<TValidationError>, TValidationError = string> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/forms/IFormCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { IConfigurableFormCollection } from './IConfigurableFormCollection'
* form sections for cases where validation and other aspects are based on the state of an entity or the form itself.
*
* @template TForm The concrete type of the form section.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IFormCollection<TForm extends Form<TValidationError>, TValidationError = string> extends IValidatable<TValidationError>, IObservableCollection<TForm>, IConfigurableFormCollection<TForm, TValidationError> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/forms/IReadOnlyFormCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { IConfigurableFormCollection } from './IConfigurableFormCollection'
* form itself.
*
* @template TForm The concrete type of the form section.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IReadOnlyFormCollection<TForm extends Form<TValidationError>, TValidationError = string> extends IValidatable<TValidationError>, IReadOnlyObservableCollection<TForm>, IConfigurableFormCollection<TForm, TValidationError> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/forms/ReadOnlyFormCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ReadOnlyObservableCollection } from '../collections';
* form itself.
*
* @template TForm The concrete type of the form section.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export class ReadOnlyFormCollection<TForm extends Form<TValidationError>, TValidationError = string> extends ReadOnlyObservableCollection<TForm> implements IReadOnlyFormCollection<TForm, TValidationError>, IValidatable<TValidationError> {
private _error: TValidationError | null;
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ export {
type IReadOnlyValidatable, type IValidatable, Validatable,

type IValidator, type ValidatorCallback,
type IReadOnlyObjectValidator, type IObjectValidator, ObjectValidator,
type IReadOnlyObjectValidator, type IObjectValidator, type IValidationTriggersSet, ObjectValidator,

type WellKnownValidationTrigger, ValidationTrigger,
type WellKnownValidationTrigger, type ValidationTriggerSelector, ValidationTrigger,

type IViewModelChangedValidationTriggerConfig, ViewModelChangedValidationTrigger,
type ICollectionChangedValidationTriggerConfig, CollectionChangedValidationTrigger,
Expand Down
2 changes: 1 addition & 1 deletion src/validation/IReadOnlyValidatable.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Represents a read-only validatable object.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IReadOnlyValidatable<TValidationError = string> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/validation/IValidatable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { IReadOnlyValidatable } from './IReadOnlyValidatable';

/**
* Represents a validatable object.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IValidatable<TValidationError = string> extends IReadOnlyValidatable<TValidationError> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/validation/IValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { IReadOnlyValidatable } from './IReadOnlyValidatable';
* additional actions need to be performed, such as flags, when a validator is added.
*
* @template TValidatable The instance type that is being validated.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IValidator<TValidatable extends IReadOnlyValidatable<TValidationError>, TValidationError = string> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/validation/Validatable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ViewModel } from '../viewModels';

/**
* Represents a base implementation for a validatable
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export class Validatable<TValidationError = string> extends ViewModel implements IValidatable<TValidationError> {
private _error: TValidationError | null;
Expand Down
5 changes: 3 additions & 2 deletions src/validation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ export type { IValidator, ValidatorCallback } from './IValidator';
export {
type IReadOnlyObjectValidator,
type IObjectValidator,
ObjectValidator
type IValidationTriggersSet,
ObjectValidator,
} from './objectValidator';

export {
type WellKnownValidationTrigger, ValidationTrigger,
type WellKnownValidationTrigger, ValidationTriggerSelector, ValidationTrigger,

type IViewModelChangedValidationTriggerConfig, ViewModelChangedValidationTrigger,
type ICollectionChangedValidationTriggerConfig, CollectionChangedValidationTrigger,
Expand Down
2 changes: 1 addition & 1 deletion src/validation/objectValidator/IObjectValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { WellKnownValidationTrigger, ValidationTrigger } from '../triggers'
/**
* Represents an object validator.
* @template TValidatable The instance type that is being validated.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IObjectValidator<TValidatable extends IValidatable<TValidationError> & INotifyPropertiesChanged, TValidationError = string> extends IReadOnlyObjectValidator<TValidatable, TValidationError> {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/validation/objectValidator/IReadOnlyObjectValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { WellKnownValidationTrigger, ValidationTrigger } from '../triggers'
/**
* Represents a read-only object validator.
* @template TValidatable The instance type that is being validated.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IReadOnlyObjectValidator<TValidatable extends IReadOnlyValidatable<TValidationError> & INotifyPropertiesChanged, TValidationError = string> {
/**
Expand Down
4 changes: 2 additions & 2 deletions src/validation/objectValidator/ObjectValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ViewModelChangedValidationTrigger, resolveValidationTriggers } from '..
/**
* Represents the object validator configuration.
* @template TValidatable The instance type that is being validated.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export interface IObjectValidatorConfig<TValidatable extends IValidatable<TValidationError> & INotifyPropertiesChanged, TValidationError = string> {
readonly target: TValidatable;
Expand All @@ -21,7 +21,7 @@ export interface IObjectValidatorConfig<TValidatable extends IValidatable<TValid
/**
* Represents a base implementation for an object validator.
* @template TValidatable The instance type that is being validated.
* @template TValidationError The concrete type for representing validaiton errors (strings, enums, numbers etc.).
* @template TValidationError The concrete type for representing validation errors (strings, enums, numbers etc.).
*/
export class ObjectValidator<TValidatable extends IValidatable<TValidationError> & INotifyPropertiesChanged, TValidationError = string> implements IObjectValidator<TValidatable, TValidationError> {
private static _defaultShouldTargetTriggerValidation<TValidationError = string>(target: IValidatable<TValidationError>, changedProperties: readonly (keyof IValidatable<TValidationError>)[]): boolean {
Expand Down
4 changes: 2 additions & 2 deletions src/validation/triggers/CollectionChangedValidationTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { ValidationTrigger } from './ValidationTrigger';
*/
export interface ICollectionChangedValidationTriggerConfig<TItem = unknown, TCollection extends INotifyCollectionChanged<TItem> = INotifyCollectionChanged<TItem>> {
/**
* Gets the collection that may trigger a validaiton.
* Gets the collection that may trigger a validation.
*/
readonly collection: TCollection;

/**
* Optional, a guard method which controls when a validaiton should be triggered.
* Optional, a guard method which controls when a validation should be triggered.
* @param collection The collection that changed.
* @param collectionChange The collection change.
*/
Expand Down
8 changes: 4 additions & 4 deletions src/validation/triggers/CollectionItemValidationTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface IItemValidationTriggers {
*/
export interface ICollectionItemValidationTriggerConfig<TItem> {
/**
* Gets the collection containing the items that may trigger validaiton.
* Gets the collection containing the items that may trigger validation.
*/
readonly collection: INotifyCollectionChanged<TItem> & Iterable<TItem>;
/**
Expand All @@ -25,15 +25,15 @@ export interface ICollectionItemValidationTriggerConfig<TItem> {
readonly validationTriggerSelector: ValidationTriggerSelector<TItem>;

/**
* Optional, a guard method which controls when a validaiton should be triggered.
* Optional, a guard method which controls when a validation should be triggered.
* @param item The item that changed which may trigger a validation.
*/
shouldTriggerValidation?(item: TItem): boolean;
}

/**
* Represents a collection item validation trigger. Instead of triggering a validaiton only when the collection changes,
* a validaiton may be triggered by any of the contained items when they themselves change.
* Represents a collection item validation trigger. Instead of triggering a validation only when the collection changes,
* a validation may be triggered by any of the contained items when they themselves change.
*
* This is useful when within the collection there is a field that needs to be unique,
* such as a unique name for each item in the collection.
Expand Down
Loading

0 comments on commit f9f59ad

Please sign in to comment.