@discourser/design-system 0.4.0 → 0.6.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.
Files changed (42) hide show
  1. package/README.md +12 -4
  2. package/dist/index.cjs +240 -260
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +67 -90
  5. package/dist/index.d.ts +67 -90
  6. package/dist/index.js +238 -258
  7. package/dist/index.js.map +1 -1
  8. package/dist/styles.css +5126 -0
  9. package/guidelines/Guidelines.md +67 -123
  10. package/guidelines/components/accordion.md +93 -0
  11. package/guidelines/components/avatar.md +70 -0
  12. package/guidelines/components/badge.md +61 -0
  13. package/guidelines/components/button.md +75 -40
  14. package/guidelines/components/card.md +84 -25
  15. package/guidelines/components/checkbox.md +88 -0
  16. package/guidelines/components/dialog.md +619 -31
  17. package/guidelines/components/drawer.md +655 -0
  18. package/guidelines/components/heading.md +71 -0
  19. package/guidelines/components/icon-button.md +92 -37
  20. package/guidelines/components/input-addon.md +685 -0
  21. package/guidelines/components/input-group.md +830 -0
  22. package/guidelines/components/input.md +92 -37
  23. package/guidelines/components/popover.md +71 -0
  24. package/guidelines/components/progress.md +63 -0
  25. package/guidelines/components/radio-group.md +95 -0
  26. package/guidelines/components/select.md +507 -0
  27. package/guidelines/components/skeleton.md +76 -0
  28. package/guidelines/components/slider.md +911 -0
  29. package/guidelines/components/spinner.md +783 -0
  30. package/guidelines/components/switch.md +105 -38
  31. package/guidelines/components/tabs.md +654 -0
  32. package/guidelines/components/textarea.md +70 -0
  33. package/guidelines/components/toast.md +77 -0
  34. package/guidelines/components/tooltip.md +80 -0
  35. package/guidelines/design-tokens/colors.md +309 -72
  36. package/guidelines/design-tokens/elevation.md +615 -45
  37. package/guidelines/design-tokens/spacing.md +654 -74
  38. package/guidelines/design-tokens/typography.md +432 -50
  39. package/guidelines/overview-components.md +9 -5
  40. package/guidelines/overview-imports.md +314 -0
  41. package/guidelines/overview-patterns.md +3852 -0
  42. package/package.json +14 -2
@@ -5,6 +5,7 @@ The design system uses Material Design 3 semantic color tokens. **Always use sem
5
5
  ## Why Semantic Colors?
6
6
 
7
7
  Semantic colors automatically adapt to light/dark themes and follow M3 color roles. Using semantic names ensures:
8
+
8
9
  - Automatic theme switching
9
10
  - Consistent contrast ratios
10
11
  - Proper color relationships
@@ -13,96 +14,105 @@ Semantic colors automatically adapt to light/dark themes and follow M3 color rol
13
14
  ## Semantic Colors Reference
14
15
 
15
16
  ### Primary Colors
17
+
16
18
  Used for primary actions, key UI elements, and brand identity.
17
19
 
18
- | Token | Light Mode | Dark Mode | Usage |
19
- |-------|-----------|-----------|-------|
20
- | `primary` | #4C662B | #B1D18A | Primary buttons, active states, links |
21
- | `onPrimary` | #FFFFFF | #1F3701 | Text/icons on primary color |
22
- | `primaryContainer` | #CDEDA3 | #354E16 | Containers for primary content |
23
- | `onPrimaryContainer` | #354E16 | #CDEDA3 | Text/icons on primary container |
20
+ | Token | Light Mode | Dark Mode | Usage |
21
+ | -------------------- | ---------- | --------- | ------------------------------------- |
22
+ | `primary` | #4C662B | #B1D18A | Primary buttons, active states, links |
23
+ | `onPrimary` | #FFFFFF | #1F3701 | Text/icons on primary color |
24
+ | `primaryContainer` | #CDEDA3 | #354E16 | Containers for primary content |
25
+ | `onPrimaryContainer` | #354E16 | #CDEDA3 | Text/icons on primary container |
24
26
 
25
27
  ### Secondary Colors
28
+
26
29
  Used for secondary actions and less prominent UI elements.
27
30
 
