sonance-brand-mcp 1.1.3 → 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.
Files changed (71) hide show
  1. package/dist/assets/components/accordion.stories.tsx +310 -0
  2. package/dist/assets/components/accordion.tsx +56 -30
  3. package/dist/assets/components/alert.stories.tsx +199 -0
  4. package/dist/assets/components/autocomplete.stories.tsx +307 -0
  5. package/dist/assets/components/autocomplete.tsx +28 -4
  6. package/dist/assets/components/avatar.stories.tsx +175 -0
  7. package/dist/assets/components/badge.stories.tsx +258 -0
  8. package/dist/assets/components/breadcrumbs.stories.tsx +175 -0
  9. package/dist/assets/components/button.stories.tsx +362 -0
  10. package/dist/assets/components/button.tsx +48 -3
  11. package/dist/assets/components/calendar.stories.tsx +247 -0
  12. package/dist/assets/components/card.stories.tsx +275 -0
  13. package/dist/assets/components/card.tsx +26 -1
  14. package/dist/assets/components/checkbox-group.stories.tsx +281 -0
  15. package/dist/assets/components/checkbox.stories.tsx +160 -0
  16. package/dist/assets/components/checkbox.tsx +32 -4
  17. package/dist/assets/components/code.stories.tsx +265 -0
  18. package/dist/assets/components/date-input.stories.tsx +278 -0
  19. package/dist/assets/components/date-input.tsx +24 -2
  20. package/dist/assets/components/date-picker.stories.tsx +337 -0
  21. package/dist/assets/components/date-picker.tsx +28 -4
  22. package/dist/assets/components/date-range-picker.stories.tsx +340 -0
  23. package/dist/assets/components/dialog.stories.tsx +285 -0
  24. package/dist/assets/components/divider.stories.tsx +176 -0
  25. package/dist/assets/components/drawer.stories.tsx +216 -0
  26. package/dist/assets/components/dropdown.stories.tsx +342 -0
  27. package/dist/assets/components/dropdown.tsx +55 -10
  28. package/dist/assets/components/form.stories.tsx +372 -0
  29. package/dist/assets/components/image.stories.tsx +348 -0
  30. package/dist/assets/components/input-otp.stories.tsx +336 -0
  31. package/dist/assets/components/input-otp.tsx +24 -2
  32. package/dist/assets/components/input.stories.tsx +223 -0
  33. package/dist/assets/components/input.tsx +27 -2
  34. package/dist/assets/components/kbd.stories.tsx +272 -0
  35. package/dist/assets/components/link.stories.tsx +199 -0
  36. package/dist/assets/components/link.tsx +50 -1
  37. package/dist/assets/components/listbox.stories.tsx +287 -0
  38. package/dist/assets/components/listbox.tsx +30 -7
  39. package/dist/assets/components/navbar.stories.tsx +218 -0
  40. package/dist/assets/components/number-input.stories.tsx +295 -0
  41. package/dist/assets/components/number-input.tsx +30 -8
  42. package/dist/assets/components/pagination.stories.tsx +280 -0
  43. package/dist/assets/components/pagination.tsx +45 -21
  44. package/dist/assets/components/popover.stories.tsx +219 -0
  45. package/dist/assets/components/progress.stories.tsx +153 -0
  46. package/dist/assets/components/radio-group.stories.tsx +187 -0
  47. package/dist/assets/components/radio-group.tsx +30 -6
  48. package/dist/assets/components/range-calendar.stories.tsx +334 -0
  49. package/dist/assets/components/scroll-shadow.stories.tsx +335 -0
  50. package/dist/assets/components/select.stories.tsx +192 -0
  51. package/dist/assets/components/select.tsx +54 -7
  52. package/dist/assets/components/skeleton.stories.tsx +166 -0
  53. package/dist/assets/components/slider.stories.tsx +145 -0
  54. package/dist/assets/components/slider.tsx +43 -8
  55. package/dist/assets/components/spacer.stories.tsx +216 -0
  56. package/dist/assets/components/spinner.stories.tsx +149 -0
  57. package/dist/assets/components/switch.stories.tsx +170 -0
  58. package/dist/assets/components/switch.tsx +29 -4
  59. package/dist/assets/components/table.stories.tsx +322 -0
  60. package/dist/assets/components/tabs.stories.tsx +306 -0
  61. package/dist/assets/components/tabs.tsx +25 -4
  62. package/dist/assets/components/textarea.stories.tsx +103 -0
  63. package/dist/assets/components/textarea.tsx +27 -3
  64. package/dist/assets/components/theme-toggle.stories.tsx +248 -0
  65. package/dist/assets/components/time-input.stories.tsx +365 -0
  66. package/dist/assets/components/time-input.tsx +25 -3
  67. package/dist/assets/components/toast.stories.tsx +195 -0
  68. package/dist/assets/components/tooltip.stories.tsx +226 -0
  69. package/dist/assets/components/user.stories.tsx +274 -0
  70. package/dist/index.js +1732 -13
  71. package/package.json +1 -1
