@discourser/design-system 0.4.0 → 0.5.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 (36) hide show
  1. package/README.md +12 -4
  2. package/dist/styles.css +5126 -0
  3. package/guidelines/Guidelines.md +67 -123
  4. package/guidelines/components/accordion.md +93 -0
  5. package/guidelines/components/avatar.md +70 -0
  6. package/guidelines/components/badge.md +61 -0
  7. package/guidelines/components/button.md +75 -40
  8. package/guidelines/components/card.md +84 -25
  9. package/guidelines/components/checkbox.md +88 -0
  10. package/guidelines/components/dialog.md +619 -31
  11. package/guidelines/components/drawer.md +655 -0
  12. package/guidelines/components/heading.md +71 -0
  13. package/guidelines/components/icon-button.md +92 -37
  14. package/guidelines/components/input-addon.md +685 -0
  15. package/guidelines/components/input-group.md +830 -0
  16. package/guidelines/components/input.md +92 -37
  17. package/guidelines/components/popover.md +71 -0
  18. package/guidelines/components/progress.md +63 -0
  19. package/guidelines/components/radio-group.md +95 -0
  20. package/guidelines/components/select.md +507 -0
  21. package/guidelines/components/skeleton.md +76 -0
  22. package/guidelines/components/slider.md +911 -0
  23. package/guidelines/components/spinner.md +783 -0
  24. package/guidelines/components/switch.md +105 -38
  25. package/guidelines/components/tabs.md +654 -0
  26. package/guidelines/components/textarea.md +70 -0
  27. package/guidelines/components/toast.md +77 -0
  28. package/guidelines/components/tooltip.md +80 -0
  29. package/guidelines/design-tokens/colors.md +309 -72
  30. package/guidelines/design-tokens/elevation.md +615 -45
  31. package/guidelines/design-tokens/spacing.md +654 -74
  32. package/guidelines/design-tokens/typography.md +432 -50
  33. package/guidelines/overview-components.md +9 -5
  34. package/guidelines/overview-imports.md +314 -0
  35. package/guidelines/overview-patterns.md +3852 -0
  36. package/package.json +4 -2
@@ -2,6 +2,61 @@
2
2
 
3
3
  **Purpose:** Text input field with built-in label, validation, and helper text following Material Design 3 patterns.
4
4
 
5
+ ## When to Use This Component
6
+
7
+ Use Input when you need **single-line text entry** from the user (names, emails, search terms, etc.).
8
+
9
+ **Decision Tree:**
10
+
11
+ | Scenario | Use This | Why |
12
+ | -------------------------------------------------- | ------------------------------------ | ------------------------------------------ |
13
+ | Single-line text (name, email, username, search) | Input ✅ | Optimized for single-line entry |
14
+ | Multi-line text (comments, descriptions, messages) | Textarea | Allows line breaks, expandable height |
15
+ | Select from predefined options (4+ choices) | Select | More efficient than typing, prevents typos |
16
+ | Select from 2-3 options | RadioGroup | Visual comparison of all options |
17
+ | Binary choice (yes/no, on/off) | Switch or Checkbox | Visual metaphor for state |
18
+ | Date selection | Input with type="date" or DatePicker | Structured date entry |
19
+ | Number entry | Input with type="number" | Numeric keyboard on mobile |
20
+
21
+ **Component Comparison:**
22
+
23
+ ```typescript
24
+ // ✅ Use Input for single-line text
25
+ <Input label="Email address" type="email" />
26
+ <Input label="Username" />
27
+ <Input label="Search products" type="search" />
28
+
29
+ // ❌ Don't use Input for multi-line text - use Textarea
30
+ <Input label="Comments" /> // Wrong - can't enter line breaks
31
+
32
+ <Textarea label="Comments" /> // Correct
33
+
34
+ // ❌ Don't use Input when Select would be clearer
35
+ <Input label="Country" placeholder="Enter country name" /> // Wrong - prone to typos
36
+
37
+ <Select.Root collection={countries}>
38
+ <Select.Label>Country</Select.Label>
39
+ <Select.Control>
40
+ <Select.Trigger>
41
+ <Select.ValueText placeholder="Select country" />
42
+ </Select.Trigger>
43
+ </Select.Control>
44
+ <Select.Content>
45
+ {/* country options */}
46
+ </Select.Content>
47
+ </Select.Root> // Correct
48
+
49
+ // ❌ Don't use Input for binary choices - use Switch
50
+ <Input label="Enable notifications" type="checkbox" /> // Wrong - not an Input use case
51
+
52
+ <Switch.Root>
53
+ <Switch.Label>Enable notifications</Switch.Label>
54
+ <Switch.Control>
55
+ <Switch.Thumb />
56
+ </Switch.Control>
57
+ </Switch.Root> // Correct
58
+ ```
59
+
5
60
  ## Import
