UNPKG

ngx-valdemort

Version:

Simple, consistent validation error messages for your Angular forms

465 lines (456 loc) 22.5 kB
import * as i0 from '@angular/core'; import { TemplateRef, AfterContentInit, DoCheck, Signal } from '@angular/core'; import { AbstractControl, NgForm, FormGroupDirective } from '@angular/forms'; import { FieldTree, ValidationError, FieldState } from '@angular/forms/signals'; /** * The context of the ValidationErrorDirective */ interface ValidationErrorContext { /** * The label */ $implicit: string | null; /** * The error */ error: any; } /** * Directive allowing to define the template for an error of a given type (using the `valError` input), using an ng-template. * It's used inside the body of the validation errors component, or inside the body of the default validation errors directive. * See the documentation of these two for example usages. */ declare class ValidationErrorDirective { readonly templateRef: TemplateRef<ValidationErrorContext>; /** * The type of the error that the content of the template must display. */ readonly type: i0.InputSignal<string>; static ngTemplateContextGuard(_directive: ValidationErrorDirective, context: unknown): context is ValidationErrorContext; static ɵfac: i0.ɵɵFactoryDeclaration<ValidationErrorDirective, never>; static ɵdir: i0.ɵɵDirectiveDeclaration<ValidationErrorDirective, "ng-template[valError]", never, { "type": { "alias": "valError"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>; } /** * The context of the ValidationFallbackDirective */ interface ValidationFallbackContext { /** * The label */ $implicit: string | null; /** * The error */ error: any; /** * The type of the error */ type: string; } /** * Directive allowing to define a fallback template for an error of a type that is not handled by any validation error directive. * It's used inside the body of the validation errors component, or inside the body of the default validation errors directive. * See the documentation of these two for example usages. * * This is useful to handle forgotten errors instead of displaying no error at all, or to handle all or several error types in the same way, * for example by relying on the error key to choose an internationalized message. */ declare class ValidationFallbackDirective { readonly templateRef: TemplateRef<ValidationFallbackContext>; static ngTemplateContextGuard(_directive: ValidationFallbackDirective, context: unknown): context is ValidationFallbackContext; static ɵfac: i0.ɵɵFactoryDeclaration<ValidationFallbackDirective, never>; static ɵdir: i0.ɵɵDirectiveDeclaration<ValidationFallbackDirective, "ng-template[valFallback]", never, {}, {}, never, never, true, never>; } /** * Directive allowing to register default templates for validation error messages. It's supposed to be used once, * typically in the root component. By using templates to do that, error messages can * - easily be i18ned * - easily use pipes * - easily use HTML * - easily be ordered * * Example usage: * ``` * <val-default-errors> * <ng-template valError="required">This field is mandatory</ng-template> * <ng-template valError="max" let-error="error">This field must be at most {{ error.max | number }}</ng-template> * </val-default-errors> * ``` * * Example usage where a label is used to make the messages less generic: * ``` * <val-default-errors> * <ng-template valError="required" let-label>{{ label }} is mandatory</ng-template> * <ng-template valError="max" let-error="error" let-label>{{ label }} must be at most {{ error.max | number }}</ng-template> * </val-default-errors> * ``` * * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control * but are not handled by any of the specific error templates: * ``` * <val-default-errors> * <ng-template valError="required" let-label>{{ label }} is mandatory</ng-template> * <ng-template valError="max" let-error="error" let-label>{{ label }} must be at most {{ error.max | number }}</ng-template> * <ng-template valFallback let-label let-type="type" let-error="error">{{ label }} has an unhandled error of type {{ type }}: {{ error | json }}</ng-template> * </val-default-errors> * ``` * Using the fallback can also be used to handle all the errors the same way, for example by using the error type as an i18n key * to display the appropriate error message. * * This directive stores the default template references in a service, that is then injected in the validation errors components * to be reused. */ declare class DefaultValidationErrorsDirective implements AfterContentInit { private defaultValidationErrors; /** * The list of validation error directives (i.e. <ng-template valError="...">) * contained inside the directive element. */ readonly errorDirectives: i0.Signal<readonly ValidationErrorDirective[]>; /** * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the directive element. */ readonly fallbackDirective: i0.Signal<ValidationFallbackDirective | undefined>; ngAfterContentInit(): void; static ɵfac: i0.ɵɵFactoryDeclaration<DefaultValidationErrorsDirective, never>; static ɵdir: i0.ɵɵDirectiveDeclaration<DefaultValidationErrorsDirective, "val-default-errors", never, {}, {}, ["errorDirectives", "fallbackDirective"], never, true, never>; } interface FallbackError { type: string; value: any; } interface ErrorsToDisplay$1 { errors: Array<ValidationErrorDirective>; fallback: ValidationFallbackDirective | undefined; fallbackErrors: Array<FallbackError>; } type ViewModel$1 = { shouldDisplayErrors: false; } | { shouldDisplayErrors: true; errorsToDisplay: ErrorsToDisplay$1; control: AbstractControl; }; /** * Component allowing to display validation error messages associated to a given form control, form group or form array. * The control is provided using the `control` input of the component. If it's used inside an enclosing form group or * form array, it can instead be provided using the `controlName` input of the component. * * Example usage where the control itself is being passed as input: * ``` * <val-errors [control]="form.controls.birthDate"> * <ng-template valError="required">The birth date is mandatory</ng-template> * <ng-template valError="max" let-error="error">The max value for the birth date is {{ error.max | number }}</ng-template> * </val-errors> * ``` * * Example usage where the control name is being passed as input: * ``` * <val-errors controlName="birthDate"> * <ng-template valError="required">The birth date is mandatory</ng-template> * <ng-template valError="max" let-error="error">The max value for the birth date is {{ error.max | number }}</ng-template> * </val-errors> * ``` * * This component, if the control is invalid, displays its validation errors using the provided templates. * The templates, as shown in the above example, have access to the validation error itself. * * The label of the control can also be provided as input, and then used in the templates: * ``` * <val-errors controlName="birthDate" label="the birth date"> * <ng-template valError="required" let-label>{{ label }} is mandatory</ng-template> * <ng-template valError="max" let-error="error" let-label>The max value for {{ label }} is {{ error.max | number }}</ng-template> * </val-errors> * ``` * * The component‘s behavior is configured globally by the Config service (see its documentation for more details). It can * - display the first error, or all the errors * - add CSS classes to its host `<val-errors>` element * - add CSS classes to each error message element being displayed * - choose when to display the errors (dirty, touched, touched and submitted, etc.) * * Global, default templates can be defined (and used by this component) using the default validation errors directive * (see its documentation for details). So, if the default error messages are defined and sufficient for a given control, all you * need is * * ``` * <val-errors controlName="birthDate"></val-errors> * ``` * * or, if the default templates expect a label: * * ``` * <val-errors controlName="birthDate" label="the birth date"></val-errors> * ``` * * If, however, you want to override one or several error messages by custom ones, you can do so by simply defining them inside the * component: * * ``` * <val-errors controlName="birthDate" label="the birth date"> * <ng-template valError="max">You're too young, sorry</ng-template> * </val-errors> * ``` * * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control * but are not handled by any of the specific error templates: * ``` * <val-errors controlName="birthDate" label="the birth date"> * <ng-template valError="max">You're too young, sorry</ng-template> * <ng-template valFallback let-label let-type="type" let-error="error">{{ label }} has an unhandled error of type {{ type }}: {{ error | json }}</ng-template> * </val-errors> * ``` * Note that, the fallback template can also be defined in the default validation errors directive (see its documentation for details). * If a fallback template is defined inside `val-errors`, it overrides the default fallback. * * If an error is present on the control, but doesn't have any template, default template or fallback template defined for its type, * then it's not displayed. If the control is valid, or if none of the errors of the component has a matching template or default template, * then this component itself is hidden. */ declare class ValidationErrorsComponent implements DoCheck { /** * The FormControl, FormGroup or FormArray containing the validation errors. * If set, the controlName input is ignored */ readonly control: i0.InputSignal<AbstractControl<any, any, any> | null>; /** * The name (or the index, in case it's contained in a FormArray) of the FormControl, FormGroup or FormArray containing the validation * errors. * Ignored if the control input is set, and only usable if the control to validate is part of a control container */ readonly controlName: i0.InputSignal<string | number | null>; /** * The label of the field, exposed to templates so they can use it in the error message. */ readonly label: i0.InputSignal<string | null>; /** * The list of validation error directives (i.e. <ng-template valError="...">) contained inside the component element. */ readonly errorDirectives: Signal<readonly ValidationErrorDirective[]>; /** * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the component element. */ readonly fallbackDirective: Signal<ValidationFallbackDirective | undefined>; /** * The Config service instance, defining the behavior of this component */ private readonly config; readonly errorsClasses: string; readonly errorClasses: string; private readonly validationState; /** * The DefaultValidationErrors service instance, holding the default error templates, * optionally defined by using the default validation errors directive */ private readonly defaultValidationErrors; /** * The control container, if it exists, as one of the 4 form group or form array directives that can "wrap" the control. * It's injected so that we can know if it exists and, if it does, if its form directive has been submitted or not: * the config service shouldDisplayErrors function can choose (and does by default) to use that information. */ private readonly controlContainer; readonly vm: Signal<ViewModel$1>; ngDoCheck(): void; private shouldDisplayErrors; private findErrorsToDisplay; private findActualControl; private hasDisplayableError; static ɵfac: i0.ɵɵFactoryDeclaration<ValidationErrorsComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<ValidationErrorsComponent, "val-errors", never, { "control": { "alias": "control"; "required": false; "isSignal": true; }; "controlName": { "alias": "controlName"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, ["errorDirectives", "fallbackDirective"], never, true, never>; } interface ErrorWithDirective { error: ValidationError.WithField; directive: ValidationErrorDirective; } interface ErrorsToDisplay { errors: Array<ErrorWithDirective>; fallback: ValidationFallbackDirective | undefined; fallbackErrors: Array<ValidationError.WithField>; } type ViewModel = { shouldDisplayErrors: false; } | { shouldDisplayErrors: true; errorsToDisplay: ErrorsToDisplay; }; /** * **Experimental** * * Component allowing to display validation error messages associated to a given field of a signal form. * The control is provided using the `forField` input of the component. * * Example usage: * ``` * <val-signal-errors [forField]="form.birthYear"> * <ng-template valError="required">The birth year is mandatory</ng-template> * <ng-template valError="max" let-error="error">The max value for the birth year is {{ error.max | number }}</ng-template> * </val-errors> * ``` * * This component, if the control is invalid, displays its validation errors using the provided templates. * The templates, as shown in the above example, have access to the validation error itself. * * The label of the control can also be provided as input, and then used in the templates: * ``` * <val-signal-errors [forField]="form.birthYear" label="the birth year"> * <ng-template valError="required" let-label>{{ label }} is mandatory</ng-template> * <ng-template valError="max" let-error="error" let-label>The max value for {{ label }} is {{ error.max | number }}</ng-template> * </val-signal-errors> * ``` * * The component‘s behavior is configured globally by the Config service (see its documentation for more details). It can * - display the first error, or all the errors * - add CSS classes to its host `<val-errors>` element * - add CSS classes to each error message element being displayed * - choose when to display the errors (dirty, touched, etc.) * * Global, default templates can be defined (and used by this component) using the default validation errors directive * (see its documentation for details). So, if the default error messages are defined and sufficient for a given control, all you * need is * * ``` * <val-signal-errors [forField]="form.birthYear" /> * ``` * * or, if the default templates expect a label: * * ``` * <val-signal-errors [forField]="form.birthYear" label="the birth year" /> * ``` * * If, however, you want to override one or several error messages by custom ones, you can do so by simply defining them inside the * component: * * ``` * <val-signal-errors [forField]="form.birthYear" label="the birth year"> * <ng-template valError="max">You're too young, sorry</ng-template> * </val-signal-errors> * ``` * * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control * but are not handled by any of the specific error templates: * ``` * <val-signal-errors [forField]="form.birthYear" label="the birth year"> * <ng-template valError="max">You're too young, sorry</ng-template> * <ng-template valFallback let-label let-type="type" let-error="error">{{ label }} has an unhandled error of kind {{ type }}: {{ error | json }}</ng-template> * </val-signal-errors> * ``` * Note that, the fallback template can also be defined in the default validation errors directive (see its documentation for details). * If a fallback template is defined inside `val-signal-errors`, it overrides the default fallback. * * If an error is present on the field, but doesn't have any template, default template or fallback template defined for its type, * then it's not displayed. If the field is valid, or if none of the errors of the component has a matching template or default template, * then this component itself is hidden. */ declare class ValidationSignalErrorsComponent { /** * The FieldTree containing the validation errors. */ readonly field: i0.InputSignal<FieldTree<unknown>>; /** * The label of the field, exposed to templates so they can use it in the error message. */ readonly label: i0.InputSignal<string | null>; /** * The list of validation error directives (i.e. <ng-template valError="...">) contained inside the component element. */ readonly errorDirectives: Signal<readonly ValidationErrorDirective[]>; /** * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the component element. */ readonly fallbackDirective: Signal<ValidationFallbackDirective | undefined>; /** * The Config service instance, defining the behavior of this component */ private readonly config; readonly errorsClasses: string; readonly errorClasses: string; /** * The DefaultValidationErrors service instance, holding the default error templates, * optionally defined by using the default validation errors directive */ private readonly defaultValidationErrors; private readonly hasDisplayableError; private readonly shouldDisplayErrors; readonly vm: Signal<ViewModel>; private findErrorsToDisplay; static ɵfac: i0.ɵɵFactoryDeclaration<ValidationSignalErrorsComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<ValidationSignalErrorsComponent, "val-signal-errors", never, { "field": { "alias": "forField"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, ["errorDirectives", "fallbackDirective"], never, true, never>; } /** * The display mode of the validation errors. For a given control, either all the validation errors * are displayed, or only the first one. */ declare enum DisplayMode { ALL = 0, ONE = 1 } /** * The configuration service used by the validation errors component to apply common rules for all * form controls. * * To change its default behavior, you can either inject this service in your root module or component and mutate it, * or define your own implementation and provide it. */ declare class ValdemortConfig { /** * The display mode of the errors. The default value is ALL, meaning that all the errors existing on a control * (and which have an error template defined) are displayed. */ displayMode: DisplayMode; /** * Specifies one or several CSS classes (separated by a white space) that are automatically added to the * validation errors element. This can be useful to reuse a standard CSS class of your CSS framework (like * .invalid-feedback in BootStrap), rather than styling the val-errors element itself. * * The default value is null (no class is added). */ errorsClasses: string | null; /** * Specifies one or several CSS classes (separated by a white space) that are automatically added to the * each validation error message element. This can be useful to reuse a standard CSS class of your CSS framework * rather than styling the div element itself. * * The default value is null (no class is added). */ errorClasses: string | null; /** * Specifies when error messages should be displayed based on the state of the control itself (touched, dirty, etc.) * and on the state of the form directive containing it (if any). This function is only called if the control is invalid * in the first place: if it's valid, errors are never displayed. * * The default value of this function returns true if the control is touched, or if the form (if any) is submitted. */ shouldDisplayErrors: (control: AbstractControl, form: NgForm | FormGroupDirective | undefined) => boolean; /** * **Experimental** * * Specifies when error messages should be displayed based on the state of the field (touched, dirty, etc.). * This function must be reactive (i.e. it must return its value by reading signals). * Note that if the field is valid, errors are never displayed, whatever ths function returns. * * The default value of this function returns true if the field is touched. */ shouldDisplayFieldErrors: (fieldState: FieldState<unknown, string | number>) => boolean; /** * Specifies if the library should throw an error when a control is not found. * For example, this can happen if a typo was made in the `controlName`. * If the check is enabled, then an error will be thrown in such a case. * Otherwise, the error is silently ignored. * * The default value of this function returns false, thus disabling the check. * * You can enable the check by giving it a function that returns true, * or you can enable it only in development for example with: * `config.shouldThrowOnMissingControl = () => !environment.production` */ shouldThrowOnMissingControl: () => boolean; static ɵfac: i0.ɵɵFactoryDeclaration<ValdemortConfig, never>; static ɵprov: i0.ɵɵInjectableDeclaration<ValdemortConfig>; } declare class ValdemortModule { static ɵfac: i0.ɵɵFactoryDeclaration<ValdemortModule, never>; static ɵmod: i0.ɵɵNgModuleDeclaration<ValdemortModule, never, [typeof ValidationErrorsComponent, typeof ValidationSignalErrorsComponent, typeof ValidationErrorDirective, typeof ValidationFallbackDirective, typeof DefaultValidationErrorsDirective], [typeof ValidationErrorsComponent, typeof ValidationSignalErrorsComponent, typeof ValidationErrorDirective, typeof ValidationFallbackDirective, typeof DefaultValidationErrorsDirective]>; static ɵinj: i0.ɵɵInjectorDeclaration<ValdemortModule>; } export { DefaultValidationErrorsDirective, DisplayMode, ValdemortConfig, ValdemortModule, ValidationErrorDirective, ValidationErrorsComponent, ValidationFallbackDirective, ValidationSignalErrorsComponent };