@@ -0,0 +1,275 @@
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, type CardState } from './card';
3
+ import { Button } from './button';
4
+
5
+ const meta: Meta<typeof Card> = {
6
+ title: 'Components/Data Display/Card',
7
+ component: Card,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: 'A versatile card component for grouping related content. Supports default and elevated variants.',
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ variant: {
18
+ control: 'select',
19
+ options: ['default', 'elevated'],
20
+ description: 'Visual style variant',
21
+ table: {
22
+ defaultValue: { summary: 'default' },
23
+ },
24
+ },
25
+ state: {
26
+ control: 'select',
27
+ options: ['default', 'hover', 'focus'],
28
+ description: 'Visual state for documentation',
29
+ table: {
30
+ defaultValue: { summary: 'default' },
31
+ },
32
+ },
33
+ },
34
+ };
35
+
36
+ export default meta;
37
+ type Story = StoryObj<typeof meta>;
38
+
39
+ // Default story
40
+ export const Default: Story = {
41
+ render: (args) => (
42
+ <Card {...args} className="w-80">
43
+ <CardHeader>
44
+ <CardTitle>Card Title</CardTitle>
45
+ <CardDescription>Card description goes here</CardDescription>
46
+ </CardHeader>
47
+ <CardContent>
48
+ <p className="text-foreground-secondary">
49
+ This is the card content area where you can place any content.
50
+ </p>
51
+ </CardContent>
52
+ </Card>
53
+ ),
54
+ };
55
+
56
+ // Elevated
57
+ export const Elevated: Story = {
58
+ render: () => (
59
+ <Card variant="elevated" className="w-80">
60
+ <CardHeader>
61
+ <CardTitle>Elevated Card</CardTitle>
62
+ <CardDescription>With shadow effect</CardDescription>
63
+ </CardHeader>
64
+ <CardContent>
65
+ <p className="text-foreground-secondary">
66
+ Elevated cards have a shadow that increases on hover.
67
+ </p>
68
+ </CardContent>
69
+ </Card>
70
+ ),
71
+ };
72
+
73
+ // With Footer
74
+ export const WithFooter: Story = {
75
+ render: () => (
76
+ <Card className="w-80">
77
+ <CardHeader>
78
+ <CardTitle>Card with Actions</CardTitle>
79
+ <CardDescription>Includes action buttons in footer</CardDescription>
80
+ </CardHeader>
81
+ <CardContent>
82
+ <p className="text-foreground-secondary">
83
+ Cards can include a footer section for actions.
84
+ </p>
85
+ </CardContent>
86
+ <CardFooter className="gap-2">
87
+ <Button variant="primary" size="sm">Save</Button>
88
+ <Button variant="secondary" size="sm">Cancel</Button>
89
+ </CardFooter>
90
+ </Card>
91
+ ),
92
+ };
93
+
94
+ // Product Card Example
95
+ export const ProductCard: Story = {
96
+ render: () => (
97
+ <Card className="w-72 overflow-hidden">
98
+ <div className="aspect-square bg-background-secondary flex items-center justify-center">
99
+ <span className="text-foreground-muted">Product Image</span>
100
+ </div>
101
+ <CardHeader>
102
+ <CardTitle>Sonance Speaker</CardTitle>
103
+ <CardDescription>Premium in-wall speaker</CardDescription>
104
+ </CardHeader>
105
+ <CardContent>
106
+ <p className="text-2xl font-light text-foreground">$1,299.00</p>
107
+ </CardContent>
108
+ <CardFooter>
109
+ <Button className="w-full">Add to Cart</Button>
110
+ </CardFooter>
111
+ </Card>
112
+ ),
113
+ };
114
+
115
+ // Grid Layout
116
+ export const GridLayout: Story = {
117
+ render: () => (
118
+ <div className="grid grid-cols-3 gap-4">
119
+ {[1, 2, 3].map((i) => (
120
+ <Card key={i} variant="elevated" className="w-64">
121
+ <CardHeader>
122
+ <CardTitle>Feature {i}</CardTitle>
123
+ <CardDescription>Feature description</CardDescription>
124
+ </CardHeader>
125
+ <CardContent>
126
+ <p className="text-foreground-secondary text-sm">
127
+ Brief explanation of this feature and its benefits.
128
+ </p>
129
+ </CardContent>
130
+ </Card>
131
+ ))}
132
+ </div>
133
+ ),
134
+ };
135
+
136
+ // Variants Comparison
137
+ export const VariantsComparison: Story = {
138
+ render: () => (
139
+ <div className="flex gap-6">
140
+ <Card className="w-64">
141
+ <CardHeader>
142
+ <CardTitle>Default Card</CardTitle>
143
+ <CardDescription>Subtle border, hover effect</CardDescription>
144
+ </CardHeader>
145
+ <CardContent>
146
+ <p className="text-foreground-secondary text-sm">
147
+ Best for content lists and grids.
148
+ </p>
149
+ </CardContent>
150
+ </Card>
151
+ <Card variant="elevated" className="w-64">
152
+ <CardHeader>
153
+ <CardTitle>Elevated Card</CardTitle>
154
+ <CardDescription>Shadow with hover enhancement</CardDescription>
155
+ </CardHeader>
156
+ <CardContent>
157
+ <p className="text-foreground-secondary text-sm">
158
+ Best for featured or important content.
159
+ </p>
160
+ </CardContent>
161
+ </Card>
162
+ </div>
163
+ ),
164
+ };
165
+
166
+ // Interactive States - for Figma documentation
167
+ export const StateMatrix: Story = {
168
+ render: () => {
169
+ const variants = ['default', 'elevated'] as const;
170
+ const states: CardState[] = ['default', 'hover', 'focus'];
171
+
172
+ return (
173
+ <div className="space-y-8">
174
+ <h3 className="text-sm font-medium text-foreground-muted">Card State Matrix</h3>
175
+ <div className="grid grid-cols-4 gap-4">
176
+ <div></div>
177
+ {states.map((state) => (
178
+ <div key={state} className="text-xs font-medium text-foreground-muted uppercase text-center">
179
+ {state}
180
+ </div>
181
+ ))}
182
+ </div>
183
+ {variants.map((variant) => (
184
+ <div key={variant} className="grid grid-cols-4 gap-4 items-start">
185
+ <div className="text-xs font-medium text-foreground-muted uppercase pt-4">{variant}</div>
186
+ {states.map((state) => (
187
+ <Card key={`${variant}-${state}`} variant={variant} state={state} className="w-full">
188
+ <CardHeader>
189
+ <CardTitle>Card Title</CardTitle>
190
+ <CardDescription>{state} state</CardDescription>
191
+ </CardHeader>
192
+ <CardContent>
193
+ <p className="text-foreground-secondary text-sm">
194
+ Card content goes here.
195
+ </p>
196
+ </CardContent>
197
+ </Card>
198
+ ))}
199
+ </div>
200
+ ))}
201
+ </div>
202
+ );
203
+ },
204
+ };
205
+
206
+ // Responsive Matrix - Mobile, Tablet, Desktop
207
+ export const ResponsiveMatrix: Story = {
208
+ render: () => (
209
+ <div className="space-y-8">
210
+ {/* Mobile */}
211
+ <div>
212
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
213
+ <div className="w-[375px] border border-dashed border-border p-4 space-y-4">
214
+ <Card className="w-full">
215
+ <CardHeader>
216
+ <CardTitle>Card Title</CardTitle>
217
+ <CardDescription>Card description</CardDescription>
218
+ </CardHeader>
219
+ <CardContent>
220
+ <p className="text-foreground-secondary text-sm">Content that fills the mobile width.</p>
221
+ </CardContent>
222
+ <CardFooter>
223
+ <Button className="w-full">Action</Button>
224
+ </CardFooter>
225
+ </Card>
226
+ </div>
227
+ </div>
228
+ {/* Tablet */}
229
+ <div>
230
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
231
+ <div className="w-[768px] border border-dashed border-border p-4">
232
+ <div className="grid grid-cols-2 gap-4">
233
+ <Card>
234
+ <CardHeader>
235
+ <CardTitle>Feature One</CardTitle>
236
+ <CardDescription>Description</CardDescription>
237
+ </CardHeader>
238
+ <CardContent>
239
+ <p className="text-foreground-secondary text-sm">Card content for tablet view.</p>
240
+ </CardContent>
241
+ </Card>
242
+ <Card>
243
+ <CardHeader>
244
+ <CardTitle>Feature Two</CardTitle>
245
+ <CardDescription>Description</CardDescription>
246
+ </CardHeader>
247
+ <CardContent>
248
+ <p className="text-foreground-secondary text-sm">Card content for tablet view.</p>
249
+ </CardContent>
250
+ </Card>
251
+ </div>
252
+ </div>
253
+ </div>
254
+ {/* Desktop */}
255
+ <div>
256
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
257
+ <div className="w-[1280px] border border-dashed border-border p-4">
258
+ <div className="grid grid-cols-4 gap-4">
259
+ {[1, 2, 3, 4].map((i) => (
260
+ <Card key={i} variant="elevated">
261
+ <CardHeader>
262
+ <CardTitle>Feature {i}</CardTitle>
263
+ <CardDescription>Feature description</CardDescription>
264
+ </CardHeader>
265
+ <CardContent>
266
+ <p className="text-foreground-secondary text-sm">Card content at desktop width.</p>
267
+ </CardContent>
268
+ </Card>
269
+ ))}
270
+ </div>
271
+ </div>
272
+ </div>
273
+ </div>
274
+ ),
275
+ };
@@ -1,12 +1,36 @@
1
1
  import { cn } from "@/lib/utils";