28
- | Token | Light Mode | Dark Mode | Usage |
29
- |-------|-----------|-----------|-------|
30
- | `secondary` | #586249 | #BFCBAD | Secondary buttons, less prominent actions |
31
- | `onSecondary` | #FFFFFF | #2A331E | Text/icons on secondary color |
32
- | `secondaryContainer` | #DCE7C8 | #404A33 | Secondary containers |
33
- | `onSecondaryContainer` | #404A33 | #DCE7C8 | Text/icons on secondary container |
31
+ | Token | Light Mode | Dark Mode | Usage |
32
+ | ---------------------- | ---------- | --------- | ----------------------------------------- |
33
+ | `secondary` | #586249 | #BFCBAD | Secondary buttons, less prominent actions |
34
+ | `onSecondary` | #FFFFFF | #2A331E | Text/icons on secondary color |
35
+ | `secondaryContainer` | #DCE7C8 | #404A33 | Secondary containers |
36
+ | `onSecondaryContainer` | #404A33 | #DCE7C8 | Text/icons on secondary container |
34
37
 
35
38
  ### Tertiary Colors
39
+
36
40
  Used for accent colors and tertiary actions.
37
41
 
38
- | Token | Light Mode | Dark Mode | Usage |
39
- |-------|-----------|-----------|-------|
40
- | `tertiary` | #386663 | #A0D0CB | Accent colors, tertiary actions |
41
- | `onTertiary` | #FFFFFF | #003735 | Text/icons on tertiary color |
42
- | `tertiaryContainer` | #BCECE7 | #1F4E4B | Tertiary containers |
43
- | `onTertiaryContainer` | #1F4E4B | #BCECE7 | Text/icons on tertiary container |
42
+ | Token | Light Mode | Dark Mode | Usage |
43
+ | --------------------- | ---------- | --------- | -------------------------------- |
44
+ | `tertiary` | #386663 | #A0D0CB | Accent colors, tertiary actions |
45
+ | `onTertiary` | #FFFFFF | #003735 | Text/icons on tertiary color |
46
+ | `tertiaryContainer` | #BCECE7 | #1F4E4B | Tertiary containers |
47
+ | `onTertiaryContainer` | #1F4E4B | #BCECE7 | Text/icons on tertiary container |
44
48
 
45
49
  ### Error Colors
50
+
46
51
  Used for error states, warnings, and destructive actions.
47
52
 
48
- | Token | Light Mode | Dark Mode | Usage |
49
- |-------|-----------|-----------|-------|
50
- | `error` | #BA1A1A | #FFB4AB | Error text, error icons |
51
- | `onError` | #FFFFFF | #690005 | Text/icons on error color |
52
- | `errorContainer` | #FFDAD6 | #93000A | Error message backgrounds |
53
- | `onErrorContainer` | #93000A | #FFDAD6 | Text/icons in error containers |
53
+ | Token | Light Mode | Dark Mode | Usage |
54
+ | ------------------ | ---------- | --------- | ------------------------------ |
55
+ | `error` | #BA1A1A | #FFB4AB | Error text, error icons |
56
+ | `onError` | #FFFFFF | #690005 | Text/icons on error color |
57
+ | `errorContainer` | #FFDAD6 | #93000A | Error message backgrounds |
58
+ | `onErrorContainer` | #93000A | #FFDAD6 | Text/icons in error containers |
54
59
 
55
60
  ### Surface Colors
61
+
56
62
  Used for backgrounds and containers at different elevations.
57
63
 
58
- | Token | Light Mode | Dark Mode | Usage |
59
- |-------|-----------|-----------|-------|
60
- | `surface` | #F9FAEF | #12140E | Default background |
61
- | `onSurface` | #1A1C16 | #E2E3D8 | Default text color |
62
- | `surfaceVariant` | #E1E4D5 | #44483D | Alternate surface (subtle contrast) |
63
- | `onSurfaceVariant` | #44483D | #C5C8BA | Text on variant surfaces |
64
+ | Token | Light Mode | Dark Mode | Usage |
65
+ | ------------------ | ---------- | --------- | ----------------------------------- |
66
+ | `surface` | #F9FAEF | #12140E | Default background |
67
+ | `onSurface` | #1A1C16 | #E2E3D8 | Default text color |
68
+ | `surfaceVariant` | #E1E4D5 | #44483D | Alternate surface (subtle contrast) |
69
+ | `onSurfaceVariant` | #44483D | #C5C8BA | Text on variant surfaces |
64
70
 
