@pshah-lab/themeswitcher 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +161 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,18 +1,104 @@
|
|
|
1
|
-
|
|
1
|
+
# @pshah-lab/themeswitcher
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A lightweight, framework-agnostic theme manager for **light**, **dark**, and **system** modes — with **SSR-safe no-flash support**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Designed to be:
|
|
6
|
+
- Minimal
|
|
7
|
+
- Predictable
|
|
8
|
+
- Copy-paste friendly
|
|
9
|
+
- Framework independent
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
• The script runs before first paint
|
|
9
|
-
• It applies the correct theme synchronously
|
|
10
|
-
• It works even before your JavaScript bundle loads
|
|
11
|
-
• This is required for SSR and strongly recommended for all setups
|
|
11
|
+
---
|
|
12
12
|
|
|
13
|
+
## Features
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
- Light / Dark / System theme support
|
|
16
|
+
- Prevents flash of incorrect theme (FOUC)
|
|
17
|
+
- SSR-safe (works before JS bundle loads)
|
|
18
|
+
- No dependencies
|
|
19
|
+
- Fully typed (TypeScript)
|
|
20
|
+
- Works with plain JS, React, Vue, or any framework
|
|
15
21
|
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
```bash
|
|
26
|
+
npm install @pshah-lab/themeswitcher
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Core Usage (Framework-agnostic)
|
|
32
|
+
```javascript
|
|
33
|
+
import { createThemeManager } from "@pshah-lab/themeswitcher";
|
|
34
|
+
|
|
35
|
+
const theme = createThemeManager();
|
|
36
|
+
|
|
37
|
+
theme.set("dark"); // "light" | "dark" | "system"
|
|
38
|
+
theme.toggle(); // toggle light ↔ dark
|
|
39
|
+
theme.get(); // resolved theme: "light" | "dark"
|
|
40
|
+
theme.getMode(); // selected mode
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The theme is applied to the document using a data attribute:
|
|
44
|
+
```html
|
|
45
|
+
<html data-theme="dark">
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Style your app using this attribute:
|
|
49
|
+
```css
|
|
50
|
+
[data-theme="dark"] {
|
|
51
|
+
background: #000;
|
|
52
|
+
color: #fff;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## React Usage
|
|
59
|
+
|
|
60
|
+
Create the hook once at module scope.
|
|
61
|
+
```typescript
|
|
62
|
+
// theme.ts
|
|
63
|
+
import { createUseTheme } from "@pshah-lab/themeswitcher";
|
|
64
|
+
|
|
65
|
+
export const useTheme = createUseTheme();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use it anywhere in your app:
|
|
69
|
+
```jsx
|
|
70
|
+
function ThemeToggle() {
|
|
71
|
+
const { theme, toggleTheme } = useTheme();
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<button onClick={toggleTheme}>
|
|
75
|
+
Current theme: {theme}
|
|
76
|
+
</button>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
⚠️ **Do not call `createUseTheme()` inside components.**
|
|
82
|
+
It must be created once and reused.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Prevent Theme Flash (Recommended)
|
|
87
|
+
|
|
88
|
+
When using light/dark themes, browsers may briefly render the page in the default theme before JavaScript loads. This causes a visible flash of incorrect theme.
|
|
89
|
+
|
|
90
|
+
To prevent this, add the following script inline in your HTML `<head>`, before any CSS is loaded.
|
|
91
|
+
|
|
92
|
+
### Why this is needed
|
|
93
|
+
|
|
94
|
+
- Runs before first paint
|
|
95
|
+
- Applies the correct theme synchronously
|
|
96
|
+
- Works before your JavaScript bundle loads
|
|
97
|
+
- Required for SSR
|
|
98
|
+
- Strongly recommended for all setups
|
|
99
|
+
|
|
100
|
+
### Add this to `<head>`
|
|
101
|
+
```html
|
|
16
102
|
<script>
|
|
17
103
|
(function () {
|
|
18
104
|
try {
|
|
@@ -42,22 +128,80 @@ Add this to <head>
|
|
|
42
128
|
}
|
|
43
129
|
})();
|
|
44
130
|
</script>
|
|
131
|
+
```
|
|
45
132
|
|
|
46
|
-
Place
|
|
47
|
-
|
|
133
|
+
Place it before your CSS:
|
|
134
|
+
```html
|
|
48
135
|
<head>
|
|
49
136
|
<!-- Prevent theme flash -->
|
|
50
|
-
<script>/* theme script */</script>
|
|
137
|
+
<script>/* pasted theme script */</script>
|
|
51
138
|
|
|
52
139
|
<link rel="stylesheet" href="styles.css" />
|
|
53
140
|
</head>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Important Notes
|
|
144
|
+
|
|
145
|
+
- Do not import this script from the package
|
|
146
|
+
- Do not bundle it
|
|
147
|
+
- Copy-paste is intentional and required for correct timing
|
|
148
|
+
- The script logic matches the internal theme manager
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Configuration
|
|
153
|
+
```javascript
|
|
154
|
+
createThemeManager({
|
|
155
|
+
defaultMode: "system", // default
|
|
156
|
+
storageKey: "theme-mode", // localStorage key
|
|
157
|
+
attribute: "data-theme", // HTML attribute
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## API Reference
|
|
164
|
+
|
|
165
|
+
### `set(mode)`
|
|
166
|
+
|
|
167
|
+
Set the theme mode.
|
|
168
|
+
```javascript
|
|
169
|
+
theme.set("dark");
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `toggle()`
|
|
173
|
+
|
|
174
|
+
Toggle between light and dark.
|
|
175
|
+
```javascript
|
|
176
|
+
theme.toggle();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### `get()`
|
|
180
|
+
|
|
181
|
+
Get the resolved theme.
|
|
182
|
+
```javascript
|
|
183
|
+
theme.get(); // "light" | "dark"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### `getMode()`
|
|
187
|
+
|
|
188
|
+
Get the selected mode.
|
|
189
|
+
```javascript
|
|
190
|
+
theme.getMode(); // "light" | "dark" | "system"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
54
194
|
|
|
195
|
+
## Design Philosophy
|
|
55
196
|
|
|
197
|
+
- Explicit over magical
|
|
198
|
+
- Copy-paste over runtime hacks
|
|
199
|
+
- No global side effects
|
|
200
|
+
- No framework lock-in
|
|
201
|
+
- Predictable behavior
|
|
56
202
|
|
|
203
|
+
---
|
|
57
204
|
|
|
205
|
+
## License
|
|
58
206
|
|
|
59
|
-
|
|
60
|
-
• Do not import this script from the package
|
|
61
|
-
• Do not bundle it
|
|
62
|
-
• Copy-paste is intentional and required for correct timing
|
|
63
|
-
• The script logic matches the internal theme manager
|
|
207
|
+
MIT
|