Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Commit

Permalink
Create FormControl component (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Anastos authored Jan 5, 2021
1 parent 5ab5602 commit 4de9a45
Show file tree
Hide file tree
Showing 24 changed files with 1,897 additions and 231 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ module.exports = {
// Enable prettier
"prettier/prettier": "error",

// No consoles!
"no-console": "error",

// We're not creating PropTypes anywhere so don't both checking for them
"react/prop-types": "off",

Expand All @@ -40,7 +43,7 @@ module.exports = {
* React hooks
*/
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"react-hooks/exhaustive-deps": "error",

// In favor of @typescript-eslint variants
"no-use-before-define": "off",
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ tsconfig.tsbuildinfo
/ConfirmationTooltip
/emotionCacheProviderFactory
/fonts
/Form*
/icons
/illustrations
/Input
/List*
/Loaders
/Menu*
Expand Down
254 changes: 110 additions & 144 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,10 @@
"@svgr/plugin-jsx": "^4.3.0",
"@svgr/plugin-prettier": "^4.2.0",
"@svgr/plugin-svgo": "^4.2.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.8",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",
"@testing-library/react-hooks": "^3.7.0",
"@testing-library/user-event": "^12.5.0",
"@types/babel__traverse": "^7.0.7",
"@types/faker": "^4.1.8",
"@types/jest": "^26.0.15",
Expand Down Expand Up @@ -148,6 +149,7 @@
"prettier": "^2.1.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-test-renderer": "^17.0.1",
"rimraf": "^2.6.3",
"rollup": "^1.27.8",
"rollup-plugin-multi-input": "^1.0.3",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function CJS() {
"downshift",
"framer-motion",
"lodash/omit",
"lodash/uniqueId",
"prop-types",
"react-dom",
"react",
Expand Down
7 changes: 7 additions & 0 deletions src/Form/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export { FormControl as Control } from "../FormControl";
export { FormDescription as Description } from "../FormDescription";
export { FormEndAdornment as EndAdornment } from "../FormEndAdornment";
export { FormErrorMessage as ErrorMessage } from "../FormErrorMessage";
export { FormHelperText as HelperText } from "../FormHelperText";
export { FormLabel as Label } from "../FormLabel";
export { FormStartAdornment as StartAdornment } from "../FormStartAdornment";
117 changes: 117 additions & 0 deletions src/FormControl/FormControl.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*eslint react/jsx-sort-props: "error" */
import "@testing-library/jest-dom";
import React from "react";
import userEvent from "@testing-library/user-event";
import { render, screen } from "@testing-library/react";
import { FormControl } from "../FormControl";
import { FormLabel } from "../FormLabel";
import { FormHelperText } from "../FormHelperText";
import { Input } from "../Input";
import { FormErrorMessage } from "../FormErrorMessage";

test("when passed a label, renders it", () => {
render(
<FormControl id="test">
<FormLabel>label text</FormLabel>
<Input />
</FormControl>,
);

expect(screen.getByText("label text")).toBeInTheDocument();
});

test("when the label is clicked it focuses the input", () => {
const labelText = "label text";
const { container } = render(
<FormControl id="test">
<FormLabel>{labelText}</FormLabel>
<Input />
</FormControl>,
);

// Use `throw` so TypeScript knows `label` is not null
const label = container.querySelector("label");
if (!label) throw new Error("Could not find label");

const input = screen.getByLabelText(labelText);
expect(input).not.toHaveFocus();

userEvent.click(label);
expect(input).toHaveFocus();
});

test("when passed `HelperText`, helper text is rendered", () => {
const { container } = render(
<FormControl id="test">
<FormHelperText>helper text</FormHelperText>
<Input />
</FormControl>,
);

expect(screen.queryByText("helper text")).toBeInTheDocument();
expect(container.querySelectorAll("svg")).toHaveLength(1);
});

test("when passed two `HelperText` and `FormErrorMessage`, only renders the `FormErrorMessage`", () => {
const { container } = render(
<FormControl id="test">
<Input />
<FormHelperText>helper text</FormHelperText>
<FormErrorMessage>error text</FormErrorMessage>
</FormControl>,
);

expect(screen.getByText("error text")).toBeInTheDocument();
expect(screen.queryByText("helper text")).not.toBeInTheDocument();
expect(container.querySelectorAll("svg")).toHaveLength(1);
});

test("when passed `<FormControl error />`, renders error and svg", () => {
const { container } = render(
<FormControl id="test">
<Input />
<FormErrorMessage>error text</FormErrorMessage>
</FormControl>,
);

expect(screen.getByText("error text")).toBeInTheDocument();
expect(container.querySelector("svg")).toBeInTheDocument();
});

test("when passed `<HelperText>` witout `showIcon` prop, renders no svg", () => {
const { container } = render(
<FormControl id="test">
<Input />
<FormHelperText>helper text</FormHelperText>
</FormControl>,
);

expect(screen.getByText("helper text")).toBeInTheDocument();
expect(container.querySelector("svg")).not.toBeInTheDocument();
});

test.only("when passed `<HelperText>` with `showIcon` prop, renders svg", () => {
const { container } = render(
<FormControl id="test">
<FormHelperText showIcon>helper text</FormHelperText>
<Input />
</FormControl>,
);

expect(screen.getByText("helper text")).toBeInTheDocument();
expect(container.querySelector("svg")).toBeInTheDocument();
});

test("when not passed `autoFocus` prop, should not have focus after mounting", () => {
const labelText = "label text";
render(
<FormControl id="test">
<FormLabel>{labelText}</FormLabel>
<Input />
</FormControl>,
);

const formField = screen.getByLabelText(labelText);

expect(formField).not.toHaveFocus();
});
Loading

0 comments on commit 4de9a45

Please sign in to comment.