From 911f3d47bc5cb1bc293028fb5ceb79d7a4f0f1f8 Mon Sep 17 00:00:00 2001 From: Bea Esguerra Date: Tue, 5 Nov 2024 16:46:49 -0700 Subject: [PATCH 1/8] Add instantValidation prop so there is an option to validate on blur. If instantValidation is false, the error is cleared on change --- .../wonder-blocks-form/text-area.stories.tsx | 48 ++++ .../components/__tests__/text-area.test.tsx | 247 +++++++++++++++++- .../src/components/text-area.tsx | 44 +++- 3 files changed, 336 insertions(+), 3 deletions(-) diff --git a/__docs__/wonder-blocks-form/text-area.stories.tsx b/__docs__/wonder-blocks-form/text-area.stories.tsx index d8cd44312..0c545291c 100644 --- a/__docs__/wonder-blocks-form/text-area.stories.tsx +++ b/__docs__/wonder-blocks-form/text-area.stories.tsx @@ -293,6 +293,54 @@ ErrorFromPropAndValidation.parameters = { }, }; +/** + * The `instantValidation` prop controls when validation is triggered. Validation + * is only triggered if the `validate` or `required` props are set. + * + * Validation is triggered: + * 1. On mount if the `value` prop is not empty + * 2. If `instantValidation` is `true`, validation occurs `onChange` (default) + * 3. If `instantValidation` is `false`, validation occurs `onBlur` + */ +export const InstantValidation: StoryComponentType = { + args: { + validate(value: string) { + const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/; + if (!emailRegex.test(value)) { + return "Please enter a valid email"; + } + }, + }, + render: (args) => { + return ( + + + Instant Validation: true + + + + Instant Validation: false + + + + ); + }, + parameters: { + chromatic: { + // Disabling because this doesn't test anything visual. + disableSnapshot: true, + }, + }, +}; + /** * A required field will have error styling if the field is left blank. To * observe this, type something into the field, backspace all the way, diff --git a/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx b/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx index 7d89d0a93..6d6d7b719 100644 --- a/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx +++ b/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import {render, screen} from "@testing-library/react"; -import {RenderStateRoot} from "@khanacademy/wonder-blocks-core"; +import {PropsFor, RenderStateRoot} from "@khanacademy/wonder-blocks-core"; import {userEvent} from "@testing-library/user-event"; import TextArea from "../text-area"; @@ -12,6 +12,11 @@ const defaultOptions = { const wrapOptions: Array<"soft" | "hard" | "off"> = ["soft", "hard", "off"]; +const ControlledTextArea = (props: Partial>) => { + const [value, setValue] = React.useState(props.value || ""); + return