UNPKG

ngx-valdemort

Version:

Simple, consistent validation error messages for your Angular forms

1 lines 53.1 kB
{"version":3,"file":"ngx-valdemort.mjs","sources":["../../../projects/ngx-valdemort/src/lib/default-validation-errors.service.ts","../../../projects/ngx-valdemort/src/lib/validation-error.directive.ts","../../../projects/ngx-valdemort/src/lib/validation-fallback.directive.ts","../../../projects/ngx-valdemort/src/lib/default-validation-errors.directive.ts","../../../projects/ngx-valdemort/src/lib/valdemort-config.service.ts","../../../projects/ngx-valdemort/src/lib/validation-errors.component.ts","../../../projects/ngx-valdemort/src/lib/validation-errors.component.html","../../../projects/ngx-valdemort/src/lib/validation-signal-errors.component.ts","../../../projects/ngx-valdemort/src/lib/validation-signal-errors.component.html","../../../projects/ngx-valdemort/src/lib/valdemort.module.ts","../../../projects/ngx-valdemort/src/public_api.ts","../../../projects/ngx-valdemort/src/ngx-valdemort.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\n\n/**\n * Service used by the default validation errors directive to store the default error template references. This\n * service is injected in the validation errors component which displays the appropriate templates and provides their context.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class DefaultValidationErrors {\n readonly directives = signal<ReadonlyArray<ValidationErrorDirective>>([]);\n readonly fallback = signal<ValidationFallbackDirective | undefined>(undefined);\n}\n","import { Directive, input, TemplateRef, inject } from '@angular/core';\n\n/**\n * The context of the ValidationErrorDirective\n */\ninterface ValidationErrorContext {\n /**\n * The label\n */\n $implicit: string | null;\n\n /**\n * The error\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any;\n}\n\n/**\n * Directive allowing to define the template for an error of a given type (using the `valError` input), using an ng-template.\n * It's used inside the body of the validation errors component, or inside the body of the default validation errors directive.\n * See the documentation of these two for example usages.\n */\n@Directive({\n selector: 'ng-template[valError]'\n})\nexport class ValidationErrorDirective {\n readonly templateRef = inject<TemplateRef<ValidationErrorContext>>(TemplateRef);\n\n /**\n * The type of the error that the content of the template must display.\n */\n readonly type = input.required<string>({ alias: 'valError' });\n\n static ngTemplateContextGuard(_directive: ValidationErrorDirective, context: unknown): context is ValidationErrorContext {\n return true;\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\n\n/**\n * The context of the ValidationFallbackDirective\n */\ninterface ValidationFallbackContext {\n /**\n * The label\n */\n $implicit: string | null;\n\n /**\n * The error\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any;\n\n /**\n * The type of the error\n */\n type: string;\n}\n\n/**\n * Directive allowing to define a fallback template for an error of a type that is not handled by any validation error directive.\n * It's used inside the body of the validation errors component, or inside the body of the default validation errors directive.\n * See the documentation of these two for example usages.\n *\n * 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,\n * for example by relying on the error key to choose an internationalized message.\n */\n@Directive({\n selector: 'ng-template[valFallback]'\n})\nexport class ValidationFallbackDirective {\n readonly templateRef = inject<TemplateRef<ValidationFallbackContext>>(TemplateRef);\n\n static ngTemplateContextGuard(_directive: ValidationFallbackDirective, context: unknown): context is ValidationFallbackContext {\n return true;\n }\n}\n","import { AfterContentInit, contentChild, contentChildren, Directive, inject } from '@angular/core';\nimport { DefaultValidationErrors } from './default-validation-errors.service';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\n\n/**\n * Directive allowing to register default templates for validation error messages. It's supposed to be used once,\n * typically in the root component. By using templates to do that, error messages can\n * - easily be i18ned\n * - easily use pipes\n * - easily use HTML\n * - easily be ordered\n *\n * Example usage:\n * ```\n * <val-default-errors>\n * <ng-template valError=\"required\">This field is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">This field must be at most {{ error.max | number }}</ng-template>\n * </val-default-errors>\n * ```\n *\n * Example usage where a label is used to make the messages less generic:\n * ```\n * <val-default-errors>\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>{{ label }} must be at most {{ error.max | number }}</ng-template>\n * </val-default-errors>\n * ```\n *\n * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control\n * but are not handled by any of the specific error templates:\n * ```\n * <val-default-errors>\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>{{ label }} must be at most {{ error.max | number }}</ng-template>\n * <ng-template valFallback let-label let-type=\"type\" let-error=\"error\">{{ label }} has an unhandled error of type {{ type }}: {{ error | json }}</ng-template>\n * </val-default-errors>\n * ```\n * 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\n * to display the appropriate error message.\n *\n * This directive stores the default template references in a service, that is then injected in the validation errors components\n * to be reused.\n */\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: 'val-default-errors'\n})\nexport class DefaultValidationErrorsDirective implements AfterContentInit {\n private defaultValidationErrors = inject(DefaultValidationErrors);\n\n /**\n * The list of validation error directives (i.e. <ng-template valError=\"...\">)\n * contained inside the directive element.\n */\n readonly errorDirectives = contentChildren(ValidationErrorDirective);\n\n /**\n * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the directive element.\n */\n readonly fallbackDirective = contentChild(ValidationFallbackDirective);\n\n ngAfterContentInit(): void {\n this.defaultValidationErrors.directives.set(this.errorDirectives());\n this.defaultValidationErrors.fallback.set(this.fallbackDirective());\n }\n}\n","import { Injectable } from '@angular/core';\nimport type { AbstractControl, FormGroupDirective, NgForm } from '@angular/forms';\nimport type { FieldState } from '@angular/forms/signals';\n\n/**\n * The display mode of the validation errors. For a given control, either all the validation errors\n * are displayed, or only the first one.\n */\nexport enum DisplayMode {\n ALL,\n ONE\n}\n\n/**\n * The configuration service used by the validation errors component to apply common rules for all\n * form controls.\n *\n * To change its default behavior, you can either inject this service in your root module or component and mutate it,\n * or define your own implementation and provide it.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ValdemortConfig {\n /**\n * The display mode of the errors. The default value is ALL, meaning that all the errors existing on a control\n * (and which have an error template defined) are displayed.\n */\n displayMode = DisplayMode.ALL;\n\n /**\n * Specifies one or several CSS classes (separated by a white space) that are automatically added to the\n * validation errors element. This can be useful to reuse a standard CSS class of your CSS framework (like\n * .invalid-feedback in BootStrap), rather than styling the val-errors element itself.\n *\n * The default value is null (no class is added).\n */\n errorsClasses: string | null = null;\n\n /**\n * Specifies one or several CSS classes (separated by a white space) that are automatically added to the\n * each validation error message element. This can be useful to reuse a standard CSS class of your CSS framework\n * rather than styling the div element itself.\n *\n * The default value is null (no class is added).\n */\n errorClasses: string | null = null;\n\n /**\n * Specifies when error messages should be displayed based on the state of the control itself (touched, dirty, etc.)\n * and on the state of the form directive containing it (if any). This function is only called if the control is invalid\n * in the first place: if it's valid, errors are never displayed.\n *\n * The default value of this function returns true if the control is touched, or if the form (if any) is submitted.\n */\n shouldDisplayErrors: (control: AbstractControl, form: NgForm | FormGroupDirective | undefined) => boolean = (\n control: AbstractControl,\n form: NgForm | FormGroupDirective | undefined\n ) => control.touched || (!!form && form.submitted);\n\n /**\n * **Experimental**\n *\n * Specifies when error messages should be displayed based on the state of the field (touched, dirty, etc.).\n * This function must be reactive (i.e. it must return its value by reading signals).\n * Note that if the field is valid, errors are never displayed, whatever ths function returns.\n *\n * The default value of this function returns true if the field is touched.\n */\n shouldDisplayFieldErrors: (fieldState: FieldState<unknown, string | number>) => boolean = (\n fieldState: FieldState<unknown, string | number>\n ) => fieldState.touched();\n\n /**\n * Specifies if the library should throw an error when a control is not found.\n * For example, this can happen if a typo was made in the `controlName`.\n * If the check is enabled, then an error will be thrown in such a case.\n * Otherwise, the error is silently ignored.\n *\n * The default value of this function returns false, thus disabling the check.\n *\n * You can enable the check by giving it a function that returns true,\n * or you can enable it only in development for example with:\n * `config.shouldThrowOnMissingControl = () => !environment.production`\n */\n shouldThrowOnMissingControl: () => boolean = () => false;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n contentChildren,\n DoCheck,\n inject,\n input,\n signal,\n Signal\n} from '@angular/core';\nimport { AbstractControl, ControlContainer, FormArray, FormGroup, FormGroupDirective, NgForm, ValidationErrors } from '@angular/forms';\nimport { DisplayMode, ValdemortConfig } from './valdemort-config.service';\nimport { DefaultValidationErrors } from './default-validation-errors.service';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\nimport { NgTemplateOutlet } from '@angular/common';\n\ninterface FallbackError {\n type: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: any;\n}\n\ninterface ErrorsToDisplay {\n // The validation error directives to display\n errors: Array<ValidationErrorDirective>;\n\n // The fallback directive to use to display the fallback errors\n fallback: ValidationFallbackDirective | undefined;\n\n // the fallback errors to display (empty if there is no fallback directive)\n fallbackErrors: Array<FallbackError>;\n}\n\ntype ViewModel =\n | {\n shouldDisplayErrors: false;\n }\n | {\n shouldDisplayErrors: true;\n errorsToDisplay: ErrorsToDisplay;\n control: AbstractControl;\n };\n\nconst NO_ERRORS: ViewModel = {\n shouldDisplayErrors: false\n};\n\ninterface ValidationState {\n control: AbstractControl | null;\n errorsDisplayed: boolean | null;\n errors: ValidationErrors | null;\n}\n\nconst NO_VALIDATION_STATE: ValidationState = {\n control: null,\n errorsDisplayed: null,\n errors: null\n};\n\nfunction areValidationStatesEqual(previous: ValidationState, current: ValidationState): boolean {\n return previous.control === current.control && previous.errorsDisplayed === current.errorsDisplayed && previous.errors === current.errors;\n}\n\n/**\n * Component allowing to display validation error messages associated to a given form control, form group or form array.\n * The control is provided using the `control` input of the component. If it's used inside an enclosing form group or\n * form array, it can instead be provided using the `controlName` input of the component.\n *\n * Example usage where the control itself is being passed as input:\n * ```\n * <val-errors [control]=\"form.controls.birthDate\">\n * <ng-template valError=\"required\">The birth date is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">The max value for the birth date is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * Example usage where the control name is being passed as input:\n * ```\n * <val-errors controlName=\"birthDate\">\n * <ng-template valError=\"required\">The birth date is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">The max value for the birth date is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * This component, if the control is invalid, displays its validation errors using the provided templates.\n * The templates, as shown in the above example, have access to the validation error itself.\n *\n * The label of the control can also be provided as input, and then used in the templates:\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\">\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>The max value for {{ label }} is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * The component‘s behavior is configured globally by the Config service (see its documentation for more details). It can\n * - display the first error, or all the errors\n * - add CSS classes to its host `<val-errors>` element\n * - add CSS classes to each error message element being displayed\n * - choose when to display the errors (dirty, touched, touched and submitted, etc.)\n *\n * Global, default templates can be defined (and used by this component) using the default validation errors directive\n * (see its documentation for details). So, if the default error messages are defined and sufficient for a given control, all you\n * need is\n *\n * ```\n * <val-errors controlName=\"birthDate\"></val-errors>\n * ```\n *\n * or, if the default templates expect a label:\n *\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\"></val-errors>\n * ```\n *\n * If, however, you want to override one or several error messages by custom ones, you can do so by simply defining them inside the\n * component:\n *\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\">\n * <ng-template valError=\"max\">You're too young, sorry</ng-template>\n * </val-errors>\n * ```\n *\n * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control\n * but are not handled by any of the specific error templates:\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\">\n * <ng-template valError=\"max\">You're too young, sorry</ng-template>\n * <ng-template valFallback let-label let-type=\"type\" let-error=\"error\">{{ label }} has an unhandled error of type {{ type }}: {{ error | json }}</ng-template>\n * </val-errors>\n * ```\n * Note that, the fallback template can also be defined in the default validation errors directive (see its documentation for details).\n * If a fallback template is defined inside `val-errors`, it overrides the default fallback.\n *\n * If an error is present on the control, but doesn't have any template, default template or fallback template defined for its type,\n * 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,\n * then this component itself is hidden.\n */\n@Component({\n selector: 'val-errors',\n templateUrl: './validation-errors.component.html',\n host: {\n '[class]': 'errorsClasses',\n '[style.display]': `vm().shouldDisplayErrors ? '' : 'none'`\n },\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ValidationErrorsComponent implements DoCheck {\n /**\n * The FormControl, FormGroup or FormArray containing the validation errors.\n * If set, the controlName input is ignored\n */\n readonly control = input<AbstractControl | null>(null);\n\n /**\n * The name (or the index, in case it's contained in a FormArray) of the FormControl, FormGroup or FormArray containing the validation\n * errors.\n * Ignored if the control input is set, and only usable if the control to validate is part of a control container\n */\n readonly controlName = input<string | number | null>(null);\n\n /**\n * The label of the field, exposed to templates so they can use it in the error message.\n */\n readonly label = input<string | null>(null);\n\n /**\n * The list of validation error directives (i.e. <ng-template valError=\"...\">) contained inside the component element.\n */\n readonly errorDirectives = contentChildren(ValidationErrorDirective);\n\n /**\n * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the component element.\n */\n readonly fallbackDirective = contentChild(ValidationFallbackDirective);\n\n /**\n * The Config service instance, defining the behavior of this component\n */\n private readonly config = inject(ValdemortConfig);\n readonly errorsClasses = this.config.errorsClasses || '';\n readonly errorClasses = this.config.errorClasses || '';\n\n private readonly validationState = signal<ValidationState>(NO_VALIDATION_STATE, { equal: areValidationStatesEqual });\n\n /**\n * The DefaultValidationErrors service instance, holding the default error templates,\n * optionally defined by using the default validation errors directive\n */\n private readonly defaultValidationErrors = inject(DefaultValidationErrors);\n\n /**\n * The control container, if it exists, as one of the 4 form group or form array directives that can \"wrap\" the control.\n * It's injected so that we can know if it exists and, if it does, if its form directive has been submitted or not:\n * the config service shouldDisplayErrors function can choose (and does by default) to use that information.\n */\n private readonly controlContainer = inject(ControlContainer, { optional: true });\n\n readonly vm: Signal<ViewModel> = computed(() => {\n const ctrl = this.validationState().control;\n if (this.shouldDisplayErrors(ctrl)) {\n const errorsToDisplay = this.findErrorsToDisplay(ctrl);\n return {\n shouldDisplayErrors: true,\n control: ctrl,\n errorsToDisplay\n };\n } else {\n return NO_ERRORS;\n }\n });\n\n ngDoCheck(): void {\n const ctrl = this.findActualControl();\n if (ctrl) {\n const formDirective = this.controlContainer?.formDirective as NgForm | FormGroupDirective | undefined;\n const errorsDisplayed = this.config.shouldDisplayErrors(ctrl, formDirective);\n this.validationState.set({\n control: ctrl,\n errorsDisplayed,\n errors: ctrl.errors\n });\n } else {\n this.validationState.set(NO_VALIDATION_STATE);\n }\n }\n\n private shouldDisplayErrors(ctrl: AbstractControl | null): ctrl is AbstractControl {\n if (!ctrl || !ctrl.invalid || !this.hasDisplayableError(ctrl)) {\n return false;\n }\n const form = this.controlContainer && (this.controlContainer.formDirective as NgForm | FormGroupDirective);\n return this.config.shouldDisplayErrors(ctrl, form ?? undefined);\n }\n\n private findErrorsToDisplay(ctrl: AbstractControl): ErrorsToDisplay {\n const mergedDirectives: Array<ValidationErrorDirective> = [];\n const fallbackErrors: Array<FallbackError> = [];\n const alreadyMetTypes = new Set<string>();\n const shouldContinue = () =>\n this.config.displayMode === DisplayMode.ALL || (mergedDirectives.length === 0 && fallbackErrors.length === 0);\n const defaultValidationErrorDirectives = this.defaultValidationErrors.directives();\n for (let i = 0; i < defaultValidationErrorDirectives.length && shouldContinue(); i++) {\n const defaultDirective = defaultValidationErrorDirectives[i];\n if (ctrl.hasError(defaultDirective.type())) {\n const customDirectiveOfSameType = this.errorDirectives().find(dir => dir.type() === defaultDirective.type());\n mergedDirectives.push(customDirectiveOfSameType || defaultDirective);\n }\n alreadyMetTypes.add(defaultDirective.type());\n }\n\n if (shouldContinue()) {\n const customDirectives = this.errorDirectives();\n for (let i = 0; i < customDirectives.length && shouldContinue(); i++) {\n const customDirective = customDirectives[i];\n if (!alreadyMetTypes.has(customDirective.type()) && ctrl.hasError(customDirective.type())) {\n mergedDirectives.push(customDirective);\n }\n alreadyMetTypes.add(customDirective.type());\n }\n }\n\n if (shouldContinue() && (this.fallbackDirective() || this.defaultValidationErrors.fallback())) {\n const allErrors = Object.entries(ctrl.errors ?? []);\n for (let i = 0; i < allErrors.length && shouldContinue(); i++) {\n const [type, value] = allErrors[i];\n if (!alreadyMetTypes.has(type)) {\n fallbackErrors.push({ type, value });\n }\n }\n }\n\n return {\n errors: mergedDirectives,\n fallback: this.fallbackDirective() ?? this.defaultValidationErrors.fallback(),\n fallbackErrors\n };\n }\n\n private findActualControl(): AbstractControl | null {\n const ctrl = this.control();\n const ctrlName = this.controlName();\n if (ctrl) {\n return ctrl;\n } else if (ctrlName != null && (this.controlContainer?.control as FormArray | FormGroup)?.controls) {\n // whether the control is a FormGroup or a FormArray, we must use .control[ctrlName] to get it\n const control = (this.controlContainer?.control as FormArray).controls[ctrlName as number];\n if (this.config.shouldThrowOnMissingControl()) {\n // if the control is null, then there are two cases:\n // - we are in a template driven form, and the controls might not be initialized yet\n // - there was an error in the control name. If so, let's throw an error to help developers\n // to avoid false positive in template driven forms, we check if the controls are initialized\n // by checking if the `controls` object or array has any element\n if (!control && Object.keys((this.controlContainer?.control as FormArray)?.controls).length > 0) {\n throw new Error(`ngx-valdemort: no control found for controlName: '${ctrlName}'.`);\n }\n }\n return control;\n }\n return null;\n }\n\n private hasDisplayableError(ctrl: AbstractControl) {\n return (\n ctrl.errors &&\n (this.fallbackDirective() ||\n this.defaultValidationErrors.fallback() ||\n Object.keys(ctrl.errors).some(\n type =>\n this.defaultValidationErrors.directives().some(dir => dir.type() === type) ||\n this.errorDirectives().some(dir => dir.type() === type)\n ))\n );\n }\n}\n","@let vm = this.vm();\n@if (vm.shouldDisplayErrors) {\n @for (errorDirective of vm.errorsToDisplay.errors; track $index) {\n <div [class]=\"errorClasses\">\n <ng-container\n *ngTemplateOutlet=\"\n errorDirective!.templateRef;\n context: {\n $implicit: label(),\n error: vm.control.errors![errorDirective.type()]\n }\n \"\n />\n </div>\n }\n @for (error of vm.errorsToDisplay.fallbackErrors; track $index) {\n <div [class]=\"errorClasses\">\n <ng-container\n *ngTemplateOutlet=\"\n vm.errorsToDisplay.fallback!.templateRef;\n context: {\n $implicit: label(),\n type: error.type,\n error: error.value\n }\n \"\n />\n </div>\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, contentChild, contentChildren, inject, input, Signal } from '@angular/core';\nimport { DisplayMode, ValdemortConfig } from './valdemort-config.service';\nimport { DefaultValidationErrors } from './default-validation-errors.service';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { FieldTree, ValidationError } from '@angular/forms/signals';\n\ninterface ErrorWithDirective {\n error: ValidationError.WithField;\n directive: ValidationErrorDirective;\n}\n\ninterface ErrorsToDisplay {\n // The validation error directives to display\n errors: Array<ErrorWithDirective>;\n\n // The fallback directive to use to display the fallback errors\n fallback: ValidationFallbackDirective | undefined;\n\n // the fallback errors to display (empty if there is no fallback directive)\n fallbackErrors: Array<ValidationError.WithField>;\n}\n\ntype ViewModel =\n | {\n shouldDisplayErrors: false;\n }\n | {\n shouldDisplayErrors: true;\n errorsToDisplay: ErrorsToDisplay;\n };\n\nconst NO_ERRORS: ViewModel = {\n shouldDisplayErrors: false\n};\n\n/**\n * **Experimental**\n *\n * Component allowing to display validation error messages associated to a given field of a signal form.\n * The control is provided using the `forField` input of the component.\n *\n * Example usage:\n * ```\n * <val-signal-errors [forField]=\"form.birthYear\">\n * <ng-template valError=\"required\">The birth year is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">The max value for the birth year is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * This component, if the control is invalid, displays its validation errors using the provided templates.\n * The templates, as shown in the above example, have access to the validation error itself.\n *\n * The label of the control can also be provided as input, and then used in the templates:\n * ```\n * <val-signal-errors [forField]=\"form.birthYear\" label=\"the birth year\">\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>The max value for {{ label }} is {{ error.max | number }}</ng-template>\n * </val-signal-errors>\n * ```\n *\n * The component‘s behavior is configured globally by the Config service (see its documentation for more details). It can\n * - display the first error, or all the errors\n * - add CSS classes to its host `<val-errors>` element\n * - add CSS classes to each error message element being displayed\n * - choose when to display the errors (dirty, touched, etc.)\n *\n * Global, default templates can be defined (and used by this component) using the default validation errors directive\n * (see its documentation for details). So, if the default error messages are defined and sufficient for a given control, all you\n * need is\n *\n * ```\n * <val-signal-errors [forField]=\"form.birthYear\" />\n * ```\n *\n * or, if the default templates expect a label:\n *\n * ```\n * <val-signal-errors [forField]=\"form.birthYear\" label=\"the birth year\" />\n * ```\n *\n * If, however, you want to override one or several error messages by custom ones, you can do so by simply defining them inside the\n * component:\n *\n * ```\n * <val-signal-errors [forField]=\"form.birthYear\" label=\"the birth year\">\n * <ng-template valError=\"max\">You're too young, sorry</ng-template>\n * </val-signal-errors>\n * ```\n *\n * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control\n * but are not handled by any of the specific error templates:\n * ```\n * <val-signal-errors [forField]=\"form.birthYear\" label=\"the birth year\">\n * <ng-template valError=\"max\">You're too young, sorry</ng-template>\n * <ng-template valFallback let-label let-type=\"type\" let-error=\"error\">{{ label }} has an unhandled error of kind {{ type }}: {{ error | json }}</ng-template>\n * </val-signal-errors>\n * ```\n * Note that, the fallback template can also be defined in the default validation errors directive (see its documentation for details).\n * If a fallback template is defined inside `val-signal-errors`, it overrides the default fallback.\n *\n * If an error is present on the field, but doesn't have any template, default template or fallback template defined for its type,\n * 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,\n * then this component itself is hidden.\n */\n@Component({\n selector: 'val-signal-errors',\n templateUrl: './validation-signal-errors.component.html',\n host: {\n '[class]': 'errorsClasses',\n '[style.display]': `vm().shouldDisplayErrors ? '' : 'none'`\n },\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ValidationSignalErrorsComponent {\n /**\n * The FieldTree containing the validation errors.\n */\n // eslint-disable-next-line @angular-eslint/no-input-rename\n readonly field = input.required<FieldTree<unknown>>({ alias: 'forField' });\n\n /**\n * The label of the field, exposed to templates so they can use it in the error message.\n */\n readonly label = input<string | null>(null);\n\n /**\n * The list of validation error directives (i.e. <ng-template valError=\"...\">) contained inside the component element.\n */\n readonly errorDirectives = contentChildren(ValidationErrorDirective);\n\n /**\n * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the component element.\n */\n readonly fallbackDirective = contentChild(ValidationFallbackDirective);\n\n /**\n * The Config service instance, defining the behavior of this component\n */\n private readonly config = inject(ValdemortConfig);\n readonly errorsClasses = this.config.errorsClasses || '';\n readonly errorClasses = this.config.errorClasses || '';\n\n /**\n * The DefaultValidationErrors service instance, holding the default error templates,\n * optionally defined by using the default validation errors directive\n */\n private readonly defaultValidationErrors = inject(DefaultValidationErrors);\n\n private readonly hasDisplayableError = computed<boolean>(() => {\n const field = this.field();\n const errors = field().errors();\n return (\n errors.length > 0 &&\n (!!this.fallbackDirective() ||\n !!this.defaultValidationErrors.fallback() ||\n errors.some(\n error =>\n this.defaultValidationErrors.directives().some(dir => dir.type() === error.kind) ||\n this.errorDirectives().some(dir => dir.type() === error.kind)\n ))\n );\n });\n\n private readonly shouldDisplayErrors = computed<boolean>(() => {\n const field = this.field();\n const fieldState = field();\n if (!fieldState.invalid() || !this.hasDisplayableError()) {\n return false;\n }\n return this.config.shouldDisplayFieldErrors(fieldState);\n });\n\n readonly vm: Signal<ViewModel> = computed(() => {\n if (this.shouldDisplayErrors()) {\n const errorsToDisplay = this.findErrorsToDisplay();\n return {\n shouldDisplayErrors: true,\n errorsToDisplay\n };\n } else {\n return NO_ERRORS;\n }\n });\n\n private findErrorsToDisplay(): ErrorsToDisplay {\n const field = this.field();\n const fieldErrors = field().errors();\n const mergedErrors: Array<ErrorWithDirective> = [];\n const fallbackErrors: Array<ValidationError.WithField> = [];\n const alreadyMetTypes = new Set<string>();\n const shouldContinue = () => this.config.displayMode === DisplayMode.ALL || (mergedErrors.length === 0 && fallbackErrors.length === 0);\n const defaultValidationErrorDirectives = this.defaultValidationErrors.directives();\n for (let i = 0; i < defaultValidationErrorDirectives.length && shouldContinue(); i++) {\n const defaultDirective = defaultValidationErrorDirectives[i];\n const error = fieldErrors.find(error => error.kind === defaultDirective.type());\n if (error) {\n const customDirectiveOfSameType = this.errorDirectives().find(dir => dir.type() === defaultDirective.type());\n mergedErrors.push({ directive: customDirectiveOfSameType ?? defaultDirective, error });\n }\n alreadyMetTypes.add(defaultDirective.type());\n }\n\n if (shouldContinue()) {\n const customDirectives = this.errorDirectives();\n for (let i = 0; i < customDirectives.length && shouldContinue(); i++) {\n const customDirective = customDirectives[i];\n if (!alreadyMetTypes.has(customDirective.type())) {\n const error = fieldErrors.find(error => error.kind === customDirective.type());\n if (error) {\n mergedErrors.push({ directive: customDirective, error });\n }\n }\n alreadyMetTypes.add(customDirective.type());\n }\n }\n\n if (shouldContinue() && (this.fallbackDirective() || this.defaultValidationErrors.fallback())) {\n for (let i = 0; i < fieldErrors.length && shouldContinue(); i++) {\n const error = fieldErrors[i];\n if (!alreadyMetTypes.has(error.kind)) {\n fallbackErrors.push(error);\n }\n }\n }\n\n return {\n errors: mergedErrors,\n fallback: this.fallbackDirective() ?? this.defaultValidationErrors.fallback(),\n fallbackErrors\n };\n }\n}\n","@let vm = this.vm();\n@if (vm.shouldDisplayErrors) {\n @for (errorWithDirective of vm.errorsToDisplay.errors; track $index) {\n <div [class]=\"errorClasses\">\n <ng-container\n *ngTemplateOutlet=\"\n errorWithDirective.directive.templateRef;\n context: {\n $implicit: label(),\n error: errorWithDirective.error\n }\n \"\n />\n </div>\n }\n @for (error of vm.errorsToDisplay.fallbackErrors; track $index) {\n <div [class]=\"errorClasses\">\n <ng-container\n *ngTemplateOutlet=\"\n vm.errorsToDisplay.fallback!.templateRef;\n context: {\n $implicit: label(),\n type: error.kind,\n error: error\n }\n \"\n />\n </div>\n }\n}\n","import { NgModule } from '@angular/core';\nimport { ValidationErrorsComponent } from './validation-errors.component';\nimport { DefaultValidationErrorsDirective } from './default-validation-errors.directive';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\nimport { ValidationSignalErrorsComponent } from './validation-signal-errors.component';\n\n@NgModule({\n imports: [\n ValidationErrorsComponent,\n ValidationSignalErrorsComponent,\n ValidationErrorDirective,\n ValidationFallbackDirective,\n DefaultValidationErrorsDirective\n ],\n exports: [\n ValidationErrorsComponent,\n ValidationSignalErrorsComponent,\n ValidationErrorDirective,\n ValidationFallbackDirective,\n DefaultValidationErrorsDirective\n ]\n})\nexport class ValdemortModule {}\n","/*\n * Public API Surface of ngx-valdemort\n */\n\nexport * from './lib/default-validation-errors.directive';\nexport * from './lib/validation-error.directive';\nexport * from './lib/validation-fallback.directive';\nexport * from './lib/validation-errors.component';\nexport * from './lib/validation-signal-errors.component';\nexport * from './lib/valdemort-config.service';\nexport * from './lib/valdemort.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["NO_ERRORS"],"mappings":"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