6
61
 
7
62
  ```typescript
@@ -12,10 +67,10 @@ import { Input } from '@discourser/design-system';
12
67
 
13
68
  The Input component supports 2 Material Design 3 variants:
14
69
 
15
- | Variant | Visual Style | Usage | When to Use |
16
- |---------|-------------|-------|-------------|
17
- | `outlined` | Outlined border around input | Default text inputs | Most common, clear boundaries |
18
- | `filled` | Filled background with bottom border | Alternative style | When you want less visual weight |
70
+ | Variant | Visual Style | Usage | When to Use |
71
+ | ---------- | ------------------------------------ | ------------------- | -------------------------------- |
72
+ | `outlined` | Outlined border around input | Default text inputs | Most common, clear boundaries |
73
+ | `filled` | Filled background with bottom border | Alternative style | When you want less visual weight |
19
74
 
20
75
  ### Visual Characteristics
21
76
 
@@ -24,28 +79,28 @@ The Input component supports 2 Material Design 3 variants:
24
79
 
25
80
  ## Sizes
26
81
 
27
- | Size | Height | Font Size | Usage |
28
- |------|--------|-----------|-------|
29
- | `sm` | 40px | bodySmall | Compact forms, dense layouts |
30
- | `md` | 56px | bodyLarge | Default, most use cases |
82
+ | Size | Height | Font Size | Usage |
83
+ | ---- | ------ | --------- | ---------------------------- |
84
+ | `sm` | 40px | bodySmall | Compact forms, dense layouts |
85
+ | `md` | 56px | bodyLarge | Default, most use cases |
31
86
 
32
87
  ## Props
33
88
 
34
- | Prop | Type | Default | Description |
35
- |------|------|---------|-------------|
36
- | `label` | `string` | - | Label text (highly recommended for accessibility) |
37
- | `helperText` | `string` | - | Helper text displayed below input |
38
- | `errorText` | `string` | - | Error message (also sets error state) |
39
- | `variant` | `'outlined' \| 'filled'` | `'outlined'` | Visual style variant |
40
- | `size` | `'sm' \| 'md'` | `'md'` | Input size |
41
- | `state` | `'error'` | - | Visual state (auto-set if errorText provided) |
42
- | `disabled` | `boolean` | `false` | Disable input |
43
- | `value` | `string` | - | Controlled value |
44
- | `defaultValue` | `string` | - | Uncontrolled default value |
45
- | `onChange` | `(event: ChangeEvent) => void` | - | Change handler |
46
- | `placeholder` | `string` | - | Placeholder text |
47
- | `type` | `string` | `'text'` | HTML input type (text, email, password, etc.) |
48
- | `required` | `boolean` | `false` | Mark as required field |
89
+ | Prop | Type | Default | Description |
90
+ | -------------- | ------------------------------ | ------------ | ------------------------------------------------- |
91
+ | `label` | `string` | - | Label text (highly recommended for accessibility) |
92
+ | `helperText` | `string` | - | Helper text displayed below input |
93
+ | `errorText` | `string` | - | Error message (also sets error state) |
94
+ | `variant` | `'outlined' \| 'filled'` | `'outlined'` | Visual style variant |
95
+ | `size` | `'sm' \| 'md'` | `'md'` | Input size |
96
+ | `state` | `'error'` | - | Visual state (auto-set if errorText provided) |
97
+ | `disabled` | `boolean` | `false` | Disable input |
98
+ | `value` | `string` | - | Controlled value |
99
+ | `defaultValue` | `string` | - | Uncontrolled default value |
100
+ | `onChange` | `(event: ChangeEvent) => void` | - | Change handler |
101
+ | `placeholder` | `string` | - | Placeholder text |
102
+ | `type` | `string` | `'text'` | HTML input type (text, email, password, etc.) |
103
+ | `required` | `boolean` | `false` | Mark as required field |
49
104
 
50
105
  **Note:** Input extends `InputHTMLAttributes<HTMLInputElement>` (excluding 'size'), so all standard HTML input attributes are supported.
51
106
 
@@ -414,23 +469,23 @@ const formik = useFormik({
414
469
 
415
470
  ## Variant Selection Guide
416
471
 
417
- | Scenario | Recommended Variant | Reasoning |
418
- |----------|-------------------|-----------|
419
- | Standard forms | `outlined` | Clear boundaries, default choice |
420
- | Dense forms | `outlined` + `size="sm"` | Compact while maintaining clarity |
421
- | Minimal UI | `filled` | Lighter visual weight |
422
- | Search bars | `outlined` or `filled` | Either works, depends on design |
423
- | Settings forms | `outlined` | Clear separation of fields |
472
+ | Scenario | Recommended Variant | Reasoning |
473
+ | -------------- | ------------------------ | --------------------------------- |
474
+ | Standard forms | `outlined` | Clear boundaries, default choice |
475
+ | Dense forms | `outlined` + `size="sm"` | Compact while maintaining clarity |
476
+ | Minimal UI | `filled` | Lighter visual weight |
477
+ | Search bars | `outlined` or `filled` | Either works, depends on design |
478
+ | Settings forms | `outlined` | Clear separation of fields |
424
479
 
425
480
  ## State Behaviors
426
481
 
427
- | State | Visual Change | Behavior |
428
- |-------|---------------|----------|
429
- | **Default** | Normal border/background | Ready for input |
430
- | **Hover** | Border darkens or background changes | Visual feedback |
431
- | **Focus** | 2px border, primary color | Active input state |
432
- | **Error** | Error color border, error message shown | Validation failed |
433
- | **Disabled** | 38% opacity, no interaction | Cannot be edited |
482
+ | State | Visual Change | Behavior |
483
+ | ------------ | --------------------------------------- | ------------------ |
484
+ | **Default** | Normal border/background | Ready for input |
485
+ | **Hover** | Border darkens or background changes | Visual feedback |
486
+ | **Focus** | 2px border, primary color | Active input state |
487
+ | **Error** | Error color border, error message shown | Validation failed |
488
+ | **Disabled** | 38% opacity, no interaction | Cannot be edited |
434
489
 
435
490
  ## Responsive Considerations
436
491
 
@@ -2,6 +2,77 @@
2
2
 
3
3
  **Purpose:** A floating panel that appears near a trigger element to display contextual content, menus, forms, or additional information. Built on Ark UI's Popover primitive with intelligent positioning and smooth animations.
4
4
 
5
+ ## When to Use This Component
6
+
7
+ Use Popover when you need to **display rich contextual content or interactive elements near a trigger** without navigating away from the current page.
8
+
9
+ ### Decision Tree
10
+
11
+ | Scenario | Use Popover? | Alternative | Reasoning |
12
+ | ------------------------------------------ | ------------ | ----------- | -------------------------------------------------- |
13
+ | Contextual menus with actions | ✅ Yes | - | Popover shows rich content near the trigger |
14
+ | Forms or color pickers attached to element | ✅ Yes | - | Perfect for inline editing without page navigation |
15
+ | User profile preview on hover/click | ✅ Yes | - | Shows detailed info without full page load |
16
+ | Simple text hints or labels | ❌ No | Tooltip | Tooltip is lighter and better for brief help text |
17
+ | Critical actions requiring focus | ❌ No | Dialog | Dialog centers attention and is modal |
18
+ | Navigation menus (mobile) | ❌ No | Drawer | Drawer slides from edge, better for mobile menus |
19
+
20
+ ### Component Comparison
21
+
22
+ ```typescript
23
+ // ✅ Popover - Rich contextual menu with form
24
+ <Popover.Root>
25
+ <Popover.Trigger asChild>
26
+ <Button>Add Comment</Button>
27
+ </Popover.Trigger>
28
+ <Popover.Positioner>
29
+ <Popover.Content>
30
+ <Popover.Title>New Comment</Popover.Title>
31
+ <Popover.Description>Add your thoughts below</Popover.Description>
32
+ <Textarea placeholder="Type your comment..." />
33
+ <Button>Submit</Button>
34
+ </Popover.Content>
35
+ </Popover.Positioner>
36
+ </Popover.Root>
37
+
38
+ // ❌ Don't use Popover for simple hints - Use Tooltip
39
+ <Popover.Root>
40
+ <Popover.Trigger asChild>
41
+ <IconButton><InfoIcon /></IconButton>
42
+ </Popover.Trigger>
43
+ <Popover.Positioner>
44
+ <Popover.Content>
45
+ This is a simple hint
46
+ </Popover.Content>
47
+ </Popover.Positioner>
48
+ </Popover.Root>
49
+
50
+ // ✅ Better: Use Tooltip for brief hints
51
+ <Tooltip content="This is a simple hint">
52
+ <IconButton><InfoIcon /></IconButton>
53
+ </Tooltip>
54
+
55
+ // ❌ Don't use Popover for critical modals - Use Dialog
56
+ <Popover.Root>
57
+ <Popover.Content>
58
+ <Popover.Title>Delete Account?</Popover.Title>
59
+ <Button>Confirm Delete</Button>
60
+ </Popover.Content>
61
+ </Popover.Root>
62
+
63
+ // ✅ Better: Use Dialog for important confirmations
64
+ <Dialog.Root>
65
+ <Dialog.Content>
66
+ <Dialog.Title>Delete Account?</Dialog.Title>
67
+ <Dialog.Description>This cannot be undone.</Dialog.Description>
68
+ <Dialog.Footer>
69
+ <Button variant="outlined">Cancel</Button>
70
+ <Button colorPalette="error">Delete</Button>
71
+ </Dialog.Footer>
72
+ </Dialog.Content>
73
+ </Dialog.Root>
74
+ ```
75
+
5
76
  ## Import
6
77
 
7
78
  ```typescript
