@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.
- package/README.md +12 -4
- package/dist/styles.css +5126 -0
- package/guidelines/Guidelines.md +67 -123
- package/guidelines/components/accordion.md +93 -0
- package/guidelines/components/avatar.md +70 -0
- package/guidelines/components/badge.md +61 -0
- package/guidelines/components/button.md +75 -40
- package/guidelines/components/card.md +84 -25
- package/guidelines/components/checkbox.md +88 -0
- package/guidelines/components/dialog.md +619 -31
- package/guidelines/components/drawer.md +655 -0
- package/guidelines/components/heading.md +71 -0
- package/guidelines/components/icon-button.md +92 -37
- package/guidelines/components/input-addon.md +685 -0
- package/guidelines/components/input-group.md +830 -0
- package/guidelines/components/input.md +92 -37
- package/guidelines/components/popover.md +71 -0
- package/guidelines/components/progress.md +63 -0
- package/guidelines/components/radio-group.md +95 -0
- package/guidelines/components/select.md +507 -0
- package/guidelines/components/skeleton.md +76 -0
- package/guidelines/components/slider.md +911 -0
- package/guidelines/components/spinner.md +783 -0
- package/guidelines/components/switch.md +105 -38
- package/guidelines/components/tabs.md +654 -0
- package/guidelines/components/textarea.md +70 -0
- package/guidelines/components/toast.md +77 -0
- package/guidelines/components/tooltip.md +80 -0
- package/guidelines/design-tokens/colors.md +309 -72
- package/guidelines/design-tokens/elevation.md +615 -45
- package/guidelines/design-tokens/spacing.md +654 -74
- package/guidelines/design-tokens/typography.md +432 -50
- package/guidelines/overview-components.md +9 -5
- package/guidelines/overview-imports.md +314 -0
- package/guidelines/overview-patterns.md +3852 -0
- 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
|
|
16
|
-
|
|
17
|
-
| `outlined` | Outlined border around input
|
|
18
|
-
| `filled`
|
|
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
|
|
30
|
-
| `md` | 56px
|
|
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
|
|
35
|
-
|
|
36
|
-
| `label`
|
|
37
|
-
| `helperText`
|
|
38
|
-
| `errorText`
|
|
39
|
-
| `variant`
|
|
40
|
-
| `size`
|
|
41
|
-
| `state`
|
|
42
|
-
| `disabled`
|
|
43
|
-
| `value`
|
|
44
|
-
| `defaultValue` | `string`
|
|
45
|
-
| `onChange`
|
|
46
|
-
| `placeholder`
|
|
47
|
-
| `type`
|
|
48
|
-
| `required`
|
|
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
|
|
418
|
-
|
|
419
|
-
| Standard forms | `outlined`
|
|
420
|
-
| Dense forms
|
|
421
|
-
| Minimal UI
|
|
422
|
-
| Search bars
|
|
423
|
-
| Settings forms | `outlined`
|
|
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
|
|
428
|
-
|
|
429
|
-
| **Default**
|
|
430
|
-
| **Hover**
|
|
431
|
-
| **Focus**
|
|
432
|
-
| **Error**
|
|
433
|
-
| **Disabled** | 38% opacity, no interaction
|
|
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
|