@tydavidson/design-system 1.1.6 → 1.1.8

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,253 @@
1
+ # Component-Specific Color System
2
+
3
+ ## Overview
4
+
5
+ The component-specific color system is designed to provide isolated, scoped color variables for individual components while maintaining consistency with our global design system. This approach allows components to have their own semantic color variables without polluting the global namespace or creating conflicts.
6
+
7
+ ## Architecture
8
+
9
+ The system follows a layered approach:
10
+
11
+ ```
12
+ src/
13
+ ├── styles/
14
+ │ ├── components/ # Component-specific CSS files
15
+ │ │ └── button.css # Button-specific variables
16
+ │ ├── constants/ # TypeScript constants
17
+ │ │ └── button-colors.ts # Button color constants
18
+ │ └── index.css # Main CSS entry point
19
+ └── components/
20
+ └── Button.tsx # Component implementation
21
+ ```
22
+
23
+ ## Naming Convention (Updated)
24
+
25
+ ### **Current Pattern: Component-First Naming**
26
+
27
+ Component-specific variables follow this pattern:
28
+ ```
29
+ --{component}-{property}-{variant}-{state}
30
+ ```
31
+
32
+ **Examples:**
33
+ - `--button-bg-primary` (Button component, background property, primary variant)
34
+ - `--button-bg-primary-hover` (Button component, background property, primary variant, hover state)
35
+ - `--input-border-focus` (Input component, border property, focus state)
36
+ - `--dropdown-item-bg-brand-hover` (Dropdown component, item sub-component, background property, brand variant, hover state)
37
+
38
+ ### **Why This Pattern?**
39
+
40
+ 1. **Component Grouping**: All variables for a component are grouped together (e.g., `--button-*`)
41
+ 2. **Developer Experience**: Autocomplete shows all related variables when typing component name
42
+ 3. **Third-party Override**: Removes namespace conflicts, allows overriding third-party library variables
43
+ 4. **Semantic Alignment**: Matches our global semantic pattern (`--bg-primary`, `--text-secondary`)
44
+
45
+ ### **Pattern Breakdown**
46
+
47
+ | Part | Purpose | Examples |
48
+ |------|---------|----------|
49
+ | `{component}` | Component name | `button`, `input`, `dropdown`, `sidebar`, `card` |
50
+ | `{property}` | CSS property type | `bg`, `text`, `border`, `shadow`, `width` |
51
+ | `{variant}` | Semantic or style variant | `primary`, `secondary`, `brand`, `error`, `outline` |
52
+ | `{state}` | Interactive state | `hover`, `focus`, `active`, `disabled`, `checked` |
53
+
54
+ ### **Complete Examples by Component**
55
+
56
+ **Button Variables:**
57
+ ```css
58
+ --button-bg-primary
59
+ --button-bg-primary-hover
60
+ --button-bg-secondary
61
+ --button-bg-destructive
62
+ --button-text-primary
63
+ --button-text-link
64
+ --button-text-link-hover
65
+ --button-border-outline
66
+ --button-border-outline-hover
67
+ --button-icon-size-sm
68
+ ```
69
+
70
+ **Input Variables:**
71
+ ```css
72
+ --input-bg
73
+ --input-bg-disabled
74
+ --input-text
75
+ --input-text-placeholder
76
+ --input-border
77
+ --input-border-hover
78
+ --input-border-focus
79
+ --input-ring
80
+ ```
81
+
82
+ **Dropdown Variables:**
83
+ ```css
84
+ --dropdown-bg
85
+ --dropdown-text
86
+ --dropdown-border
87
+ --dropdown-item-bg-hover
88
+ --dropdown-item-text-brand-hover
89
+ --dropdown-separator-bg
90
+ ```
91
+
92
+ ### **Alignment with Global Semantic Variables**
93
+
94
+ Our component variables perfectly complement the global semantic system:
95
+
96
+ ```css
97
+ /* Global Semantic Variables */
98
+ --bg-primary, --bg-secondary, --bg-brand-primary
99
+ --text-primary, --text-error-primary
100
+ --border-primary, --border-brand
101
+
102
+ /* Component Variables (Same Pattern) */
103
+ --button-bg-primary, --button-text-primary, --button-border-primary
104
+ --input-bg, --input-text, --input-border-focus
105
+ --dropdown-bg, --dropdown-item-bg-hover
106
+ ```
107
+
108
+ ## Implementation Details
109
+
110
+ ### 1. CSS Variables (button.css)
111
+
112
+ Component-specific variables are defined at the root level:
113
+
114
+ ```css
115
+ :root {
116
+ --button-bg-primary: var(--color-brand-700);
117
+ --button-bg-primary-hover: var(--color-brand-800);
118
+ --button-text-primary: white;
119
+ --button-text-primary-hover: white;
120
+ --button-border-primary: var(--color-brand-700);
121
+ --button-border-primary-hover: var(--color-brand-800);
122
+ }
123
+
124
+ .dark {
125
+ --button-bg-primary: var(--color-brand-700);
126
+ --button-bg-primary-hover: var(--color-brand-800);
127
+ /* Dark theme overrides */
128
+ }
129
+ ```
130
+
131
+ ### 2. TypeScript Constants (button-colors.ts)
132
+
133
+ For type safety and autocompletion, we define constants:
134
+
135
+ ```typescript
136
+ export const BUTTON_COLORS = {
137
+ primary: {
138
+ bg: 'var(--button-bg-primary)',
139
+ bgHover: 'var(--button-bg-primary-hover)',
140
+ text: 'var(--button-text-primary)',
141
+ textHover: 'var(--button-text-primary-hover)',
142
+ border: 'var(--button-border-primary)',
143
+ borderHover: 'var(--button-border-primary-hover)',
144
+ },
145
+ // ... other variants
146
+ } as const;
147
+
148
+ export type ButtonVariant = keyof typeof BUTTON_COLORS;
149
+ ```
150
+
151
+ ### 3. Usage in Components
152
+
153
+ Components use these variables through Tailwind's arbitrary value syntax:
154
+
155
+ ```tsx
156
+ <button
157
+ className={cn(
158
+ 'bg-[var(--button-bg-primary)]',
159
+ 'text-[var(--button-text-primary)]',
160
+ 'border-[var(--button-border-primary)]',
161
+ 'hover:bg-[var(--button-bg-primary-hover)]',
162
+ 'hover:text-[var(--button-text-primary-hover)]'
163
+ )}
164
+ >
165
+ ```
166
+
167
+ ## Benefits
168
+
169
+ 1. **Component Grouping**: All variables for a component are logically grouped
170
+ 2. **Autocomplete Friendly**: Type `--button-` to see all button-related variables
171
+ 3. **Third-party Integration**: Can override third-party library variables with same names
172
+ 4. **Semantic Consistency**: Aligns with global design system naming patterns
173
+ 5. **Type Safety**: TypeScript constants provide type checking and autocompletion
174
+ 6. **Maintainability**: Clear organization and naming conventions
175
+ 7. **Flexibility**: Easy to modify component-specific colors without affecting global system
176
+
177
+ ## Best Practices
178
+
179
+ 1. **Consistent Naming**: Always follow the `--{component}-{property}-{variant}-{state}` pattern
180
+ 2. **Property Names**: Use consistent property names (`bg`, `text`, `border`, not `background`, `color`, `border-color`)
181
+ 3. **Semantic Variants**: Use semantic names (`primary`, `secondary`) over style names (`blue`, `large`)
182
+ 4. **Global References**: Always reference global design tokens for actual color values
183
+ 5. **Documentation**: Keep component-specific variables documented
184
+ 6. **TypeScript**: Create corresponding TypeScript constants for all CSS variables
185
+
186
+ ## Adding New Components
187
+
188
+ To add component-specific colors for a new component:
189
+
190
+ 1. Create a new CSS file in `styles/components/`
191
+ 2. Define variables following the naming convention: `--{component}-{property}-{variant}`
192
+ 3. Create corresponding TypeScript constants
193
+ 4. Import the CSS file in `globals.css`
194
+ 5. Use the variables in your component
195
+
196
+ ## Example: Adding a New Component
197
+
198
+ ```css
199
+ /* styles/components/card.css */
200
+ :root {
201
+ --card-bg-default: var(--bg-secondary);
202
+ --card-bg-subtle: var(--bg-primary);
203
+ --card-border: var(--border-tertiary);
204
+ --card-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.05);
205
+ --card-title-text: var(--text-primary);
206
+ --card-description-text: var(--text-tertiary);
207
+ }
208
+ ```
209
+
210
+ ```typescript
211
+ // styles/constants/card-colors.ts
212
+ export const CARD_COLORS = {
213
+ default: {
214
+ bg: 'var(--card-bg-default)',
215
+ border: 'var(--card-border)',
216
+ shadow: 'var(--card-shadow)',
217
+ },
218
+ subtle: {
219
+ bg: 'var(--card-bg-subtle)',
220
+ border: 'var(--card-border)',
221
+ },
222
+ title: {
223
+ text: 'var(--card-title-text)',
224
+ },
225
+ description: {
226
+ text: 'var(--card-description-text)',
227
+ },
228
+ } as const;
229
+ ```
230
+
231
+ ## Migration Guide
232
+
233
+ When migrating from the old `--float-*` naming convention:
234
+
235
+ 1. **Identify all existing variables** used by the component
236
+ 2. **Map to new naming pattern**:
237
+ - `--float-button-primary-bg` → `--button-bg-primary`
238
+ - `--float-input-border-focus` → `--input-border-focus`
239
+ - `--float-dropdown-item-brand-bg-hover` → `--dropdown-item-bg-brand-hover`
240
+ 3. **Update CSS files** with new variable names
241
+ 4. **Update TypeScript constants** to reference new variables
242
+ 5. **Update component usage** to use new variable names
243
+ 6. **Remove old variables** once migration is complete
244
+
245
+ ## Troubleshooting
246
+
247
+ Common issues and solutions:
248
+
249
+ 1. **Variables not applying**: Ensure variables are defined in `:root` scope, not component-scoped classes
250
+ 2. **Type errors**: Check that TypeScript constants are properly exported and imported
251
+ 3. **Missing variables**: Verify that all needed variables are defined following the naming pattern
252
+ 4. **Inconsistent colors**: Ensure variables reference the correct global design tokens
253
+ 5. **Autocomplete not working**: Verify variable names follow the exact pattern `--{component}-{property}-{variant}`
@@ -0,0 +1,373 @@
1
+ # Design System Setup Guide
2
+
3
+ This guide helps you set up the Float Design System in your project and avoid common integration issues.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @tydavidson/design-system
9
+ ```
10
+
11
+ ## Required Dependencies
12
+
13
+ The design system requires these peer dependencies (only Tabler icons are used):
14
+
15
+ ```bash
16
+ npm install react react-dom next-themes @tabler/icons-react
17
+ ```
18
+
19
+ ## CSS Setup
20
+
21
+ ### 1. Import Theme CSS
22
+
23
+ Import the theme CSS file in your app's root layout or main CSS file:
24
+
25
+ ```css
26
+ /* In your global CSS file */
27
+ @import '@tydavidson/design-system/themes/theme.css';
28
+ ```
29
+
30
+ Or in your Next.js app:
31
+
32
+ ```tsx
33
+ // app/layout.tsx or pages/_app.tsx
34
+ import '@tydavidson/design-system/themes/theme.css';
35
+ ```
36
+
37
+ ### 2. Configure Tailwind CSS
38
+
39
+ Add the design system's color tokens to your `tailwind.config.js`:
40
+
41
+ ```js
42
+ // tailwind.config.js
43
+ module.exports = {
44
+ darkMode: ["class"],
45
+ content: [
46
+ "./src/**/*.{js,ts,jsx,tsx}",
47
+ "./node_modules/@tydavidson/design-system/dist/**/*.{js,mjs}",
48
+ ],
49
+ theme: {
50
+ extend: {
51
+ colors: {
52
+ // Background colors
53
+ bg: {
54
+ primary: 'var(--bg-primary)',
55
+ secondary: 'var(--bg-secondary)',
56
+ tertiary: 'var(--bg-tertiary)',
57
+ quaternary: 'var(--bg-quaternary)',
58
+ disabled: 'var(--bg-disabled)',
59
+ overlay: 'var(--bg-overlay)',
60
+ 'brand-primary': 'var(--bg-brand-primary)',
61
+ 'error-primary': 'var(--bg-error-primary)',
62
+ 'warning-primary': 'var(--bg-warning-primary)',
63
+ 'success-primary': 'var(--bg-success-primary)',
64
+ },
65
+ // Text colors
66
+ text: {
67
+ primary: 'var(--text-primary)',
68
+ secondary: 'var(--text-secondary)',
69
+ tertiary: 'var(--text-tertiary)',
70
+ disabled: 'var(--text-disabled)',
71
+ 'brand-primary': 'var(--text-brand-primary)',
72
+ 'error-primary': 'var(--text-error-primary)',
73
+ 'warning-primary': 'var(--text-warning-primary)',
74
+ 'success-primary': 'var(--text-success-primary)',
75
+ },
76
+ // Border colors
77
+ border: {
78
+ primary: 'var(--border-primary)',
79
+ secondary: 'var(--border-secondary)',
80
+ tertiary: 'var(--border-tertiary)',
81
+ disabled: 'var(--border-disabled)',
82
+ brand: 'var(--border-brand)',
83
+ error: 'var(--border-error)',
84
+ warning: 'var(--border-warning)',
85
+ success: 'var(--border-success)',
86
+ }
87
+ }
88
+ }
89
+ },
90
+ plugins: [],
91
+ }
92
+ ```
93
+
94
+ ## Theme Provider Setup
95
+
96
+ ### Next.js App Router
97
+
98
+ **Option 1: Safe Theme Provider (Recommended)**
99
+ ```tsx
100
+ // app/layout.tsx
101
+ import { SafeThemeProvider } from '@tydavidson/design-system/themes';
102
+
103
+ export default function RootLayout({
104
+ children,
105
+ }: {
106
+ children: React.ReactNode;
107
+ }) {
108
+ return (
109
+ <html lang="en" suppressHydrationWarning>
110
+ <body>
111
+ <SafeThemeProvider>
112
+ {children}
113
+ </SafeThemeProvider>
114
+ </body>
115
+ </html>
116
+ );
117
+ }
118
+ ```
119
+
120
+ **Option 2: NoSSR Theme Provider**
121
+ ```tsx
122
+ // app/layout.tsx
123
+ import { ThemeProviderNoSSR } from '@tydavidson/design-system/themes';
124
+
125
+ export default function RootLayout({
126
+ children,
127
+ }: {
128
+ children: React.ReactNode;
129
+ }) {
130
+ return (
131
+ <html lang="en" suppressHydrationWarning>
132
+ <body>
133
+ <ThemeProviderNoSSR>
134
+ {children}
135
+ </ThemeProviderNoSSR>
136
+ </body>
137
+ </html>
138
+ );
139
+ }
140
+ ```
141
+
142
+ **Option 3: Dynamic Import (For Server Components)**
143
+ ```tsx
144
+ // app/layout.tsx
145
+ import { DynamicThemeProvider } from '@tydavidson/design-system/themes';
146
+
147
+ export default function RootLayout({
148
+ children,
149
+ }: {
150
+ children: React.ReactNode;
151
+ }) {
152
+ return (
153
+ <html lang="en" suppressHydrationWarning>
154
+ <body>
155
+ <DynamicThemeProvider>
156
+ {children}
157
+ </DynamicThemeProvider>
158
+ </body>
159
+ </html>
160
+ );
161
+ }
162
+ ```
163
+
164
+ ### Next.js Pages Router
165
+
166
+ ```tsx
167
+ // pages/_app.tsx
168
+ import { ThemeProvider } from '@tydavidson/design-system/themes';
169
+
170
+ export default function App({ Component, pageProps }) {
171
+ return (
172
+ <ThemeProvider>
173
+ <Component {...pageProps} />
174
+ </ThemeProvider>
175
+ );
176
+ }
177
+ ```
178
+
179
+ ### React (Create React App)
180
+
181
+ ```tsx
182
+ // App.tsx
183
+ import { ThemeProvider } from '@tydavidson/design-system/themes';
184
+
185
+ function App() {
186
+ return (
187
+ <ThemeProvider>
188
+ {/* Your app content */}
189
+ </ThemeProvider>
190
+ );
191
+ }
192
+ ```
193
+
194
+ ## Usage Examples
195
+
196
+ ### Basic Theme Usage
197
+
198
+ ```tsx
199
+ import { useTheme, ThemeToggle } from '@tydavidson/design-system/themes';
200
+
201
+ function MyComponent() {
202
+ const { theme, setTheme, isDark } = useTheme();
203
+
204
+ return (
205
+ <div>
206
+ <p>Current theme: {theme}</p>
207
+ <p>Is dark mode: {isDark ? 'Yes' : 'No'}</p>
208
+ <ThemeToggle />
209
+ </div>
210
+ );
211
+ }
212
+ ```
213
+
214
+ ### Using UI Components
215
+
216
+ ```tsx
217
+ import { Button, Card, CardContent, CardHeader, CardTitle } from '@tydavidson/design-system';
218
+
219
+ function MyPage() {
220
+ return (
221
+ <Card>
222
+ <CardHeader>
223
+ <CardTitle>My Card</CardTitle>
224
+ </CardHeader>
225
+ <CardContent>
226
+ <Button>Click me</Button>
227
+ </CardContent>
228
+ </Card>
229
+ );
230
+ }
231
+ ```
232
+
233
+ ## Server Component Compatibility
234
+
235
+ ### Using Theme System in Server Components
236
+
237
+ The design system provides several options for using theme functionality in Next.js App Router Server Components:
238
+
239
+ **For Server Components:**
240
+ ```tsx
241
+ // Use the server-safe hook
242
+ import { useThemeServer } from '@tydavidson/design-system/themes';
243
+
244
+ export default function ServerComponent() {
245
+ const { theme, isDark } = useThemeServer();
246
+
247
+ return (
248
+ <div className={isDark ? 'dark' : 'light'}>
249
+ Current theme: {theme}
250
+ </div>
251
+ );
252
+ }
253
+ ```
254
+
255
+ **For Client Components:**
256
+ ```tsx
257
+ 'use client';
258
+ import { useTheme } from '@tydavidson/design-system/themes';
259
+
260
+ export default function ClientComponent() {
261
+ const { theme, setTheme, isDark } = useTheme();
262
+
263
+ return (
264
+ <button onClick={() => setTheme('dark')}>
265
+ Switch to Dark Mode
266
+ </button>
267
+ );
268
+ }
269
+ ```
270
+
271
+ **Dynamic Theme Toggle in Server Components:**
272
+ ```tsx
273
+ import { DynamicThemeToggle } from '@tydavidson/design-system/themes';
274
+
275
+ export default function ServerComponent() {
276
+ return (
277
+ <div>
278
+ <h1>My Page</h1>
279
+ <DynamicThemeToggle />
280
+ </div>
281
+ );
282
+ }
283
+ ```
284
+
285
+ ## Common Issues and Solutions
286
+
287
+ ### 1. React Context Errors in Server Components
288
+
289
+ **Problem**: Server-side rendering doesn't match client-side rendering.
290
+
291
+ **Solution**:
292
+ - Add `suppressHydrationWarning` to your `<html>` element
293
+ - Use the `mounted` pattern for client-only components:
294
+
295
+ ```tsx
296
+ function ClientOnlyComponent() {
297
+ const [mounted, setMounted] = useState(false);
298
+
299
+ useEffect(() => {
300
+ setMounted(true);
301
+ }, []);
302
+
303
+ if (!mounted) return null;
304
+
305
+ return <ThemeToggle />;
306
+ }
307
+ ```
308
+
309
+ ### 2. CSS Variables Not Working
310
+
311
+ **Problem**: Theme colors aren't applying correctly.
312
+
313
+ **Solution**:
314
+ - Ensure you've imported the theme CSS file
315
+ - Check that your Tailwind config includes the color tokens
316
+ - Verify the CSS variables are being set on the `:root` element
317
+
318
+ ### 3. Icons Not Displaying
319
+
320
+ **Problem**: Icons appear as empty boxes or don't render.
321
+
322
+ **Solution**:
323
+ - Install required icon library: `npm install @tabler/icons-react`
324
+ - Ensure the icon library is available in your bundle
325
+
326
+ ### 4. TypeScript Errors
327
+
328
+ **Problem**: TypeScript can't find types for the design system.
329
+
330
+ **Solution**:
331
+ - The package includes TypeScript declarations
332
+ - Make sure your `tsconfig.json` includes `node_modules` in the module resolution
333
+ - If using path aliases, ensure they're configured correctly
334
+
335
+ ### 5. Bundle Size Issues
336
+
337
+ **Problem**: The design system is making your bundle too large.
338
+
339
+ **Solution**:
340
+ - The package uses tree-shaking, so unused components won't be included
341
+ - Icon libraries are external dependencies, so they won't be bundled
342
+ - Consider using dynamic imports for large components:
343
+
344
+ ```tsx
345
+ const DynamicComponent = dynamic(() => import('@tydavidson/design-system').then(mod => ({ default: mod.SomeLargeComponent })));
346
+ ```
347
+
348
+ ## Browser Compatibility
349
+
350
+ The design system supports:
351
+ - Modern browsers (Chrome, Firefox, Safari, Edge)
352
+ - React 18+
353
+ - Next.js 13+ (App Router and Pages Router)
354
+ - Create React App
355
+
356
+ ## Performance Considerations
357
+
358
+ 1. **Tree Shaking**: Only import what you need
359
+ 2. **CSS Variables**: Theme changes are handled via CSS variables for optimal performance
360
+ 3. **Icon Library**: Icons are external dependencies to avoid duplication
361
+ 4. **Bundle Splitting**: Consider code-splitting for large applications
362
+
363
+ ## Troubleshooting
364
+
365
+ If you encounter issues:
366
+
367
+ 1. Check the browser console for errors
368
+ 2. Verify all dependencies are installed
369
+ 3. Ensure CSS is properly imported
370
+ 4. Check that the ThemeProvider is wrapping your app
371
+ 5. Verify Tailwind configuration includes the design system's content paths
372
+
373
+ For additional help, refer to the [theme usage documentation](./theme-usage.md).