From d834231132032b080344863fade6d18dad44d706 Mon Sep 17 00:00:00 2001 From: Matthew Wilcoxson Date: Wed, 18 Dec 2024 17:02:15 +0000 Subject: [PATCH] Colour scheme switcher. --- src/components/ColourSchemeButton.stories.tsx | 23 ++++++++ src/components/ColourSchemeButton.test.tsx | 52 +++++++++++++++++++ src/components/ColourSchemeButton.tsx | 41 +++++++++++++++ src/index.ts | 3 +- src/utils/globals.ts | 1 + 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/components/ColourSchemeButton.stories.tsx create mode 100644 src/components/ColourSchemeButton.test.tsx create mode 100644 src/components/ColourSchemeButton.tsx create mode 100644 src/utils/globals.ts diff --git a/src/components/ColourSchemeButton.stories.tsx b/src/components/ColourSchemeButton.stories.tsx new file mode 100644 index 0000000..65e8447 --- /dev/null +++ b/src/components/ColourSchemeButton.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { ColourSchemeButton } from "./ColourSchemeButton"; + + +const meta: Meta = { + title: "SciReactUI/Control/ColorSchemeButton", + component: ColourSchemeButton, + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: 'Switch between dark and light modes.' + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const LightSelected: Story = { + args: {} +}; \ No newline at end of file diff --git a/src/components/ColourSchemeButton.test.tsx b/src/components/ColourSchemeButton.test.tsx new file mode 100644 index 0000000..6021293 --- /dev/null +++ b/src/components/ColourSchemeButton.test.tsx @@ -0,0 +1,52 @@ +import "@testing-library/jest-dom"; +import { render, fireEvent } from "@testing-library/react"; + +import { ColourSchemeButton } from "./ColourSchemeButton"; +import {ColourSchemes} from "../utils/globals"; + +let mockSetColorScheme = jest.fn() +jest.mock("@mui/material", () => { + return { + ...jest.requireActual("@mui/material"), + useColorScheme: jest.fn().mockReturnValue({ + colorScheme: jest.requireActual("../utils/globals").ColourSchemes.Dark, + setColorScheme: (scheme : ColourSchemes) => mockSetColorScheme(scheme) + }) + }; +}) + +describe("ColourSchemeButton", () => { + + it("should render without errors", () => { + render(); + }); + + it("should show dark icon and button", () => { + const {getByTestId, getByRole} = render(); + + const button = getByRole("button") + expect(button).toBeInTheDocument() + + const icon = getByTestId("BedtimeIcon") + expect(icon).toBeInTheDocument() + }); + + it("should change colour scheme on click", () => { + const {getByRole} = render(); + + const button = getByRole("button") + fireEvent.click(button); + + expect(mockSetColorScheme).toHaveBeenCalledWith(ColourSchemes.Light) + }); + + it("should call local onclick when button clicked", () => { + const mockOnClick = jest.fn(); + const {getByRole} = render(); + + const button = getByRole("button") + fireEvent.click(button); + + expect(mockOnClick).toHaveBeenCalled() + }); +}) \ No newline at end of file diff --git a/src/components/ColourSchemeButton.tsx b/src/components/ColourSchemeButton.tsx new file mode 100644 index 0000000..85a39cb --- /dev/null +++ b/src/components/ColourSchemeButton.tsx @@ -0,0 +1,41 @@ +import {useColorScheme, useTheme} from "@mui/material"; +import {IconButton, IconButtonProps} from "@mui/material"; +import {LightMode, Bedtime} from "@mui/icons-material"; + +import {ColourSchemes} from "../utils/globals"; + +const ColourSchemeButton = (props: IconButtonProps)=> { + const theme = useTheme(); + const {colorScheme: colourScheme, setColorScheme: setColourScheme} = useColorScheme() + + if( !colourScheme ) return undefined; + + const isDark = () : boolean => colourScheme === ColourSchemes.Dark + + return { + setColourScheme( isDark() ? ColourSchemes.Light : ColourSchemes.Dark ) + if( props.onClick ) props.onClick(event) + }} + > + { isDark() ? : } + +}; + +export type {IconButtonProps}; +export {ColourSchemeButton}; diff --git a/src/index.ts b/src/index.ts index eee9b6a..0b4b2c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,8 @@ // components export * from "./components/Breadcrumbs"; -export * from "./components/Navbar"; +export * from "./components/ColourSchemeButton"; export * from "./components/Footer"; +export * from "./components/Navbar"; export * from "./components/User"; export * from "./components/VisitInput"; export * from "./components/ImageColorSchemeSwitch"; diff --git a/src/utils/globals.ts b/src/utils/globals.ts new file mode 100644 index 0000000..d1c09fd --- /dev/null +++ b/src/utils/globals.ts @@ -0,0 +1 @@ +export enum ColourSchemes { Light="light", Dark="dark" } \ No newline at end of file