Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 1x 227x 227x 227x 1x 73x 73x 1x 154x 154x 40x 40x 154x | import type { Signal } from '@angular/core'; import { FormControl, Validators } from '@angular/forms'; import type { AbstractControl, ValidationErrors } from '@angular/forms'; import { PASSWORDS } from '@app/shared/constants'; import { controlErrorsSignal } from '@app/shared/control-errors-signal.util'; import { controlInvalidSignal } from '@app/shared/control-invalid-signal.util'; import { passwordFirebaseValidator, passwordStrengthValidator } from './validators/passwords'; /** * Pair control with Angular Signals for handling validation in the template. */ const getControlStructure = <T extends AbstractControl>(control: T): ControlStruct<T> => { const $invalid = controlInvalidSignal(control); const $errors = controlErrorsSignal(control); return { $errors, $invalid, control }; }; export { PASSWORDS }; /** * For each Identity Control generate two Signals for error handling. */ export interface ControlStruct<T extends AbstractControl = FormControl> { /** Returns errors for the control, but only when the control is dirty. */ readonly $errors: Signal<ValidationErrors | undefined>; /** Flag for aria-invalid, but only when the control is modified, invalid, and interacted with. */ readonly $invalid: Signal<boolean>; /** Identity control. */ readonly control: T; } /** * Emails are required and must be a valid email address. */ export const createEmailControl = (): ControlStruct<FormControl> => { // eslint-disable-next-line unicorn/no-null -- DOM forms use null const control = new FormControl<string | null>(null, [ Validators.required, Validators.email ]); return getControlStructure(control); }; /** * Passwords are required and have length requirements. Complexity is required for new password fields. * @param isNewPassword - Adds extra validators to control when being used to create a new password. * Note: this should only be used on the first password field, not the confirm * field. */ export const createPasswordControl = (isNewPassword: boolean = false): ControlStruct<FormControl> => { const control = new FormControl<string | null>( null, // eslint-disable-line unicorn/no-null -- DOM forms use null [ Validators.required, Validators.minLength(PASSWORDS.minLength), Validators.maxLength(PASSWORDS.maxLength), ], ); if (isNewPassword) { control.addValidators(passwordStrengthValidator); control.addAsyncValidators(passwordFirebaseValidator()); } return getControlStructure(control); }; |