65
71
  ### Surface Container Elevations
72
+
66
73
  M3 uses surface tints instead of shadows for elevation. Higher elevations get lighter in light mode, darker in dark mode.
67
74
 
68
- | Token | Light Mode | Dark Mode | Usage |
69
- |-------|-----------|-----------|-------|
70
- | `surfaceContainerLowest` | #FFFFFF | #0C0F09 | Lowest elevation (0dp) |
71
- | `surfaceContainerLow` | #F3F4E9 | #1A1C16 | Low elevation (1dp) - Cards |
72
- | `surfaceContainer` | #EEEFE3 | #1E201A | Default containers (3dp) |
73
- | `surfaceContainerHigh` | #E8E9DE | #282B24 | High elevation (4dp) - Dialogs |
74
- | `surfaceContainerHighest` | #E2E3D8 | #33362E | Highest elevation (5dp) |
75
+ | Token | Light Mode | Dark Mode | Usage |
76
+ | ------------------------- | ---------- | --------- | ------------------------------ |
77
+ | `surfaceContainerLowest` | #FFFFFF | #0C0F09 | Lowest elevation (0dp) |
78
+ | `surfaceContainerLow` | #F3F4E9 | #1A1C16 | Low elevation (1dp) - Cards |
79
+ | `surfaceContainer` | #EEEFE3 | #1E201A | Default containers (3dp) |
80
+ | `surfaceContainerHigh` | #E8E9DE | #282B24 | High elevation (4dp) - Dialogs |
81
+ | `surfaceContainerHighest` | #E2E3D8 | #33362E | Highest elevation (5dp) |
75
82
 
76
83
  ### Outline Colors
84
+
77
85
  Used for borders and dividers.
78
86
 
79
- | Token | Light Mode | Dark Mode | Usage |
80
- |-------|-----------|-----------|-------|
81
- | `outline` | #75796C | #8F9285 | Borders, dividers |
82
- | `outlineVariant` | #C5C8BA | #44483D | Subtle borders |
87
+ | Token | Light Mode | Dark Mode | Usage |
88
+ | ---------------- | ---------- | --------- | ----------------- |
89
+ | `outline` | #75796C | #8F9285 | Borders, dividers |
90
+ | `outlineVariant` | #C5C8BA | #44483D | Subtle borders |
83
91
 
84
92
  ### Inverse Colors
93
+
85
94
  Used for inverse color schemes (e.g., snackbars).
86
95
 
87
- | Token | Light Mode | Dark Mode | Usage |
88
- |-------|-----------|-----------|-------|
89
- | `inverseSurface` | #2F312A | #E2E3D8 | Inverse backgrounds |
90
- | `inverseOnSurface` | #F1F2E6 | #2F312A | Text on inverse surfaces |
91
- | `inversePrimary` | #B1D18A | #4C662B | Primary color on inverse |
96
+ | Token | Light Mode | Dark Mode | Usage |
97
+ | ------------------ | ---------- | --------- | ------------------------ |
98
+ | `inverseSurface` | #2F312A | #E2E3D8 | Inverse backgrounds |
99
+ | `inverseOnSurface` | #F1F2E6 | #2F312A | Text on inverse surfaces |
100
+ | `inversePrimary` | #B1D18A | #4C662B | Primary color on inverse |
92
101
 
93
102
  ### Background Colors
103
+
94
104
  Used for page/app backgrounds.
95
105
 
96
- | Token | Light Mode | Dark Mode | Usage |
97
- |-------|-----------|-----------|-------|
98
- | `background` | #F9FAEF | #12140E | Page background |
99
- | `onBackground` | #1A1C16 | #E2E3D8 | Text on background |
106
+ | Token | Light Mode | Dark Mode | Usage |
107
+ | -------------- | ---------- | --------- | ------------------ |
108
+ | `background` | #F9FAEF | #12140E | Page background |
109
+ | `onBackground` | #1A1C16 | #E2E3D8 | Text on background |
100
110
 
