diff --git a/src/components/ToggleSwitch/__test__/ToggleSwitch.spec.tsx b/src/components/ToggleSwitch/__test__/ToggleSwitch.spec.tsx new file mode 100644 index 00000000..249c06ac --- /dev/null +++ b/src/components/ToggleSwitch/__test__/ToggleSwitch.spec.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import { render } from "@testing-library/react"; +import { ToggleSwitch } from ".."; +import userEvent from "@testing-library/user-event"; + +describe("ToggleSwitch Component", () => { + it("should renders with correct value passed as prop", () => { + const { getByRole, rerender } = render(); + const toggleSwitch = getByRole("checkbox"); + expect(toggleSwitch).toBeChecked(); + rerender(); + expect(toggleSwitch).not.toBeChecked(); + }); + + it("should be set to false when no value prop is provided", () => { + const { getByRole } = render(); + const toggleSwitch = getByRole("checkbox"); + expect(toggleSwitch).not.toBeChecked(); + }); + it("should update the value when user clicks on it", async () => { + const { getByRole } = render(); + const toggleSwitch = getByRole("checkbox"); + expect(toggleSwitch).not.toBeChecked(); + await userEvent.click(toggleSwitch); + expect(toggleSwitch).toBeChecked(); + }); + + it("should call the onChange prop when user clicks on it", async () => { + const mockedOnChange = jest.fn(); + const { getByRole } = render(); + const toggleSwitch = getByRole("checkbox"); + await userEvent.click(toggleSwitch); + expect(mockedOnChange).toHaveBeenCalled(); + }); + + + it("should apply wrapperClassName and className correctly", () => { + const { container } = render( + + ); + const wrapper = container.querySelector(".deriv-toggle-switch.wrapper-class"); + expect(wrapper).toBeInTheDocument(); + const input = wrapper?.querySelector("input"); + expect(input).toHaveClass("custom-class"); + }); + + it("applies wrapperStyle and style correctly", () => { + const { container } = render( + + ); + const input = container.querySelector(".deriv-toggle-switch input"); + expect(input).toHaveStyle({ fontSize: "16px" }); + const label = input?.parentElement; + expect(label).toHaveStyle({ backgroundColor: "red" }); + }); +}); diff --git a/src/components/ToggleSwitch/index.tsx b/src/components/ToggleSwitch/index.tsx index ebdebe6a..97bba2b9 100644 --- a/src/components/ToggleSwitch/index.tsx +++ b/src/components/ToggleSwitch/index.tsx @@ -1,11 +1,11 @@ -import React, { ChangeEvent, forwardRef } from "react"; +import React, { ChangeEvent, forwardRef, useEffect, useState } from "react"; import clsx from "clsx"; import { Input } from "../Input"; import "./ToggleSwitch.scss"; interface ToggleSwitchProps { - onChange: (event: ChangeEvent) => void; - value: boolean; + onChange?: (event: ChangeEvent) => void; + value?: boolean; wrapperClassName?: React.ComponentProps["wrapperClassName"]; className?: React.ComponentProps["className"]; wrapperStyle?: React.CSSProperties; @@ -14,22 +14,44 @@ interface ToggleSwitchProps { export const ToggleSwitch = forwardRef( ( - { onChange, value, wrapperClassName, className, wrapperStyle, style }, + { + onChange, + value = false, + wrapperClassName, + className, + wrapperStyle, + style, + }, ref, - ) => ( - - ), + ) => { + const [isChecked, setIsChecked] = useState(value); + + useEffect(() => { + if (value !== undefined) { + setIsChecked(value); + } + }, [value]); + + const onClickHandler = (event: ChangeEvent) => { + setIsChecked(!isChecked); + onChange?.(event); + }; + + return ( + + ); + }, ); diff --git a/stories/ToggleSwitch.stories.ts b/stories/ToggleSwitch.stories.ts index 21d402c3..e688a354 100644 --- a/stories/ToggleSwitch.stories.ts +++ b/stories/ToggleSwitch.stories.ts @@ -5,6 +5,7 @@ import { ToggleSwitch } from "../src/components/ToggleSwitch"; const meta = { title: "Components/ToggleSwitch", component: ToggleSwitch, + tags: ["autodocs"], args: { onChange: action("ToggleSwitch changed"), value: false, @@ -22,9 +23,3 @@ export const Default: Story = { }, }; -export const Checked: Story = { - args: { - ...Default.args, - value: true, - }, -};