diff --git a/.changeset/three-keys-add.md b/.changeset/three-keys-add.md new file mode 100644 index 000000000..1f69d7919 --- /dev/null +++ b/.changeset/three-keys-add.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/wonder-blocks-icon-button": minor +--- + +Add type=submit prop to allow submitting forms with the button diff --git a/__docs__/wonder-blocks-icon-button/icon-button.stories.tsx b/__docs__/wonder-blocks-icon-button/icon-button.stories.tsx index 7e1e004f2..806ec390b 100644 --- a/__docs__/wonder-blocks-icon-button/icon-button.stories.tsx +++ b/__docs__/wonder-blocks-icon-button/icon-button.stories.tsx @@ -21,6 +21,7 @@ import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; import ComponentInfo from "../../.storybook/components/component-info"; import packageConfig from "../../packages/wonder-blocks-icon-button/package.json"; import IconButtonArgtypes from "./icon-button.argtypes"; +import TextField from "../../packages/wonder-blocks-form/src/components/text-field"; /** * An `IconButton` is a button whose contents are an SVG image. @@ -355,6 +356,45 @@ export const WithRouter: StoryComponentType = { ), }; +/** + * If the button is inside a form, you can use the `type="submit"` prop, so the + * form will be submitted on click or by pressing `Enter`. + */ +export const SubmittingForms: StoryComponentType = { + name: "Submitting forms", + render: () => ( +
+ ), + parameters: { + chromatic: { + // We are testing the form submission, not UI changes. + disableSnapshot: true, + }, + }, +}; + const styles = StyleSheet.create({ dark: { backgroundColor: color.darkBlue, @@ -366,6 +406,7 @@ const styles = StyleSheet.create({ width: spacing.xxxLarge_64, }, row: { + display: "flex", flexDirection: "row", gap: spacing.medium_16, alignItems: "center", diff --git a/packages/wonder-blocks-icon-button/src/components/__tests__/icon-button.test.tsx b/packages/wonder-blocks-icon-button/src/components/__tests__/icon-button.test.tsx index 6145231b8..cc4f6d215 100644 --- a/packages/wonder-blocks-icon-button/src/components/__tests__/icon-button.test.tsx +++ b/packages/wonder-blocks-icon-button/src/components/__tests__/icon-button.test.tsx @@ -320,4 +320,51 @@ describe("IconButton", () => { expect(onClickMock).toHaveBeenCalledTimes(1); }); }); + + describe("type='submit'", () => { + it("should submit button within form via click", async () => { + // Arrange + const submitFnMock = jest.fn(); + render( + , + ); + + // Act + const button = await screen.findByRole("button"); + await userEvent.click(button); + + // Assert + expect(submitFnMock).toHaveBeenCalled(); + }); + + it("should submit button within form via keyboard", async () => { + // Arrange + const submitFnMock = jest.fn(); + render( + , + ); + + // Act + const button = await screen.findByRole("button"); + await userEvent.type(button, "{enter}"); + + // Assert + expect(submitFnMock).toHaveBeenCalled(); + }); + + it("should submit button doesn't break if it's not in a form", async () => { + // Arrange + render(