101
111
  ### Special Colors
102
112
 
103
- | Token | Value | Usage |
104
- |-------|-------|-------|
105
- | `scrim` | #000000 | Overlay behind modals/dialogs |
113
+ | Token | Value | Usage |
114
+ | -------- | ------- | ----------------------------------- |
115
+ | `scrim` | #000000 | Overlay behind modals/dialogs |
106
116
  | `shadow` | #000000 | Shadow color (rarely used directly) |
107
117
 
108
118
  ## Usage in Code
@@ -116,17 +126,17 @@ import { css } from '@discourser/design-system/styled-system/css';
116
126
  const container = css({
117
127
  bg: 'surfaceContainerLow',
118
128
  color: 'onSurface',
119
- borderColor: 'outline'
129
+ borderColor: 'outline',
120
130
  });
121
131
 
122
132
  const primaryAction = css({
123
133
  bg: 'primary',
124
- color: 'onPrimary'
134
+ color: 'onPrimary',
125
135
  });
126
136
 
127
137
  const errorMessage = css({
128
138
  bg: 'errorContainer',
129
- color: 'onErrorContainer'
139
+ color: 'onErrorContainer',
130
140
  });
131
141
  ```
132
142
 
@@ -134,21 +144,21 @@ const errorMessage = css({
134
144
 
135
145
  ```typescript
136
146
  // Card backgrounds
137
- bg: 'surfaceContainerLow' // For elevated cards
138
- bg: 'surface' // For filled/outlined cards
147
+ bg: 'surfaceContainerLow'; // For elevated cards
148
+ bg: 'surface'; // For filled/outlined cards
139
149
 
140
150
  // Text colors
141
- color: 'onSurface' // Primary text
142
- color: 'onSurfaceVariant' // Secondary text
151
+ color: 'onSurface'; // Primary text
152
+ color: 'onSurfaceVariant'; // Secondary text
143
153
 
144
154
  // Borders
145
- borderColor: 'outline' // Standard borders
146
- borderColor: 'outlineVariant' // Subtle borders
155
+ borderColor: 'outline'; // Standard borders
156
+ borderColor: 'outlineVariant'; // Subtle borders
147
157
 
148
158
  // Interactive states
