mirror of
https://github.com/bitwarden/browser
synced 2025-12-21 02:33:46 +00:00
[CL-124] Add validator stories (#15400)
* adding validation stories * add one story for all validations * fix form field story import * move validation docs * fix maxValue default value * add play function to submit form
This commit is contained in:
@@ -1,13 +1,6 @@
|
||||
import {
|
||||
AbstractControl,
|
||||
FormBuilder,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ValidationErrors,
|
||||
ValidatorFn,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { FormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
|
||||
import { userEvent, getByText } from "@storybook/test";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
||||
@@ -15,6 +8,7 @@ import { ButtonModule } from "../button";
|
||||
import { CheckboxModule } from "../checkbox";
|
||||
import { FormControlModule } from "../form-control";
|
||||
import { FormFieldModule } from "../form-field";
|
||||
import { trimValidator, forbiddenCharacters } from "../form-field/bit-validators";
|
||||
import { InputModule } from "../input/input.module";
|
||||
import { MultiSelectModule } from "../multi-select";
|
||||
import { RadioButtonModule } from "../radio-button";
|
||||
@@ -48,13 +42,19 @@ export default {
|
||||
required: "required",
|
||||
checkboxRequired: "Option is required",
|
||||
inputRequired: "Input is required.",
|
||||
inputEmail: "Input is not an email-address.",
|
||||
inputEmail: "Input is not an email address.",
|
||||
inputForbiddenCharacters: (char) =>
|
||||
`The following characters are not allowed: "${char}"`,
|
||||
inputMinValue: (min) => `Input value must be at least ${min}.`,
|
||||
inputMaxValue: (max) => `Input value must not exceed ${max}.`,
|
||||
inputMinLength: (min) => `Input value must be at least ${min} characters long.`,
|
||||
inputMaxLength: (max) => `Input value must not exceed ${max} characters in length.`,
|
||||
inputTrimValidator: `Input must not contain only whitespace.`,
|
||||
multiSelectPlaceholder: "-- Type to Filter --",
|
||||
multiSelectLoading: "Retrieving options...",
|
||||
multiSelectNotFound: "No items found",
|
||||
multiSelectClearAll: "Clear all",
|
||||
fieldsNeedAttention: "__$1__ field(s) above need your attention.",
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
const fb = new FormBuilder();
|
||||
const exampleFormObj = fb.group({
|
||||
name: ["", [Validators.required]],
|
||||
email: ["", [Validators.required, Validators.email, forbiddenNameValidator(/bit/i)]],
|
||||
email: ["", [Validators.required, Validators.email, forbiddenCharacters(["#"])]],
|
||||
country: [undefined as string | undefined, [Validators.required]],
|
||||
groups: [],
|
||||
terms: [false, [Validators.requiredTrue]],
|
||||
@@ -80,14 +80,6 @@ const exampleFormObj = fb.group({
|
||||
age: [null, [Validators.min(0), Validators.max(150)]],
|
||||
});
|
||||
|
||||
// Custom error message, `message` is shown as the error message
|
||||
function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
const forbidden = nameRe.test(control.value);
|
||||
return forbidden ? { forbiddenName: { message: "forbiddenName" } } : null;
|
||||
};
|
||||
}
|
||||
|
||||
type Story = StoryObj;
|
||||
|
||||
export const FullExample: Story = {
|
||||
@@ -177,3 +169,95 @@ export const FullExample: Story = {
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const showValidationsFormObj = fb.group({
|
||||
required: ["", [Validators.required]],
|
||||
whitespace: [" ", trimValidator],
|
||||
email: ["example?bad-email", [Validators.email]],
|
||||
minLength: ["Hello", [Validators.minLength(8)]],
|
||||
maxLength: ["Hello there", [Validators.maxLength(8)]],
|
||||
minValue: [9, [Validators.min(10)]],
|
||||
maxValue: [15, [Validators.max(10)]],
|
||||
forbiddenChars: ["Th!$ value cont#in$ forbidden char$", forbiddenCharacters(["#", "!", "$"])],
|
||||
});
|
||||
|
||||
export const Validations: Story = {
|
||||
render: (args) => ({
|
||||
props: {
|
||||
formObj: showValidationsFormObj,
|
||||
submit: () => showValidationsFormObj.markAllAsTouched(),
|
||||
...args,
|
||||
},
|
||||
template: /*html*/ `
|
||||
<form [formGroup]="formObj" (ngSubmit)="submit()">
|
||||
<bit-form-field>
|
||||
<bit-label>Required validation</bit-label>
|
||||
<input bitInput formControlName="required" />
|
||||
<bit-hint>This field is required. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>Email validation</bit-label>
|
||||
<input bitInput type="email" formControlName="email" />
|
||||
<bit-hint>This field contains a malformed email address. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>Min length validation</bit-label>
|
||||
<input bitInput formControlName="minLength" />
|
||||
<bit-hint>Value must be at least 8 characters. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>Max length validation</bit-label>
|
||||
<input bitInput formControlName="maxLength" />
|
||||
<bit-hint>Value must be less then 8 characters. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>Min number value validation</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
type="number"
|
||||
formControlName="minValue"
|
||||
/>
|
||||
<bit-hint>Value must be greater than 10. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>Max number value validation</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
type="number"
|
||||
formControlName="maxValue"
|
||||
/>
|
||||
<bit-hint>Value must be less than than 10. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>Forbidden characters validation</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
formControlName="forbiddenChars"
|
||||
/>
|
||||
<bit-hint>Value must not contain '#', '!' or '$'. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-label>White space validation</bit-label>
|
||||
<input bitInput formControlName="whitespace" />
|
||||
<bit-hint>This input contains only white space. Submit form or blur input to see error</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<button type="submit" bitButton buttonType="primary">Submit</button>
|
||||
<bit-error-summary [formGroup]="formObj"></bit-error-summary>
|
||||
</form>
|
||||
`,
|
||||
}),
|
||||
play: async (context) => {
|
||||
const canvas = context.canvasElement;
|
||||
const submitButton = getByText(canvas, "Submit");
|
||||
|
||||
await userEvent.click(submitButton);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user