From f24017eb6dd815c1324343cd068c92bb932ad02c Mon Sep 17 00:00:00 2001 From: KishiTheMechanic Date: Mon, 28 Oct 2024 04:11:07 +0100 Subject: [PATCH] improve --- README.md | 21 +++++++++++++++++++++ deno.json | 2 +- mod.ts | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3b1e184..4de56f0 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,27 @@ Adjusts the `` element to reflect the new theme. - **Parameters**: - `newTheme` - The desired theme, either `'dark'` or `'light'`. +### useTheme hook + +```typescript +import { useTheme } from 'jsr:@elsoul/fresh-theme' + +function ThemeToggleButton() { + const { theme, setTheme } = useTheme() + + const toggleTheme = () => { + const newTheme = theme === 'dark' ? 'light' : 'dark' + setTheme(newTheme) + } + + return ( + + ) +} +``` + ## Contributing Bug reports and pull requests are welcome on GitHub at diff --git a/deno.json b/deno.json index 6636330..0e75931 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@elsoul/fresh-theme", - "version": "1.0.4", + "version": "1.0.5", "description": "Theme Module for Fresh v2 App.", "runtimes": ["deno", "browser"], "exports": "./mod.ts", diff --git a/mod.ts b/mod.ts index a278bd6..59a73d1 100644 --- a/mod.ts +++ b/mod.ts @@ -73,27 +73,50 @@ export function setTheme(newTheme: 'dark' | 'light'): void { /** * Custom hook to manage the theme (light or dark) based on localStorage. - * Returns the current theme value. + * Provides a function to set the theme and returns the current theme value. * - * @returns {'dark' | 'light'} The current theme. + * @returns {{ theme: 'dark' | 'light', setTheme: (newTheme: 'dark' | 'light') => void }} + * An object containing the current theme and a function to set the theme. */ -export function useTheme(): 'dark' | 'light' { +export function useTheme() { const theme = useSignal<'dark' | 'light'>( - localStorage.getItem('theme') as 'dark' | 'light' || 'dark', + (localStorage.getItem('theme') as 'dark' | 'light') || 'dark', ) useEffect(() => { const handleStorageChange = () => { - theme.value = localStorage.getItem('theme') as 'dark' | 'light' || 'dark' + theme.value = (localStorage.getItem('theme') as 'dark' | 'light') || + 'dark' } - globalThis.addEventListener('themeLocalStorage', handleStorageChange) + // Add listener for storage changes (works across tabs) + globalThis.addEventListener('storage', handleStorageChange) // Cleanup the event listener on unmount return () => { - globalThis.removeEventListener('themeLocalStorage', handleStorageChange) + globalThis.removeEventListener('storage', handleStorageChange) } }, []) - return theme.value + /** + * Sets the theme to either 'dark' or 'light' mode and saves the choice in localStorage. + * When a user toggles the theme, this function updates the theme in localStorage + * and adjusts the `dark` class on the `` element. + * + * @param {'dark' | 'light'} newTheme - The theme to set, either 'dark' or 'light'. + */ + const setTheme = (newTheme: 'dark' | 'light'): void => { + localStorage.setItem('theme', newTheme) + + // If running in a client environment with document access + if (globalThis.document) { + // Apply or remove the 'dark' class on the element + document.documentElement.classList.toggle('dark', newTheme === 'dark') + } + + // Update the signal value + theme.value = newTheme + } + + return { theme: theme.value, setTheme } }