infinity-theme 1.3.0

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 ADDED
@@ -0,0 +1,114 @@
1
+ # Infinity Theme
2
+
3
+ A lightweight React theme system with dark/light mode and 5 color themes using CSS custom properties.
4
+
5
+ ## Features
6
+
7
+ - **Dark/Light mode** toggle with system preference detection
8
+ - **5 color themes**: Purple, Red, Blue, Green, Orange
9
+ - **Persistent** — saves preferences to localStorage
10
+ - **PWA-ready** — updates manifest theme-color dynamically
11
+ - **Zero dependencies** — just React peer dependency
12
+ - **~2KB** gzipped
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install infinity-theme
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### 1. Wrap your app with `ThemeProvider`
23
+
24
+ ```jsx
25
+ import { ThemeProvider } from 'infinity-theme';
26
+ import 'infinity-theme/globals.css';
27
+
28
+ function App() {
29
+ return (
30
+ <ThemeProvider>
31
+ <YourApp />
32
+ </ThemeProvider>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ### 2. Use the `ThemeToggle` component
38
+
39
+ ```jsx
40
+ import { ThemeToggle } from 'infinity-theme';
41
+
42
+ function Header() {
43
+ return (
44
+ <header>
45
+ <h1>My App</h1>
46
+ <ThemeToggle />
47
+ </header>
48
+ );
49
+ }
50
+ ```
51
+
52
+ ### 3. Use theme colors in your CSS
53
+
54
+ The theme uses CSS custom properties in HSL format:
55
+
56
+ ```css
57
+ .card {
58
+ background: hsl(var(--card));
59
+ color: hsl(var(--card-foreground));
60
+ border: 1px solid hsl(var(--border));
61
+ }
62
+
63
+ .btn {
64
+ background: hsl(var(--primary));
65
+ color: hsl(var(--primary-foreground));
66
+ }
67
+ ```
68
+
69
+ ### Available CSS Variables
70
+
71
+ | Variable | Usage |
72
+ |---|---|
73
+ | `--background` | Page background |
74
+ | `--foreground` | Default text color |
75
+ | `--card` | Card/container background |
76
+ | `--card-foreground` | Card text color |
77
+ | `--primary` | Primary accent color |
78
+ | `--primary-foreground` | Text on primary |
79
+ | `--secondary` | Secondary accent |
80
+ | `--secondary-foreground` | Text on secondary |
81
+ | `--muted` | Muted backgrounds |
82
+ | `--muted-foreground` | Muted text |
83
+ | `--border` | Border colors |
84
+ | `--ring` | Focus rings, scrollbars |
85
+ | `--radius` | Border radius |
86
+
87
+ ## API
88
+
89
+ ### `useTheme()`
90
+
91
+ ```jsx
92
+ import { useTheme } from 'infinity-theme';
93
+
94
+ function MyComponent() {
95
+ const { theme, toggleTheme, colorTheme, setColorTheme, colorThemes } = useTheme();
96
+ // theme: 'light' | 'dark'
97
+ // colorTheme: 'purple' | 'red' | 'blue' | 'green' | 'orange'
98
+ // colorThemes: array of available colors
99
+ }
100
+ ```
101
+
102
+ ## Color Themes
103
+
104
+ | Color | Light Primary | Dark Primary |
105
+ |---|---|---|
106
+ | Purple (default) | `hsl(270 90% 60%)` | `hsl(270 90% 70%)` |
107
+ | Red | `hsl(0 85% 60%)` | `hsl(0 85% 65%)` |
108
+ | Blue | `hsl(220 90% 60%)` | `hsl(220 90% 70%)` |
109
+ | Green | `hsl(140 70% 45%)` | `hsl(140 70% 55%)` |
110
+ | Orange | `hsl(25 95% 55%)` | `hsl(25 95% 60%)` |
111
+
112
+ ## License
113
+
114
+ MIT
@@ -0,0 +1,503 @@
1
+ :root {
2
+ --background: 270 100% 99%;
3
+ --foreground: 270 50% 10%;
4
+ --card: 0 0% 100%;
5
+ --card-foreground: 270 50% 10%;
6
+ --primary: 270 90% 60%;
7
+ --primary-foreground: 0 0% 100%;
8
+ --secondary: 270 30% 95%;
9
+ --secondary-foreground: 270 50% 20%;
10
+ --muted: 270 20% 96%;
11
+ --muted-foreground: 270 10% 40%;
12
+ --border: 270 20% 90%;
13
+ --ring: 270 90% 60%;
14
+ --radius: 0.75rem;
15
+ }
16
+
17
+ .dark {
18
+ --background: 270 50% 4%;
19
+ --foreground: 270 20% 95%;
20
+ --card: 270 50% 6%;
21
+ --card-foreground: 270 20% 95%;
22
+ --primary: 270 90% 70%;
23
+ --primary-foreground: 270 50% 5%;
24
+ --secondary: 270 40% 12%;
25
+ --secondary-foreground: 270 20% 95%;
26
+ --muted: 270 40% 12%;
27
+ --muted-foreground: 270 10% 60%;
28
+ --border: 270 40% 15%;
29
+ --ring: 270 90% 70%;
30
+ }
31
+
32
+ .red {
33
+ --background: 0 100% 98%;
34
+ --foreground: 0 50% 12%;
35
+ --card: 0 0% 100%;
36
+ --card-foreground: 0 50% 12%;
37
+ --primary: 0 85% 60%;
38
+ --primary-foreground: 0 0% 100%;
39
+ --secondary: 0 30% 95%;
40
+ --secondary-foreground: 0 50% 20%;
41
+ --muted: 0 20% 96%;
42
+ --muted-foreground: 0 10% 40%;
43
+ --border: 0 20% 90%;
44
+ --ring: 0 85% 60%;
45
+ }
46
+
47
+ .red.dark {
48
+ --background: 0 50% 6%;
49
+ --foreground: 0 20% 95%;
50
+ --card: 0 50% 8%;
51
+ --card-foreground: 0 20% 95%;
52
+ --primary: 0 85% 65%;
53
+ --primary-foreground: 0 50% 5%;
54
+ --secondary: 0 40% 14%;
55
+ --secondary-foreground: 0 20% 95%;
56
+ --muted: 0 40% 14%;
57
+ --muted-foreground: 0 10% 60%;
58
+ --border: 0 40% 18%;
59
+ --ring: 0 85% 65%;
60
+ }
61
+
62
+ .blue {
63
+ --background: 220 100% 98%;
64
+ --foreground: 220 50% 12%;
65
+ --card: 220 0% 100%;
66
+ --card-foreground: 220 50% 12%;
67
+ --primary: 220 90% 60%;
68
+ --primary-foreground: 220 0% 100%;
69
+ --secondary: 220 30% 95%;
70
+ --secondary-foreground: 220 50% 20%;
71
+ --muted: 220 20% 96%;
72
+ --muted-foreground: 220 10% 40%;
73
+ --border: 220 20% 90%;
74
+ --ring: 220 90% 60%;
75
+ }
76
+
77
+ .blue.dark {
78
+ --background: 220 50% 6%;
79
+ --foreground: 220 20% 95%;
80
+ --card: 220 50% 8%;
81
+ --card-foreground: 220 20% 95%;
82
+ --primary: 220 90% 70%;
83
+ --primary-foreground: 220 50% 5%;
84
+ --secondary: 220 40% 14%;
85
+ --secondary-foreground: 220 20% 95%;
86
+ --muted: 220 40% 14%;
87
+ --muted-foreground: 220 10% 60%;
88
+ --border: 220 40% 18%;
89
+ --ring: 220 90% 70%;
90
+ }
91
+
92
+ .green {
93
+ --background: 140 80% 98%;
94
+ --foreground: 140 50% 12%;
95
+ --card: 140 0% 100%;
96
+ --card-foreground: 140 50% 12%;
97
+ --primary: 140 70% 45%;
98
+ --primary-foreground: 140 0% 100%;
99
+ --secondary: 140 30% 95%;
100
+ --secondary-foreground: 140 50% 20%;
101
+ --muted: 140 20% 96%;
102
+ --muted-foreground: 140 10% 40%;
103
+ --border: 140 20% 90%;
104
+ --ring: 140 70% 45%;
105
+ }
106
+
107
+ .green.dark {
108
+ --background: 140 50% 6%;
109
+ --foreground: 140 20% 95%;
110
+ --card: 140 50% 8%;
111
+ --card-foreground: 140 20% 95%;
112
+ --primary: 140 70% 55%;
113
+ --primary-foreground: 140 50% 5%;
114
+ --secondary: 140 40% 14%;
115
+ --secondary-foreground: 140 20% 95%;
116
+ --muted: 140 40% 14%;
117
+ --muted-foreground: 140 10% 60%;
118
+ --border: 140 40% 18%;
119
+ --ring: 140 70% 55%;
120
+ }
121
+
122
+ .orange {
123
+ --background: 30 100% 97%;
124
+ --foreground: 30 50% 12%;
125
+ --card: 30 0% 100%;
126
+ --card-foreground: 30 50% 12%;
127
+ --primary: 25 95% 55%;
128
+ --primary-foreground: 30 0% 100%;
129
+ --secondary: 30 30% 95%;
130
+ --secondary-foreground: 30 50% 20%;
131
+ --muted: 30 20% 96%;
132
+ --muted-foreground: 30 10% 40%;
133
+ --border: 30 20% 90%;
134
+ --ring: 25 95% 55%;
135
+ }
136
+
137
+ .orange.dark {
138
+ --background: 25 50% 6%;
139
+ --foreground: 25 20% 95%;
140
+ --card: 25 50% 8%;
141
+ --card-foreground: 25 20% 95%;
142
+ --primary: 25 95% 60%;
143
+ --primary-foreground: 25 50% 5%;
144
+ --secondary: 25 40% 14%;
145
+ --secondary-foreground: 25 20% 95%;
146
+ --muted: 25 40% 14%;
147
+ --muted-foreground: 25 10% 60%;
148
+ --border: 25 40% 18%;
149
+ --ring: 25 95% 60%;
150
+ }
151
+
152
+ * {
153
+ border-color: var(--border);
154
+ scrollbar-width: thin;
155
+ scrollbar-color: hsl(var(--ring) / 0.3) transparent;
156
+ }
157
+
158
+ *::-webkit-scrollbar {
159
+ width: 8px;
160
+ height: 8px;
161
+ }
162
+
163
+ *::-webkit-scrollbar-track {
164
+ background: transparent;
165
+ }
166
+
167
+ *::-webkit-scrollbar-thumb {
168
+ background: hsl(var(--ring) / 0.3);
169
+ border-radius: 999px;
170
+ }
171
+
172
+ html {
173
+ scroll-behavior: smooth;
174
+ }
175
+
176
+ body {
177
+ background: hsl(var(--background));
178
+ color: hsl(var(--foreground));
179
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, sans-serif;
180
+ -webkit-font-smoothing: antialiased;
181
+ -moz-osx-font-smoothing: grayscale;
182
+ }
183
+
184
+ /* Links — inherit color by default, primary on hover */
185
+ a {
186
+ color: inherit;
187
+ text-decoration: none;
188
+ }
189
+
190
+ a:hover {
191
+ color: hsl(var(--primary));
192
+ text-decoration: underline;
193
+ }
194
+
195
+ a:visited {
196
+ color: inherit;
197
+ }
198
+
199
+ /* Headings */
200
+ h1, h2, h3, h4, h5, h6 {
201
+ color: hsl(var(--foreground));
202
+ }
203
+
204
+ /* Paragraphs & text */
205
+ p, span {
206
+ color: hsl(var(--foreground));
207
+ }
208
+
209
+ small {
210
+ color: hsl(var(--muted-foreground));
211
+ }
212
+
213
+ strong, b {
214
+ color: hsl(var(--foreground));
215
+ }
216
+
217
+ em, i {
218
+ color: hsl(var(--foreground));
219
+ }
220
+
221
+ /* Code */
222
+ code, pre, kbd {
223
+ background-color: hsl(var(--muted));
224
+ color: hsl(var(--muted-foreground));
225
+ }
226
+
227
+ pre {
228
+ border-color: hsl(var(--border));
229
+ }
230
+
231
+ /* Buttons — primary color, muted when disabled */
232
+ button {
233
+ background-color: hsl(var(--primary));
234
+ color: hsl(var(--primary-foreground));
235
+ border-color: hsl(var(--border));
236
+ }
237
+
238
+ button:hover {
239
+ background-color: hsl(var(--primary) / 0.85);
240
+ }
241
+
242
+ button:active {
243
+ background-color: hsl(var(--primary) / 0.75);
244
+ }
245
+
246
+ button:disabled {
247
+ background-color: hsl(var(--muted));
248
+ color: hsl(var(--muted-foreground));
249
+ border-color: hsl(var(--border));
250
+ cursor: not-allowed;
251
+ }
252
+
253
+ /* Inputs & Textareas */
254
+ input[type="text"],
255
+ input[type="password"],
256
+ input[type="email"],
257
+ input[type="number"],
258
+ input[type="search"],
259
+ input[type="tel"],
260
+ input[type="url"],
261
+ input:not([type]),
262
+ textarea,
263
+ select {
264
+ background-color: hsl(var(--card));
265
+ color: hsl(var(--card-foreground));
266
+ border-color: hsl(var(--border));
267
+ }
268
+
269
+ input::placeholder,
270
+ textarea::placeholder {
271
+ color: hsl(var(--muted-foreground));
272
+ }
273
+
274
+ input[type="text"]:focus,
275
+ input[type="password"]:focus,
276
+ input[type="email"]:focus,
277
+ input[type="number"]:focus,
278
+ input[type="search"]:focus,
279
+ input[type="tel"]:focus,
280
+ input[type="url"]:focus,
281
+ input:not([type]):focus,
282
+ textarea:focus,
283
+ select:focus {
284
+ border-color: hsl(var(--ring));
285
+ outline: none;
286
+ }
287
+
288
+ /* Checkbox & Radio */
289
+ input[type="checkbox"],
290
+ input[type="radio"] {
291
+ accent-color: hsl(var(--primary));
292
+ }
293
+
294
+ /* Range */
295
+ input[type="range"] {
296
+ accent-color: hsl(var(--primary));
297
+ }
298
+
299
+ input[type="range"]::-webkit-slider-runnable-track {
300
+ background-color: hsl(var(--muted));
301
+ }
302
+
303
+ input[type="range"]::-webkit-slider-thumb {
304
+ background-color: hsl(var(--primary));
305
+ }
306
+
307
+ /* Select dropdown arrow */
308
+ select {
309
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='hsl(var(--muted-foreground))' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
310
+ background-repeat: no-repeat;
311
+ background-position: right 0.5rem center;
312
+ }
313
+
314
+ /* Tables */
315
+ table {
316
+ border-color: hsl(var(--border));
317
+ }
318
+
319
+ th {
320
+ background-color: hsl(var(--muted));
321
+ color: hsl(var(--muted-foreground));
322
+ }
323
+
324
+ td {
325
+ border-color: hsl(var(--border));
326
+ }
327
+
328
+ tr:nth-child(even) {
329
+ background-color: hsl(var(--muted) / 0.3);
330
+ }
331
+
332
+ /* Lists */
333
+ ul, ol {
334
+ color: hsl(var(--foreground));
335
+ }
336
+
337
+ li::marker {
338
+ color: hsl(var(--muted-foreground));
339
+ }
340
+
341
+ /* Blockquote */
342
+ blockquote {
343
+ border-left-color: hsl(var(--primary));
344
+ color: hsl(var(--muted-foreground));
345
+ }
346
+
347
+ /* Horizontal rule */
348
+ hr {
349
+ border-color: hsl(var(--border));
350
+ }
351
+
352
+ /* Text selection */
353
+ ::selection {
354
+ background-color: hsl(var(--primary) / 0.3);
355
+ color: hsl(var(--foreground));
356
+ }
357
+
358
+ /* Focus visible */
359
+ :focus-visible {
360
+ outline-color: hsl(var(--ring));
361
+ }
362
+
363
+ /* Details / Summary */
364
+ details {
365
+ border-color: hsl(var(--border));
366
+ background-color: hsl(var(--card));
367
+ color: hsl(var(--card-foreground));
368
+ }
369
+
370
+ summary {
371
+ color: hsl(var(--foreground));
372
+ }
373
+
374
+ summary:hover {
375
+ color: hsl(var(--primary));
376
+ }
377
+
378
+ /* Progress */
379
+ progress {
380
+ accent-color: hsl(var(--primary));
381
+ }
382
+
383
+ progress::-webkit-progress-bar {
384
+ background-color: hsl(var(--muted));
385
+ }
386
+
387
+ progress::-webkit-progress-value {
388
+ background-color: hsl(var(--primary));
389
+ }
390
+
391
+ /* Meter */
392
+ meter::-webkit-meter-optimum-value {
393
+ background-color: hsl(var(--primary));
394
+ }
395
+
396
+ meter::-webkit-meter-bar {
397
+ background-color: hsl(var(--muted));
398
+ border-color: hsl(var(--border));
399
+ }
400
+
401
+ /* File input */
402
+ input[type="file"] {
403
+ color: hsl(var(--muted-foreground));
404
+ }
405
+
406
+ input[type="file"]::file-selector-button {
407
+ background-color: hsl(var(--secondary));
408
+ color: hsl(var(--secondary-foreground));
409
+ border-color: hsl(var(--border));
410
+ }
411
+
412
+ input[type="file"]::file-selector-button:hover {
413
+ background-color: hsl(var(--secondary) / 0.8);
414
+ }
415
+
416
+ /* Color input */
417
+ input[type="color"] {
418
+ border-color: hsl(var(--border));
419
+ background-color: hsl(var(--card));
420
+ }
421
+
422
+ /* Date/time inputs */
423
+ input[type="date"],
424
+ input[type="time"],
425
+ input[type="datetime-local"],
426
+ input[type="month"],
427
+ input[type="week"] {
428
+ background-color: hsl(var(--card));
429
+ color: hsl(var(--card-foreground));
430
+ border-color: hsl(var(--border));
431
+ }
432
+
433
+ /* Images */
434
+ img {
435
+ color: hsl(var(--muted-foreground));
436
+ }
437
+
438
+ /* Mark / highlight */
439
+ mark {
440
+ background-color: hsl(var(--primary) / 0.2);
441
+ color: hsl(var(--foreground));
442
+ }
443
+
444
+ /* Legend */
445
+ legend {
446
+ color: hsl(var(--foreground));
447
+ }
448
+
449
+ /* Fieldset */
450
+ fieldset {
451
+ border-color: hsl(var(--border));
452
+ }
453
+
454
+ /* Output */
455
+ output {
456
+ color: hsl(var(--foreground));
457
+ }
458
+
459
+ /* Citation */
460
+ cite {
461
+ color: hsl(var(--muted-foreground));
462
+ }
463
+
464
+ /* Definition */
465
+ dfn {
466
+ color: hsl(var(--foreground));
467
+ }
468
+
469
+ /* Address */
470
+ address {
471
+ color: hsl(var(--muted-foreground));
472
+ }
473
+
474
+ /* Figcaption */
475
+ figcaption {
476
+ color: hsl(var(--muted-foreground));
477
+ }
478
+
479
+ /* Time */
480
+ time {
481
+ color: hsl(var(--muted-foreground));
482
+ }
483
+
484
+ /* Iframe */
485
+ iframe {
486
+ border-color: hsl(var(--border));
487
+ }
488
+
489
+ /* Video / Audio */
490
+ video, audio {
491
+ background-color: hsl(var(--card));
492
+ border-color: hsl(var(--border));
493
+ }
494
+
495
+ /* Object / Embed */
496
+ object, embed {
497
+ border-color: hsl(var(--border));
498
+ }
499
+
500
+ /* Abbreviation */
501
+ abbr {
502
+ color: hsl(var(--muted-foreground));
503
+ }
package/dist/index.js ADDED
@@ -0,0 +1,142 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/index.js
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ ThemeProvider: () => ThemeProvider,
33
+ ThemeToggle: () => ThemeToggle,
34
+ useTheme: () => useTheme
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/theme-context.jsx
39
+ var import_react = __toESM(require("react"));
40
+ var COLOR_THEMES = ["purple", "red", "blue", "green", "orange"];
41
+ var COLOR_HEX = {
42
+ purple: "#6c55e7",
43
+ red: "#e74c3c",
44
+ blue: "#3498db",
45
+ green: "#2ecc71",
46
+ orange: "#f39c12"
47
+ };
48
+ var ThemeContext = (0, import_react.createContext)(null);
49
+ function ThemeProvider({ children }) {
50
+ const [theme, setThemeState] = (0, import_react.useState)(() => {
51
+ if (typeof window === "undefined") return "light";
52
+ const saved = localStorage.getItem("infinity-theme");
53
+ if (saved) return saved;
54
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
55
+ });
56
+ const [colorTheme, setColorThemeState] = (0, import_react.useState)(() => {
57
+ if (typeof window === "undefined") return "purple";
58
+ const saved = localStorage.getItem("infinity-color-theme");
59
+ if (saved && COLOR_THEMES.includes(saved)) return saved;
60
+ return "purple";
61
+ });
62
+ (0, import_react.useEffect)(() => {
63
+ const root = document.documentElement;
64
+ root.classList.remove("light", "dark");
65
+ root.classList.add(theme);
66
+ localStorage.setItem("infinity-theme", theme);
67
+ }, [theme]);
68
+ (0, import_react.useEffect)(() => {
69
+ const root = document.documentElement;
70
+ root.classList.remove(...COLOR_THEMES);
71
+ if (colorTheme !== "purple") {
72
+ root.classList.add(colorTheme);
73
+ }
74
+ localStorage.setItem("infinity-color-theme", colorTheme);
75
+ const metaThemeColor = document.getElementById("theme-color-meta");
76
+ if (metaThemeColor) {
77
+ metaThemeColor.setAttribute("content", COLOR_HEX[colorTheme] || COLOR_HEX.purple);
78
+ }
79
+ }, [colorTheme]);
80
+ const toggleTheme = () => {
81
+ setThemeState((prev) => prev === "light" ? "dark" : "light");
82
+ };
83
+ const setColorTheme = (color) => {
84
+ setColorThemeState(color);
85
+ };
86
+ return /* @__PURE__ */ import_react.default.createElement(ThemeContext.Provider, { value: { theme, toggleTheme, colorTheme, setColorTheme, colorThemes: COLOR_THEMES } }, children);
87
+ }
88
+ function useTheme() {
89
+ const context = (0, import_react.useContext)(ThemeContext);
90
+ if (!context) {
91
+ throw new Error("useTheme must be used within a ThemeProvider");
92
+ }
93
+ return context;
94
+ }
95
+
96
+ // src/ThemeToggle.jsx
97
+ var import_react2 = __toESM(require("react"));
98
+ var COLOR_OPTIONS = {
99
+ purple: { label: "Purple", color: "#a855f7" },
100
+ red: { label: "Red", color: "#ef4444" },
101
+ blue: { label: "Blue", color: "#3b82f6" },
102
+ green: { label: "Green", color: "#22c55e" },
103
+ orange: { label: "Orange", color: "#f97316" }
104
+ };
105
+ function ThemeToggle({ className = "" }) {
106
+ const { theme, toggleTheme, colorTheme, setColorTheme, colorThemes } = useTheme();
107
+ const [showColors, setShowColors] = (0, import_react2.useState)(false);
108
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: `infinity-theme-controls ${className}` }, /* @__PURE__ */ import_react2.default.createElement(
109
+ "button",
110
+ {
111
+ onClick: toggleTheme,
112
+ className: "infinity-theme-toggle-btn",
113
+ "aria-label": `Switch to ${theme === "light" ? "dark" : "light"} mode`,
114
+ title: "Toggle dark/light mode"
115
+ },
116
+ theme === "light" ? /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })) : /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "5" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" }))
117
+ ), /* @__PURE__ */ import_react2.default.createElement("div", { className: "infinity-color-picker-wrapper" }, /* @__PURE__ */ import_react2.default.createElement(
118
+ "button",
119
+ {
120
+ onClick: () => setShowColors(!showColors),
121
+ className: "infinity-color-picker-btn",
122
+ "aria-label": "Select color theme",
123
+ title: "Color theme"
124
+ },
125
+ /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "13.5", cy: "6.5", r: "2.5" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "17.5", cy: "10.5", r: "2.5" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "8.5", cy: "7.5", r: "2.5" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "6.5", cy: "12.5", r: "2.5" }), /* @__PURE__ */ import_react2.default.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.9 0 1.7-.8 1.7-1.7 0-.4-.2-.8-.4-1.1-.3-.3-.4-.7-.4-1.1 0-.9.8-1.7 1.7-1.7H16c3.3 0 6-2.7 6-6 0-5.5-4.5-9.4-10-9.4z" }))
126
+ ), showColors && /* @__PURE__ */ import_react2.default.createElement("div", { className: "infinity-color-picker-dropdown" }, colorThemes.map((color) => /* @__PURE__ */ import_react2.default.createElement(
127
+ "button",
128
+ {
129
+ key: color,
130
+ onClick: () => {
131
+ setColorTheme(color);
132
+ setShowColors(false);
133
+ },
134
+ className: `infinity-color-option ${colorTheme === color ? "active" : ""}`,
135
+ style: { backgroundColor: COLOR_OPTIONS[color].color },
136
+ "aria-label": `${COLOR_OPTIONS[color].label} theme`,
137
+ title: COLOR_OPTIONS[color].label
138
+ },
139
+ colorTheme === color && /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "20 6 9 17 4 12" }))
140
+ )))));
141
+ }
142
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.js", "../src/theme-context.jsx", "../src/ThemeToggle.jsx"],
4
+ "sourcesContent": ["export { ThemeProvider, useTheme } from './theme-context';\nexport { ThemeToggle } from './ThemeToggle';\n// import './globals.css';", "import React,{ createContext, useContext, useEffect, useState } from 'react';\n\nconst COLOR_THEMES = ['purple', 'red', 'blue', 'green', 'orange'];\n\nconst COLOR_HEX = {\n purple: '#6c55e7',\n red: '#e74c3c',\n blue: '#3498db',\n green: '#2ecc71',\n orange: '#f39c12',\n};\n\nconst ThemeContext = createContext(null);\n\nexport function ThemeProvider({ children }) {\n const [theme, setThemeState] = useState(() => {\n if (typeof window === 'undefined') return 'light';\n const saved = localStorage.getItem('infinity-theme');\n if (saved) return saved;\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n });\n\n const [colorTheme, setColorThemeState] = useState(() => {\n if (typeof window === 'undefined') return 'purple';\n const saved = localStorage.getItem('infinity-color-theme');\n if (saved && COLOR_THEMES.includes(saved)) return saved;\n return 'purple';\n });\n\n useEffect(() => {\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n root.classList.add(theme);\n localStorage.setItem('infinity-theme', theme);\n }, [theme]);\n\n useEffect(() => {\n const root = document.documentElement;\n root.classList.remove(...COLOR_THEMES);\n if (colorTheme !== 'purple') {\n root.classList.add(colorTheme);\n }\n localStorage.setItem('infinity-color-theme', colorTheme);\n\n const metaThemeColor = document.getElementById('theme-color-meta');\n if (metaThemeColor) {\n metaThemeColor.setAttribute('content', COLOR_HEX[colorTheme] || COLOR_HEX.purple);\n }\n }, [colorTheme]);\n\n const toggleTheme = () => {\n setThemeState((prev) => (prev === 'light' ? 'dark' : 'light'));\n };\n\n const setColorTheme = (color) => {\n setColorThemeState(color);\n };\n\n return (\n <ThemeContext.Provider value={{ theme, toggleTheme, colorTheme, setColorTheme, colorThemes: COLOR_THEMES }}>\n {children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n", "import React, { useState } from 'react';\nimport { useTheme } from './theme-context';\n\nconst COLOR_OPTIONS = {\n purple: { label: 'Purple', color: '#a855f7' },\n red: { label: 'Red', color: '#ef4444' },\n blue: { label: 'Blue', color: '#3b82f6' },\n green: { label: 'Green', color: '#22c55e' },\n orange: { label: 'Orange', color: '#f97316' },\n};\n\nexport function ThemeToggle({ className = '' }) {\n const { theme, toggleTheme, colorTheme, setColorTheme, colorThemes } = useTheme();\n const [showColors, setShowColors] = useState(false);\n\n return (\n <div className={`infinity-theme-controls ${className}`}>\n <button\n onClick={toggleTheme}\n className=\"infinity-theme-toggle-btn\"\n aria-label={`Switch to ${theme === 'light' ? 'dark' : 'light'} mode`}\n title=\"Toggle dark/light mode\"\n >\n {theme === 'light' ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\" />\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\" />\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\" />\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\" />\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\" />\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\" />\n </svg>\n )}\n </button>\n\n <div className=\"infinity-color-picker-wrapper\">\n <button\n onClick={() => setShowColors(!showColors)}\n className=\"infinity-color-picker-btn\"\n aria-label=\"Select color theme\"\n title=\"Color theme\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"13.5\" cy=\"6.5\" r=\"2.5\" />\n <circle cx=\"17.5\" cy=\"10.5\" r=\"2.5\" />\n <circle cx=\"8.5\" cy=\"7.5\" r=\"2.5\" />\n <circle cx=\"6.5\" cy=\"12.5\" r=\"2.5\" />\n <path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.9 0 1.7-.8 1.7-1.7 0-.4-.2-.8-.4-1.1-.3-.3-.4-.7-.4-1.1 0-.9.8-1.7 1.7-1.7H16c3.3 0 6-2.7 6-6 0-5.5-4.5-9.4-10-9.4z\" />\n </svg>\n </button>\n\n {showColors && (\n <div className=\"infinity-color-picker-dropdown\">\n {colorThemes.map((color) => (\n <button\n key={color}\n onClick={() => {\n setColorTheme(color);\n setShowColors(false);\n }}\n className={`infinity-color-option ${colorTheme === color ? 'active' : ''}`}\n style={{ backgroundColor: COLOR_OPTIONS[color].color }}\n aria-label={`${COLOR_OPTIONS[color].label} theme`}\n title={COLOR_OPTIONS[color].label}\n >\n {colorTheme === color && (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "import_react", "React"]
7
+ }
package/dist/index.mjs ADDED
@@ -0,0 +1,110 @@
1
+ // src/theme-context.jsx
2
+ import React, { createContext, useContext, useEffect, useState } from "react";
3
+ var COLOR_THEMES = ["purple", "red", "blue", "green", "orange"];
4
+ var COLOR_HEX = {
5
+ purple: "#6c55e7",
6
+ red: "#e74c3c",
7
+ blue: "#3498db",
8
+ green: "#2ecc71",
9
+ orange: "#f39c12"
10
+ };
11
+ var ThemeContext = createContext(null);
12
+ function ThemeProvider({ children }) {
13
+ const [theme, setThemeState] = useState(() => {
14
+ if (typeof window === "undefined") return "light";
15
+ const saved = localStorage.getItem("infinity-theme");
16
+ if (saved) return saved;
17
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
18
+ });
19
+ const [colorTheme, setColorThemeState] = useState(() => {
20
+ if (typeof window === "undefined") return "purple";
21
+ const saved = localStorage.getItem("infinity-color-theme");
22
+ if (saved && COLOR_THEMES.includes(saved)) return saved;
23
+ return "purple";
24
+ });
25
+ useEffect(() => {
26
+ const root = document.documentElement;
27
+ root.classList.remove("light", "dark");
28
+ root.classList.add(theme);
29
+ localStorage.setItem("infinity-theme", theme);
30
+ }, [theme]);
31
+ useEffect(() => {
32
+ const root = document.documentElement;
33
+ root.classList.remove(...COLOR_THEMES);
34
+ if (colorTheme !== "purple") {
35
+ root.classList.add(colorTheme);
36
+ }
37
+ localStorage.setItem("infinity-color-theme", colorTheme);
38
+ const metaThemeColor = document.getElementById("theme-color-meta");
39
+ if (metaThemeColor) {
40
+ metaThemeColor.setAttribute("content", COLOR_HEX[colorTheme] || COLOR_HEX.purple);
41
+ }
42
+ }, [colorTheme]);
43
+ const toggleTheme = () => {
44
+ setThemeState((prev) => prev === "light" ? "dark" : "light");
45
+ };
46
+ const setColorTheme = (color) => {
47
+ setColorThemeState(color);
48
+ };
49
+ return /* @__PURE__ */ React.createElement(ThemeContext.Provider, { value: { theme, toggleTheme, colorTheme, setColorTheme, colorThemes: COLOR_THEMES } }, children);
50
+ }
51
+ function useTheme() {
52
+ const context = useContext(ThemeContext);
53
+ if (!context) {
54
+ throw new Error("useTheme must be used within a ThemeProvider");
55
+ }
56
+ return context;
57
+ }
58
+
59
+ // src/ThemeToggle.jsx
60
+ import React2, { useState as useState2 } from "react";
61
+ var COLOR_OPTIONS = {
62
+ purple: { label: "Purple", color: "#a855f7" },
63
+ red: { label: "Red", color: "#ef4444" },
64
+ blue: { label: "Blue", color: "#3b82f6" },
65
+ green: { label: "Green", color: "#22c55e" },
66
+ orange: { label: "Orange", color: "#f97316" }
67
+ };
68
+ function ThemeToggle({ className = "" }) {
69
+ const { theme, toggleTheme, colorTheme, setColorTheme, colorThemes } = useTheme();
70
+ const [showColors, setShowColors] = useState2(false);
71
+ return /* @__PURE__ */ React2.createElement("div", { className: `infinity-theme-controls ${className}` }, /* @__PURE__ */ React2.createElement(
72
+ "button",
73
+ {
74
+ onClick: toggleTheme,
75
+ className: "infinity-theme-toggle-btn",
76
+ "aria-label": `Switch to ${theme === "light" ? "dark" : "light"} mode`,
77
+ title: "Toggle dark/light mode"
78
+ },
79
+ theme === "light" ? /* @__PURE__ */ React2.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React2.createElement("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })) : /* @__PURE__ */ React2.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React2.createElement("circle", { cx: "12", cy: "12", r: "5" }), /* @__PURE__ */ React2.createElement("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), /* @__PURE__ */ React2.createElement("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), /* @__PURE__ */ React2.createElement("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), /* @__PURE__ */ React2.createElement("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), /* @__PURE__ */ React2.createElement("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), /* @__PURE__ */ React2.createElement("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), /* @__PURE__ */ React2.createElement("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), /* @__PURE__ */ React2.createElement("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" }))
80
+ ), /* @__PURE__ */ React2.createElement("div", { className: "infinity-color-picker-wrapper" }, /* @__PURE__ */ React2.createElement(
81
+ "button",
82
+ {
83
+ onClick: () => setShowColors(!showColors),
84
+ className: "infinity-color-picker-btn",
85
+ "aria-label": "Select color theme",
86
+ title: "Color theme"
87
+ },
88
+ /* @__PURE__ */ React2.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React2.createElement("circle", { cx: "13.5", cy: "6.5", r: "2.5" }), /* @__PURE__ */ React2.createElement("circle", { cx: "17.5", cy: "10.5", r: "2.5" }), /* @__PURE__ */ React2.createElement("circle", { cx: "8.5", cy: "7.5", r: "2.5" }), /* @__PURE__ */ React2.createElement("circle", { cx: "6.5", cy: "12.5", r: "2.5" }), /* @__PURE__ */ React2.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.9 0 1.7-.8 1.7-1.7 0-.4-.2-.8-.4-1.1-.3-.3-.4-.7-.4-1.1 0-.9.8-1.7 1.7-1.7H16c3.3 0 6-2.7 6-6 0-5.5-4.5-9.4-10-9.4z" }))
89
+ ), showColors && /* @__PURE__ */ React2.createElement("div", { className: "infinity-color-picker-dropdown" }, colorThemes.map((color) => /* @__PURE__ */ React2.createElement(
90
+ "button",
91
+ {
92
+ key: color,
93
+ onClick: () => {
94
+ setColorTheme(color);
95
+ setShowColors(false);
96
+ },
97
+ className: `infinity-color-option ${colorTheme === color ? "active" : ""}`,
98
+ style: { backgroundColor: COLOR_OPTIONS[color].color },
99
+ "aria-label": `${COLOR_OPTIONS[color].label} theme`,
100
+ title: COLOR_OPTIONS[color].label
101
+ },
102
+ colorTheme === color && /* @__PURE__ */ React2.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React2.createElement("polyline", { points: "20 6 9 17 4 12" }))
103
+ )))));
104
+ }
105
+ export {
106
+ ThemeProvider,
107
+ ThemeToggle,
108
+ useTheme
109
+ };
110
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/theme-context.jsx", "../src/ThemeToggle.jsx"],
4
+ "sourcesContent": ["import React,{ createContext, useContext, useEffect, useState } from 'react';\n\nconst COLOR_THEMES = ['purple', 'red', 'blue', 'green', 'orange'];\n\nconst COLOR_HEX = {\n purple: '#6c55e7',\n red: '#e74c3c',\n blue: '#3498db',\n green: '#2ecc71',\n orange: '#f39c12',\n};\n\nconst ThemeContext = createContext(null);\n\nexport function ThemeProvider({ children }) {\n const [theme, setThemeState] = useState(() => {\n if (typeof window === 'undefined') return 'light';\n const saved = localStorage.getItem('infinity-theme');\n if (saved) return saved;\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n });\n\n const [colorTheme, setColorThemeState] = useState(() => {\n if (typeof window === 'undefined') return 'purple';\n const saved = localStorage.getItem('infinity-color-theme');\n if (saved && COLOR_THEMES.includes(saved)) return saved;\n return 'purple';\n });\n\n useEffect(() => {\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n root.classList.add(theme);\n localStorage.setItem('infinity-theme', theme);\n }, [theme]);\n\n useEffect(() => {\n const root = document.documentElement;\n root.classList.remove(...COLOR_THEMES);\n if (colorTheme !== 'purple') {\n root.classList.add(colorTheme);\n }\n localStorage.setItem('infinity-color-theme', colorTheme);\n\n const metaThemeColor = document.getElementById('theme-color-meta');\n if (metaThemeColor) {\n metaThemeColor.setAttribute('content', COLOR_HEX[colorTheme] || COLOR_HEX.purple);\n }\n }, [colorTheme]);\n\n const toggleTheme = () => {\n setThemeState((prev) => (prev === 'light' ? 'dark' : 'light'));\n };\n\n const setColorTheme = (color) => {\n setColorThemeState(color);\n };\n\n return (\n <ThemeContext.Provider value={{ theme, toggleTheme, colorTheme, setColorTheme, colorThemes: COLOR_THEMES }}>\n {children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n", "import React, { useState } from 'react';\nimport { useTheme } from './theme-context';\n\nconst COLOR_OPTIONS = {\n purple: { label: 'Purple', color: '#a855f7' },\n red: { label: 'Red', color: '#ef4444' },\n blue: { label: 'Blue', color: '#3b82f6' },\n green: { label: 'Green', color: '#22c55e' },\n orange: { label: 'Orange', color: '#f97316' },\n};\n\nexport function ThemeToggle({ className = '' }) {\n const { theme, toggleTheme, colorTheme, setColorTheme, colorThemes } = useTheme();\n const [showColors, setShowColors] = useState(false);\n\n return (\n <div className={`infinity-theme-controls ${className}`}>\n <button\n onClick={toggleTheme}\n className=\"infinity-theme-toggle-btn\"\n aria-label={`Switch to ${theme === 'light' ? 'dark' : 'light'} mode`}\n title=\"Toggle dark/light mode\"\n >\n {theme === 'light' ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\" />\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\" />\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\" />\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\" />\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\" />\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\" />\n </svg>\n )}\n </button>\n\n <div className=\"infinity-color-picker-wrapper\">\n <button\n onClick={() => setShowColors(!showColors)}\n className=\"infinity-color-picker-btn\"\n aria-label=\"Select color theme\"\n title=\"Color theme\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"13.5\" cy=\"6.5\" r=\"2.5\" />\n <circle cx=\"17.5\" cy=\"10.5\" r=\"2.5\" />\n <circle cx=\"8.5\" cy=\"7.5\" r=\"2.5\" />\n <circle cx=\"6.5\" cy=\"12.5\" r=\"2.5\" />\n <path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.9 0 1.7-.8 1.7-1.7 0-.4-.2-.8-.4-1.1-.3-.3-.4-.7-.4-1.1 0-.9.8-1.7 1.7-1.7H16c3.3 0 6-2.7 6-6 0-5.5-4.5-9.4-10-9.4z\" />\n </svg>\n </button>\n\n {showColors && (\n <div className=\"infinity-color-picker-dropdown\">\n {colorThemes.map((color) => (\n <button\n key={color}\n onClick={() => {\n setColorTheme(color);\n setShowColors(false);\n }}\n className={`infinity-color-option ${colorTheme === color ? 'active' : ''}`}\n style={{ backgroundColor: COLOR_OPTIONS[color].color }}\n aria-label={`${COLOR_OPTIONS[color].label} theme`}\n title={COLOR_OPTIONS[color].label}\n >\n {colorTheme === color && (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "useState", "useState", "React"]
7
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "infinity-theme",
3
+ "version": "1.3.0",
4
+ "description": "A lightweight React theme system with dark/light mode and 5 color themes using CSS custom properties",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.js"
11
+ },
12
+ "./globals.css": "./dist/globals.css"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "types": "dist/index.d.ts",
18
+ "sideEffects": [
19
+ "*.css"
20
+ ],
21
+ "browser": "dist/index.mjs",
22
+ "scripts": {
23
+ "build": "node build.mjs",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "react",
28
+ "theme",
29
+ "dark-mode",
30
+ "color-theme",
31
+ "css-variables",
32
+ "theme-provider",
33
+ "light-dark"
34
+ ],
35
+ "author": "",
36
+ "license": "MIT",
37
+ "peerDependencies": {
38
+ "react": ">=17.0.0",
39
+ "react-dom": ">=17.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "esbuild": "^0.25.0"
43
+ }
44
+ }