@@ -2,6 +2,69 @@
2
2
 
3
3
  **Purpose:** Visual indicator that displays the completion status of a task or operation, providing feedback to users about ongoing processes following Material Design 3 patterns.
4
4
 
5
+ ## When to Use This Component
6
+
7
+ Use Progress when you need to **visually indicate the completion percentage of a determinate process** where progress can be measured.
8
+
9
+ ### Decision Tree
10
+
11
+ | Scenario | Use Progress? | Alternative | Reasoning |
12
+ | --------------------------------- | ------------- | ------------------- | ----------------------------------------- |
13
+ | File upload with known progress | ✅ Yes | - | Progress bar shows percentage complete |
14
+ | Multi-step form progress | ✅ Yes | - | Visual indicator of completion |
15
+ | Task completion tracking | ✅ Yes | - | Shows how much work remains |
16
+ | Unknown duration loading | ❌ No | Spinner or Skeleton | Progress needs measurable completion |
17
+ | Page content loading | ❌ No | Skeleton | Skeleton preserves layout during load |
18
+ | Quick operations (under 1 second) | ❌ No | Nothing or Spinner | Progress is too heavy for instant actions |
19
+
20
+ ### Component Comparison
21
+
22
+ ```typescript
23
+ // ✅ Progress - File upload with percentage
24
+ const [progress, setProgress] = useState(0);
25
+
26
+ <Progress.Root value={progress} striped animated>
27
+ <Progress.Label>Uploading {fileName}</Progress.Label>
28
+ <Progress.Track>
29
+ <Progress.Range />
30
+ </Progress.Track>
31
+ <Progress.ValueText />
32
+ </Progress.Root>
33
+
34
+ // ❌ Don't use Progress for unknown duration - Use Spinner
35
+ <Progress.Root value={null}>
36
+ <Progress.Track>
37
+ <Progress.Range />
38
+ </Progress.Track>
39
+ </Progress.Root>
40
+
41
+ // ✅ Better: Use Spinner for indeterminate loading
42
+ <Spinner size="lg" />
43
+
44
+ // ❌ Don't use Progress for content loading - Use Skeleton
45
+ <Progress.Root value={null} size="sm">
46
+ <Progress.Track>
47
+ <Progress.Range />
48
+ </Progress.Track>
49
+ </Progress.Root>
50
+ {/* Then content loads */}
51
+
52
+ // ✅ Better: Use Skeleton for content placeholders
53
+ <SkeletonText noOfLines={3} />
54
+
55
+ // ✅ Progress - Multi-step form
56
+ const currentStep = 2;
57
+ const totalSteps = 4;
58
+ const progress = (currentStep / totalSteps) * 100;
59
+
60
+ <Progress.Root value={progress}>
61
+ <Progress.Label>Step {currentStep} of {totalSteps}</Progress.Label>
62
+ <Progress.Track>
63
+ <Progress.Range />
64
+ </Progress.Track>
65
+ </Progress.Root>
66
+ ```
67
+
5
68
  ## Import
