Skip to content

Commit

Permalink
refactor: unite data-testid, htmlFor, id property
Browse files Browse the repository at this point in the history
  • Loading branch information
toothlessdev committed Nov 21, 2024
1 parent ca28686 commit b2d2546
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 54 deletions.
53 changes: 10 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,17 @@
# React + TypeScript + Vite
Form Control Convention

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
1. data-testid

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default tseslint.config({
languageOptions: {
// other options...
parserOptions: {
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
tsconfigRootDir: import.meta.dirname,
},
},
});
```
data-testid: <UI>_{option.label}
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
- Optionally add `...tseslint.configs.stylisticTypeChecked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
ex.
<CheckBoxWithLabelForm/>
data-testid: checkbox\_{option.label}
```

```js
// eslint.config.js
import react from "eslint-plugin-react";
2. htmlFor, id

export default tseslint.config({
// Set the react version
settings: { react: { version: "18.3" } },
plugins: {
// Add the react plugin
react,
},
rules: {
// other rules...
// Enable its recommended rules
...react.configs.recommended.rules,
...react.configs["jsx-runtime"].rules,
},
});
```
const id = useId();
```
8 changes: 6 additions & 2 deletions src/components/forms/CheckBoxWithLabelForm.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useId } from "react";

import { Checkbox } from "@/components/ui/checkbox";

import { FormState, Question } from "./FormRenderer";
Expand All @@ -13,6 +15,8 @@ export const CheckBoxWithLabelForm = ({
formState,
setFormState,
}: CheckBoxWithLabelFormProps) => {
const htmlFor = useId();

return (
<div className="flex flex-col gap-1" data-testid="checkbox-with-label-form">
<p className="font-bold">{questionText}</p>
Expand All @@ -22,7 +26,7 @@ export const CheckBoxWithLabelForm = ({
<div key={index} className="flex items-center gap-1">
<Checkbox
data-testid={`checkbox_${option.label}`}
id={`checkbox_${option.label}`}
id={htmlFor}
className="block w-5 h-5"
checked={formState[questionText]
.map((state) => state.value)
Expand All @@ -47,7 +51,7 @@ export const CheckBoxWithLabelForm = ({
}
}}
/>
<label htmlFor={`checkbox_${option}`}>{option.label}</label>
<label htmlFor={`checkbox_${option.label}`}>{option.label}</label>
</div>
);
})}
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/SelectorWithLabelForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const SelectorWithLabelForm = ({
<SelectItem
key={index}
value={option.value as string}
data-testid={`select-options_${index + 1}`}
data-testid={`select-options_${option.label}`}
>
{option.label as string}
</SelectItem>
Expand Down
35 changes: 27 additions & 8 deletions src/components/forms/__test__/FormRenderer.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { FormProps, FormRenderer } from "../FormRenderer";
import { fireEvent, render, screen } from "@testing-library/react";

/**
* Each Element's following options data-testid and id
*
* <CheckBoxWithLabelForm/>
* id : checkbox_{option.label}
* data-testid : checkbox_{option.label}
*
* <SelectorWithLabelForm/>
* data-testid : select-options_{option.label}
*
*/
describe("<FormRenderer/>", () => {
describe("<SelectorWithLabelForm/>", () => {
const formState = {
Expand All @@ -17,7 +28,11 @@ describe("<FormRenderer/>", () => {
questionText: "test-question-selector",
questionType: "selector",
dataType: "string",
options: ["options1", "options2", "options3"],
options: [
{ label: "options1", value: "options1" },
{ label: "options2", value: "options2" },
{ label: "options3", value: "options3" },
],
},
],
};
Expand Down Expand Up @@ -53,7 +68,7 @@ describe("<FormRenderer/>", () => {

expect(setFormState).toHaveBeenCalledWith({
...formState,
"test-question-selector": [option],
"test-question-selector": [{ value: option }],
});
});
});
Expand All @@ -74,7 +89,11 @@ describe("<FormRenderer/>", () => {
questionText: "test-question-checkbox",
questionType: "checkbox",
dataType: "number",
options: [1, 2, 3],
options: [
{ label: "options1", value: 1 },
{ label: "options2", value: 2 },
{ label: "options3", value: 3 },
],
},
],
};
Expand All @@ -99,15 +118,15 @@ describe("<FormRenderer/>", () => {
});

test("should call setFormState once when checkbox is clicked", async () => {
const checkbox = await screen.findByTestId("checkbox_1");
const checkbox = await screen.findByTestId(`checkbox_options1`);
expect(checkbox.getAttribute("data-state")).toBe("unchecked");

fireEvent.click(checkbox);
expect(setFormState).toHaveBeenCalledTimes(1);
});

test("should call setFormState twice when checkbox is clicked twice", async () => {
const checkbox = await screen.findByTestId("checkbox_1");
const checkbox = await screen.findByTestId("checkbox_options1");

fireEvent.click(checkbox);
expect(setFormState).toHaveBeenCalledTimes(1);
Expand All @@ -117,14 +136,14 @@ describe("<FormRenderer/>", () => {
});

test("should call setFormState with appropriate values", () => {
const checkboxes = [1, 2, 3];
const checkboxes = [{ label: "options1" }];

checkboxes.forEach((checkbox) => {
fireEvent.click(screen.getByTestId(`checkbox_${checkbox}`));
fireEvent.click(screen.getByTestId(`checkbox_${checkbox.label}`));

expect(setFormState).toHaveBeenCalledWith({
...formState,
"test-question-checkbox": [checkbox],
"test-question-checkbox": [{ value: true }],
});
});
});
Expand Down

0 comments on commit b2d2546

Please sign in to comment.