Skip to content

Commit

Permalink
refactor: CheckBoxWithLabelForm fit into Question Schema
Browse files Browse the repository at this point in the history
  • Loading branch information
toothlessdev committed Nov 21, 2024
1 parent 882dc6f commit b61a0fb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 28 deletions.
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const config: JestConfigWithTsJest = {
moduleNameMapper: {
"^.+\\.svg$": "jest-svg-transformer",
"\\.(css|less|sass|scss)$": "identity-obj-proxy",
"@/(.*)$": "<rootDir>/src/$1",
},
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
globals: {
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"test": "jest --config jest.config.ts"
},
"dependencies": {
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-checkbox": "^1.1.2",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-popover": "^1.1.2",
Expand All @@ -33,6 +34,7 @@
"react-dom": "^18.3.1",
"react-redux": "^9.1.2",
"react-router-dom": "^6.28.0",
"recharts": "^2.13.3",
"tailwind-merge": "^2.5.4",
"tailwindcss-animate": "^1.0.7",
"vaul": "^1.1.1"
Expand All @@ -49,6 +51,7 @@
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
"add": "^2.0.6",
"autoprefixer": "^10.4.20",
"eslint": "^9.13.0",
"eslint-plugin-react-hooks": "^5.0.0",
Expand Down
63 changes: 36 additions & 27 deletions src/components/forms/CheckBoxWithLabelForm.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,57 @@
import { useEffect, useState } from "react";
import { useState } from "react";

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

import { FormState, Question } from "./Form";

export type CheckBoxItem = {
id: string;
label: string;
};

export interface RadioWithLabelFormProps {
label: string;
items: CheckBoxItem[];
checkedValues: string[];
onCheckedValuesChange?: (checkedIds: string[]) => void;
}
// prettier-ignore
export type CheckBoxWithLabelFormProps =
Omit<Question<string>, "questionType" | "dataType"> &
FormState;

export const CheckBoxWithLabelForm = ({
label,
items,
checkedValues,
onCheckedValuesChange,
}: RadioWithLabelFormProps) => {
const [checked, setChecked] = useState<string[]>(checkedValues);

useEffect(() => {
onCheckedValuesChange && onCheckedValuesChange(checked);
}, [checked]);

questionText,
options,
formState,
setFormState,
}: CheckBoxWithLabelFormProps) => {
return (
<div className="flex flex-col gap-1">
<p className="font-bold">{label}</p>
<div className="flex flex-col gap-1" data-testid="checkbox-with-label-form">
<p className="font-bold">{questionText}</p>

{items.map((item) => {
{options.map((option, index) => {
return (
<div className="flex items-center gap-1">
<div key={index} className="flex items-center gap-1">
<Checkbox
id={item.id}
data-testid={`checkbox_${option}`}
id={`checkbox_${option}`}
className="block w-5 h-5"
checked={checked.includes(item.id)}
checked={(formState[questionText] as Array<string>).includes(option)}
onCheckedChange={(isChecked) => {
if (isChecked) setChecked([...checked, item.id]);
else setChecked(checked.filter((id) => id !== item.id));
if (isChecked) {
setFormState({
...formState,
[questionText]: [
...(formState[questionText] as Array<string>),
option,
],
});
} else {
setFormState({
...formState,
[questionText]: (
formState[questionText] as Array<string>
).filter((item) => item !== option),
});
}
}}
/>
<label htmlFor={item.id}>{item.label}</label>
<label htmlFor={`checkbox_${option}`}>{option}</label>
</div>
);
})}
Expand Down
41 changes: 41 additions & 0 deletions src/components/forms/__test__/form-element.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { CheckBoxWithLabelForm } from "../CheckBoxWithLabelForm";
import "@testing-library/jest-dom";
import { fireEvent, render, screen } from "@testing-library/react";

describe("FormElements", () => {
describe("<CheckBoxWithLabelForm/>", () => {
const formState = {
"test-question-text": [],
};
const setFormState = jest.fn();

beforeEach(() => {
render(
<CheckBoxWithLabelForm
questionText={"test-question-text"}
options={["options1", "options2", "options3"]}
formState={formState}
setFormState={setFormState}
/>,
);
});

test("should render Container properly", () => {
expect(screen.getByTestId("checkbox-with-label-form")).toBeInTheDocument();
});

test("should render each options properly", () => {
expect(screen.getByText("options1")).toBeInTheDocument();
expect(screen.getByText("options2")).toBeInTheDocument();
expect(screen.getByText("options3")).toBeInTheDocument();
});

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

fireEvent.click(checkbox);
expect(setFormState).toHaveBeenCalledTimes(2);
});
});
});
2 changes: 1 addition & 1 deletion tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"typeRoots": ["node_modules/@types", "src/@types"],
"types": ["jest"],
"types": ["jest", "@testing-library/jest-dom"],

"esModuleInterop": true,
"jsx": "react-jsx",
Expand Down

0 comments on commit b61a0fb

Please sign in to comment.