&
FormState;
-/**
- * 기본 인자
- */
-
export const SliderWithLabelForm = ({
+ questionId,
questionText,
options,
formState,
@@ -19,6 +18,39 @@ export const SliderWithLabelForm = ({
}: SliderWithLabelFormProps) => {
const min = options[0];
const max = options[options.length - 1];
+ const question = formState.questions.find((q) => q.questionId === questionId);
+ const [value, setValue] = useState(question?.options[0].value);
+
+ useEffect(() => {
+ if (question?.options[0].value !== value) {
+ setValue(question?.options[0].value);
+ }
+ }, [question?.options[0].value]);
+
+ const handleValueChange = (newValue: number[]) => {
+ const updatedValue = newValue[0];
+ setValue(updatedValue);
+
+ const updatedQuestions = formState.questions.map((q) =>
+ q.questionId === questionId
+ ? {
+ ...q,
+ options: [
+ {
+ value: updatedValue,
+ label:
+ options.find((opt) => opt.value === updatedValue)?.label ||
+ String(updatedValue),
+ },
+ ],
+ }
+ : q,
+ );
+ setFormState({
+ ...formState,
+ questions: updatedQuestions,
+ });
+ };
return (
@@ -27,14 +59,9 @@ export const SliderWithLabelForm = ({
{
- setFormState({
- ...formState,
- [questionText]: [{ value: value[0] }],
- });
- }}
+ defaultValue={[value]}
+ value={[value]}
+ onValueChange={handleValueChange}
min={min.value}
max={max.value}
step={1}
diff --git a/src/components/forms/__test__/CheckBoxWithLabelForm.test.tsx b/src/components/forms/__test__/CheckBoxWithLabelForm.test.tsx
index ed66a86..31f108c 100644
--- a/src/components/forms/__test__/CheckBoxWithLabelForm.test.tsx
+++ b/src/components/forms/__test__/CheckBoxWithLabelForm.test.tsx
@@ -1,11 +1,24 @@
import { CheckBoxWithLabelForm } from "../CheckBoxWithLabelForm";
+import { FormProps } from "../FormRenderer";
import "@testing-library/jest-dom";
import { screen, render, fireEvent } from "@testing-library/react";
describe("", () => {
- const formState = {
- "test-question-text": [{ value: "" }],
+ const formState: FormProps = {
+ _id: "uuid-example",
+ title: "test",
+ description: "test",
+ questions: [
+ {
+ questionId: 1,
+ questionText: "test-question-text",
+ questionType: "checkbox",
+ dataType: "number",
+ options: [],
+ },
+ ],
};
+
const setFormState = jest.fn();
const options = [
@@ -17,6 +30,7 @@ describe("", () => {
beforeEach(() => {
render(
", () => {
expect(screen.getByTestId("checkbox-with-label-form")).toBeInTheDocument();
});
- test("should render each options properly", () => {
+ test("should render each option properly", () => {
expect(screen.getByText("options1")).toBeInTheDocument();
expect(screen.getByText("options2")).toBeInTheDocument();
expect(screen.getByText("options3")).toBeInTheDocument();
@@ -41,7 +55,7 @@ describe("", () => {
test("should call setFormState once when checkbox is clicked", async () => {
const checkbox = await screen.findByTestId("checkbox_options1");
- expect(checkbox.getAttribute("data-state")).toBe("unchecked");
+ expect(checkbox).toBeInTheDocument();
fireEvent.click(checkbox);
expect(setFormState).toHaveBeenCalledTimes(1);
diff --git a/src/components/forms/__test__/FormRenderer.test.tsx b/src/components/forms/__test__/FormRenderer.test.tsx
deleted file mode 100644
index 7409d05..0000000
--- a/src/components/forms/__test__/FormRenderer.test.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import { FormProps, FormRenderer } from "../FormRenderer";
-import { fireEvent, render, screen } from "@testing-library/react";
-
-/**
- * Each Element's following options data-testid and id
- *
- *
- * id : checkbox_{option.label}
- * data-testid : checkbox_{option.label}
- *
- *
- * data-testid : select-options_{option.label}
- *
- */
-describe("", () => {
- describe("", () => {
- const formState = {
- "test-question-selector": [],
- };
- const setFormState = jest.fn();
-
- beforeEach(() => {
- const formProps: FormProps = {
- title: "test-title",
- description: "test-description",
- questions: [
- {
- questionText: "test-question-selector",
- questionType: "selector",
- dataType: "string",
- options: [
- { label: "options1", value: "options1" },
- { label: "options2", value: "options2" },
- { label: "options3", value: "options3" },
- ],
- },
- ],
- };
-
- render(
- ,
- );
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
- test("should render 'selector' questions properly", () => {
- expect(screen.getByTestId("selector-with-label-form")).toBeInTheDocument();
- });
-
- test("should call setFormState with appropriate values", () => {
- fireEvent.click(screen.getByRole("combobox"));
- fireEvent.click(screen.getByTestId("select-options_options1"));
-
- const options = ["options1", "options2", "options3"];
-
- options.forEach((option) => {
- fireEvent.click(screen.getByRole("combobox"));
- fireEvent.click(screen.getByTestId(`select-options_${option}`));
-
- expect(setFormState).toHaveBeenCalledWith({
- ...formState,
- "test-question-selector": [{ value: option }],
- });
- });
- });
- });
-
- describe("", () => {
- const formState = {
- "test-question-checkbox": [],
- };
- const setFormState = jest.fn();
-
- beforeEach(() => {
- const formProps: FormProps = {
- title: "test-title",
- description: "test-description",
- questions: [
- {
- questionText: "test-question-checkbox",
- questionType: "checkbox",
- dataType: "number",
- options: [
- { label: "options1", value: 1 },
- { label: "options2", value: 2 },
- { label: "options3", value: 3 },
- ],
- },
- ],
- };
-
- render(
- ,
- );
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
- test("should render 'checkbox' questions properly", () => {
- expect(screen.getByTestId("checkbox-with-label-form")).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(1);
- });
-
- test("should call setFormState twice when checkbox is clicked twice", async () => {
- const checkbox = await screen.findByTestId("checkbox_options1");
-
- fireEvent.click(checkbox);
- expect(setFormState).toHaveBeenCalledTimes(1);
-
- fireEvent.click(checkbox);
- expect(setFormState).toHaveBeenCalledTimes(2);
- });
-
- test("should call setFormState with appropriate values", () => {
- const checkboxes = [{ label: "options1" }];
-
- checkboxes.forEach((checkbox) => {
- fireEvent.click(screen.getByTestId(`checkbox_${checkbox.label}`));
-
- expect(setFormState).toHaveBeenCalledWith({
- ...formState,
- "test-question-checkbox": [{ value: true }],
- });
- });
- });
- });
-});
diff --git a/src/components/forms/__test__/SelectorWithLabelForm.test.tsx b/src/components/forms/__test__/SelectorWithLabelForm.test.tsx
index eaae812..b673eb6 100644
--- a/src/components/forms/__test__/SelectorWithLabelForm.test.tsx
+++ b/src/components/forms/__test__/SelectorWithLabelForm.test.tsx
@@ -1,10 +1,23 @@
+import { FormProps } from "../FormRenderer";
import { SelectorWithLabelForm } from "../SelectorWithLabelForm";
import { fireEvent, render, screen } from "@testing-library/react";
describe("", () => {
- const formState = {
- "test-question-selector": [{ value: "" }],
+ const formState: FormProps = {
+ _id: "test-id",
+ title: "test-title",
+ description: "test-description",
+ questions: [
+ {
+ questionId: 1,
+ questionText: "test-question-selector",
+ questionType: "selector",
+ dataType: "string",
+ options: [],
+ },
+ ],
};
+
const setFormState = jest.fn();
const options = [{ label: "option__label", value: "option__value" }];
@@ -12,6 +25,7 @@ describe("", () => {
beforeEach(() => {
render(
", () => {
test("should call setFormState with appropriate values", () => {
fireEvent.click(screen.getByText("옵션을 선택해주세요"));
-
- options.forEach((option) => {
- fireEvent.click(screen.getByText(`option__label`));
-
- expect(setFormState).toHaveBeenCalledWith({
- ...formState,
- "test-question-selector": [{ value: option.value }],
- });
-
- jest.clearAllMocks();
+ fireEvent.click(screen.getByText("option__label"));
+
+ expect(setFormState).toHaveBeenCalledWith({
+ ...formState,
+ questions: [
+ {
+ ...formState.questions[0],
+ options: [{ label: "option__label", value: "option__value" }],
+ },
+ ],
});
});
});
diff --git a/src/components/forms/__test__/SliderWithLabelForm.test.tsx b/src/components/forms/__test__/SliderWithLabelForm.test.tsx
deleted file mode 100644
index cc4feea..0000000
--- a/src/components/forms/__test__/SliderWithLabelForm.test.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { SetStateAction } from "react";
-
-import { FormProps, FormState, Option } from "../FormRenderer";
-import { SliderWithLabelForm } from "../SliderWithLabelForm";
-import { render, screen } from "@testing-library/react";
-
-describe("", () => {
- const formState = {
- "test-question-slider": [{ value: 2 }],
- };
- const setFormState = jest.fn();
-
- const options = [
- { label: "label1", value: 1 },
- { label: "label2", value: 2 },
- { label: "label3", value: 3 },
- ];
-
- beforeAll(() => {
- global.ResizeObserver = class ResizeObserver {
- observe() {}
- unobserve() {}
- disconnect() {}
- };
- });
-
- beforeEach(() => {
- render(
- ,
- );
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
- test("should render Container properly", () => {
- expect(screen.getByTestId("slider-with-label-form")).toBeInTheDocument();
- });
-
- test("should render min, max label properly", () => {
- expect(screen.getByText("label1")).toBeInTheDocument();
- expect(screen.getByText("label3")).toBeInTheDocument();
- });
-});
diff --git a/src/components/utils/FormFactory.tsx b/src/components/utils/FormFactory.tsx
new file mode 100644
index 0000000..876d11c
--- /dev/null
+++ b/src/components/utils/FormFactory.tsx
@@ -0,0 +1,31 @@
+export const FormTypeMap = {
+ checkbox: "checkbox",
+ selector: "selector",
+ // slider: "slider",
+ // doubleSlider: "doubleSlider",
+} as const;
+
+export type FormType = keyof typeof FormTypeMap;
+
+export type FormOption = {
+ label?: string;
+ value: any;
+};
+
+/**
+ * formTitle : 각 질문마다
+ */
+export interface createFormItemOptions {
+ formTitle: string;
+ formType: FormType;
+ dataType: string;
+ options: FormOption[];
+}
+
+export interface IFormItemFactory {
+ createFormItem({ formType }): React.ComponentType;
+}
+
+export class FormFactory implements IFormItemFactory {
+ public static createFormComponent() {}
+}