Skip to content

Commit 8bc1cf1

Browse files
authored
Merge pull request #45 from olafsulich/develop
✨ Add useTheme hook
2 parents 7448aa7 + 7a15c4b commit 8bc1cf1

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282

8383
- [`useMeasure`](./docs/useMeasure.md) — gives sizes of an element and its position
8484

85+
- [`useTheme`](./docs/useTheme.md) — dynamically change the appearance of your app using CSS variables with light/dark mode.
86+
8587
<br />
8688

8789
## Technologies

docs/useTheme.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# `useEventListener`
2+
3+
This hook helps you implement light/dark mode in your app, based on prefers-color-scheme and localStorage.
4+
5+
## Usage
6+
7+
Component:
8+
9+
```jsx
10+
import { useEventListener } from 'use-haki';
11+
12+
const App = () => {
13+
const [theme, setTheme] = useTheme();
14+
15+
return (
16+
<section>
17+
<h2>Current theme: {theme}</h2>
18+
<button onClick={() => setTheme('dark')}>Set dark theme<button>
19+
<button onClick={() => setTheme('light')}>Set light theme<button>
20+
<section />
21+
)
22+
};
23+
```
24+
25+
CSS:
26+
27+
```css
28+
html[data-theme='dark'] {
29+
--text-color: #f0f0f0;
30+
--background-body: #1c1c1c;
31+
--other-var: #111111;
32+
}
33+
34+
html[data-theme='light'] {
35+
--text-color: #111111;
36+
--background-body: #fafafa;
37+
--other-var: #ffffff;
38+
}
39+
40+
body {
41+
color: var(--text-color);
42+
background-color: var(--background-body);
43+
}
44+
```
45+
46+
## Reference
47+
48+
```ts
49+
const [theme, setTheme] = useTheme();
50+
```
51+
52+
- **theme** - current theme, based on prefers-color-scheme
53+
- **setTheme** - function that set theme

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ export { default as useDateTimeFormat } from './useDateTimeFormat';
1717
export { default as usePluralRules } from './usePluralRules';
1818
export { default as useIntersection } from './useIntersection';
1919
export { default as useMeasure } from './useMeasure';
20+
export { default as useTheme } from './useTheme';

src/useTheme.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { useState, useLayoutEffect } from 'react';
2+
3+
const preferDarkSchema = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
4+
const defaultTheme = preferDarkSchema ? 'dark' : 'light';
5+
6+
const useTheme = () => {
7+
const [theme, setTheme] = useState(localStorage.getItem('theme') || defaultTheme);
8+
9+
useLayoutEffect(() => {
10+
document.documentElement.setAttribute('data-theme', theme);
11+
localStorage.setItem('theme', theme);
12+
}, [theme]);
13+
14+
return [theme, setTheme];
15+
};
16+
17+
export default useTheme;

0 commit comments

Comments
 (0)