feat: Types and Intellisense Improvements (#231)

This commit is contained in:
Fazza Razaq Amiarso 2022-12-08 02:56:27 +07:00 committed by GitHub
parent 5b539c809c
commit 25ce684d23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 1 deletions

View file

@ -14,8 +14,14 @@ import type {
} from '@astro-reactive/common';
import ShortUniqueId from 'short-unique-id';
/**
* Type of form controls
*/
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 {
private _id = '';
private _name = '';
@ -41,6 +47,11 @@ export class FormControl {
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) {
const {
name,
@ -135,18 +146,29 @@ export class FormControl {
return this._cols;
}
/**
* Sets the form control value dynamically
* @param value - new value to set
*/
setValue(value: string) {
this._value = value;
this._isPristine = false;
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[]) {
this._validators = validators;
const valueStr: string = this._value?.toString() || '';
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) {
if (validateOnLoad) {
import('@astro-reactive/validator').then((validator) => {
@ -166,10 +188,17 @@ export class FormControl {
}
}
/**
* Clears all errors from a form contol
*/
clearErrors() {
this._errors = [];
}
/**
* Sets an error dynamically
* @param error - A `ValidationError` object
*/
setError(error: ValidationError) {
this._errors = [...(this._errors || []), error];
}

View file

@ -1,11 +1,19 @@
import { ControlConfig, FormControl } from './form-control';
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 {
controls: FormControl[];
name?: 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 = '') {
const uid = new ShortUniqueId({ length: 9 });
this.name = name;
@ -15,10 +23,16 @@ export class FormGroup {
.map((control) => new FormControl(control));
}
/**
* Gets a form control by its name
*/
get(name: string): FormControl | undefined {
return this.controls.find((control) => control.name === name);
}
/**
* Sets the `FormGroup`'s form controls value
*/
setValue(values: object) {
Object.keys(values).forEach((name) => this.get(name)?.setValue(values[name as keyof object]));
}

View file

@ -2,7 +2,7 @@ import type { ValidationError, ValidatorRules } from '@astro-reactive/common';
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 validators - names of validation logic to be applied
* @returns errors - array of errors `ValidationError`
@ -59,6 +59,10 @@ export function validate(value: string, validators: ValidatorRules): ValidationE
.filter((result) => result !== null) as ValidationError[];
}
/**
* Clears all validation errors triggered by `Validator` component
* @param event - A DOM event
*/
export function clearErrors(event: Event) {
const categories = ['error', 'warn', 'info'];
const element = event.target as HTMLInputElement;

View file

@ -1,5 +1,12 @@
/**
* Provides a set of built-in validators that can be used by form controls.
*/
// improvement: implement min&max inclusive/exclusive
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 {
const label = 'validator-min';
if (min !== undefined) {
@ -8,6 +15,10 @@ export class Validators {
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 {
const label = 'validator-max';
if (max !== undefined) {
@ -16,18 +27,31 @@ export class Validators {
return label;
}
/**
* Validator that requires a non-empty value.
*/
static get required(): string {
return `validator-required`;
}
/**
* Validator that requires a field to be checked
*/
static get requiredChecked(): string {
return `validator-required:checked`;
}
/**
* Validator that requires the value to have a valid email format.
*/
static get email(): string {
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 {
const label = 'validator-minlength';
if (minLength !== undefined) {
@ -36,6 +60,10 @@ export class Validators {
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 {
const label = 'validator-maxlength';
if (maxLength !== undefined) {