From dcb9037ef9cfa45e6d9b17624c2d87382136f7ca Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Mon, 4 Oct 2021 12:18:50 -0600 Subject: [PATCH 01/21] added description type --- packages/components/src/FormField/FormFieldTypes.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/components/src/FormField/FormFieldTypes.ts b/packages/components/src/FormField/FormFieldTypes.ts index b53c2c4504..e9c98e93b0 100644 --- a/packages/components/src/FormField/FormFieldTypes.ts +++ b/packages/components/src/FormField/FormFieldTypes.ts @@ -54,6 +54,11 @@ export interface CommonFormFieldProps { */ readonly defaultValue?: string; + /** + * Further description of the input, can be used for a hint. + */ + readonly description?: string; + /** * Disable the input */ From 6cc95f39f64661adf25b1ce410e6d89c01b37675 Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Mon, 4 Oct 2021 12:21:57 -0600 Subject: [PATCH 02/21] added component to display form field description --- .../src/FormField/FormFieldDescription.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 packages/components/src/FormField/FormFieldDescription.tsx diff --git a/packages/components/src/FormField/FormFieldDescription.tsx b/packages/components/src/FormField/FormFieldDescription.tsx new file mode 100644 index 0000000000..9130d002b8 --- /dev/null +++ b/packages/components/src/FormField/FormFieldDescription.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import { Text } from "../Text"; + +interface FormFieldDescriptionProps { + description: string; +} +export function FormFieldDescription({ + description, +}: FormFieldDescriptionProps) { + return ( + + {description} + + ); +} From 97e33852b6296f2cead19fe99961b2f6eff07c29 Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Mon, 4 Oct 2021 12:26:16 -0600 Subject: [PATCH 03/21] added description usage to the form field --- packages/components/src/FormField/FormFieldWrapper.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/components/src/FormField/FormFieldWrapper.tsx b/packages/components/src/FormField/FormFieldWrapper.tsx index ab7641d6f0..8ae2570aa2 100644 --- a/packages/components/src/FormField/FormFieldWrapper.tsx +++ b/packages/components/src/FormField/FormFieldWrapper.tsx @@ -9,6 +9,7 @@ import classnames from "classnames"; import { FormFieldProps } from "./FormFieldTypes"; import styles from "./FormField.css"; import { AffixIcon, AffixLabel } from "./FormFieldAffix"; +import { FormFieldDescription } from "./FormFieldDescription"; import { InputValidation } from "../InputValidation"; interface FormFieldWrapperProps extends FormFieldProps { @@ -23,6 +24,7 @@ interface LabelPadding { export function FormFieldWrapper({ align, + description, placeholder, value, children, @@ -94,6 +96,7 @@ export function FormFieldWrapper({ )} + {description && } {error && !inline && } ); From ef8c8efec3e442d8a998cff9d8f1b0064d17a2d4 Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Mon, 4 Oct 2021 12:27:33 -0600 Subject: [PATCH 04/21] refactored formfield tests --- .../src/FormField/FormField.test.tsx | 753 ++++++++---------- .../__snapshots__/FormField.test.tsx.snap | 120 +++ 2 files changed, 455 insertions(+), 418 deletions(-) create mode 100644 packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap diff --git a/packages/components/src/FormField/FormField.test.tsx b/packages/components/src/FormField/FormField.test.tsx index 0a85090105..49fc999ebe 100644 --- a/packages/components/src/FormField/FormField.test.tsx +++ b/packages/components/src/FormField/FormField.test.tsx @@ -4,178 +4,347 @@ import { cleanup, fireEvent, render, waitFor } from "@testing-library/react"; import { FormField } from "."; afterEach(cleanup); -it("renders correctly with no props", () => { - const tree = renderer.create().toJSON(); - expect(tree).toMatchInlineSnapshot(` -
-
-
-
- `); -}); -it("renders correctly with a placeholder", () => { - const tree = renderer - .create() - .toJSON(); - expect(tree).toMatchInlineSnapshot(` -
-
- - -
-
- `); -}); +// eslint-disable-next-line max-statements +describe("FormField", () => { + describe("with no props", () => { + it("renders", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + }); -it("renders correctly as small", () => { - const tree = renderer.create().toJSON(); - expect(tree).toMatchInlineSnapshot(` -
-
-
-
- `); -}); + describe("with a placeholder", () => { + it("renders", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + it("renders as a label", () => { + const placeholder = "The best placeholder!"; + const { getByLabelText } = render( + , + ); + expect(getByLabelText(placeholder)).toBeInTheDocument(); + }); + }); -it("renders correctly in a readonly state", () => { - const tree = renderer.create().toJSON(); - expect(tree).toMatchInlineSnapshot(` -
-
-
-
- `); -}); + describe("when small", () => { + it("renders", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + }); -it("renders correctly in a disabled state", () => { - const tree = renderer.create().toJSON(); - expect(tree).toMatchInlineSnapshot(` -
-
-
-
- `); + describe("when readonly", () => { + it("renders", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + }); + + describe("when disabled", () => { + it("renders", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + }); + + describe("with a controlled value", () => { + it("should set the value", () => { + const value = "Look, some words!"; + const { getByDisplayValue } = render(); + + expect(getByDisplayValue(value)).toBeDefined(); + }); + }); + + describe("on keystroke", () => { + describe("enter key", () => { + it("should trigger onEnter", () => { + const enterHandler = jest.fn(); + const placeholder = "Milk heals bones"; + + const { getByLabelText } = render( + , + ); + + fireEvent.keyDown(getByLabelText(placeholder), { + key: "Enter", + code: "Enter", + }); + + expect(enterHandler).toHaveBeenCalledTimes(1); + + fireEvent.keyDown(getByLabelText(placeholder), { + key: "Enter", + code: "Enter", + }); + + expect(enterHandler).toHaveBeenCalledTimes(2); + }); + }); + + describe("enter key + shift key", () => { + it("should not trigger onEnter", () => { + const enterHandler = jest.fn(); + const placeholder = "Milk heals bones"; + + const { getByLabelText } = render( + , + ); + + fireEvent.keyDown(getByLabelText(placeholder), { + key: "Enter", + code: "Enter", + shiftKey: true, + }); + + expect(enterHandler).toHaveBeenCalledTimes(0); + }); + }); + + describe("enter key + ctrl key", () => { + it("should not trigger onEnter", () => { + const enterHandler = jest.fn(); + const placeholder = "Milk heals bones"; + + const { getByLabelText } = render( + , + ); + + fireEvent.keyDown(getByLabelText(placeholder), { + key: "Enter", + code: "Enter", + ctrlKey: true, + }); + + expect(enterHandler).toHaveBeenCalledTimes(0); + }); + }); + }); + + describe("when triggering change", () => { + it("should trigger onChange", () => { + const placeholder = "I hold places."; + const newValue = + "The snake which cannot cast its skin has to die. As well the minds which are prevented from changing their opinions; they cease to be mind."; + const newerValue = + "They always say time changes things, but you actually have to change them yourself."; + const changeHandler = jest.fn(); + + const { getByLabelText } = render( + , + ); + + fireEvent.change(getByLabelText(placeholder), { + target: { value: newValue }, + }); + expect(changeHandler).toHaveBeenCalledWith(newValue); + + fireEvent.change(getByLabelText(placeholder), { + target: { value: newerValue }, + }); + expect(changeHandler).toHaveBeenCalledWith(newerValue); + }); + + describe("without validation errors", () => { + it("should trigger onValidation with undefined", () => { + const validationHandler = jest.fn(); + + render( + , + ); + + expect(validationHandler).toHaveBeenCalled(); + expect(validationHandler).toHaveBeenCalledWith(undefined); + }); + }); + + describe("with validation errors", () => { + it("should trigger onValidation with error message", async () => { + const validationHandler = jest.fn(); + const validate = val => (val == "Bob" ? "message" : "foo"); + + const { getByLabelText } = render( + , + ); + + getByLabelText("I hold places").focus(); + fireEvent.change(getByLabelText("I hold places"), { + target: { value: "Bob" }, + }); + getByLabelText("I hold places").blur(); + + await waitFor(() => { + expect(validationHandler).toHaveBeenCalledWith("message"); + }); + }); + }); + }); + + describe("name attribute", () => { + it("should not have one by default", () => { + const { getByLabelText } = render(); + expect(getByLabelText("foo")).not.toHaveAttribute("name"); + }); + + describe("when set", () => { + it("should set the name", () => { + const { getByLabelText } = render( + , + ); + expect(getByLabelText("foo")).toHaveAttribute("name", "dillan"); + }); + }); + + describe("with validations enabled", () => { + it("should set the name", () => { + const { getByLabelText } = render( + , + ); + const input = getByLabelText("foo"); + const name = input.getAttribute("name"); + expect(name).toContain("generatedName--"); + }); + }); + }); + + describe("with keyboard mode", () => { + it("should set the keyboard inputMode", () => { + const keyboardMode = "numeric"; + const { getByLabelText } = render( + , + ); + const input = getByLabelText("foo"); + const name = input.getAttribute("inputMode"); + expect(name).toContain(keyboardMode); + }); + }); + + describe("when loading", () => { + it("should render the spinner", () => { + const { getByLabelText } = render( + , + ); + const spinner = getByLabelText("loading"); + + expect(spinner).toBeInstanceOf(HTMLElement); + }); + }); + + describe("when autocomplete", () => { + describe("when one-time-code", () => { + it("should set the autocomplete type", () => { + const { getByLabelText } = render( + , + ); + const input = getByLabelText("foo"); + const autocomplete = input.getAttribute("autocomplete"); + expect(autocomplete).toContain("one-time-code"); + }); + }); + describe("when address-line1", () => { + it("should set the autocomplete type", () => { + const { getByLabelText } = render( + , + ); + const input = getByLabelText("foo"); + const autocomplete = input.getAttribute("autocomplete"); + expect(autocomplete).toContain("address-line1"); + }); + }); + describe("when address-line2", () => { + it("should set the autocomplete type", () => { + const { getByLabelText } = render( + , + ); + const input = getByLabelText("foo"); + const autocomplete = input.getAttribute("autocomplete"); + expect(autocomplete).toContain("address-line2"); + }); + }); + + describe("when off", () => { + it("should set the autocomplete type", () => { + const { getByLabelText } = render( + , + ); + const input = getByLabelText("foo"); + const autocomplete = input.getAttribute("autocomplete"); + expect(autocomplete).toContain("autocomplete-off"); + }); + }); + }); + + describe("with a prefix", () => { + it("should render the icon", () => { + const { getByTestId } = render(); + + expect(getByTestId("home")).toBeInstanceOf(SVGElement); + }); + }); + + describe("with a suffix", () => { + it("should render the icon", () => { + const { getByTestId } = render(); + + expect(getByTestId("home")).toBeInstanceOf(SVGElement); + }); + + describe("with an onClick", () => { + it("should trigger", () => { + const clickHandler = jest.fn(); + const { getByTestId } = render( + , + ); + + const icon = getByTestId("home"); + fireEvent.click(icon); + + expect(clickHandler).toHaveBeenCalled(); + expect(clickHandler).toHaveBeenCalledTimes(1); + }); + }); + }); }); -it("renders a field with error", () => { +// @TODO: validate that this actually produces an error and is an expected test +it.skip("renders a field with error", () => { const tree = renderer.create().toJSON(); expect(tree).toMatchInlineSnapshot(`
{
`); }); - -it("it should set the value", () => { - const value = "Look, some words!"; - const { getByDisplayValue } = render(); - - expect(getByDisplayValue(value)).toBeDefined(); -}); - -test("it should call the handler with the new value", () => { - const placeholder = "I hold places."; - const newValue = - "The snake which cannot cast its skin has to die. As well the minds which are prevented from changing their opinions; they cease to be mind."; - const newerValue = - "They always say time changes things, but you actually have to change them yourself."; - const changeHandler = jest.fn(); - - const { getByLabelText } = render( - , - ); - - fireEvent.change(getByLabelText(placeholder), { - target: { value: newValue }, - }); - expect(changeHandler).toHaveBeenCalledWith(newValue); - - fireEvent.change(getByLabelText(placeholder), { - target: { value: newerValue }, - }); - expect(changeHandler).toHaveBeenCalledWith(newerValue); -}); - -test("it should call the validation handler when typing a new value", () => { - const validationHandler = jest.fn(); - - render( - , - ); - - expect(validationHandler).toHaveBeenCalled(); - expect(validationHandler).toHaveBeenCalledWith(undefined); -}); - -test("it should call the validation handler with a message when there is an error", async () => { - const validationHandler = jest.fn(); - const validate = val => (val == "Bob" ? "message" : "foo"); - - const { getByLabelText } = render( - , - ); - - getByLabelText("I hold places").focus(); - fireEvent.change(getByLabelText("I hold places"), { - target: { value: "Bob" }, - }); - getByLabelText("I hold places").blur(); - - await waitFor(() => { - expect(validationHandler).toHaveBeenCalledWith("message"); - }); -}); - -test("it should handle when the enter key is pressed", () => { - const enterHandler = jest.fn(); - const placeholder = "Milk heals bones"; - - const { getByLabelText } = render( - , - ); - - fireEvent.keyDown(getByLabelText(placeholder), { - key: "Enter", - code: "Enter", - }); - - expect(enterHandler).toHaveBeenCalledTimes(1); - - fireEvent.keyDown(getByLabelText(placeholder), { - key: "Enter", - code: "Enter", - }); - - expect(enterHandler).toHaveBeenCalledTimes(2); -}); - -test("it should not handle when the shift key and enter key are pressed", () => { - const enterHandler = jest.fn(); - const placeholder = "Milk heals bones"; - - const { getByLabelText } = render( - , - ); - - fireEvent.keyDown(getByLabelText(placeholder), { - key: "Enter", - code: "Enter", - shiftKey: true, - }); - - expect(enterHandler).toHaveBeenCalledTimes(0); -}); - -test("it should not handle when the shift key and control key are pressed", () => { - const enterHandler = jest.fn(); - const placeholder = "Milk heals bones"; - - const { getByLabelText } = render( - , - ); - - fireEvent.keyDown(getByLabelText(placeholder), { - key: "Enter", - code: "Enter", - ctrlKey: true, - }); - - expect(enterHandler).toHaveBeenCalledTimes(0); -}); - -test("it should not have a name by default", () => { - const { getByLabelText } = render(); - expect(getByLabelText("foo")).not.toHaveAttribute("name"); -}); - -test("it should use the name prop when set", () => { - const { getByLabelText } = render( - , - ); - expect(getByLabelText("foo")).toHaveAttribute("name", "dillan"); -}); - -test("it should generate a name if validations are set", () => { - const { getByLabelText } = render( - , - ); - const input = getByLabelText("foo"); - const name = input.getAttribute("name"); - expect(name).toContain("generatedName--"); -}); - -test("it should set the inputMode when the keyboard prop is set", () => { - const keyboardMode = "numeric"; - const { getByLabelText } = render( - , - ); - const input = getByLabelText("foo"); - const name = input.getAttribute("inputMode"); - expect(name).toContain(keyboardMode); -}); - -test("it should render the spinner when loading is true", () => { - const { getByLabelText } = render( - , - ); - const spinner = getByLabelText("loading"); - - expect(spinner).toBeInstanceOf(HTMLElement); -}); - -it("it should set the autocomplete value with one-time-code", () => { - const { getByLabelText } = render( - , - ); - const input = getByLabelText("foo"); - const autocomplete = input.getAttribute("autocomplete"); - expect(autocomplete).toContain("one-time-code"); -}); - -it("it should set the autocomplete value with address-line1", () => { - const { getByLabelText } = render( - , - ); - const input = getByLabelText("foo"); - const autocomplete = input.getAttribute("autocomplete"); - expect(autocomplete).toContain("address-line1"); -}); - -it("it should set the autocomplete value with address-line2", () => { - const { getByLabelText } = render( - , - ); - const input = getByLabelText("foo"); - const autocomplete = input.getAttribute("autocomplete"); - expect(autocomplete).toContain("address-line2"); -}); - -it("it should set the autocomplete value to off", () => { - const { getByLabelText } = render( - , - ); - const input = getByLabelText("foo"); - const autocomplete = input.getAttribute("autocomplete"); - expect(autocomplete).toContain("autocomplete-off"); -}); - -describe("when the formfield has a prefix", () => { - it("shows an icon", () => { - const { getByTestId } = render(); - - expect(getByTestId("home")).toBeInstanceOf(SVGElement); - }); -}); - -describe("when the formfield has a suffix", () => { - it("shows an icon", () => { - const { getByTestId } = render(); - - expect(getByTestId("home")).toBeInstanceOf(SVGElement); - }); - - it("calls the onClick when set", () => { - const clickHandler = jest.fn(); - const { getByTestId } = render( - , - ); - - const icon = getByTestId("home"); - fireEvent.click(icon); - - expect(clickHandler).toHaveBeenCalled(); - expect(clickHandler).toHaveBeenCalledTimes(1); - }); -}); diff --git a/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap b/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap new file mode 100644 index 0000000000..bfab7e910a --- /dev/null +++ b/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap @@ -0,0 +1,120 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FormField when disabled renders 1`] = ` +
+
+
+
+
+
+`; + +exports[`FormField when readonly renders 1`] = ` +
+
+
+
+
+
+`; + +exports[`FormField when small renders 1`] = ` +
+
+
+
+
+
+`; + +exports[`FormField with a placeholder renders 1`] = ` +
+
+
+ + +
+
+
+`; + +exports[`FormField with no props renders 1`] = ` +
+
+
+
+
+
+`; From 68b9e271ba5615caa28a98a396798db1c4ea74ee Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Mon, 4 Oct 2021 12:29:31 -0600 Subject: [PATCH 05/21] added test to find description --- packages/components/src/FormField/FormField.test.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/components/src/FormField/FormField.test.tsx b/packages/components/src/FormField/FormField.test.tsx index 49fc999ebe..a4d77f72a3 100644 --- a/packages/components/src/FormField/FormField.test.tsx +++ b/packages/components/src/FormField/FormField.test.tsx @@ -50,6 +50,15 @@ describe("FormField", () => { }); }); + describe("with a description", () => { + const label = "This is a hint!"; + + it("renders", () => { + const { getByText } = render(); + expect(getByText(label)).toBeInTheDocument(); + }); + }); + describe("with a controlled value", () => { it("should set the value", () => { const value = "Look, some words!"; From 43f730f504f1278bcc4eef8e57ef48788105d375 Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Mon, 4 Oct 2021 17:25:16 -0600 Subject: [PATCH 06/21] updated htype declaration --- packages/components/src/FormField/FormFieldDescription.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/components/src/FormField/FormFieldDescription.tsx b/packages/components/src/FormField/FormFieldDescription.tsx index 9130d002b8..f4b71abb3c 100644 --- a/packages/components/src/FormField/FormFieldDescription.tsx +++ b/packages/components/src/FormField/FormFieldDescription.tsx @@ -2,8 +2,9 @@ import React from "react"; import { Text } from "../Text"; interface FormFieldDescriptionProps { - description: string; + readonly description: string; } + export function FormFieldDescription({ description, }: FormFieldDescriptionProps) { From dbfb53e8d6b1dc6352e396bc9ff639e62cccb530 Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Tue, 5 Oct 2021 12:44:10 -0600 Subject: [PATCH 07/21] added aria-describedby, spacing between description and field, and switched to base size --- packages/components/src/FormField/FormField.css | 8 ++++++++ .../components/src/FormField/FormField.css.d.ts | 1 + .../components/src/FormField/FormField.test.tsx | 5 +++++ packages/components/src/FormField/FormField.tsx | 5 ++++- .../src/FormField/FormFieldDescription.tsx | 9 ++++++--- .../src/FormField/FormFieldWrapper.tsx | 6 +++++- .../__snapshots__/FormField.test.tsx.snap | 16 ++++++++-------- 7 files changed, 37 insertions(+), 13 deletions(-) diff --git a/packages/components/src/FormField/FormField.css b/packages/components/src/FormField/FormField.css index ea505a7b0e..0396848e1e 100644 --- a/packages/components/src/FormField/FormField.css +++ b/packages/components/src/FormField/FormField.css @@ -277,3 +277,11 @@ .miniLabel:not(.small) .affixLabel { padding-top: calc(var(--field--padding-top) - 2px); } + +/** + * Description + **/ + +.description { + margin-top: var(--space-smaller); +} diff --git a/packages/components/src/FormField/FormField.css.d.ts b/packages/components/src/FormField/FormField.css.d.ts index 46c7dc6aff..d67f73edd8 100644 --- a/packages/components/src/FormField/FormField.css.d.ts +++ b/packages/components/src/FormField/FormField.css.d.ts @@ -19,6 +19,7 @@ declare const styles: { readonly "suffix": string; readonly "hasAction": string; readonly "affixLabel": string; + readonly "description": string; }; export = styles; diff --git a/packages/components/src/FormField/FormField.test.tsx b/packages/components/src/FormField/FormField.test.tsx index a4d77f72a3..db86a9e82e 100644 --- a/packages/components/src/FormField/FormField.test.tsx +++ b/packages/components/src/FormField/FormField.test.tsx @@ -57,6 +57,11 @@ describe("FormField", () => { const { getByText } = render(); expect(getByText(label)).toBeInTheDocument(); }); + + it("should have assistive descriptor `aria-describedby`", () => { + const { getByRole } = render(); + expect(getByRole("textbox")).toHaveAttribute("aria-describedby"); + }); }); describe("with a controlled value", () => { diff --git a/packages/components/src/FormField/FormField.tsx b/packages/components/src/FormField/FormField.tsx index b31a01c2de..b19e076a24 100644 --- a/packages/components/src/FormField/FormField.tsx +++ b/packages/components/src/FormField/FormField.tsx @@ -20,6 +20,7 @@ export function FormField(props: FormFieldProps) { autocomplete = true, children, defaultValue, + description, disabled, inputRef, keyboard, @@ -46,7 +47,7 @@ export function FormField(props: FormFieldProps) { : useForm({ mode: "onTouched" }); const [identifier] = useState(uuid.v1()); - + const [descriptionUUID] = useState(`descriptionUUID--${uuid.v1()}`); /** * Generate a name if one is not supplied, this is the name * that will be used for react-hook-form and not neccessarily @@ -92,6 +93,7 @@ export function FormField(props: FormFieldProps) { readOnly: readonly, inputMode: keyboard, onChange: handleChange, + ...(description && { "aria-describedby": descriptionUUID }), }; const textFieldProps = { @@ -107,6 +109,7 @@ export function FormField(props: FormFieldProps) { value={rest.value} error={error} identifier={identifier} + descriptionUUID={descriptionUUID} > {renderField()} diff --git a/packages/components/src/FormField/FormFieldDescription.tsx b/packages/components/src/FormField/FormFieldDescription.tsx index f4b71abb3c..d638f30613 100644 --- a/packages/components/src/FormField/FormFieldDescription.tsx +++ b/packages/components/src/FormField/FormFieldDescription.tsx @@ -1,16 +1,19 @@ import React from "react"; +import styles from "./FormField.css"; import { Text } from "../Text"; interface FormFieldDescriptionProps { + readonly id: string; readonly description: string; } export function FormFieldDescription({ + id, description, }: FormFieldDescriptionProps) { return ( - - {description} - +
+ {description} +
); } diff --git a/packages/components/src/FormField/FormFieldWrapper.tsx b/packages/components/src/FormField/FormFieldWrapper.tsx index 8ae2570aa2..d24ed42920 100644 --- a/packages/components/src/FormField/FormFieldWrapper.tsx +++ b/packages/components/src/FormField/FormFieldWrapper.tsx @@ -15,6 +15,7 @@ import { InputValidation } from "../InputValidation"; interface FormFieldWrapperProps extends FormFieldProps { error: string; identifier: string; + descriptionUUID: string; } interface LabelPadding { @@ -25,6 +26,7 @@ interface LabelPadding { export function FormFieldWrapper({ align, description, + descriptionUUID, placeholder, value, children, @@ -96,7 +98,9 @@ export function FormFieldWrapper({ )} - {description && } + {description && ( + + )} {error && !inline && } ); diff --git a/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap b/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap index bfab7e910a..e74499911c 100644 --- a/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap +++ b/packages/components/src/FormField/__snapshots__/FormField.test.tsx.snap @@ -10,12 +10,12 @@ exports[`FormField when disabled renders 1`] = ` >