feat: Types and Intellisense Improvements (#231)
This commit is contained in:
parent
5b539c809c
commit
25ce684d23
4 changed files with 76 additions and 1 deletions
|
@ -14,8 +14,14 @@ import type {
|
||||||
} from '@astro-reactive/common';
|
} from '@astro-reactive/common';
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import ShortUniqueId from 'short-unique-id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of form controls
|
||||||
|
*/
|
||||||
export type ControlConfig = ControlBase | Checkbox | Radio | Submit | Button | Dropdown | TextArea;
|
export type ControlConfig = ControlBase | Checkbox | Radio | Submit | Button | Dropdown | TextArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an individual control that will be rendered as an input element.
|
||||||
|
*/
|
||||||
export class FormControl {
|
export class FormControl {
|
||||||
private _id = '';
|
private _id = '';
|
||||||
private _name = '';
|
private _name = '';
|
||||||
|
@ -41,6 +47,11 @@ export class FormControl {
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks the value and validation status of an individual form control.
|
||||||
|
* @param config - interface of a `FormControl`'s configuration.
|
||||||
|
* @param validateOnLoad - determines if a control will be validated before rendering on the server. Defaults to `false`
|
||||||
|
*/
|
||||||
constructor(private config: ControlConfig, validateOnLoad = false) {
|
constructor(private config: ControlConfig, validateOnLoad = false) {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
@ -135,18 +146,29 @@ export class FormControl {
|
||||||
return this._cols;
|
return this._cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the form control value dynamically
|
||||||
|
* @param value - new value to set
|
||||||
|
*/
|
||||||
setValue(value: string) {
|
setValue(value: string) {
|
||||||
this._value = value;
|
this._value = value;
|
||||||
this._isPristine = false;
|
this._isPristine = false;
|
||||||
this._errors = this.validate(value, this.config.validators || []);
|
this._errors = this.validate(value, this.config.validators || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets validators dynamically for the form control
|
||||||
|
* @param validators - array of `Validators` return value
|
||||||
|
*/
|
||||||
setValidators(validators: string[]) {
|
setValidators(validators: string[]) {
|
||||||
this._validators = validators;
|
this._validators = validators;
|
||||||
const valueStr: string = this._value?.toString() || '';
|
const valueStr: string = this._value?.toString() || '';
|
||||||
this._errors = this.validate(valueStr, this._validators || []);
|
this._errors = this.validate(valueStr, this._validators || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the property that determines if control will be validated before rendering on the server
|
||||||
|
*/
|
||||||
setValidateOnLoad(validateOnLoad: boolean) {
|
setValidateOnLoad(validateOnLoad: boolean) {
|
||||||
if (validateOnLoad) {
|
if (validateOnLoad) {
|
||||||
import('@astro-reactive/validator').then((validator) => {
|
import('@astro-reactive/validator').then((validator) => {
|
||||||
|
@ -166,10 +188,17 @@ export class FormControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all errors from a form contol
|
||||||
|
*/
|
||||||
clearErrors() {
|
clearErrors() {
|
||||||
this._errors = [];
|
this._errors = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an error dynamically
|
||||||
|
* @param error - A `ValidationError` object
|
||||||
|
*/
|
||||||
setError(error: ValidationError) {
|
setError(error: ValidationError) {
|
||||||
this._errors = [...(this._errors || []), error];
|
this._errors = [...(this._errors || []), error];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
import { ControlConfig, FormControl } from './form-control';
|
import { ControlConfig, FormControl } from './form-control';
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import ShortUniqueId from 'short-unique-id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a group of controls that will be rendered as a fieldset element in a form.
|
||||||
|
*/
|
||||||
export class FormGroup {
|
export class FormGroup {
|
||||||
controls: FormControl[];
|
controls: FormControl[];
|
||||||
name?: string;
|
name?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks the value and validity state of a group of `FormControl` instances.
|
||||||
|
* @param controls - an array of `FormControl` configuration
|
||||||
|
* @param name - optional form name
|
||||||
|
*/
|
||||||
constructor(controls: ControlConfig[], name = '') {
|
constructor(controls: ControlConfig[], name = '') {
|
||||||
const uid = new ShortUniqueId({ length: 9 });
|
const uid = new ShortUniqueId({ length: 9 });
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -15,10 +23,16 @@ export class FormGroup {
|
||||||
.map((control) => new FormControl(control));
|
.map((control) => new FormControl(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a form control by its name
|
||||||
|
*/
|
||||||
get(name: string): FormControl | undefined {
|
get(name: string): FormControl | undefined {
|
||||||
return this.controls.find((control) => control.name === name);
|
return this.controls.find((control) => control.name === name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the `FormGroup`'s form controls value
|
||||||
|
*/
|
||||||
setValue(values: object) {
|
setValue(values: object) {
|
||||||
Object.keys(values).forEach((name) => this.get(name)?.setValue(values[name as keyof object]));
|
Object.keys(values).forEach((name) => this.get(name)?.setValue(values[name as keyof object]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import type { ValidationError, ValidatorRules } from '@astro-reactive/common';
|
||||||
import { Validators } from './validator-names';
|
import { Validators } from './validator-names';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* given the value and validators, `validate()` returns an array of errors
|
* Given the value and validators, `validate()` returns an array of errors
|
||||||
* @param value - value to be validated
|
* @param value - value to be validated
|
||||||
* @param validators - names of validation logic to be applied
|
* @param validators - names of validation logic to be applied
|
||||||
* @returns errors - array of errors `ValidationError`
|
* @returns errors - array of errors `ValidationError`
|
||||||
|
@ -59,6 +59,10 @@ export function validate(value: string, validators: ValidatorRules): ValidationE
|
||||||
.filter((result) => result !== null) as ValidationError[];
|
.filter((result) => result !== null) as ValidationError[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all validation errors triggered by `Validator` component
|
||||||
|
* @param event - A DOM event
|
||||||
|
*/
|
||||||
export function clearErrors(event: Event) {
|
export function clearErrors(event: Event) {
|
||||||
const categories = ['error', 'warn', 'info'];
|
const categories = ['error', 'warn', 'info'];
|
||||||
const element = event.target as HTMLInputElement;
|
const element = event.target as HTMLInputElement;
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Provides a set of built-in validators that can be used by form controls.
|
||||||
|
*/
|
||||||
// improvement: implement min&max inclusive/exclusive
|
// improvement: implement min&max inclusive/exclusive
|
||||||
export class Validators {
|
export class Validators {
|
||||||
|
/**
|
||||||
|
* Validator that requires the value to be greater than or equal to the provided number.
|
||||||
|
* @param min - minimum number
|
||||||
|
*/
|
||||||
static min(min?: number): string {
|
static min(min?: number): string {
|
||||||
const label = 'validator-min';
|
const label = 'validator-min';
|
||||||
if (min !== undefined) {
|
if (min !== undefined) {
|
||||||
|
@ -8,6 +15,10 @@ export class Validators {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator that requires the value to be less than or equal to the provided number.
|
||||||
|
* @param max - maximum number
|
||||||
|
*/
|
||||||
static max(max?: number): string {
|
static max(max?: number): string {
|
||||||
const label = 'validator-max';
|
const label = 'validator-max';
|
||||||
if (max !== undefined) {
|
if (max !== undefined) {
|
||||||
|
@ -16,18 +27,31 @@ export class Validators {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator that requires a non-empty value.
|
||||||
|
*/
|
||||||
static get required(): string {
|
static get required(): string {
|
||||||
return `validator-required`;
|
return `validator-required`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator that requires a field to be checked
|
||||||
|
*/
|
||||||
static get requiredChecked(): string {
|
static get requiredChecked(): string {
|
||||||
return `validator-required:checked`;
|
return `validator-required:checked`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator that requires the value to have a valid email format.
|
||||||
|
*/
|
||||||
static get email(): string {
|
static get email(): string {
|
||||||
return `validator-email`;
|
return `validator-email`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator that requires the length of the value to be greater than or equal to the provided minimum length.
|
||||||
|
* @param minLength - minimum string length
|
||||||
|
*/
|
||||||
static minLength(minLength?: number): string {
|
static minLength(minLength?: number): string {
|
||||||
const label = 'validator-minlength';
|
const label = 'validator-minlength';
|
||||||
if (minLength !== undefined) {
|
if (minLength !== undefined) {
|
||||||
|
@ -36,6 +60,10 @@ export class Validators {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator that requires the length of the value to be less than or equal to the provided maximum length
|
||||||
|
* @param maxLength - maximum string length
|
||||||
|
*/
|
||||||
static maxLength(maxLength?: number): string {
|
static maxLength(maxLength?: number): string {
|
||||||
const label = 'validator-maxlength';
|
const label = 'validator-maxlength';
|
||||||
if (maxLength !== undefined) {
|
if (maxLength !== undefined) {
|
||||||
|
|
Loading…
Reference in a new issue