Skip to content

Commit

Permalink
improve
Browse files Browse the repository at this point in the history
  • Loading branch information
KishiTheMechanic committed Oct 28, 2024
1 parent d8359ed commit f24017e
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 9 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ Adjusts the `<html>` 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 (
<button onClick={toggleTheme}>
Switch to {theme === 'dark' ? 'Light' : 'Dark'} Mode
</button>
)
}
```

## Contributing

Bug reports and pull requests are welcome on GitHub at
Expand Down
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
39 changes: 31 additions & 8 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<html>` 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 <html> element
document.documentElement.classList.toggle('dark', newTheme === 'dark')
}

// Update the signal value
theme.value = newTheme
}

return { theme: theme.value, setTheme }
}

0 comments on commit f24017e

Please sign in to comment.