2
2
  import { forwardRef } from "react";
3
3
 
4
+ export type CardState = "default" | "hover" | "focus";
5
+
4
6
  interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
5
7
  variant?: "default" | "elevated";
8
+ /** Visual state for Storybook/Figma documentation */
9
+ state?: CardState;
6
10
  }
7
11
 
12
+ // State styles for Storybook/Figma visualization
13
+ const getStateStyles = (variant: string, state?: CardState) => {
14
+ if (!state || state === "default") return "";
15
+
16
+ if (variant === "elevated") {
17
+ const stateMap: Record<string, string> = {
18
+ hover: "shadow-lg",
19
+ focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
20
+ };
21
+ return stateMap[state] || "";
22
+ }
23
+
24
+ const stateMap: Record<string, string> = {
25
+ hover: "border-border-hover bg-card-hover",
26
+ focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
27
+ };
28
+
29
+ return stateMap[state] || "";
30
+ };
31
+
8
32
  export const Card = forwardRef<HTMLDivElement, CardProps>(
9
- ({ className, variant = "default", ...props }, ref) => {
33
+ ({ className, variant = "default", state, ...props }, ref) => {
10
34
  return (
11
35
  <div
12
36
  ref={ref}
@@ -14,6 +38,7 @@ export const Card = forwardRef<HTMLDivElement, CardProps>(
14
38
  "bg-card border border-card-border transition-all duration-200",
15
39
  variant === "elevated" && "shadow-md hover:shadow-lg",
16
40
  variant === "default" && "hover:border-border-hover hover:bg-card-hover",
41
+ getStateStyles(variant, state),
17
42
  className
18
43
  )}
19
44
  {...props}
@@ -0,0 +1,281 @@
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
+ import { useState } from 'react';
3
+ import { CheckboxGroup, CheckboxGroupItem, CheckboxList } from './checkbox-group';
4
+
5
+ const meta: Meta<typeof CheckboxGroup> = {
6
+ title: 'Components/Forms/CheckboxGroup',
7
+ component: CheckboxGroup,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: 'A group of checkboxes for selecting multiple options. Supports vertical and horizontal layouts, labels, descriptions, and error states.',
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ orientation: {
18
+ control: 'select',
19
+ options: ['vertical', 'horizontal'],
20
+ description: 'Layout orientation of the checkbox group',
21
+ table: {
22
+ defaultValue: { summary: 'vertical' },
23
+ },
24
+ },
25
+ disabled: {
26
+ control: 'boolean',
27
+ description: 'Disable all checkboxes in the group',
28
+ },
29
+ label: {
30
+ control: 'text',
31
+ description: 'Group label text',
32
+ },
33
+ error: {
34
+ control: 'text',
35
+ description: 'Error message',
36
+ },
37
+ },
38
+ };
39
+
40
+ export default meta;
41
+ type Story = StoryObj<typeof meta>;
42
+
43
+ // Default
44
+ export const Default: Story = {
45
+ render: () => {
46
+ const [values, setValues] = useState<string[]>([]);
47
+ return (
48
+ <CheckboxGroup value={values} onValueChange={setValues}>
49
+ <CheckboxGroupItem value="option1" label="Option 1" />
50
+ <CheckboxGroupItem value="option2" label="Option 2" />
51
+ <CheckboxGroupItem value="option3" label="Option 3" />
52
+ </CheckboxGroup>
53
+ );
54
+ },
55
+ };
56
+
57
+ // With Label
58
+ export const WithLabel: Story = {
59
+ render: () => {
60
+ const [values, setValues] = useState<string[]>(['notifications']);
61
+ return (
62
+ <CheckboxGroup
63
+ label="Communication Preferences"
64
+ value={values}
65
+ onValueChange={setValues}
66
+ >
67
+ <CheckboxGroupItem
68
+ value="notifications"
69
+ label="Push notifications"
70
+ description="Receive notifications on your device"
71
+ />
72
+ <CheckboxGroupItem
73
+ value="emails"
74
+ label="Email updates"
75
+ description="Receive product updates via email"
76
+ />
77
+ <CheckboxGroupItem
78
+ value="sms"
79
+ label="SMS alerts"
80
+ description="Receive text message alerts"
81
+ />
82
+ </CheckboxGroup>
83
+ );
84
+ },
85
+ };
86
+
87
+ // Horizontal Layout
88
+ export const Horizontal: Story = {
89
+ render: () => {
90
+ const [values, setValues] = useState<string[]>([]);
91
+ return (
92
+ <CheckboxGroup
93
+ label="Select sizes"
94
+ orientation="horizontal"
95
+ value={values}
96
+ onValueChange={setValues}
97
+ >
98
+ <CheckboxGroupItem value="small" label="Small" />
99
+ <CheckboxGroupItem value="medium" label="Medium" />
100
+ <CheckboxGroupItem value="large" label="Large" />
101
+ <CheckboxGroupItem value="xlarge" label="X-Large" />
102
+ </CheckboxGroup>
103
+ );
104
+ },
105
+ };
106
+
107
+ // With Error
108
+ export const WithError: Story = {
109
+ render: () => {
110
+ const [values, setValues] = useState<string[]>([]);
111
+ return (
112
+ <CheckboxGroup
113
+ label="Required Selection"
114
+ error="Please select at least one option"
115
+ value={values}
116
+ onValueChange={setValues}
117
+ >
118
+ <CheckboxGroupItem value="agree" label="I agree to the terms" />
119
+ <CheckboxGroupItem value="marketing" label="I want to receive marketing emails" />
120
+ </CheckboxGroup>
121
+ );
122
+ },
123
+ };
124
+
125
+ // Disabled
126
+ export const Disabled: Story = {
127
+ render: () => {
128
+ return (
129
+ <CheckboxGroup
130
+ label="Disabled Group"
131
+ disabled
132
+ defaultValue={['option1']}
133
+ >
134
+ <CheckboxGroupItem value="option1" label="Option 1 (pre-selected)" />
135
+ <CheckboxGroupItem value="option2" label="Option 2" />
136
+ <CheckboxGroupItem value="option3" label="Option 3" />
137
+ </CheckboxGroup>
138
+ );
139
+ },
140
+ };
141
+
142
+ // Individual Disabled Items
143
+ export const IndividualDisabled: Story = {
144
+ render: () => {
145
+ const [values, setValues] = useState<string[]>(['basic']);
146
+ return (
147
+ <CheckboxGroup
148
+ label="Select Features"
149
+ value={values}
150
+ onValueChange={setValues}
151
+ >
152
+ <CheckboxGroupItem value="basic" label="Basic features" description="Always included" />
153
+ <CheckboxGroupItem value="advanced" label="Advanced features" description="Requires Pro plan" />
154
+ <CheckboxGroupItem
155
+ value="enterprise"
156
+ label="Enterprise features"
157
+ description="Contact sales for access"
158
+ disabled
159
+ />
160
+ </CheckboxGroup>
161
+ );
162
+ },
163
+ };
164
+
165
+ // Using CheckboxList (convenience component)
166
+ export const UsingCheckboxList: Story = {
167
+ render: () => {
168
+ const [values, setValues] = useState<string[]>(['speaker']);
169
+ const options = [
170
+ { value: 'speaker', label: 'In-Wall Speakers', description: 'Premium architectural speakers' },
171
+ { value: 'soundbar', label: 'Soundbar', description: 'For home theater setups' },
172
+ { value: 'subwoofer', label: 'Subwoofer', description: 'Deep bass performance' },
173
+ { value: 'outdoor', label: 'Outdoor Speakers', description: 'Weather-resistant design', disabled: true },
174
+ ];
175
+
176
+ return (
177
+ <CheckboxList
178
+ label="Product Interests"
179
+ options={options}
180
+ value={values}
181
+ onValueChange={setValues}
182
+ />
183
+ );
184
+ },
185
+ };
186
+
187
+ // Form Example
188
+ export const FormExample: Story = {
189
+ render: () => {
190
+ const [interests, setInterests] = useState<string[]>([]);
191
+ const [agreements, setAgreements] = useState<string[]>([]);
192
+
193
+ return (
194
+ <div className="space-y-8 max-w-md">
195
+ <CheckboxGroup
196
+ label="Areas of Interest"
197
+ value={interests}
198
+ onValueChange={setInterests}
199
+ >
200
+ <CheckboxGroupItem value="residential" label="Residential Audio" />
201
+ <CheckboxGroupItem value="commercial" label="Commercial Installations" />
202
+ <CheckboxGroupItem value="outdoor" label="Outdoor Sound Systems" />
203
+ <CheckboxGroupItem value="marine" label="Marine Audio" />
204
+ </CheckboxGroup>
205
+
206
+ <CheckboxGroup
207
+ label="Agreements"
208
+ value={agreements}
209
+ onValueChange={setAgreements}
210
+ error={agreements.length === 0 ? "Please accept the required agreements" : undefined}
211
+ >
212
+ <CheckboxGroupItem
213
+ value="terms"
214
+ label="I accept the terms and conditions"
215
+ />
216
+ <CheckboxGroupItem
217
+ value="privacy"
218
+ label="I have read the privacy policy"
219
+ />
220
+ <CheckboxGroupItem
221
+ value="newsletter"
222
+ label="Subscribe to newsletter (optional)"
223
+ />
224
+ </CheckboxGroup>
225
+
226
+ <div className="text-sm text-foreground-muted">
227
+ <p>Interests: {interests.join(', ') || 'None selected'}</p>
228
+ <p>Agreements: {agreements.join(', ') || 'None selected'}</p>
229
+ </div>
230
+ </div>
231
+ );
232
+ },
233
+ };
234
+
235
+ // Responsive Matrix - Mobile, Tablet, Desktop
236
+ export const ResponsiveMatrix: Story = {
237
+ render: () => (
238
+ <div className="space-y-8">
239
+ {/* Mobile */}
240
+ <div>
241
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
242
+ <div className="w-[375px] border border-dashed border-border p-4">
243
+ <CheckboxGroup label="Select Options" defaultValue={['option1']}>
244
+ <CheckboxGroupItem value="option1" label="Option 1" />
245
+ <CheckboxGroupItem value="option2" label="Option 2" />
246
+ <CheckboxGroupItem value="option3" label="Option 3" />
247
+ </CheckboxGroup>
248
+ </div>
249
+ </div>
250
+ {/* Tablet */}
251
+ <div>
252
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
253
+ <div className="w-[768px] border border-dashed border-border p-4">
254
+ <CheckboxGroup label="Select Sizes" orientation="horizontal" defaultValue={['medium']}>
255
+ <CheckboxGroupItem value="small" label="Small" />
256
+ <CheckboxGroupItem value="medium" label="Medium" />
257
+ <CheckboxGroupItem value="large" label="Large" />
258
+ <CheckboxGroupItem value="xlarge" label="X-Large" />
259
+ </CheckboxGroup>
260
+ </div>
261
+ </div>
262
+ {/* Desktop */}
263
+ <div>
264
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
265
+ <div className="w-[1280px] border border-dashed border-border p-4">
266
+ <div className="grid grid-cols-2 gap-8">
267
+ <CheckboxGroup label="Features" defaultValue={['basic']}>
268
+ <CheckboxGroupItem value="basic" label="Basic features" description="Always included" />
269
+ <CheckboxGroupItem value="advanced" label="Advanced features" description="Pro plan" />
270
+ <CheckboxGroupItem value="enterprise" label="Enterprise" description="Contact sales" disabled />
271
+ </CheckboxGroup>
272
+ <CheckboxGroup label="With Error" error="Please select at least one">
273
+ <CheckboxGroupItem value="agree" label="I agree to terms" />
274
+ <CheckboxGroupItem value="marketing" label="Marketing emails" />
275
+ </CheckboxGroup>
276
+ </div>
277
+ </div>
278
+ </div>
279
+ </div>
280
+ ),
281
+ };