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,153 @@
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
+ import { Progress, CircularProgress } from './progress';
3
+
4
+ const meta: Meta<typeof Progress> = {
5
+ title: 'Components/Feedback/Progress',
6
+ component: Progress,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component: 'Progress indicators for showing completion status. Includes linear and circular variants.',
12
+ },
13
+ },
14
+ },
15
+ argTypes: {
16
+ value: { control: { type: 'range', min: 0, max: 100 } },
17
+ max: { control: 'number' },
18
+ label: { control: 'text' },
19
+ showValue: { control: 'boolean' },
20
+ size: { control: 'select', options: ['sm', 'md', 'lg'] },
21
+ },
22
+ };
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof meta>;
26
+
27
+ export const Default: Story = {
28
+ args: {
29
+ value: 60,
30
+ },
31
+ };
32
+
33
+ export const WithLabel: Story = {
34
+ args: {
35
+ value: 75,
36
+ label: 'Progress',
37
+ },
38
+ };
39
+
40
+ export const WithValue: Story = {
41
+ args: {
42
+ value: 45,
43
+ label: 'Upload Progress',
44
+ showValue: true,
45
+ },
46
+ };
47
+
48
+ export const AllSizes: Story = {
49
+ render: () => (
50
+ <div className="space-y-6 w-80">
51
+ <Progress value={60} size="sm" label="Small" />
52
+ <Progress value={60} size="md" label="Medium" />
53
+ <Progress value={60} size="lg" label="Large" />
54
+ </div>
55
+ ),
56
+ };
57
+
58
+ export const DifferentValues: Story = {
59
+ render: () => (
60
+ <div className="space-y-4 w-80">
61
+ <Progress value={0} showValue />
62
+ <Progress value={25} showValue />
63
+ <Progress value={50} showValue />
64
+ <Progress value={75} showValue />
65
+ <Progress value={100} showValue />
66
+ </div>
67
+ ),
68
+ };
69
+
70
+ // Circular Progress Stories
71
+ export const Circular: StoryObj<typeof CircularProgress> = {
72
+ render: () => <CircularProgress value={65} />,
73
+ };
74
+
75
+ export const CircularWithValue: StoryObj<typeof CircularProgress> = {
76
+ render: () => <CircularProgress value={75} showValue />,
77
+ };
78
+
79
+ export const CircularSizes: StoryObj<typeof CircularProgress> = {
80
+ render: () => (
81
+ <div className="flex items-center gap-6">
82
+ <CircularProgress value={60} size="sm" showValue />
83
+ <CircularProgress value={60} size="md" showValue />
84
+ <CircularProgress value={60} size="lg" showValue />
85
+ </div>
86
+ ),
87
+ };
88
+
89
+ export const CircularCustomSize: StoryObj<typeof CircularProgress> = {
90
+ render: () => (
91
+ <CircularProgress value={80} size={100} strokeWidth={8} showValue />
92
+ ),
93
+ };
94
+
95
+ export const LoadingExample: Story = {
96
+ render: () => (
97
+ <div className="space-y-6 w-96">
98
+ <div>
99
+ <h4 className="text-sm font-medium text-foreground mb-2">File Upload</h4>
100
+ <Progress value={67} label="document.pdf" showValue />
101
+ </div>
102
+ <div>
103
+ <h4 className="text-sm font-medium text-foreground mb-2">Installation Progress</h4>
104
+ <Progress value={45} label="Installing dependencies..." showValue />
105
+ </div>
106
+ </div>
107
+ ),
108
+ };
109
+
110
+ // Responsive Matrix - Mobile, Tablet, Desktop
111
+ export const ResponsiveMatrix: Story = {
112
+ render: () => (
113
+ <div className="space-y-8">
114
+ {/* Mobile */}
115
+ <div>
116
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
117
+ <div className="w-[375px] border border-dashed border-border p-4 space-y-6">
118
+ <Progress value={65} label="Upload Progress" showValue />
119
+ <div className="flex justify-center">
120
+ <CircularProgress value={75} showValue />
121
+ </div>
122
+ </div>
123
+ </div>
124
+ {/* Tablet */}
125
+ <div>
126
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
127
+ <div className="w-[768px] border border-dashed border-border p-4">
128
+ <div className="grid grid-cols-2 gap-8 items-center">
129
+ <Progress value={45} label="Installation" showValue />
130
+ <div className="flex justify-center gap-4">
131
+ <CircularProgress value={60} size="sm" showValue />
132
+ <CircularProgress value={85} size="md" showValue />
133
+ </div>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ {/* Desktop */}
138
+ <div>
139
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
140
+ <div className="w-[1280px] border border-dashed border-border p-4">
141
+ <div className="grid grid-cols-4 gap-8 items-center">
142
+ <Progress value={25} size="sm" showValue />
143
+ <Progress value={50} size="md" showValue />
144
+ <Progress value={75} size="lg" showValue />
145
+ <div className="flex justify-center">
146
+ <CircularProgress value={90} size="lg" showValue />
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ ),
153
+ };
@@ -0,0 +1,187 @@
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
+ import { ComponentProps } from 'react';
3
+ import { RadioGroup, RadioGroupItem, type RadioGroupItemState } from './radio-group';
4
+
5
+ type RadioGroupStoryProps = ComponentProps<typeof RadioGroup> & {
6
+ state?: RadioGroupItemState;
7
+ };
8
+
9
+ const meta: Meta<RadioGroupStoryProps> = {
10
+ title: 'Components/Forms/RadioGroup',
11
+ component: RadioGroup,
12
+ tags: ['autodocs'],
13
+ parameters: {
14
+ docs: {
15
+ description: {
16
+ component: 'A group of radio buttons for selecting a single option from multiple choices.',
17
+ },
18
+ },
19
+ },
20
+ argTypes: {
21
+ orientation: {
22
+ control: 'select',
23
+ options: ['vertical', 'horizontal'],
24
+ },
25
+ state: {
26
+ control: 'select',
27
+ options: ['default', 'hover', 'focus', 'checked', 'disabled'],
28
+ description: 'Visual state for documentation (RadioGroupItem)',
29
+ table: {
30
+ defaultValue: { summary: 'default' },
31
+ },
32
+ },
33
+ },
34
+ };
35
+
36
+ export default meta;
37
+ type Story = StoryObj<RadioGroupStoryProps>;
38
+
39
+ export const Default: Story = {
40
+ render: () => (
41
+ <RadioGroup defaultValue="option1">
42
+ <RadioGroupItem value="option1" label="Option 1" />
43
+ <RadioGroupItem value="option2" label="Option 2" />
44
+ <RadioGroupItem value="option3" label="Option 3" />
45
+ </RadioGroup>
46
+ ),
47
+ };
48
+
49
+ export const WithDescriptions: Story = {
50
+ render: () => (
51
+ <RadioGroup defaultValue="standard">
52
+ <RadioGroupItem
53
+ value="standard"
54
+ label="Standard Shipping"
55
+ description="Delivery in 5-7 business days"
56
+ />
57
+ <RadioGroupItem
58
+ value="express"
59
+ label="Express Shipping"
60
+ description="Delivery in 2-3 business days"
61
+ />
62
+ <RadioGroupItem
63
+ value="overnight"
64
+ label="Overnight Shipping"
65
+ description="Next day delivery"
66
+ />
67
+ </RadioGroup>
68
+ ),
69
+ };
70
+
71
+ export const Horizontal: Story = {
72
+ render: () => (
73
+ <RadioGroup defaultValue="small" orientation="horizontal">
74
+ <RadioGroupItem value="small" label="Small" />
75
+ <RadioGroupItem value="medium" label="Medium" />
76
+ <RadioGroupItem value="large" label="Large" />
77
+ </RadioGroup>
78
+ ),
79
+ };
80
+
81
+ export const WithDisabledOption: Story = {
82
+ render: () => (
83
+ <RadioGroup defaultValue="available">
84
+ <RadioGroupItem value="available" label="Available" />
85
+ <RadioGroupItem value="limited" label="Limited Stock" />
86
+ <RadioGroupItem value="outofstock" label="Out of Stock" disabled />
87
+ </RadioGroup>
88
+ ),
89
+ };
90
+
91
+ export const PlanSelection: Story = {
92
+ render: () => (
93
+ <div className="w-80">
94
+ <h3 className="text-sm font-medium text-foreground mb-4">Select a Plan</h3>
95
+ <RadioGroup defaultValue="pro">
96
+ <RadioGroupItem
97
+ value="free"
98
+ label="Free"
99
+ description="Basic features for personal use"
100
+ />
101
+ <RadioGroupItem
102
+ value="pro"
103
+ label="Pro"
104
+ description="Advanced features for professionals"
105
+ />
106
+ <RadioGroupItem
107
+ value="enterprise"
108
+ label="Enterprise"
109
+ description="Custom solutions for large teams"
110
+ />
111
+ </RadioGroup>
112
+ </div>
113
+ ),
114
+ };
115
+
116
+ // State Matrix - Visual documentation of all states
117
+ export const StateMatrix: Story = {
118
+ render: () => {
119
+ const states: RadioGroupItemState[] = ['default', 'hover', 'focus', 'checked', 'disabled'];
120
+ return (
121
+ <div className="space-y-6">
122
+ <h3 className="text-sm font-medium text-foreground-muted">RadioGroupItem States</h3>
123
+ <div className="space-y-4">
124
+ {states.map((state) => (
125
+ <div key={state} className="flex items-center gap-4">
126
+ <span className="text-xs font-medium text-foreground-muted uppercase w-20">{state}</span>
127
+ <RadioGroup>
128
+ <RadioGroupItem
129
+ value="demo"
130
+ label={`${state} state`}
131
+ state={state}
132
+ />
133
+ </RadioGroup>
134
+ </div>
135
+ ))}
136
+ </div>
137
+ </div>
138
+ );
139
+ },
140
+ };
141
+
142
+ // Responsive Matrix - Mobile, Tablet, Desktop
143
+ export const ResponsiveMatrix: Story = {
144
+ render: () => (
145
+ <div className="space-y-8">
146
+ {/* Mobile */}
147
+ <div>
148
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
149
+ <div className="w-[375px] border border-dashed border-border p-4">
150
+ <RadioGroup defaultValue="standard">
151
+ <RadioGroupItem value="standard" label="Standard" description="5-7 business days" />
152
+ <RadioGroupItem value="express" label="Express" description="2-3 business days" />
153
+ <RadioGroupItem value="overnight" label="Overnight" description="Next day" />
154
+ </RadioGroup>
155
+ </div>
156
+ </div>
157
+ {/* Tablet */}
158
+ <div>
159
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
160
+ <div className="w-[768px] border border-dashed border-border p-4">
161
+ <div className="grid grid-cols-2 gap-8">
162
+ <RadioGroup defaultValue="small">
163
+ <RadioGroupItem value="small" label="Small" />
164
+ <RadioGroupItem value="medium" label="Medium" />
165
+ <RadioGroupItem value="large" label="Large" />
166
+ </RadioGroup>
167
+ <RadioGroup defaultValue="monthly" orientation="horizontal">
168
+ <RadioGroupItem value="monthly" label="Monthly" />
169
+ <RadioGroupItem value="yearly" label="Yearly" />
170
+ </RadioGroup>
171
+ </div>
172
+ </div>
173
+ </div>
174
+ {/* Desktop */}
175
+ <div>
176
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
177
+ <div className="w-[1280px] border border-dashed border-border p-4">
178
+ <RadioGroup defaultValue="pro" orientation="horizontal" className="flex gap-8">
179
+ <RadioGroupItem value="free" label="Free" description="Basic features" />
180
+ <RadioGroupItem value="pro" label="Pro" description="Advanced features" />
181
+ <RadioGroupItem value="enterprise" label="Enterprise" description="Custom solutions" />
182
+ </RadioGroup>
183
+ </div>
184
+ </div>
185
+ </div>
186
+ ),
187
+ };
@@ -1,8 +1,24 @@
1
1
  "use client";
