@asafarim/react-themes 1.8.1-canary.4dcbef8.3 β 1.8.2-canary.b5e58bd.4
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 +217 -348
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
ο»Ώ$ @"
|
|
1
2
|
# @asafarim/react-themes
|
|
2
3
|
|
|
3
4
|
A comprehensive theme management system for React applications with automatic dark/light mode detection, custom theme creation, and smooth transitions.
|
|
@@ -8,105 +9,106 @@ A comprehensive theme management system for React applications with automatic da
|
|
|
8
9
|
|
|
9
10
|
## πΈ Preview
|
|
10
11
|
|
|
11
|
-
Experience the theme system in action with our
|
|
12
|
+
Experience the theme system in action with our Live Interactive Demo:
|
|
13
|
+
|
|
14
|
+
- https://alisafari-it.github.io/react-themes/
|
|
12
15
|
|
|
13
16
|
### π― Demo Showcases
|
|
14
17
|
|
|
15
18
|
The live demo demonstrates all package capabilities:
|
|
16
19
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
20
|
+
- π¨ Theme Switching: Real-time theme transitions between light, dark, and auto modes
|
|
21
|
+
- π§ Component Gallery: All built-in components (ThemeToggle, ThemeSelector) in action
|
|
22
|
+
- π± Responsive Design: How themes adapt across different screen sizes
|
|
23
|
+
- πͺ CSS Variables: Live CSS variable updates and their effects
|
|
24
|
+
- β‘ Performance: Smooth animations and transitions
|
|
25
|
+
- βΏ Accessibility: Keyboard navigation and screen reader support
|
|
23
26
|
|
|
24
27
|
<table>
|
|
25
28
|
<tr>
|
|
26
29
|
<td align="center">
|
|
27
30
|
<img src="./src/react-themes-light.png" alt="Light Theme Preview" width="400"/>
|
|
28
31
|
<br/>
|
|
29
|
-
<em>Light Theme
|
|
32
|
+
<em>Light Theme β Clean and Modern</em>
|
|
30
33
|
</td>
|
|
31
34
|
<td align="center">
|
|
32
35
|
<img src="./src/react-themes-dark.png" alt="Dark Theme Preview" width="400"/>
|
|
33
36
|
<br/>
|
|
34
|
-
<em>Dark Theme
|
|
37
|
+
<em>Dark Theme β Elegant and Eyeβfriendly</em>
|
|
35
38
|
</td>
|
|
36
39
|
</tr>
|
|
37
40
|
</table>
|
|
38
41
|
|
|
39
42
|
### π Try It Live
|
|
40
43
|
|
|
41
|
-
Visit
|
|
44
|
+
Visit https://alisafari-it.github.io/react-themes/ to:
|
|
42
45
|
|
|
43
|
-
1.
|
|
44
|
-
2.
|
|
45
|
-
3.
|
|
46
|
-
4.
|
|
47
|
-
5.
|
|
48
|
-
6.
|
|
46
|
+
1. Interactive Testing: Toggle between themes and see instant changes
|
|
47
|
+
2. Code Examples: View implementation examples for each feature
|
|
48
|
+
3. Performance Metrics: See how fast theme switching works
|
|
49
|
+
4. Integration Examples: Real-world usage with other components
|
|
50
|
+
5. Customization Demo: Examples of custom theme creation
|
|
51
|
+
6. Browser Compatibility: Test across different browsers and devices
|
|
49
52
|
|
|
50
53
|
## β¨ Features
|
|
51
54
|
|
|
52
|
-
### π
|
|
55
|
+
### π Smart Theme Management
|
|
53
56
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
57
|
+
- Auto Detection: Follows system dark/light mode preferences
|
|
58
|
+
- Manual Override: Users can manually select their preferred theme mode
|
|
59
|
+
- Persistence: Remembers user choice across sessions (localStorage)
|
|
60
|
+
- Real-time Updates: Instantly responds to system theme changes
|
|
58
61
|
|
|
59
|
-
### π¨
|
|
62
|
+
### π¨ Advanced Theming System
|
|
60
63
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
64
|
+
- Built-in Themes: Professionally designed light and dark themes
|
|
65
|
+
- Custom Themes: Create unlimited custom themes with full control
|
|
66
|
+
- Theme Merging: Easily extend existing themes with custom properties
|
|
67
|
+
- CSS Variables: Automatic injection of CSS custom properties
|
|
65
68
|
|
|
66
|
-
### β‘
|
|
69
|
+
### β‘ Performance & UX
|
|
67
70
|
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
71
|
+
- Smooth Transitions: Beautiful transitions between theme changes
|
|
72
|
+
- Zero Flicker: Prevents flash of unstyled content during init
|
|
73
|
+
- Lightweight: Minimal bundle size impact (~8KB gzipped)
|
|
74
|
+
- Tree-shakeable: Import only what you need
|
|
72
75
|
|
|
73
|
-
### π§
|
|
76
|
+
### π§ Developer Experience
|
|
74
77
|
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
78
|
+
- TypeScript First: Full type definitions
|
|
79
|
+
- React 18-ready: Works with React 16.8+ (Hooks) and optimized for React 18
|
|
80
|
+
- Hooks API: Intuitive React hooks for theme management
|
|
81
|
+
- Components: Pre-built, accessible components for common use cases
|
|
79
82
|
|
|
80
|
-
### π―
|
|
83
|
+
### π― Integration & Compatibility
|
|
81
84
|
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
85
|
+
- Framework Agnostic: Next.js, Gatsby, CRA, Vite, etc.
|
|
86
|
+
- CSS-in-JS Compatible: styled-components, emotion, etc.
|
|
87
|
+
- Tailwind Ready: Use via CSS variables
|
|
88
|
+
- SSR Support: Hydration-safe with sensible fallbacks
|
|
86
89
|
|
|
87
|
-
### βΏ
|
|
90
|
+
### βΏ Accessibility
|
|
88
91
|
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
- **Reduced Motion**: Respects user's motion preferences
|
|
92
|
+
- WCAG Friendly: High contrast, readable defaults
|
|
93
|
+
- Keyboard Navigation: Full keyboard support
|
|
94
|
+
- Screen Reader Support: Proper ARIA labels
|
|
95
|
+
- Reduced Motion: Respects user preferences
|
|
94
96
|
|
|
95
97
|
## π¦ Installation
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
~~~bash
|
|
98
100
|
npm install @asafarim/react-themes
|
|
99
101
|
# or
|
|
100
102
|
yarn add @asafarim/react-themes
|
|
101
103
|
# or
|
|
102
104
|
pnpm add @asafarim/react-themes
|
|
103
|
-
|
|
105
|
+
~~~
|
|
104
106
|
|
|
105
107
|
## π Quick Start
|
|
106
108
|
|
|
107
|
-
### 1
|
|
109
|
+
### 1) Wrap your app with ThemeProvider
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
~~~tsx
|
|
110
112
|
import React from 'react';
|
|
111
113
|
import { ThemeProvider } from '@asafarim/react-themes';
|
|
112
114
|
import '@asafarim/react-themes/styles.css'; // Optional base styles
|
|
@@ -118,36 +120,35 @@ function App() {
|
|
|
118
120
|
</ThemeProvider>
|
|
119
121
|
);
|
|
120
122
|
}
|
|
121
|
-
|
|
123
|
+
~~~
|
|
122
124
|
|
|
123
|
-
### 2
|
|
125
|
+
### 2) Use the theme in your components
|
|
124
126
|
|
|
125
|
-
|
|
127
|
+
~~~tsx
|
|
126
128
|
import React from 'react';
|
|
127
129
|
import { useTheme, ThemeToggle } from '@asafarim/react-themes';
|
|
128
130
|
|
|
129
131
|
function MyComponent() {
|
|
130
|
-
const { mode, currentTheme
|
|
132
|
+
const { mode, currentTheme } = useTheme();
|
|
131
133
|
|
|
132
134
|
return (
|
|
133
|
-
<div>
|
|
135
|
+
<div style={{ background: currentTheme.colors.background, color: currentTheme.colors.text }}>
|
|
134
136
|
<h1>Current mode: {mode}</h1>
|
|
135
137
|
<ThemeToggle />
|
|
136
|
-
{/* Your component content */}
|
|
137
138
|
</div>
|
|
138
139
|
);
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
+
~~~
|
|
141
142
|
|
|
142
143
|
## π― Use Cases & Examples
|
|
143
144
|
|
|
144
|
-
### π
|
|
145
|
+
### π Real-World Applications
|
|
145
146
|
|
|
146
|
-
|
|
147
|
+
See the demo for these practical implementations:
|
|
147
148
|
|
|
148
|
-
#### π
|
|
149
|
+
#### π Web Applications
|
|
149
150
|
|
|
150
|
-
|
|
151
|
+
~~~tsx
|
|
151
152
|
// E-commerce dashboard with theme switching
|
|
152
153
|
import { ThemeProvider, ThemeToggle } from '@asafarim/react-themes';
|
|
153
154
|
|
|
@@ -158,248 +159,155 @@ function EcommerceDashboard() {
|
|
|
158
159
|
<h1>Sales Dashboard</h1>
|
|
159
160
|
<ThemeToggle size="sm" showLabels={true} />
|
|
160
161
|
</header>
|
|
161
|
-
<main className="dashboard-content">
|
|
162
|
-
{/* Dashboard content adapts automatically */}
|
|
163
|
-
</main>
|
|
162
|
+
<main className="dashboard-content">{/* ... */}</main>
|
|
164
163
|
</ThemeProvider>
|
|
165
164
|
);
|
|
166
165
|
}
|
|
167
|
-
|
|
166
|
+
~~~
|
|
168
167
|
|
|
169
|
-
#### π±
|
|
168
|
+
#### π± Mobile-First Design
|
|
170
169
|
|
|
171
|
-
|
|
170
|
+
~~~css
|
|
172
171
|
/* Responsive design that adapts to theme */
|
|
173
172
|
.mobile-card {
|
|
174
173
|
background: var(--theme-color-background-secondary);
|
|
175
174
|
border: 1px solid var(--theme-color-border);
|
|
176
175
|
padding: var(--theme-spacing-md);
|
|
177
176
|
border-radius: var(--theme-radius-lg);
|
|
178
|
-
|
|
179
|
-
/* Automatic dark mode styling */
|
|
180
|
-
box-shadow: var(--theme-shadow-sm);
|
|
177
|
+
box-shadow: var(--theme-color-shadow, 0 1px 3px 0 rgba(0, 0, 0, 0.1));
|
|
181
178
|
transition: var(--theme-transition-normal);
|
|
182
179
|
}
|
|
183
|
-
|
|
180
|
+
~~~
|
|
184
181
|
|
|
185
|
-
#### π¨
|
|
182
|
+
#### π¨ Design Systems
|
|
186
183
|
|
|
187
|
-
|
|
184
|
+
~~~tsx
|
|
188
185
|
// Integration with component libraries
|
|
189
186
|
import { Button, Card } from 'your-ui-library';
|
|
190
187
|
import { useTheme } from '@asafarim/react-themes';
|
|
191
188
|
|
|
192
189
|
function ThemedComponents() {
|
|
193
190
|
const { currentTheme } = useTheme();
|
|
194
|
-
|
|
195
191
|
return (
|
|
196
|
-
<Card
|
|
197
|
-
style={{
|
|
198
|
-
backgroundColor: currentTheme.colors.background,
|
|
199
|
-
color: currentTheme.colors.text
|
|
200
|
-
}}
|
|
201
|
-
>
|
|
192
|
+
<Card style={{ backgroundColor: currentTheme.colors.background, color: currentTheme.colors.text }}>
|
|
202
193
|
<Button variant={currentTheme.mode === 'dark' ? 'outlined' : 'filled'}>
|
|
203
194
|
Themed Button
|
|
204
195
|
</Button>
|
|
205
196
|
</Card>
|
|
206
197
|
);
|
|
207
198
|
}
|
|
208
|
-
|
|
199
|
+
~~~
|
|
209
200
|
|
|
210
|
-
### π
|
|
201
|
+
### π Advanced Patterns
|
|
211
202
|
|
|
212
|
-
#### πͺ
|
|
203
|
+
#### πͺ Dynamic Theme Loading
|
|
213
204
|
|
|
214
|
-
|
|
215
|
-
// Load themes dynamically based on user preferences
|
|
205
|
+
~~~tsx
|
|
216
206
|
import { createTheme, useTheme } from '@asafarim/react-themes';
|
|
217
207
|
|
|
218
208
|
function DynamicThemeLoader() {
|
|
219
209
|
const { setTheme } = useTheme();
|
|
220
|
-
|
|
221
210
|
const loadUserTheme = async (userId: string) => {
|
|
222
|
-
const
|
|
223
|
-
const themeData = await
|
|
224
|
-
|
|
225
|
-
const customTheme = createTheme(themeData);
|
|
211
|
+
const resp = await fetch(`/api/users/${userId}/theme`);
|
|
212
|
+
const themeData = await resp.json();
|
|
213
|
+
const customTheme = createTheme(lightTheme, themeData);
|
|
226
214
|
setTheme(customTheme);
|
|
227
215
|
};
|
|
228
|
-
|
|
229
216
|
return <div>Loading personalized theme...</div>;
|
|
230
217
|
}
|
|
231
|
-
|
|
218
|
+
~~~
|
|
232
219
|
|
|
233
|
-
#### π’
|
|
220
|
+
#### π’ Multi-Brand Applications
|
|
234
221
|
|
|
235
|
-
|
|
236
|
-
// Switch between different brand themes
|
|
222
|
+
~~~tsx
|
|
237
223
|
const brandThemes = {
|
|
238
|
-
corporate: createTheme(lightTheme, {
|
|
239
|
-
|
|
240
|
-
colors: { primary: '#0066cc', secondary: '#004499' }
|
|
241
|
-
}),
|
|
242
|
-
creative: createTheme(darkTheme, {
|
|
243
|
-
name: 'creative',
|
|
244
|
-
colors: { primary: '#ff6b6b', secondary: '#4ecdc4' }
|
|
245
|
-
})
|
|
224
|
+
corporate: createTheme(lightTheme, { name: 'corporate', colors: { primary: '#0066cc', secondary: '#004499' } }),
|
|
225
|
+
creative: createTheme(darkTheme, { name: 'creative', colors: { primary: '#ff6b6b', secondary: '#4ecdc4' } })
|
|
246
226
|
};
|
|
247
227
|
|
|
248
|
-
<ThemeProvider customThemes={brandThemes}>
|
|
228
|
+
<ThemeProvider customThemes={{ ...brandThemes }}>
|
|
249
229
|
<BrandSwitcher />
|
|
250
230
|
</ThemeProvider>
|
|
251
|
-
|
|
231
|
+
~~~
|
|
252
232
|
|
|
253
233
|
## π API Reference
|
|
254
234
|
|
|
255
235
|
### ποΈ ThemeProvider
|
|
256
236
|
|
|
257
|
-
|
|
237
|
+
Manages theme state and applies CSS variables throughout your app.
|
|
258
238
|
|
|
259
|
-
|
|
239
|
+
~~~tsx
|
|
260
240
|
interface ThemeProviderProps {
|
|
261
241
|
children: ReactNode;
|
|
262
242
|
defaultMode?: 'light' | 'dark' | 'auto';
|
|
263
|
-
defaultTheme?: string;
|
|
264
|
-
persistMode?: boolean;
|
|
265
|
-
storageKey?: string;
|
|
243
|
+
defaultTheme?: string; // 'default' | custom theme name
|
|
244
|
+
persistMode?: boolean; // default: true
|
|
245
|
+
storageKey?: string; // default: 'asafarim-theme-mode'
|
|
266
246
|
customThemes?: Record<string, Theme>;
|
|
267
|
-
config?: ThemeConfig;
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**Essential Props:**
|
|
272
|
-
|
|
273
|
-
| Prop | Type | Default | Description |
|
|
274
|
-
|------|------|---------|-------------|
|
|
275
|
-
| `children` | `ReactNode` | **required** | Child components to provide theme context to |
|
|
276
|
-
| `defaultMode` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Initial theme mode on first load |
|
|
277
|
-
| `defaultTheme` | `string` | `'default'` | Name of the default theme to use |
|
|
278
|
-
| `persistMode` | `boolean` | `true` | Whether to save user's theme choice to localStorage |
|
|
279
|
-
| `storageKey` | `string` | `'asafarim-theme-mode'` | localStorage key for persistence |
|
|
280
|
-
| `customThemes` | `Record<string, Theme>` | `{}` | Additional themes to make available |
|
|
281
|
-
|
|
282
|
-
**Advanced Configuration:**
|
|
283
|
-
|
|
284
|
-
```tsx
|
|
285
|
-
// Extended configuration options
|
|
286
|
-
interface ThemeConfig {
|
|
287
|
-
transitionDuration?: string;
|
|
288
|
-
breakpoints?: Record<string, string>;
|
|
289
|
-
enableSystemTheme?: boolean;
|
|
290
|
-
cssVariablePrefix?: string;
|
|
291
247
|
}
|
|
248
|
+
~~~
|
|
292
249
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}}
|
|
299
|
-
>
|
|
300
|
-
<App />
|
|
301
|
-
</ThemeProvider>
|
|
302
|
-
```
|
|
250
|
+
- defaultMode: Initial mode on first load
|
|
251
|
+
- defaultTheme: Name of the default theme to use
|
|
252
|
+
- persistMode: Save user's mode to localStorage
|
|
253
|
+
- storageKey: Key used for persistence
|
|
254
|
+
- customThemes: Provide additional themes
|
|
303
255
|
|
|
304
256
|
### πͺ useTheme Hook
|
|
305
257
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
```tsx
|
|
258
|
+
~~~tsx
|
|
309
259
|
interface UseThemeReturn {
|
|
310
|
-
currentTheme: Theme;
|
|
311
|
-
mode: ThemeMode;
|
|
312
|
-
setMode: (mode: ThemeMode) => void;
|
|
313
|
-
setTheme: (theme: Theme) => void;
|
|
314
|
-
themes: Record<string, Theme>;
|
|
315
|
-
toggleMode: () => void;
|
|
260
|
+
currentTheme: Theme;
|
|
261
|
+
mode: ThemeMode; // 'light' | 'dark' | 'auto'
|
|
262
|
+
setMode: (mode: ThemeMode) => void;
|
|
263
|
+
setTheme: (theme: Theme) => void;
|
|
264
|
+
themes: Record<string, Theme>;
|
|
265
|
+
toggleMode: () => void; // cycles light β dark (auto flips to opposite of system)
|
|
316
266
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
**Real-world Example:**
|
|
320
|
-
|
|
321
|
-
```tsx
|
|
322
|
-
function ThemeAwareComponent() {
|
|
323
|
-
const { currentTheme, mode, setMode, toggleMode } = useTheme();
|
|
324
|
-
|
|
325
|
-
// Conditional styling based on theme
|
|
326
|
-
const isDarkMode = mode === 'dark' ||
|
|
327
|
-
(mode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
|
328
|
-
|
|
329
|
-
return (
|
|
330
|
-
<div style={{
|
|
331
|
-
backgroundColor: currentTheme.colors.background,
|
|
332
|
-
color: currentTheme.colors.text
|
|
333
|
-
}}>
|
|
334
|
-
<h2>Current Theme: {currentTheme.name}</h2>
|
|
335
|
-
<p>Mode: {mode} {isDarkMode ? 'π' : 'βοΈ'}</p>
|
|
336
|
-
<button onClick={toggleMode}>Toggle Theme</button>
|
|
337
|
-
</div>
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
```
|
|
267
|
+
~~~
|
|
341
268
|
|
|
342
269
|
### β‘ useThemeToggle Hook
|
|
343
270
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
```tsx
|
|
271
|
+
~~~tsx
|
|
347
272
|
interface UseThemeToggleReturn {
|
|
348
|
-
mode: ThemeMode;
|
|
349
|
-
setMode: (mode: ThemeMode) => void;
|
|
350
|
-
toggleMode: () => void;
|
|
351
|
-
isDark: boolean;
|
|
352
|
-
isLight: boolean;
|
|
353
|
-
isAuto: boolean;
|
|
354
|
-
effectiveMode: 'light' | 'dark';
|
|
273
|
+
mode: ThemeMode;
|
|
274
|
+
setMode: (mode: ThemeMode) => void;
|
|
275
|
+
toggleMode: () => void;
|
|
276
|
+
isDark: boolean;
|
|
277
|
+
isLight: boolean;
|
|
278
|
+
isAuto: boolean;
|
|
279
|
+
effectiveMode: 'light' | 'dark';
|
|
355
280
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
**Practical Usage:**
|
|
359
|
-
|
|
360
|
-
```tsx
|
|
361
|
-
function SmartThemeButton() {
|
|
362
|
-
const { mode, toggleMode, isDark, effectiveMode } = useThemeToggle();
|
|
363
|
-
|
|
364
|
-
const getIcon = () => {
|
|
365
|
-
if (mode === 'auto') return 'π';
|
|
366
|
-
return isDark ? 'π' : 'βοΈ';
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
const getLabel = () => {
|
|
370
|
-
if (mode === 'auto') return `Auto (${effectiveMode})`;
|
|
371
|
-
return mode === 'dark' ? 'Dark Mode' : 'Light Mode';
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
return (
|
|
375
|
-
<button onClick={toggleMode} title={getLabel()}>
|
|
376
|
-
{getIcon()} {getLabel()}
|
|
377
|
-
</button>
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
```
|
|
281
|
+
~~~
|
|
381
282
|
|
|
382
283
|
### Components
|
|
383
284
|
|
|
384
285
|
#### ThemeToggle
|
|
385
286
|
|
|
386
|
-
A pre-built theme toggle button.
|
|
287
|
+
A pre-built theme toggle button with variants and icon customization.
|
|
288
|
+
|
|
289
|
+
~~~tsx
|
|
290
|
+
import { ThemeToggle } from '@asafarim/react-themes';
|
|
291
|
+
import { Sun, Moon } from 'lucide-react';
|
|
387
292
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
293
|
+
<ThemeToggle
|
|
294
|
+
size="md" // 'sm' | 'md' | 'lg'
|
|
295
|
+
showLabels={false}
|
|
296
|
+
variant="default" // 'default' | 'outline' | 'ghost' | 'link' | 'circle' | 'icon'
|
|
297
|
+
ariaLabel="Toggle theme"
|
|
298
|
+
lightIcon={<Sun />}
|
|
299
|
+
darkIcon={<Moon />}
|
|
392
300
|
className="custom-class"
|
|
393
301
|
style={{ margin: '10px' }}
|
|
394
302
|
/>
|
|
395
|
-
|
|
303
|
+
~~~
|
|
396
304
|
|
|
397
305
|
#### ThemeSelector
|
|
398
306
|
|
|
399
307
|
A dropdown selector for theme modes.
|
|
400
308
|
|
|
401
|
-
|
|
402
|
-
<ThemeSelector
|
|
309
|
+
~~~tsx
|
|
310
|
+
<ThemeSelector
|
|
403
311
|
showLabels={true}
|
|
404
312
|
className="custom-class"
|
|
405
313
|
options={[
|
|
@@ -408,14 +316,12 @@ A dropdown selector for theme modes.
|
|
|
408
316
|
{ mode: 'auto', label: 'Auto', icon: 'π' }
|
|
409
317
|
]}
|
|
410
318
|
/>
|
|
411
|
-
|
|
319
|
+
~~~
|
|
412
320
|
|
|
413
321
|
## π¨ Custom Themes
|
|
414
322
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
```tsx
|
|
418
|
-
import { createTheme, lightTheme } from '@asafarim/react-themes';
|
|
323
|
+
~~~tsx
|
|
324
|
+
import { createTheme, lightTheme, ThemeProvider } from '@asafarim/react-themes';
|
|
419
325
|
|
|
420
326
|
const myCustomTheme = createTheme(lightTheme, {
|
|
421
327
|
name: 'my-theme',
|
|
@@ -427,17 +333,14 @@ const myCustomTheme = createTheme(lightTheme, {
|
|
|
427
333
|
}
|
|
428
334
|
});
|
|
429
335
|
|
|
430
|
-
// Use with provider
|
|
431
336
|
<ThemeProvider customThemes={{ 'my-theme': myCustomTheme }}>
|
|
432
337
|
<App />
|
|
433
338
|
</ThemeProvider>
|
|
434
|
-
|
|
339
|
+
~~~
|
|
435
340
|
|
|
436
341
|
### Using CSS Variables
|
|
437
342
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
```css
|
|
343
|
+
~~~css
|
|
441
344
|
.my-component {
|
|
442
345
|
background-color: var(--theme-color-background);
|
|
443
346
|
color: var(--theme-color-text);
|
|
@@ -456,119 +359,76 @@ The package automatically injects CSS variables that you can use in your styles:
|
|
|
456
359
|
.my-button:hover {
|
|
457
360
|
background-color: var(--theme-color-primary-hover);
|
|
458
361
|
}
|
|
459
|
-
|
|
362
|
+
~~~
|
|
460
363
|
|
|
461
364
|
## π― Integration with @asafarim/dd-menu
|
|
462
365
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
```tsx
|
|
366
|
+
~~~tsx
|
|
466
367
|
import { DDMenu } from '@asafarim/dd-menu';
|
|
467
368
|
import { useTheme } from '@asafarim/react-themes';
|
|
468
369
|
|
|
469
370
|
function NavMenu() {
|
|
470
371
|
const { mode } = useTheme();
|
|
471
|
-
|
|
472
372
|
return (
|
|
473
|
-
<DDMenu
|
|
474
|
-
items={menuItems}
|
|
475
|
-
theme={mode} // Pass current theme mode
|
|
476
|
-
variant="navbar"
|
|
477
|
-
/>
|
|
373
|
+
<DDMenu items={menuItems} theme={mode} variant="navbar" />
|
|
478
374
|
);
|
|
479
375
|
}
|
|
480
|
-
|
|
376
|
+
~~~
|
|
481
377
|
|
|
482
378
|
## π Live Demo & Showcase
|
|
483
379
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
Experience all features at **[bibliography.asafarim.com/react-themes/demo](https://bibliography.asafarim.com/react-themes/demo)**
|
|
487
|
-
|
|
488
|
-
The demo is a comprehensive showcase featuring:
|
|
489
|
-
|
|
490
|
-
#### π¨ **Theme Gallery**
|
|
491
|
-
|
|
492
|
-
- **Light Theme**: Clean, modern interface with excellent readability
|
|
493
|
-
- **Dark Theme**: Elegant dark mode optimized for low-light environments
|
|
494
|
-
- **Auto Mode**: Intelligent system preference detection with seamless switching
|
|
495
|
-
- **Custom Themes**: Examples of brand-specific and specialized themes
|
|
496
|
-
|
|
497
|
-
#### π οΈ **Component Showcase**
|
|
498
|
-
|
|
499
|
-
- **ThemeToggle Variants**: Different sizes, styles, and label configurations
|
|
500
|
-
- **ThemeSelector**: Dropdown with icons, labels, and custom options
|
|
501
|
-
- **Integration Examples**: Real components using theme variables
|
|
502
|
-
- **Performance Metrics**: Live transition timing and smoothness demos
|
|
503
|
-
|
|
504
|
-
#### π **Technical Demonstrations**
|
|
505
|
-
|
|
506
|
-
- **CSS Variables Live**: Watch variables update in real-time as themes change
|
|
507
|
-
- **Browser Compatibility**: Cross-browser testing interface
|
|
508
|
-
- **Accessibility Features**: Screen reader announcements and keyboard navigation
|
|
509
|
-
- **Mobile Responsiveness**: Touch-optimized controls and layouts
|
|
510
|
-
|
|
511
|
-
#### π§ **Developer Tools**
|
|
380
|
+
Experience all features at:
|
|
512
381
|
|
|
513
|
-
-
|
|
514
|
-
- **Theme Inspector**: Live theme object visualization
|
|
515
|
-
- **CSS Variable Explorer**: All available variables with current values
|
|
516
|
-
- **Performance Monitor**: Bundle size and render time metrics
|
|
382
|
+
- https://alisafari-it.github.io/react-themes/
|
|
517
383
|
|
|
518
|
-
|
|
384
|
+
The demo highlights:
|
|
519
385
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
-
|
|
523
|
-
-
|
|
524
|
-
-
|
|
525
|
-
- Battery-conscious animations
|
|
526
|
-
|
|
527
|
-
### π― **Use Cases Demonstrated**
|
|
528
|
-
|
|
529
|
-
1. **E-commerce Interface**: Product cards, navigation, and checkout flows
|
|
530
|
-
2. **Dashboard Layout**: Charts, tables, and control panels
|
|
531
|
-
3. **Content Management**: Text editors, media galleries, and forms
|
|
532
|
-
4. **Social Platform**: Posts, comments, and user profiles
|
|
533
|
-
5. **Documentation Site**: Code blocks, navigation, and search interfaces
|
|
386
|
+
- Theme Gallery: Light, Dark, Auto, Custom Themes
|
|
387
|
+
- Component Showcase: ThemeToggle variants, ThemeSelector
|
|
388
|
+
- CSS Variables Live: Watch variables update in real time
|
|
389
|
+
- Accessibility: Keyboard, screen readers, reduced motion
|
|
390
|
+
- Mobile Optimizations: Touch-friendly controls and layouts
|
|
534
391
|
|
|
535
392
|
## π§ Advanced Usage
|
|
536
393
|
|
|
537
|
-
### Custom Theme Structure
|
|
394
|
+
### Custom Theme Structure (partial)
|
|
538
395
|
|
|
539
|
-
|
|
396
|
+
~~~tsx
|
|
540
397
|
interface Theme {
|
|
541
398
|
name: string;
|
|
542
399
|
mode: 'light' | 'dark' | 'auto';
|
|
543
400
|
colors: {
|
|
544
401
|
background: string;
|
|
545
402
|
backgroundSecondary: string;
|
|
403
|
+
backgroundTertiary: string;
|
|
546
404
|
text: string;
|
|
547
405
|
textSecondary: string;
|
|
406
|
+
textMuted: string;
|
|
407
|
+
border: string;
|
|
408
|
+
borderLight: string;
|
|
409
|
+
borderHover: string;
|
|
548
410
|
primary: string;
|
|
549
411
|
primaryHover: string;
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
lg: string;
|
|
558
|
-
// ... more spacing
|
|
412
|
+
primaryActive: string;
|
|
413
|
+
hover: string;
|
|
414
|
+
active: string;
|
|
415
|
+
focus: string;
|
|
416
|
+
shadow: string;
|
|
417
|
+
shadowMd: string;
|
|
418
|
+
shadowLg: string;
|
|
559
419
|
};
|
|
420
|
+
spacing: { xs: string; sm: string; md: string; lg: string; xl: string; '2xl': string; '3xl': string; '4xl': string };
|
|
560
421
|
// ... typography, radius, transitions, zIndex
|
|
561
422
|
}
|
|
562
|
-
|
|
423
|
+
~~~
|
|
563
424
|
|
|
564
425
|
### Programmatic Theme Application
|
|
565
426
|
|
|
566
|
-
|
|
427
|
+
~~~tsx
|
|
567
428
|
import { applyTheme } from '@asafarim/react-themes';
|
|
568
429
|
|
|
569
|
-
// Apply theme manually
|
|
570
430
|
applyTheme(customTheme, 'dark');
|
|
571
|
-
|
|
431
|
+
~~~
|
|
572
432
|
|
|
573
433
|
## π Browser Support
|
|
574
434
|
|
|
@@ -580,80 +440,88 @@ applyTheme(customTheme, 'dark');
|
|
|
580
440
|
|
|
581
441
|
## π€ Contributing
|
|
582
442
|
|
|
583
|
-
We welcome contributions! The project is open
|
|
443
|
+
We welcome contributions! The project is open-source and actively maintained.
|
|
584
444
|
|
|
585
|
-
### π οΈ
|
|
445
|
+
### π οΈ Development Setup
|
|
586
446
|
|
|
587
|
-
|
|
588
|
-
git clone https://github.com/AliSafari-IT/
|
|
589
|
-
cd
|
|
447
|
+
~~~bash
|
|
448
|
+
git clone https://github.com/AliSafari-IT/react-themes.git
|
|
449
|
+
cd react-themes
|
|
590
450
|
pnpm install
|
|
591
451
|
pnpm build
|
|
592
|
-
|
|
593
|
-
|
|
452
|
+
# optional during development
|
|
453
|
+
pnpm dev
|
|
454
|
+
# quality
|
|
455
|
+
pnpm type-check
|
|
456
|
+
pnpm lint
|
|
457
|
+
~~~
|
|
594
458
|
|
|
595
|
-
###
|
|
459
|
+
### π¬ Local Verification
|
|
596
460
|
|
|
597
|
-
|
|
598
|
-
#
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
pnpm start
|
|
602
|
-
# Visit http://localhost:3004/react-themes/demo
|
|
603
|
-
```
|
|
461
|
+
~~~bash
|
|
462
|
+
# After build, you can quickly verify exports
|
|
463
|
+
node test-import.js
|
|
464
|
+
~~~
|
|
604
465
|
|
|
605
|
-
### π
|
|
466
|
+
### π Contribution Guidelines
|
|
606
467
|
|
|
607
468
|
- Follow TypeScript best practices
|
|
608
|
-
- Add tests for new features
|
|
469
|
+
- Add tests (where applicable) for new features
|
|
609
470
|
- Update documentation and examples
|
|
610
471
|
- Ensure accessibility compliance
|
|
611
472
|
- Test across different browsers
|
|
612
473
|
|
|
613
474
|
## π License
|
|
614
475
|
|
|
615
|
-
MIT License
|
|
476
|
+
MIT License β see the [LICENSE](LICENSE) file for details.
|
|
616
477
|
|
|
617
|
-
## π
|
|
478
|
+
## π Why Choose @asafarim/react-themes?
|
|
618
479
|
|
|
619
|
-
### β
|
|
480
|
+
### β
Production Ready
|
|
620
481
|
|
|
621
|
-
- Used in production at
|
|
622
|
-
-
|
|
482
|
+
- Used in production at ASafariM projects
|
|
483
|
+
- Tested across browsers and devices
|
|
623
484
|
- Optimized for performance and accessibility
|
|
624
485
|
- Regular updates and maintenance
|
|
625
486
|
|
|
626
|
-
### π―
|
|
487
|
+
### π― Developer Focused
|
|
627
488
|
|
|
628
489
|
- Extensive TypeScript support
|
|
629
490
|
- Comprehensive documentation with live examples
|
|
630
491
|
- Active community support
|
|
631
|
-
- Regular feature updates
|
|
492
|
+
- Regular feature updates
|
|
632
493
|
|
|
633
|
-
### π
|
|
494
|
+
### π Modern Standards
|
|
634
495
|
|
|
635
|
-
- React
|
|
636
|
-
-
|
|
496
|
+
- React 16.8+ (Hooks) and React 18 optimized
|
|
497
|
+
- CSS Custom Properties
|
|
637
498
|
- ES2020+ JavaScript features
|
|
638
499
|
- Modern bundling and tree-shaking support
|
|
639
500
|
|
|
640
501
|
## π Related Packages & Ecosystem
|
|
641
502
|
|
|
642
|
-
-
|
|
643
|
-
|
|
644
|
-
|
|
503
|
+
- [`@asafarim/dd-menu`](https://www.npmjs.com/package/@asafarim/dd-menu) β Elegant dropdown menu component with theme integration
|
|
504
|
+
|
|
505
|
+
## π Project Stats
|
|
506
|
+
|
|
507
|
+
- ποΈ Built with: TypeScript, React, CSS Custom Properties
|
|
508
|
+
- π¦ Bundle Size: ~8KB gzipped
|
|
509
|
+
- π Browser Support: Chrome 49+, Firefox 31+, Safari 9.1+, Edge 16+
|
|
510
|
+
- β‘ Performance: Zeroβflicker theme switching, optimized reβrenders
|
|
511
|
+
- βΏ Accessibility: WCAG 2.1 AA-friendly
|
|
645
512
|
|
|
646
|
-
##
|
|
513
|
+
## π Changelog
|
|
647
514
|
|
|
648
|
-
|
|
649
|
-
- π¦ **Bundle Size**: ~8KB gzipped
|
|
650
|
-
- π **Browser Support**: Modern browsers (Chrome 49+, Firefox 31+, Safari 9.1+, Edge 16+)
|
|
651
|
-
- β‘ **Performance**: Zero-flicker theme switching, optimized re-renders
|
|
652
|
-
- βΏ **Accessibility**: WCAG 2.1 AA compliant
|
|
515
|
+
### v1.8.1 β Latest
|
|
653
516
|
|
|
654
|
-
|
|
517
|
+
- New: ThemeToggle variants (default, outline, ghost, link, circle, icon)
|
|
518
|
+
- New: Custom icon support via lucide-react (lightIcon/darkIcon)
|
|
519
|
+
- New: mergeThemes, mergeThemeColors, deepMergeThemes utilities
|
|
520
|
+
- Improved: TypeScript types and CSS variable coverage
|
|
521
|
+
- Improved: SSR behavior and localStorage persistence handling
|
|
522
|
+
- Docs: Unified demo links, updated examples
|
|
655
523
|
|
|
656
|
-
###
|
|
524
|
+
### v1.1.0
|
|
657
525
|
|
|
658
526
|
- Enhanced TypeScript definitions
|
|
659
527
|
- Improved performance and bundle size
|
|
@@ -661,9 +529,9 @@ MIT License - see the [LICENSE](LICENSE) file for details.
|
|
|
661
529
|
- Extended browser compatibility
|
|
662
530
|
- New theme customization options
|
|
663
531
|
|
|
664
|
-
###
|
|
532
|
+
### v1.0.0 β Initial Release
|
|
665
533
|
|
|
666
|
-
- Core
|
|
534
|
+
- Core ThemeProvider functionality
|
|
667
535
|
- Auto mode detection with system preference sync
|
|
668
536
|
- CSS variable injection system
|
|
669
537
|
- Built-in components (ThemeToggle, ThemeSelector)
|
|
@@ -674,12 +542,13 @@ MIT License - see the [LICENSE](LICENSE) file for details.
|
|
|
674
542
|
|
|
675
543
|
<div align="center">
|
|
676
544
|
|
|
677
|
-
### π
|
|
545
|
+
### π Experience the Future of React Theming
|
|
678
546
|
|
|
679
|
-
|
|
547
|
+
<a href="https://alisafari-it.github.io/react-themes">Try the Live Demo</a> Β· <a href="https://www.npmjs.com/package/@asafarim/react-themes">View on npm</a> Β· <a href="https://github.com/AliSafari-IT/react-themes">Source Code</a>
|
|
680
548
|
|
|
681
|
-
Made with β€οΈ and β by
|
|
549
|
+
Made with β€οΈ and β by <a href="https://asafarim.com">ASafariM</a>
|
|
682
550
|
|
|
683
|
-
|
|
551
|
+
<em>Empowering developers to create beautiful, accessible, and userβfriendly themed applications</em>
|
|
684
552
|
|
|
685
553
|
</div>
|
|
554
|
+
"@ | Set-Content -Path README.md -Encoding UTF8
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asafarim/react-themes",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2-canary.b5e58bd.4",
|
|
4
4
|
"description": "A comprehensive theme management system for React applications with automatic dark/light mode detection, custom theme creation, and smooth transitions.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|