convert to JSDoc comments
This commit is contained in:
151
index.ts
151
index.ts
@@ -1,60 +1,70 @@
|
||||
import type { Action } from 'svelte/action';
|
||||
|
||||
// InputElement is a union of all input types that can be validated.
|
||||
/** InputElement is a union of all input types that can be validated. */
|
||||
export type InputElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
||||
// InputNodeList is a union of all node lists that can be validated.
|
||||
/** InputNodeList is a union of all node lists that can be validated. */
|
||||
export type InputNodeList = NodeListOf<HTMLInputElement> | NodeListOf<HTMLTextAreaElement> | [];
|
||||
|
||||
// ValidatorOptions configures the behavior of a validator.
|
||||
/** ValidatorOptions configures the behavior of a validator. */
|
||||
export type ValidatorOptions = {
|
||||
required?: boolean; // required is a flag that indicates whether the input is required.
|
||||
pattern?: RegExp; // pattern is a regex pattern that the input value must match.
|
||||
minlength?: number; // minlength is the minimum length of the input value.
|
||||
maxlength?: number; // maxlength is the maximum length of the input value.
|
||||
length?: number; // length is the exact length of the input value.
|
||||
type?: 'email' | 'phone' | 'score'; // NOT IMPLEMENTED. type is a predefined validation type.
|
||||
baseval?: string; // baseval is a value that the input value must not match (an alternate zero-value).
|
||||
autovalOnInvalid?: boolean; // autovalOnInvalid is a flag that automatically adds a keyup listener to the input on invalid.
|
||||
/** required is a flag that indicates whether the input is required. */
|
||||
required?: boolean;
|
||||
/** pattern is a regex pattern that the input value must match. */
|
||||
pattern?: RegExp;
|
||||
/** minlength is the minimum length of the input value. */
|
||||
minlength?: number;
|
||||
/** maxlength is the maximum length of the input value. */
|
||||
maxlength?: number;
|
||||
/** length is the exact length of the input value. */
|
||||
length?: number;
|
||||
/** NOT IMPLEMENTED. type is a predefined validation type. */
|
||||
type?: 'email' | 'phone' | 'score';
|
||||
/** baseval is a value that the input value must not match (an alternate zero-value). */
|
||||
baseval?: string;
|
||||
/** autovalOnInvalid is a flag that automatically adds a keyup listener to the input on invalid. */
|
||||
autovalOnInvalid?: boolean;
|
||||
func?: (node: InputElement) => boolean | Promise<boolean>;
|
||||
valfunc?: (val: string) => boolean | Promise<boolean>;
|
||||
};
|
||||
|
||||
// InputValidatorPayload carries the current value of an input element when it is validated.
|
||||
/** InputValidatorPayload carries the current value of an input element when it is validated. */
|
||||
export type InputValidatorPayload = { value: string; valid: boolean };
|
||||
// InputValidatorEvent is a custom event that is dispatched when an input is validated.
|
||||
/** InputValidatorEvent is a custom event that is dispatched when an input is validated. */
|
||||
export class InputValidatorEvent extends CustomEvent<InputValidatorPayload> {}
|
||||
// FormValidatorPayload carries a list of invalid and valid inputs when a form is validated.
|
||||
/** FormValidatorPayload carries a list of invalid and valid inputs when a form is validated. */
|
||||
export type FormValidatorPayload = {
|
||||
invalidInputs: InputElement[];
|
||||
validInputs: InputElement[];
|
||||
valid: boolean;
|
||||
};
|
||||
// FormValidatorEvent is a custom event that is dispatched when a form is validated.
|
||||
/** FormValidatorEvent is a custom event that is dispatched when a form is validated. */
|
||||
export class FormValidatorEvent extends CustomEvent<FormValidatorPayload> {}
|
||||
|
||||
// ValidatorState is the state of a validator.
|
||||
/** ValidatorState is the state of a validator. */
|
||||
export type ValidatorState = 'unknown' | 'valid' | 'invalid';
|
||||
const VALIDATOR_VALID: ValidatorState = 'valid';
|
||||
const VALIDATOR_INVALID: ValidatorState = 'invalid';
|
||||
const VALIDATOR_UNKNOWN: ValidatorState = 'unknown';
|
||||
|
||||
// QUERY_INPUTS is the query string for all input elements that can be validated.
|
||||
/** QUERY_INPUTS is the query string for all input elements that can be validated. */
|
||||
const QUERY_INPUTS = 'input[data-validate-identifier], textarea[data-validate-identifier]';
|
||||
|
||||
// DATA_ID is the key for the validator index in the input element's dataset.
|
||||
/** DATA_ID is the key for the validator index in the input element's dataset. */
|
||||
const DATA_ID = 'validateIdentifier';
|
||||
// DATA_STATE is the key for the validation state in the input element's dataset.
|
||||
/** DATA_STATE is the key for the validation state in the input element's dataset. */
|
||||
const DATA_STATE = 'validateState';
|
||||
|
||||
// email is a regex pattern for validating email addresses.
|
||||
/** email is a regex pattern for validating email addresses. */
|
||||
export const email: RegExp = new RegExp(String.raw`^[^@\s]+@[^@\s]+\.[^@\s]+$`);
|
||||
// phone is a regex pattern for validating phone numbers.
|
||||
/** phone is a regex pattern for validating phone numbers. */
|
||||
export const phone: RegExp = new RegExp(String.raw`^(\+)?(\(?\d+\)?)(([\s-]+)?(\d+)){0,}$`);
|
||||
// score is a regex pattern for validating lesson grades.
|
||||
/** score is a regex pattern for validating lesson grades. */
|
||||
export const score: RegExp = new RegExp(String.raw`^(-?\d{0,2}|100)$`);
|
||||
|
||||
// InputState is some historical state of an input element, tracking its value,
|
||||
// selectionStart and selectionEnd.
|
||||
/**
|
||||
* InputState is some historical state of an input element, tracking its value,
|
||||
* selectionStart and selectionEnd.
|
||||
*/
|
||||
export type InputState = {
|
||||
value: string;
|
||||
selectionStart: number;
|
||||
@@ -65,8 +75,10 @@ let nextValidatorID = 0;
|
||||
const validators: Record<number, ValidatorOptions> = {};
|
||||
const lastState: Record<number, InputState> = {};
|
||||
|
||||
// validate attaches rules to an input element that can be used to validate the input.
|
||||
// If opts is undefined, no validation rules will be attached.
|
||||
/**
|
||||
* validate attaches rules to an input element that can be used to validate the input.
|
||||
* If opts is undefined, no validation rules will be attached.
|
||||
*/
|
||||
export const validate: Action<
|
||||
InputElement,
|
||||
ValidatorOptions | undefined,
|
||||
@@ -105,10 +117,12 @@ export const validate: Action<
|
||||
};
|
||||
};
|
||||
|
||||
// keydownValidator attaches a keydown event listener to an input element that will
|
||||
// process the input value according to any attached validation rules, triggering
|
||||
// valid or invalid depending on validation success. If opts.constrain is true,
|
||||
// the input value will be constrained to valid characters.
|
||||
/**
|
||||
* keydownValidator attaches a keydown event listener to an input element that will
|
||||
* process the input value according to any attached validation rules, triggering
|
||||
* valid or invalid depending on validation success. If opts.constrain is true,
|
||||
* the input value will be constrained to valid characters.
|
||||
*/
|
||||
export const keydownValidator: Action<
|
||||
InputElement,
|
||||
{
|
||||
@@ -131,9 +145,11 @@ export const keydownValidator: Action<
|
||||
});
|
||||
};
|
||||
|
||||
// keyupValidator attaches a keydown event listener to an input element that will
|
||||
// process the input value according to any attached validation rules, triggering
|
||||
// the `validate` event with the input value and validation state.
|
||||
/**
|
||||
* keyupValidator attaches a keydown event listener to an input element that will
|
||||
* process the input value according to any attached validation rules, triggering
|
||||
* the `validate` event with the input value and validation state.
|
||||
*/
|
||||
export const keyupValidator: Action<InputElement> = (el) => {
|
||||
const node = el as HTMLInputElement;
|
||||
|
||||
@@ -147,9 +163,11 @@ export const keyupValidator: Action<InputElement> = (el) => {
|
||||
});
|
||||
};
|
||||
|
||||
// inputValidator attaches an oninput event listener to an input element that will
|
||||
// process the input value according to any attached validation rules, triggering
|
||||
// the `validate` event with the input value and validation state.
|
||||
/**
|
||||
* inputValidator attaches an oninput event listener to an input element that will
|
||||
* process the input value according to any attached validation rules, triggering
|
||||
* the `validate` event with the input value and validation state.
|
||||
*/
|
||||
export const inputValidator: Action<InputElement> = (el) => {
|
||||
const node = el as HTMLInputElement;
|
||||
|
||||
@@ -162,10 +180,12 @@ export const inputValidator: Action<InputElement> = (el) => {
|
||||
});
|
||||
};
|
||||
|
||||
// liveValidator attaches multiple event listeners to an input element that will
|
||||
// process the input value according to any attached validation rules, triggering
|
||||
// the `validate` event with the input value and validation state. liveValidator
|
||||
// supports the constrain option without introducing edge cases with text selection.
|
||||
/**
|
||||
* liveValidator attaches multiple event listeners to an input element that will
|
||||
* process the input value according to any attached validation rules, triggering
|
||||
* the `validate` event with the input value and validation state. liveValidator
|
||||
* supports the constrain option without introducing edge cases with text selection.
|
||||
*/
|
||||
export const liveValidator: Action<
|
||||
InputElement,
|
||||
{
|
||||
@@ -227,11 +247,13 @@ export const liveValidator: Action<
|
||||
node.addEventListener('input', inputHandler);
|
||||
};
|
||||
|
||||
// submitValidator attaches a submit event listener to a form element that will
|
||||
// process the input values of all children according to any attached validation
|
||||
// rules, triggering the validate event for individual input elements
|
||||
// depending on validation success. Similarly, the validate event
|
||||
// event will be triggered on the form element itself.
|
||||
/**
|
||||
* submitValidator attaches a submit event listener to a form element that will
|
||||
* process the input values of all children according to any attached validation
|
||||
* rules, triggering the validate event for individual input elements
|
||||
* depending on validation success. Similarly, the validate event
|
||||
* event will be triggered on the form element itself.
|
||||
*/
|
||||
export const submitValidator: Action<
|
||||
HTMLFormElement,
|
||||
undefined,
|
||||
@@ -254,8 +276,7 @@ export const submitValidator: Action<
|
||||
});
|
||||
};
|
||||
|
||||
// disableFormDefault helper action prevents the default form submission behavior
|
||||
// and disables all browser validation.
|
||||
/** disableFormDefault helper action prevents the default form submission behavior and disables all browser validation. */
|
||||
export const disableFormDefault: Action<HTMLFormElement> = (form) => {
|
||||
form.setAttribute('novalidate', 'true');
|
||||
form.addEventListener('submit', (event) => {
|
||||
@@ -263,10 +284,12 @@ export const disableFormDefault: Action<HTMLFormElement> = (form) => {
|
||||
});
|
||||
};
|
||||
|
||||
// validateInput checks an input element's value against its validation rules, triggering
|
||||
// the validate events with the current value and validation state, updating the input's
|
||||
// dataset accordingly. If opts.autovalOnInvalid is true, the input will be revalidated on
|
||||
// on keyup automatically from now on.
|
||||
/**
|
||||
* validateInput checks an input element's value against its validation rules, triggering
|
||||
* the validate events with the current value and validation state, updating the input's
|
||||
* dataset accordingly. If opts.autovalOnInvalid is true, the input will be revalidated on
|
||||
* on keyup automatically from now on.
|
||||
*/
|
||||
export const validateInput = async (
|
||||
input: InputElement,
|
||||
valueOverride?: string
|
||||
@@ -289,9 +312,11 @@ export const validateInput = async (
|
||||
return valid;
|
||||
};
|
||||
|
||||
// validateForm checks all input elements in a form element against their validation rules,
|
||||
// triggering valid or invalid events for individual input elements depending on validation
|
||||
// success. Similarly, valid and invalid events will be triggered on the form element.
|
||||
/**
|
||||
* validateForm checks all input elements in a form element against their validation rules,
|
||||
* triggering valid or invalid events for individual input elements depending on validation
|
||||
* success. Similarly, valid and invalid events will be triggered on the form element.
|
||||
*/
|
||||
export const validateForm = async (form: HTMLFormElement): Promise<boolean> => {
|
||||
const inputs = form.querySelectorAll(QUERY_INPUTS);
|
||||
|
||||
@@ -321,7 +346,7 @@ export const validateForm = async (form: HTMLFormElement): Promise<boolean> => {
|
||||
return valid;
|
||||
};
|
||||
|
||||
// isInputValid checks an input element's value against its validation rules.
|
||||
/** isInputValid checks an input element's value against its validation rules. */
|
||||
export const isInputValid = async (
|
||||
input: InputElement,
|
||||
valueOverride?: string
|
||||
@@ -360,7 +385,7 @@ export const isInputValid = async (
|
||||
return true;
|
||||
};
|
||||
|
||||
// isFormValid checks all input elements in a form element against their validation rules.
|
||||
/** isFormValid checks all input elements in a form element against their validation rules. */
|
||||
export const isFormValid = async (form: HTMLFormElement): Promise<boolean> => {
|
||||
const inputs = form.querySelectorAll(QUERY_INPUTS);
|
||||
|
||||
@@ -375,8 +400,10 @@ export const isFormValid = async (form: HTMLFormElement): Promise<boolean> => {
|
||||
return valid;
|
||||
};
|
||||
|
||||
// isValueValid checks a value against a set of validation rules. Note: node-based
|
||||
// custom validator functions are not supported by this function.
|
||||
/**
|
||||
* isValueValid checks a value against a set of validation rules. Note: node-based
|
||||
* custom validator functions are not supported by this function.
|
||||
*/
|
||||
export const isValueValid = async (val: string, opts: ValidatorOptions): Promise<boolean> => {
|
||||
console.debug('isValueValid', `val="${val}"`, 'opts:', opts);
|
||||
// if input is required and empty, return false
|
||||
@@ -424,15 +451,17 @@ export const isValueValid = async (val: string, opts: ValidatorOptions): Promise
|
||||
return true;
|
||||
};
|
||||
|
||||
// getid returns the validator ID attached to an input element. Returns -1 if
|
||||
// no ID is attached.
|
||||
/**
|
||||
* getid returns the validator ID attached to an input element. Returns -1 if
|
||||
* no ID is attached.
|
||||
*/
|
||||
export const getid = (input: InputElement): number => {
|
||||
const idstr = input.dataset[DATA_ID] || '-1';
|
||||
const id = parseInt(idstr);
|
||||
return id;
|
||||
};
|
||||
|
||||
// getopts returns the validation rules attached to an input element.
|
||||
/** getopts returns the validation rules attached to an input element. */
|
||||
export const getopts = (input: InputElement): ValidatorOptions | undefined => {
|
||||
const id = getid(input);
|
||||
return validators[id];
|
||||
|
||||
Reference in New Issue
Block a user