2
2
 
3
- import { forwardRef, createContext, useContext, useState } from "react";
3
+ import { forwardRef, createContext, useContext, useState, useId } from "react";
4
4
  import { cn } from "@/lib/utils";
5
5
 
6
+ export type RadioGroupItemState = "default" | "hover" | "focus" | "checked" | "disabled";
7
+
8
+ // State styles for Storybook/Figma visualization
9
+ const getStateStyles = (state?: RadioGroupItemState) => {
10
+ if (!state || state === "default") return "";
11
+
12
+ const stateMap: Record<string, string> = {
13
+ hover: "border-border-hover",
14
+ focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
15
+ checked: "border-primary",
16
+ disabled: "opacity-50 cursor-not-allowed",
17
+ };
18
+
19
+ return stateMap[state] || "";
20
+ };
21
+
6
22
  interface RadioGroupContextValue {
7
23
  value: string;
8
24
  onChange: (value: string) => void;
@@ -25,13 +41,15 @@ export function RadioGroup({
25
41
  value: controlledValue,
26
42
  defaultValue = "",
27
43
  onValueChange,
28
- name = `radio-group-${Math.random().toString(36).substr(2, 9)}`,
44
+ name,
29
45
  className,
30
46
  children,
31
47
  orientation = "vertical",
32
48
  }: RadioGroupProps) {
33
49
  const [internalValue, setInternalValue] = useState(defaultValue);
34
50
  const value = controlledValue ?? internalValue;
51
+ const uniqueId = useId();
52
+ const groupName = name || `radio-group-${uniqueId}`;
35
53
 
36
54
  const onChange = (newValue: string) => {
37
55
  setInternalValue(newValue);
@@ -39,7 +57,7 @@ export function RadioGroup({
39
57
  };
40
58
 
41
59
  return (
42
- <RadioGroupContext.Provider value={{ value, onChange, name }}>
60
+ <RadioGroupContext.Provider value={{ value, onChange, name: groupName }}>
43
61
  <div
44
62
  role="radiogroup"
45
63
  className={cn(
@@ -58,10 +76,12 @@ interface RadioGroupItemProps extends Omit<React.InputHTMLAttributes<HTMLInputEl
58
76
  value: string;
59
77
  label?: string;
60
78
  description?: string;
79
+ /** Visual state for Storybook/Figma documentation */
80
+ state?: RadioGroupItemState;
61
81
  }
62
82
 
63
83
  export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
64
- ({ className, value, label, description, id, ...props }, ref) => {
84
+ ({ className, value, label, description, id, state, disabled, ...props }, ref) => {
65
85
  const context = useContext(RadioGroupContext);
66
86
  if (!context) {
67
87
  throw new Error("RadioGroupItem must be used within a RadioGroup");
@@ -69,7 +89,8 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
69
89
 
70
90
  const { value: groupValue, onChange, name } = context;
71
91
  const inputId = id || `radio-${value}`;
72
- const isChecked = groupValue === value;
92
+ const isChecked = groupValue === value || state === "checked";
93
+ const isDisabled = disabled || state === "disabled";
73
94
 
74
95
  return (
75
96
  <div className="flex items-start gap-3">
@@ -82,12 +103,14 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
82
103
  value={value}
83
104
  checked={isChecked}
84
105
  onChange={() => onChange(value)}
106
+ disabled={isDisabled}
85
107
  className={cn(
86
108
  "peer h-5 w-5 shrink-0 appearance-none rounded-full border border-border bg-input",
87
109
  "checked:border-primary",
88
110
  "focus:outline-none focus:ring-2 focus:ring-border-focus focus:ring-offset-2 focus:ring-offset-background",
89
111
  "disabled:cursor-not-allowed disabled:opacity-50",
90
112
  "transition-colors duration-150",
113
+ getStateStyles(state),
91
114
  className
92
115
  )}
93
116
  {...props}
@@ -95,7 +118,8 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
95
118
  <div
96
119
  className={cn(
97
120
  "pointer-events-none absolute h-2.5 w-2.5 rounded-full bg-primary",
98
- "scale-0 peer-checked:scale-100 transition-transform duration-150"
121
+ "scale-0 transition-transform duration-150",
122
+ isChecked && "scale-100"
99
123
  )}
100
124
  />
101
125
  </div>