149
- bg: 'primary' // Default
150
- bg: 'primaryContainer' // Hover/focus
151
- color: 'onPrimary' // Text on primary
159
+ bg: 'primary'; // Default
160
+ bg: 'primaryContainer'; // Hover/focus
161
+ color: 'onPrimary'; // Text on primary
152
162
  ```
153
163
 
154
164
  ## What NOT to Do
@@ -171,14 +181,241 @@ const correct = css({ bg: 'surface' });
171
181
 
172
182
  Always pair colors with their corresponding "on" color for proper contrast:
173
183
 
174
- | Background | Text/Icon Color | Use Case |
175
- |-----------|----------------|----------|
176
- | `primary` | `onPrimary` | Filled buttons |
184
+ | Background | Text/Icon Color | Use Case |
185
+ | ------------------ | -------------------- | -------------------- |
186
+ | `primary` | `onPrimary` | Filled buttons |
177
187
  | `primaryContainer` | `onPrimaryContainer` | Tonal buttons, chips |
178
- | `surface` | `onSurface` | Default backgrounds |
179
- | `surfaceVariant` | `onSurfaceVariant` | Alternate surfaces |
180
- | `error` | `onError` | Error badges |
181
- | `errorContainer` | `onErrorContainer` | Error messages |
188
+ | `surface` | `onSurface` | Default backgrounds |
189
+ | `surfaceVariant` | `onSurfaceVariant` | Alternate surfaces |
190
+ | `error` | `onError` | Error badges |
191
+ | `errorContainer` | `onErrorContainer` | Error messages |
192
+
193
+ ## How Color Tokens Work With Other Tokens
194
+
195
+ Color tokens are rarely used in isolation. Here are real-world examples showing how colors combine with typography, spacing, and elevation tokens:
196
+
197
+ ### Primary Button (Filled Variant)
198
+
199
+ ```typescript
200
+ import { Button } from '@discourser/design-system';
201
+
202
+ // Button uses these tokens together:
203
+ <Button variant="filled">
204
+ {/* Component internally uses: */}
205
+ bg: 'primary' // Color token - #4C662B in light mode
206
+ color: 'onPrimary' // Color token - #FFFFFF in light mode
207
+ textStyle: 'labelLarge' // Typography token - 14px/20px
208
+ px: 'lg' // Spacing token - 24px
209
+ height: '40px' // Size token - md variant
210
+ borderRadius: 'full' // Border radius - fully rounded
211
+ _hover: {
212
+ bg: 'primaryContainer' // Color token - hover state
213
+ }
214
+ </Button>
215
+ ```
216
+
217
+ ### Elevated Card Component
218
+
219
+ ```typescript
220
+ import { Card } from '@discourser/design-system';
221
+ import { css } from '@discourser/design-system/styled-system/css';
222
+
223
+ <Card variant="elevated">
224
+ {/* Card uses these tokens together: */}
225
+ bg: 'surfaceContainerLow' // Color token - elevated surface
226
+ color: 'onSurface' // Color token - default text
227
+ borderRadius: 'l3' // Border radius - 12px
228
+ boxShadow: 'level1' // Elevation token - subtle shadow
229
+ _hover: {
230
+ boxShadow: 'level2' // Elevation token - hover shadow
231
+ }
232
+
233
+ <div className={css({ p: 'lg' })}>
234
+ {/* Content padding: Spacing token - 24px */}
235
+
236
+ <h3 className={css({
237
+ textStyle: 'titleLarge', // Typography - 22px/28px
238
+ color: 'onSurface', // Color - primary text
239
+ mb: 'sm' // Spacing - 8px bottom margin
240
+ })}>
241
+ Card Title
242
+ </h3>
243
+
244
+ <p className={css({
245
+ textStyle: 'bodyMedium', // Typography - 14px/20px
246
+ color: 'onSurfaceVariant' // Color - secondary text
247
+ })}>
248
+ Card description with proper contrast.
249
+ </p>
250
+ </div>
251
+ </Card>
252
+ ```
253
+
254
+ ### Form Input with Error State
255
+
256
+ ```typescript
257
+ import { Input } from '@discourser/design-system';
258
+
259
+ <Input
260
+ label="Email"
261
+ errorText="Invalid email address"
262
+ {/* Input combines these tokens: */}
263
+ bg: 'surface' // Color - transparent/white
264
+ color: 'onSurface' // Color - input text
265
+ borderColor: 'error' // Color - error state border
266
+ textStyle: 'bodyLarge' // Typography - 16px/24px
267
+ px: 'md' // Spacing - 16px horizontal padding
268
+ py: 'sm' // Spacing - 8px vertical padding
269
+ height: '56px' // Size - md variant
270
+ borderRadius: 'l1' // Border radius - 4px
271
+
272
+ {/* Error text uses: */}
273
+ errorTextColor: 'error' // Color - #BA1A1A
274
+ errorTextStyle: 'bodySmall' // Typography - 12px/16px
275
+ />
276
+ ```
277
+
278
+ ### Dialog with Actions
279
+
280
+ ```typescript
281
+ import { Dialog, Button } from '@discourser/design-system';
282
+ import { css } from '@discourser/design-system/styled-system/css';
283
+
284
+ <Dialog.Root>
285
+ <Dialog.Backdrop
286
+ bg: 'scrim' // Color - semi-transparent black
287
+ opacity: 0.32 // Opacity for backdrop
288
+ />
289
+
290
+ <Dialog.Content
291
+ bg: 'surfaceContainerHigh' // Color - high elevation surface
292
+ color: 'onSurface' // Color - default text
293
+ borderRadius: 'l4' // Border radius - 28px
294
+ p: 'xl' // Spacing - 32px padding
295
+ boxShadow: 'level3' // Elevation - dialog shadow
296
+ minWidth: '280px' // Size - sm variant
297
+ >
298
+ <Dialog.Title
299
+ textStyle: 'headlineSmall' // Typography - 24px/32px
300
+ color: 'onSurface' // Color - primary text
301
+ mb: 'md' // Spacing - 16px bottom margin
302
+ >
303
+ Confirm Action
304
+ </Dialog.Title>
305
+
306
+ <Dialog.Description
307
+ textStyle: 'bodyMedium' // Typography - 14px/20px
308
+ color: 'onSurfaceVariant' // Color - secondary text
309
+ mb: 'lg' // Spacing - 24px bottom margin
310
+ >
311
+ Are you sure you want to proceed?
312
+ </Dialog.Description>
313
+
314
+ <div className={css({
315
+ display: 'flex',
316
+ gap: 'sm', // Spacing - 8px between buttons
317
+ justifyContent: 'flex-end'
318
+ })}>
319
+ <Button variant="text"
320
+ color: 'primary' // Color - text button
321
+ textStyle: 'labelLarge' // Typography - 14px/20px
322
+ px: 'lg' // Spacing - 24px horizontal
323
+ >
324
+ Cancel
325
+ </Button>
326
+
327
+ <Button variant="filled"
328
+ bg: 'primary' // Color - primary background
329
+ color: 'onPrimary' // Color - white text
330
+ textStyle: 'labelLarge' // Typography - 14px/20px
331
+ px: 'lg' // Spacing - 24px horizontal
332
+ >
333
+ Confirm
334
+ </Button>
335
+ </div>
336
+ </Dialog.Content>
337
+ </Dialog.Root>
338
+ ```
339
+
340
+ ### Toast Notification (Success)
341
+
342
+ ```typescript
343
+ import { toaster } from '@discourser/design-system';
344
+
345
+ toaster.success({
346
+ title: "Changes saved",
347
+ {/* Toast combines: */}
348
+ bg: 'inverseSurface' // Color - dark background
349
+ color: 'inverseOnSurface' // Color - light text
350
+ borderRadius: 'l1' // Border radius - 4px
351
+ p: 'md' // Spacing - 16px padding
352
+ textStyle: 'bodyMedium' // Typography - 14px/20px
353
+ boxShadow: 'level2' // Elevation - floating shadow
354
+
355
+ {/* Success icon uses: */}
356
+ iconColor: 'inversePrimary' // Color - brand color on dark
357
+ });
358
+ ```
359
+
360
+ ### Badge Component
361
+
362
+ ```typescript
363
+ import { Badge } from '@discourser/design-system';
364
+
365
+ <Badge variant="solid" colorPalette="error">
366
+ {/* Badge combines: */}
367
+ bg: 'error' // Color - error background
368
+ color: 'onError' // Color - white text
369
+ textStyle: 'labelSmall' // Typography - 11px/16px
370
+ px: 'sm' // Spacing - 8px horizontal
371
+ py: '2xs' // Spacing - 2px vertical
372
+ borderRadius: 'full' // Border radius - fully rounded
373
+ height: '20px' // Size - sm variant
374
+ </Badge>
375
+ ```
376
+
377
+ ### Multi-Token Pattern Summary
378
+
379
+ When designing components, tokens typically combine in these patterns:
380
+
381
+ **Container Pattern:**
382
+
383
+ ```typescript
384
+ {
385
+ bg: 'surface*', // Surface color token
386
+ color: 'onSurface*', // Corresponding text color
387
+ p: 'md-xl', // Spacing for padding
388
+ borderRadius: 'l1-l4', // Border radius
389
+ boxShadow: 'level*' // Elevation (if elevated)
390
+ }
391
+ ```
392
+
393
+ **Text Pattern:**
394
+
395
+ ```typescript
396
+ {
397
+ textStyle: 'body*|title*', // Typography token
398
+ color: 'onSurface*', // Color token for text
399
+ mb/mt: 'sm-lg' // Spacing for margins
400
+ }
401
+ ```
402
+
403
+ **Interactive Pattern:**
404
+
405
+ ```typescript
406
+ {
407
+ bg: 'primary*', // Color for background
408
+ color: 'onPrimary*', // Contrast color for text
409
+ textStyle: 'label*', // Typography for labels
410
+ px: 'lg', // Horizontal spacing
411
+ py: 'sm', // Vertical spacing
412
+ borderRadius: 'full', // Border radius
413
+ _hover: {
414
+ bg: 'primaryContainer', // Hover state color
415
+ boxShadow: 'level1' // Hover elevation
416
+ }
417
+ }
418
+ ```
182
419
 
183
420
  ## Accessibility
184
421