@tydavidson/design-system 1.1.5 → 1.1.7

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.
@@ -0,0 +1,668 @@
1
+ # Float Design System - Theme System Guide
2
+
3
+ A comprehensive guide for implementing and using the Float Design System's theme system in your React applications.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Quick Start](#quick-start)
9
+ - [Core Components](#core-components)
10
+ - [Theme Variables](#theme-variables)
11
+ - [Advanced Usage](#advanced-usage)
12
+ - [Framework Integration](#framework-integration)
13
+ - [Troubleshooting](#troubleshooting)
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @tydavidson/design-system
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Import Theme CSS
24
+
25
+ Import the theme CSS to get access to all theme variables:
26
+
27
+ ```css
28
+ /* In your main CSS file */
29
+ @import '@tydavidson/design-system/themes/theme.css';
30
+ ```
31
+
32
+ Or in your JavaScript/TypeScript:
33
+
34
+ ```typescript
35
+ import '@tydavidson/design-system/themes/theme.css';
36
+ ```
37
+
38
+ ### 2. Set up Theme Providers
39
+
40
+ Wrap your app with the theme providers:
41
+
42
+ ```tsx
43
+ import { ThemeProvider, ThemeContextProvider } from '@tydavidson/design-system';
44
+
45
+ function App() {
46
+ return (
47
+ <ThemeProvider>
48
+ <ThemeContextProvider>
49
+ {/* Your app content */}
50
+ <Header />
51
+ <Main />
52
+ <Footer />
53
+ </ThemeContextProvider>
54
+ </ThemeProvider>
55
+ );
56
+ }
57
+ ```
58
+
59
+ ### 3. Add Theme Toggle
60
+
61
+ Add the theme toggle component to your app:
62
+
63
+ ```tsx
64
+ import { ThemeToggle } from '@tydavidson/design-system';
65
+
66
+ function Header() {
67
+ return (
68
+ <header className="bg-bg-primary border-b border-border-primary p-4">
69
+ <div className="flex items-center justify-between">
70
+ <h1 className="text-text-primary text-xl font-bold">My App</h1>
71
+ <ThemeToggle variant="icon" size="md" />
72
+ </div>
73
+ </header>
74
+ );
75
+ }
76
+ ```
77
+
78
+ ## Core Components
79
+
80
+ ### ThemeToggle
81
+
82
+ A flexible component for switching between light and dark themes with multiple variants.
83
+
84
+ ```tsx
85
+ import { ThemeToggle } from '@tydavidson/design-system';
86
+
87
+ // Icon variant (default) - Compact toggle with sun/moon icons
88
+ <ThemeToggle variant="icon" size="md" />
89
+
90
+ // Button variant - Full button with text
91
+ <ThemeToggle variant="button" size="lg" />
92
+
93
+ // Switch variant - Toggle switch style
94
+ <ThemeToggle variant="switch" size="sm" />
95
+ ```
96
+
97
+ **Props:**
98
+ - `variant`: `'icon' | 'switch' | 'button'` (default: `'icon'`)
99
+ - `size`: `'sm' | 'md' | 'lg'` (default: `'md'`)
100
+ - `className`: Additional CSS classes
101
+
102
+ **Examples:**
103
+
104
+ ```tsx
105
+ // In a header
106
+ <div className="flex items-center gap-4">
107
+ <ThemeToggle variant="icon" size="sm" />
108
+ <ThemeToggle variant="button" size="md" />
109
+ </div>
110
+
111
+ // In a sidebar
112
+ <nav className="flex flex-col gap-2">
113
+ <ThemeToggle variant="switch" size="lg" />
114
+ </nav>
115
+ ```
116
+
117
+ ### useTheme Hook
118
+
119
+ Access theme state and functions in your components:
120
+
121
+ ```tsx
122
+ import { useTheme } from '@tydavidson/design-system';
123
+
124
+ function ThemeAwareComponent() {
125
+ const {
126
+ theme, // Current theme setting ('light', 'dark', 'system')
127
+ setTheme, // Function to change theme
128
+ resolvedTheme, // Actual theme ('light' or 'dark')
129
+ isDark, // Boolean for dark mode
130
+ isClient // Boolean for client-side rendering
131
+ } = useTheme();
132
+
133
+ return (
134
+ <div className="p-4 bg-bg-secondary border border-border-primary rounded-lg">
135
+ <h3 className="text-text-primary font-semibold mb-2">Theme Information</h3>
136
+ <div className="space-y-1 text-sm text-text-secondary">
137
+ <p>Current setting: {theme}</p>
138
+ <p>Resolved theme: {resolvedTheme}</p>
139
+ <p>Is dark mode: {isDark ? 'Yes' : 'No'}</p>
140
+ </div>
141
+
142
+ <div className="flex gap-2 mt-4">
143
+ <button
144
+ onClick={() => setTheme('light')}
145
+ className="px-3 py-1 bg-bg-primary border border-border-primary rounded text-text-primary hover:bg-bg-tertiary"
146
+ >
147
+ Light
148
+ </button>
149
+ <button
150
+ onClick={() => setTheme('dark')}
151
+ className="px-3 py-1 bg-bg-primary border border-border-primary rounded text-text-primary hover:bg-bg-tertiary"
152
+ >
153
+ Dark
154
+ </button>
155
+ <button
156
+ onClick={() => setTheme('system')}
157
+ className="px-3 py-1 bg-bg-primary border border-border-primary rounded text-text-primary hover:bg-bg-tertiary"
158
+ >
159
+ System
160
+ </button>
161
+ </div>
162
+ </div>
163
+ );
164
+ }
165
+ ```
166
+
167
+ ## Theme Variables
168
+
169
+ ### CSS Variables
170
+
171
+ The theme system provides comprehensive CSS custom properties:
172
+
173
+ ```css
174
+ /* Background colors */
175
+ .my-component {
176
+ background-color: var(--bg-primary);
177
+ color: var(--text-primary);
178
+ border: 1px solid var(--border-primary);
179
+ }
180
+
181
+ /* Semantic colors */
182
+ .success-message {
183
+ background-color: var(--bg-success-primary);
184
+ color: var(--text-success-primary);
185
+ border-color: var(--border-success);
186
+ }
187
+
188
+ .error-message {
189
+ background-color: var(--bg-error-primary);
190
+ color: var(--text-error-primary);
191
+ border-color: var(--border-error);
192
+ }
193
+ ```
194
+
195
+ ### Tailwind Classes
196
+
197
+ Use semantic color classes with Tailwind CSS:
198
+
199
+ ```tsx
200
+ // Basic layout
201
+ <div className="bg-bg-primary text-text-primary min-h-screen">
202
+ <header className="bg-bg-secondary border-b border-border-primary p-4">
203
+ <h1 className="text-text-primary font-bold">My App</h1>
204
+ </header>
205
+
206
+ <main className="p-6">
207
+ <div className="bg-bg-tertiary border border-border-secondary rounded-lg p-4">
208
+ <p className="text-text-secondary">Content goes here</p>
209
+ </div>
210
+ </main>
211
+ </div>
212
+
213
+ // Semantic components
214
+ <div className="space-y-4">
215
+ <div className="bg-bg-success-primary text-text-success-primary border border-border-success rounded p-3">
216
+ Success message
217
+ </div>
218
+
219
+ <div className="bg-bg-error-primary text-text-error-primary border border-border-error rounded p-3">
220
+ Error message
221
+ </div>
222
+
223
+ <div className="bg-bg-warning-primary text-text-warning-primary border border-border-warning rounded p-3">
224
+ Warning message
225
+ </div>
226
+ </div>
227
+ ```
228
+
229
+ ### Available Color Variables
230
+
231
+ #### Background Colors
232
+ - `--bg-primary` / `bg-bg-primary` - Main background
233
+ - `--bg-secondary` / `bg-bg-secondary` - Secondary background
234
+ - `--bg-tertiary` / `bg-bg-tertiary` - Tertiary background
235
+ - `--bg-quaternary` / `bg-bg-quaternary` - Quaternary background
236
+ - `--bg-disabled` / `bg-bg-disabled` - Disabled state background
237
+ - `--bg-overlay` / `bg-bg-overlay` - Overlay/modal background
238
+
239
+ #### Text Colors
240
+ - `--text-primary` / `text-text-primary` - Primary text
241
+ - `--text-secondary` / `text-text-secondary` - Secondary text
242
+ - `--text-tertiary` / `text-text-tertiary` - Tertiary text
243
+ - `--text-disabled` / `text-text-disabled` - Disabled text
244
+
245
+ #### Border Colors
246
+ - `--border-primary` / `border-border-primary` - Primary borders
247
+ - `--border-secondary` / `border-border-secondary` - Secondary borders
248
+ - `--border-tertiary` / `border-border-tertiary` - Tertiary borders
249
+ - `--border-disabled` / `border-border-disabled` - Disabled borders
250
+
251
+ #### Brand Colors
252
+ - `--bg-brand-primary` / `bg-bg-brand-primary` - Brand background
253
+ - `--text-brand-primary` / `text-text-brand-primary` - Brand text
254
+ - `--border-brand` / `border-border-brand` - Brand borders
255
+
256
+ #### Semantic Colors
257
+ - **Error**: `--bg-error-primary`, `--text-error-primary`, `--border-error`
258
+ - **Warning**: `--bg-warning-primary`, `--text-warning-primary`, `--border-warning`
259
+ - **Success**: `--bg-success-primary`, `--text-success-primary`, `--border-success`
260
+
261
+ ## Advanced Usage
262
+
263
+ ### Custom Theme Detection
264
+
265
+ ```tsx
266
+ import { isDarkTheme } from '@tydavidson/design-system';
267
+
268
+ function ConditionalComponent() {
269
+ const { theme, systemTheme } = useTheme();
270
+ const isDark = isDarkTheme(theme, systemTheme);
271
+
272
+ return (
273
+ <div className={isDark ? 'dark-mode-styles' : 'light-mode-styles'}>
274
+ {isDark ? 'Dark mode content' : 'Light mode content'}
275
+ </div>
276
+ );
277
+ }
278
+ ```
279
+
280
+ ### Color Mapping Utilities
281
+
282
+ ```tsx
283
+ import {
284
+ mapColorToShadcnVariant,
285
+ mapVariantToShadcnVariant,
286
+ getColorVariantClasses
287
+ } from '@tydavidson/design-system';
288
+
289
+ // Map design system colors to shadcn variants
290
+ const variant = mapColorToShadcnVariant('brand'); // returns 'default'
291
+ const errorVariant = mapColorToShadcnVariant('error'); // returns 'destructive'
292
+
293
+ // Map design system variants to shadcn variants
294
+ const shadcnVariant = mapVariantToShadcnVariant('primary'); // returns 'default'
295
+ const outlineVariant = mapVariantToShadcnVariant('secondary'); // returns 'outline'
296
+
297
+ // Get Tailwind classes for color/variant combinations
298
+ const primaryClasses = getColorVariantClasses('brand', 'primary');
299
+ // returns: 'bg-brand-600 hover:bg-brand-700 text-white focus-visible:ring-brand-500'
300
+
301
+ const secondaryClasses = getColorVariantClasses('error', 'secondary');
302
+ // returns: 'border-error-300 text-error-700 hover:bg-error-50 focus-visible:ring-error-500'
303
+ ```
304
+
305
+ ### Dynamic Theme Switching
306
+
307
+ ```tsx
308
+ import { useTheme } from '@tydavidson/design-system';
309
+
310
+ function ThemeSwitcher() {
311
+ const { theme, setTheme, resolvedTheme } = useTheme();
312
+
313
+ const themes = [
314
+ { value: 'light', label: 'Light', icon: '☀️' },
315
+ { value: 'dark', label: 'Dark', icon: '🌙' },
316
+ { value: 'system', label: 'System', icon: '💻' }
317
+ ];
318
+
319
+ return (
320
+ <div className="flex gap-2">
321
+ {themes.map(({ value, label, icon }) => (
322
+ <button
323
+ key={value}
324
+ onClick={() => setTheme(value)}
325
+ className={`px-3 py-2 rounded border transition-colors ${
326
+ theme === value
327
+ ? 'bg-bg-brand-primary text-text-brand-primary border-border-brand'
328
+ : 'bg-bg-primary text-text-primary border-border-primary hover:bg-bg-secondary'
329
+ }`}
330
+ >
331
+ <span className="mr-2">{icon}</span>
332
+ {label}
333
+ </button>
334
+ ))}
335
+ </div>
336
+ );
337
+ }
338
+ ```
339
+
340
+ ### Theme-Aware Components
341
+
342
+ ```tsx
343
+ import { useTheme } from '@tydavidson/design-system';
344
+
345
+ function ThemeAwareCard({ title, children, variant = 'default' }) {
346
+ const { isDark } = useTheme();
347
+
348
+ const variants = {
349
+ default: 'bg-bg-primary border-border-primary',
350
+ elevated: isDark ? 'bg-bg-secondary border-border-secondary shadow-lg' : 'bg-white border-border-primary shadow-md',
351
+ brand: 'bg-bg-brand-primary border-border-brand',
352
+ error: 'bg-bg-error-primary border-border-error',
353
+ success: 'bg-bg-success-primary border-border-success'
354
+ };
355
+
356
+ return (
357
+ <div className={`p-6 rounded-lg border ${variants[variant]}`}>
358
+ <h3 className="text-text-primary font-semibold mb-3">{title}</h3>
359
+ <div className="text-text-secondary">{children}</div>
360
+ </div>
361
+ );
362
+ }
363
+
364
+ // Usage
365
+ <ThemeAwareCard title="Default Card" variant="default">
366
+ This is a default card
367
+ </ThemeAwareCard>
368
+
369
+ <ThemeAwareCard title="Brand Card" variant="brand">
370
+ This is a brand-themed card
371
+ </ThemeAwareCard>
372
+ ```
373
+
374
+ ## Framework Integration
375
+
376
+ ### Next.js App Router
377
+
378
+ ```tsx
379
+ // app/layout.tsx
380
+ import { ThemeProvider, ThemeContextProvider } from '@tydavidson/design-system';
381
+ import '@tydavidson/design-system/themes/theme.css';
382
+
383
+ export default function RootLayout({
384
+ children,
385
+ }: {
386
+ children: React.ReactNode
387
+ }) {
388
+ return (
389
+ <html lang="en" suppressHydrationWarning>
390
+ <body className="bg-bg-primary text-text-primary">
391
+ <ThemeProvider>
392
+ <ThemeContextProvider>
393
+ {children}
394
+ </ThemeContextProvider>
395
+ </ThemeProvider>
396
+ </body>
397
+ </html>
398
+ );
399
+ }
400
+ ```
401
+
402
+ ### Next.js Pages Router
403
+
404
+ ```tsx
405
+ // pages/_app.tsx
406
+ import { ThemeProvider, ThemeContextProvider } from '@tydavidson/design-system';
407
+ import '@tydavidson/design-system/themes/theme.css';
408
+
409
+ function MyApp({ Component, pageProps }) {
410
+ return (
411
+ <ThemeProvider>
412
+ <ThemeContextProvider>
413
+ <Component {...pageProps} />
414
+ </ThemeContextProvider>
415
+ </ThemeProvider>
416
+ );
417
+ }
418
+
419
+ export default MyApp;
420
+ ```
421
+
422
+ ### Create React App
423
+
424
+ ```tsx
425
+ // src/App.tsx
426
+ import { ThemeProvider, ThemeContextProvider } from '@tydavidson/design-system';
427
+ import '@tydavidson/design-system/themes/theme.css';
428
+
429
+ function App() {
430
+ return (
431
+ <ThemeProvider>
432
+ <ThemeContextProvider>
433
+ <div className="bg-bg-primary text-text-primary min-h-screen">
434
+ {/* Your app content */}
435
+ </div>
436
+ </ThemeContextProvider>
437
+ </ThemeProvider>
438
+ );
439
+ }
440
+
441
+ export default App;
442
+ ```
443
+
444
+ ### Tailwind Configuration
445
+
446
+ Extend your Tailwind config to use theme variables:
447
+
448
+ ```js
449
+ // tailwind.config.js
450
+ module.exports = {
451
+ darkMode: ["class"],
452
+ content: [
453
+ "./src/**/*.{js,ts,jsx,tsx}",
454
+ ],
455
+ theme: {
456
+ extend: {
457
+ colors: {
458
+ // Background colors
459
+ bg: {
460
+ primary: 'var(--bg-primary)',
461
+ secondary: 'var(--bg-secondary)',
462
+ tertiary: 'var(--bg-tertiary)',
463
+ quaternary: 'var(--bg-quaternary)',
464
+ disabled: 'var(--bg-disabled)',
465
+ overlay: 'var(--bg-overlay)',
466
+ 'brand-primary': 'var(--bg-brand-primary)',
467
+ 'error-primary': 'var(--bg-error-primary)',
468
+ 'warning-primary': 'var(--bg-warning-primary)',
469
+ 'success-primary': 'var(--bg-success-primary)',
470
+ },
471
+ // Text colors
472
+ text: {
473
+ primary: 'var(--text-primary)',
474
+ secondary: 'var(--text-secondary)',
475
+ tertiary: 'var(--text-tertiary)',
476
+ disabled: 'var(--text-disabled)',
477
+ 'brand-primary': 'var(--text-brand-primary)',
478
+ 'error-primary': 'var(--text-error-primary)',
479
+ 'warning-primary': 'var(--text-warning-primary)',
480
+ 'success-primary': 'var(--text-success-primary)',
481
+ },
482
+ // Border colors
483
+ border: {
484
+ primary: 'var(--border-primary)',
485
+ secondary: 'var(--border-secondary)',
486
+ tertiary: 'var(--border-tertiary)',
487
+ disabled: 'var(--border-disabled)',
488
+ brand: 'var(--border-brand)',
489
+ error: 'var(--border-error)',
490
+ warning: 'var(--border-warning)',
491
+ success: 'var(--border-success)',
492
+ }
493
+ }
494
+ }
495
+ },
496
+ plugins: [],
497
+ }
498
+ ```
499
+
500
+ ## Troubleshooting
501
+
502
+ ### Hydration Mismatch
503
+
504
+ **Problem**: Server-side rendering doesn't match client-side rendering.
505
+
506
+ **Solutions**:
507
+ 1. Add `suppressHydrationWarning` to the HTML element
508
+ 2. Check `isClient` before rendering theme-dependent content
509
+ 3. Use the `useTheme` hook properly
510
+
511
+ ```tsx
512
+ function ThemeDependentComponent() {
513
+ const { isClient, isDark } = useTheme();
514
+
515
+ // Don't render until client-side
516
+ if (!isClient) return null;
517
+
518
+ return (
519
+ <div className={isDark ? 'dark-styles' : 'light-styles'}>
520
+ Theme-dependent content
521
+ </div>
522
+ );
523
+ }
524
+ ```
525
+
526
+ ### Theme Not Switching
527
+
528
+ **Problem**: Theme toggle doesn't change the appearance.
529
+
530
+ **Solutions**:
531
+ 1. Verify theme CSS is imported
532
+ 2. Check theme providers are wrapping your app
533
+ 3. Ensure `next-themes` is properly configured
534
+ 4. Confirm Tailwind config includes theme variables
535
+
536
+ ```tsx
537
+ // Debug theme state
538
+ function ThemeDebugger() {
539
+ const { theme, setTheme, resolvedTheme, isDark, isClient } = useTheme();
540
+
541
+ return (
542
+ <div className="p-4 bg-bg-secondary border border-border-primary rounded">
543
+ <h3 className="text-text-primary font-semibold mb-2">Theme Debug</h3>
544
+ <div className="text-sm text-text-secondary space-y-1">
545
+ <p>Client: {isClient ? 'Yes' : 'No'}</p>
546
+ <p>Theme: {theme}</p>
547
+ <p>Resolved: {resolvedTheme}</p>
548
+ <p>Is Dark: {isDark ? 'Yes' : 'No'}</p>
549
+ </div>
550
+ </div>
551
+ );
552
+ }
553
+ ```
554
+
555
+ ### Styling Issues
556
+
557
+ **Problem**: Theme styles aren't applying correctly.
558
+
559
+ **Solutions**:
560
+ 1. Verify CSS variables are imported
561
+ 2. Check Tailwind configuration includes theme colors
562
+ 3. Ensure correct class names are used
563
+ 4. Confirm theme providers are in correct order
564
+
565
+ ```css
566
+ /* Test CSS variables are working */
567
+ .theme-test {
568
+ background-color: var(--bg-primary);
569
+ color: var(--text-primary);
570
+ border: 1px solid var(--border-primary);
571
+ }
572
+ ```
573
+
574
+ ### Performance Optimization
575
+
576
+ **Best Practices**:
577
+ 1. Use CSS variables for dynamic theming
578
+ 2. Avoid inline styles for theme-dependent styles
579
+ 3. Use Tailwind classes when possible
580
+ 4. Minimize theme-dependent JavaScript
581
+
582
+ ```tsx
583
+ // Good: Use CSS variables and Tailwind
584
+ <div className="bg-bg-primary text-text-primary border border-border-primary">
585
+ Content
586
+ </div>
587
+
588
+ // Avoid: Inline styles for theme
589
+ <div style={{
590
+ backgroundColor: isDark ? '#000' : '#fff',
591
+ color: isDark ? '#fff' : '#000'
592
+ }}>
593
+ Content
594
+ </div>
595
+ ```
596
+
597
+ ## Examples
598
+
599
+ ### Complete App Example
600
+
601
+ ```tsx
602
+ import { ThemeProvider, ThemeContextProvider, ThemeToggle } from '@tydavidson/design-system';
603
+ import '@tydavidson/design-system/themes/theme.css';
604
+
605
+ function App() {
606
+ return (
607
+ <ThemeProvider>
608
+ <ThemeContextProvider>
609
+ <div className="min-h-screen bg-bg-primary text-text-primary">
610
+ <Header />
611
+ <Main />
612
+ <Footer />
613
+ </div>
614
+ </ThemeContextProvider>
615
+ </ThemeProvider>
616
+ );
617
+ }
618
+
619
+ function Header() {
620
+ return (
621
+ <header className="bg-bg-secondary border-b border-border-primary p-4">
622
+ <div className="max-w-6xl mx-auto flex items-center justify-between">
623
+ <h1 className="text-xl font-bold text-text-primary">My App</h1>
624
+ <ThemeToggle variant="icon" size="md" />
625
+ </div>
626
+ </header>
627
+ );
628
+ }
629
+
630
+ function Main() {
631
+ return (
632
+ <main className="max-w-6xl mx-auto p-6">
633
+ <div className="grid gap-6">
634
+ <section className="bg-bg-secondary border border-border-primary rounded-lg p-6">
635
+ <h2 className="text-lg font-semibold text-text-primary mb-4">Welcome</h2>
636
+ <p className="text-text-secondary">
637
+ This app uses the Float Design System theme system.
638
+ </p>
639
+ </section>
640
+
641
+ <section className="grid grid-cols-1 md:grid-cols-3 gap-4">
642
+ <div className="bg-bg-success-primary text-text-success-primary border border-border-success rounded-lg p-4">
643
+ Success Card
644
+ </div>
645
+ <div className="bg-bg-error-primary text-text-error-primary border border-border-error rounded-lg p-4">
646
+ Error Card
647
+ </div>
648
+ <div className="bg-bg-warning-primary text-text-warning-primary border border-border-warning rounded-lg p-4">
649
+ Warning Card
650
+ </div>
651
+ </section>
652
+ </div>
653
+ </main>
654
+ );
655
+ }
656
+
657
+ function Footer() {
658
+ return (
659
+ <footer className="bg-bg-secondary border-t border-border-primary p-4 mt-auto">
660
+ <div className="max-w-6xl mx-auto text-center text-text-secondary">
661
+ © 2024 My App. Built with Float Design System.
662
+ </div>
663
+ </footer>
664
+ );
665
+ }
666
+ ```
667
+
668
+ This comprehensive guide should help you implement and use the Float Design System theme system effectively in your projects!