6
69
 
7
70
  ```typescript
@@ -2,6 +2,101 @@
2
2
 
3
3
  **Purpose:** Provides mutually exclusive selection between multiple options, allowing users to choose exactly one item from a set of choices.
4
4
 
5
+ ## When to Use This Component
6
+
7
+ Use RadioGroup when the user must **select exactly one option from a visible set of mutually exclusive choices** (typically 2-7 options).
8
+
9
+ ### Decision Tree
10
+
11
+ | Scenario | Use RadioGroup? | Alternative | Reasoning |
12
+ | ---------------------------------------------------------- | --------------- | ------------------------ | -------------------------------------------------------- |
13
+ | User must pick exactly one option from 2-7 visible choices | ✅ Yes | - | RadioGroup shows all options at once for easy comparison |
14
+ | Single selection from many options (8+) | ❌ No | Select | Dropdown saves vertical space for long lists |
15
+ | User can select multiple items | ❌ No | Checkbox | Checkboxes allow multiple selections |
16
+ | Single choice with on/off state only | ❌ No | Switch | Switch is clearer for binary toggles |
17
+ | Optional single selection (can select none) | ⚠️ Maybe | Select with empty option | RadioGroup typically requires a selection |
18
+ | Navigation between views | ❌ No | Tabs | Tabs are designed for view switching |
19
+
20
+ ### Component Comparison
21
+
22
+ ```typescript
23
+ // ✅ RadioGroup - Single choice from visible options
24
+ <RadioGroup.Root defaultValue="email">
25
+ <RadioGroup.Label>Notification Method</RadioGroup.Label>
26
+ <RadioGroup.Item value="email">
27
+ <RadioGroup.ItemControl>
28
+ <RadioGroup.Indicator />
29
+ </RadioGroup.ItemControl>
30
+ <RadioGroup.ItemText>Email notifications</RadioGroup.ItemText>
31
+ <RadioGroup.ItemHiddenInput />
32
+ </RadioGroup.Item>
33
+ <RadioGroup.Item value="sms">
34
+ <RadioGroup.ItemControl>
35
+ <RadioGroup.Indicator />
36
+ </RadioGroup.ItemControl>
37
+ <RadioGroup.ItemText>SMS notifications</RadioGroup.ItemText>
38
+ <RadioGroup.ItemHiddenInput />
39
+ </RadioGroup.Item>
40
+ <RadioGroup.Item value="none">
41
+ <RadioGroup.ItemControl>
42
+ <RadioGroup.Indicator />
43
+ </RadioGroup.ItemControl>
44
+ <RadioGroup.ItemText>No notifications</RadioGroup.ItemText>
45
+ <RadioGroup.ItemHiddenInput />
46
+ </RadioGroup.Item>
47
+ </RadioGroup.Root>
48
+
49
+ // ❌ Don't use RadioGroup for many options - Use Select instead
50
+ <RadioGroup.Root defaultValue="country">
51
+ <RadioGroup.Item value="us">United States</RadioGroup.Item>
52
+ <RadioGroup.Item value="uk">United Kingdom</RadioGroup.Item>
53
+ {/* ...50 more countries - too many for radio buttons */}
54
+ </RadioGroup.Root>
55
+
56
+ // ✅ Better: Use Select for long lists
57
+ <Select.Root>
58
+ <Select.Trigger>
59
+ <Select.ValueText placeholder="Select country" />
60
+ </Select.Trigger>
61
+ <Select.Content>
62
+ {countries.map((country) => (
63
+ <Select.Item key={country.value} item={country.value}>
64
+ <Select.ItemText>{country.label}</Select.ItemText>
65
+ </Select.Item>
66
+ ))}
67
+ </Select.Content>
68
+ </Select.Root>
69
+
70
+ // ❌ Don't use RadioGroup for multiple selections - Use Checkbox instead
71
+ <RadioGroup.Root>
72
+ <RadioGroup.Label>Select features (can't pick multiple)</RadioGroup.Label>
73
+ <RadioGroup.Item value="feature1">Feature 1</RadioGroup.Item>
74
+ <RadioGroup.Item value="feature2">Feature 2</RadioGroup.Item>
75
+ </RadioGroup.Root>
76
+
77
+ // ✅ Better: Use Checkbox for multiple selections
78
+ <Stack gap="2">
79
+ <Checkbox value="feature1">Feature 1</Checkbox>
80
+ <Checkbox value="feature2">Feature 2</Checkbox>
81
+ <Checkbox value="feature3">Feature 3</Checkbox>
82
+ </Stack>
83
+
84
+ // ❌ Don't use RadioGroup for binary on/off - Use Switch instead
85
+ <RadioGroup.Root defaultValue="off">
86
+ <RadioGroup.Label>Notifications</RadioGroup.Label>
87
+ <RadioGroup.Item value="on">Enable notifications</RadioGroup.Item>
88
+ <RadioGroup.Item value="off">Disable notifications</RadioGroup.Item>
89
+ </RadioGroup.Root>
90
+
91
+ // ✅ Better: Use Switch for binary toggle
92
+ <Switch.Root>
93
+ <Switch.Label>Enable notifications</Switch.Label>
94
+ <Switch.Control>
95
+ <Switch.Thumb />
96
+ </Switch.Control>
97
+ </Switch.Root>
98
+ ```
99
+
5
100
  ## Import
6
101
 
7
102
  ```typescript