Skip to content

Commit 9ed7bd5

Browse files
authored
Add instantValidation prop for TextArea (#2355)
## Summary: - Adds instantValidation prop so there is an option to validate on blur. If instantValidation is false, the error is also cleared on change - If textarea is required and instantValidation is false, validate whenever the user tabs away from the field Issue: WB-1781 Next: I'll work on refactoring TextField to a function component first and then will add the same `instantValidation` prop to TextField ## Test plan: - Instant Validation docs are reviewed (`/?path=/docs/packages-form-textarea--docs#instant%20validation`) - Instant Validation works as expected (see docs for expected behaviour) (`/?path=/story/packages-form-textarea--instant-validation`) Author: beaesguerra Reviewers: beaesguerra, jandrade, marcysutton Required Reviewers: Approved By: jandrade Checks: ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 20.x), ✅ Test / Test (ubuntu-latest, 20.x, 2/2), ✅ Test / Test (ubuntu-latest, 20.x, 1/2), ✅ Lint / Lint (ubuntu-latest, 20.x), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ⏭️ Chromatic - Skip on Release PR (changesets), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ gerald, ⏭️ dependabot Pull Request URL: #2355
1 parent cdcfe1b commit 9ed7bd5

File tree

4 files changed

+585
-3
lines changed

4 files changed

+585
-3
lines changed

.changeset/chatty-moles-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@khanacademy/wonder-blocks-form": minor
3+
---
4+
5+
Adds `instantValidation` prop for TextArea

__docs__/wonder-blocks-form/text-area.stories.tsx

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,99 @@ ErrorFromPropAndValidation.parameters = {
293293
},
294294
};
295295

296+
/**
297+
* The `instantValidation` prop controls when validation is triggered. Validation
298+
* is triggered if the `validate` or `required` props are set.
299+
*
300+
* It is preferred to set `instantValidation` to `false` so that the user isn't
301+
* shown an error until they are done with a field. Note: if `instantValidation`
302+
* is not explicitly set, it defaults to `true` since this is the current
303+
* behaviour of existing usage. Validation on blur needs to be opted in.
304+
*
305+
* Validation is triggered:
306+
* - On mount if the `value` prop is not empty
307+
* - If `instantValidation` is `true`, validation occurs `onChange` (default)
308+
* - If `instantValidation` is `false`, validation occurs `onBlur`
309+
*
310+
* When `required` is set to `true`:
311+
* - If `instantValidation` is `true`, the required error message is shown after
312+
* a value is cleared
313+
* - If `instantValidation` is `false`, the required error message is shown
314+
* whenever the user tabs away from the required field
315+
*/
316+
export const InstantValidation: StoryComponentType = {
317+
args: {
318+
validate(value: string) {
319+
const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
320+
if (!emailRegex.test(value)) {
321+
return "Please enter a valid email";
322+
}
323+
},
324+
},
325+
render: (args) => {
326+
return (
327+
<View style={{gap: spacing.small_12}}>
328+
<LabelSmall htmlFor="instant-validation-true-not-required">
329+
Validation on mount if there is a value
330+
</LabelSmall>
331+
<ControlledTextArea
332+
{...args}
333+
id="instant-validation-true-not-required"
334+
value="invalid"
335+
/>
336+
<LabelSmall htmlFor="instant-validation-true-not-required">
337+
Error shown immediately (instantValidation: true, required:
338+
false)
339+
</LabelSmall>
340+
<ControlledTextArea
341+
{...args}
342+
id="instant-validation-true-not-required"
343+
instantValidation={true}
344+
/>
345+
<LabelSmall htmlFor="instant-validation-false-not-required">
346+
Error shown onBlur (instantValidation: false, required:
347+
false)
348+
</LabelSmall>
349+
<ControlledTextArea
350+
{...args}
351+
id="instant-validation-false-not-required"
352+
instantValidation={false}
353+
/>
354+
355+
<LabelSmall htmlFor="instant-validation-true-required">
356+
Error shown immediately after clearing the value
357+
(instantValidation: true, required: true)
358+
</LabelSmall>
359+
<ControlledTextArea
360+
{...args}
361+
validate={undefined}
362+
value="T"
363+
id="instant-validation-true-required"
364+
instantValidation={true}
365+
required="Required"
366+
/>
367+
<LabelSmall htmlFor="instant-validation-false-required">
368+
Error shown on blur if it is empty (instantValidation:
369+
false, required: true)
370+
</LabelSmall>
371+
<ControlledTextArea
372+
{...args}
373+
validate={undefined}
374+
id="instant-validation-false-required"
375+
instantValidation={false}
376+
required="Required"
377+
/>
378+
</View>
379+
);
380+
},
381+
parameters: {
382+
chromatic: {
383+
// Disabling because this doesn't test anything visual.
384+
disableSnapshot: true,
385+
},
386+
},
387+
};
388+
296389
/**
297390
* A required field will have error styling if the field is left blank. To
298391
* observe this, type something into the field, backspace all the way,

0 commit comments

Comments
 (0)