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';
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -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]));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue