sonance-brand-mcp 1.1.4 → 1.2.2
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/dist/assets/BRAND_GUIDELINES.md +0 -8
- package/dist/assets/components/accordion.stories.tsx +310 -0
- package/dist/assets/components/accordion.tsx +56 -30
- package/dist/assets/components/alert.stories.tsx +199 -0
- package/dist/assets/components/autocomplete.stories.tsx +307 -0
- package/dist/assets/components/autocomplete.tsx +28 -4
- package/dist/assets/components/avatar.stories.tsx +175 -0
- package/dist/assets/components/badge.stories.tsx +258 -0
- package/dist/assets/components/breadcrumbs.stories.tsx +175 -0
- package/dist/assets/components/button.stories.tsx +362 -0
- package/dist/assets/components/button.tsx +48 -3
- package/dist/assets/components/calendar.stories.tsx +247 -0
- package/dist/assets/components/card.stories.tsx +275 -0
- package/dist/assets/components/card.tsx +26 -1
- package/dist/assets/components/checkbox-group.stories.tsx +281 -0
- package/dist/assets/components/checkbox.stories.tsx +160 -0
- package/dist/assets/components/checkbox.tsx +32 -4
- package/dist/assets/components/code.stories.tsx +265 -0
- package/dist/assets/components/date-input.stories.tsx +278 -0
- package/dist/assets/components/date-input.tsx +24 -2
- package/dist/assets/components/date-picker.stories.tsx +337 -0
- package/dist/assets/components/date-picker.tsx +28 -4
- package/dist/assets/components/date-range-picker.stories.tsx +340 -0
- package/dist/assets/components/dialog.stories.tsx +285 -0
- package/dist/assets/components/divider.stories.tsx +176 -0
- package/dist/assets/components/drawer.stories.tsx +216 -0
- package/dist/assets/components/dropdown.stories.tsx +342 -0
- package/dist/assets/components/dropdown.tsx +55 -10
- package/dist/assets/components/form.stories.tsx +372 -0
- package/dist/assets/components/image.stories.tsx +348 -0
- package/dist/assets/components/input-otp.stories.tsx +336 -0
- package/dist/assets/components/input-otp.tsx +24 -2
- package/dist/assets/components/input.stories.tsx +223 -0
- package/dist/assets/components/input.tsx +27 -2
- package/dist/assets/components/kbd.stories.tsx +272 -0
- package/dist/assets/components/link.stories.tsx +199 -0
- package/dist/assets/components/link.tsx +50 -1
- package/dist/assets/components/listbox.stories.tsx +287 -0
- package/dist/assets/components/listbox.tsx +30 -7
- package/dist/assets/components/navbar.stories.tsx +218 -0
- package/dist/assets/components/number-input.stories.tsx +295 -0
- package/dist/assets/components/number-input.tsx +30 -8
- package/dist/assets/components/pagination.stories.tsx +280 -0
- package/dist/assets/components/pagination.tsx +45 -21
- package/dist/assets/components/popover.stories.tsx +219 -0
- package/dist/assets/components/progress.stories.tsx +153 -0
- package/dist/assets/components/radio-group.stories.tsx +187 -0
- package/dist/assets/components/radio-group.tsx +30 -6
- package/dist/assets/components/range-calendar.stories.tsx +334 -0
- package/dist/assets/components/scroll-shadow.stories.tsx +335 -0
- package/dist/assets/components/select.stories.tsx +192 -0
- package/dist/assets/components/select.tsx +54 -7
- package/dist/assets/components/skeleton.stories.tsx +166 -0
- package/dist/assets/components/slider.stories.tsx +145 -0
- package/dist/assets/components/slider.tsx +43 -8
- package/dist/assets/components/spacer.stories.tsx +216 -0
- package/dist/assets/components/spinner.stories.tsx +149 -0
- package/dist/assets/components/switch.stories.tsx +170 -0
- package/dist/assets/components/switch.tsx +29 -4
- package/dist/assets/components/table.stories.tsx +322 -0
- package/dist/assets/components/tabs.stories.tsx +306 -0
- package/dist/assets/components/tabs.tsx +25 -4
- package/dist/assets/components/textarea.stories.tsx +103 -0
- package/dist/assets/components/textarea.tsx +27 -3
- package/dist/assets/components/theme-toggle.stories.tsx +248 -0
- package/dist/assets/components/time-input.stories.tsx +365 -0
- package/dist/assets/components/time-input.tsx +25 -3
- package/dist/assets/components/toast.stories.tsx +195 -0
- package/dist/assets/components/tooltip.stories.tsx +226 -0
- package/dist/assets/components/user.stories.tsx +274 -0
- package/dist/assets/logo-manifest.json +0 -18
- package/dist/index.js +2142 -85
- package/package.json +1 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
2
|
+
import { Checkbox } from './checkbox';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Checkbox> = {
|
|
5
|
+
title: 'Components/Forms/Checkbox',
|
|
6
|
+
component: Checkbox,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: 'A checkbox input with optional label and description. Clean, minimal design.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
argTypes: {
|
|
16
|
+
label: {
|
|
17
|
+
control: 'text',
|
|
18
|
+
description: 'Label text',
|
|
19
|
+
},
|
|
20
|
+
description: {
|
|
21
|
+
control: 'text',
|
|
22
|
+
description: 'Description text below the label',
|
|
23
|
+
},
|
|
24
|
+
checked: {
|
|
25
|
+
control: 'boolean',
|
|
26
|
+
description: 'Checked state',
|
|
27
|
+
},
|
|
28
|
+
disabled: {
|
|
29
|
+
control: 'boolean',
|
|
30
|
+
description: 'Disabled state',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default meta;
|
|
36
|
+
type Story = StoryObj<typeof meta>;
|
|
37
|
+
|
|
38
|
+
// Default
|
|
39
|
+
export const Default: Story = {
|
|
40
|
+
args: {},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// With Label
|
|
44
|
+
export const WithLabel: Story = {
|
|
45
|
+
args: {
|
|
46
|
+
label: 'Accept terms and conditions',
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// With Description
|
|
51
|
+
export const WithDescription: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
label: 'Marketing emails',
|
|
54
|
+
description: 'Receive emails about new products, features, and more.',
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Checked
|
|
59
|
+
export const Checked: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
label: 'Remember me',
|
|
62
|
+
defaultChecked: true,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Disabled
|
|
67
|
+
export const Disabled: Story = {
|
|
68
|
+
args: {
|
|
69
|
+
label: 'Disabled option',
|
|
70
|
+
disabled: true,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Disabled Checked
|
|
75
|
+
export const DisabledChecked: Story = {
|
|
76
|
+
args: {
|
|
77
|
+
label: 'Disabled checked',
|
|
78
|
+
disabled: true,
|
|
79
|
+
defaultChecked: true,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// All States
|
|
84
|
+
export const AllStates: Story = {
|
|
85
|
+
render: () => (
|
|
86
|
+
<div className="space-y-4">
|
|
87
|
+
<Checkbox label="Unchecked" />
|
|
88
|
+
<Checkbox label="Checked" defaultChecked />
|
|
89
|
+
<Checkbox label="With description" description="Additional information about this option" />
|
|
90
|
+
<Checkbox label="Disabled" disabled />
|
|
91
|
+
<Checkbox label="Disabled checked" disabled defaultChecked />
|
|
92
|
+
</div>
|
|
93
|
+
),
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Form Example
|
|
97
|
+
export const FormExample: Story = {
|
|
98
|
+
render: () => (
|
|
99
|
+
<div className="space-y-6 w-80">
|
|
100
|
+
<div className="space-y-4">
|
|
101
|
+
<h3 className="text-sm font-medium text-foreground">Notification Preferences</h3>
|
|
102
|
+
<Checkbox
|
|
103
|
+
label="Email notifications"
|
|
104
|
+
description="Get notified about account activity via email"
|
|
105
|
+
defaultChecked
|
|
106
|
+
/>
|
|
107
|
+
<Checkbox
|
|
108
|
+
label="SMS notifications"
|
|
109
|
+
description="Get notified via text message"
|
|
110
|
+
/>
|
|
111
|
+
<Checkbox
|
|
112
|
+
label="Push notifications"
|
|
113
|
+
description="Get notified on your mobile device"
|
|
114
|
+
defaultChecked
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Responsive Matrix - Mobile, Tablet, Desktop
|
|
122
|
+
export const ResponsiveMatrix: Story = {
|
|
123
|
+
render: () => (
|
|
124
|
+
<div className="space-y-8">
|
|
125
|
+
{/* Mobile */}
|
|
126
|
+
<div>
|
|
127
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
128
|
+
<div className="w-[375px] border border-dashed border-border p-4 space-y-4">
|
|
129
|
+
<Checkbox label="Accept terms and conditions" />
|
|
130
|
+
<Checkbox label="Subscribe to newsletter" description="Receive updates about new features" />
|
|
131
|
+
<Checkbox label="Remember me" defaultChecked />
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
{/* Tablet */}
|
|
135
|
+
<div>
|
|
136
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
137
|
+
<div className="w-[768px] border border-dashed border-border p-4">
|
|
138
|
+
<div className="grid grid-cols-2 gap-4">
|
|
139
|
+
<Checkbox label="Email notifications" description="Get notified via email" defaultChecked />
|
|
140
|
+
<Checkbox label="SMS notifications" description="Get notified via text" />
|
|
141
|
+
<Checkbox label="Push notifications" description="Mobile app notifications" defaultChecked />
|
|
142
|
+
<Checkbox label="Marketing emails" description="Product updates and offers" />
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
{/* Desktop */}
|
|
147
|
+
<div>
|
|
148
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
149
|
+
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
150
|
+
<div className="grid grid-cols-4 gap-4">
|
|
151
|
+
<Checkbox label="Unchecked" />
|
|
152
|
+
<Checkbox label="Checked" defaultChecked />
|
|
153
|
+
<Checkbox label="Disabled" disabled />
|
|
154
|
+
<Checkbox label="Disabled checked" disabled defaultChecked />
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
),
|
|
160
|
+
};
|
|
@@ -1,17 +1,38 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { forwardRef } from "react";
|
|
3
|
+
import { forwardRef, useId } from "react";
|
|
4
4
|
import { Check } from "lucide-react";
|
|
5
5
|
import { cn } from "@/lib/utils";
|
|
6
6
|
|
|
7
|
+
export type CheckboxState = "default" | "hover" | "focus" | "checked" | "disabled";
|
|
8
|
+
|
|
7
9
|
interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
8
10
|
label?: string;
|
|
9
11
|
description?: string;
|
|
12
|
+
/** Visual state for Storybook/Figma documentation */
|
|
13
|
+
state?: CheckboxState;
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
// State styles for Storybook/Figma visualization
|
|
17
|
+
const getStateStyles = (state?: CheckboxState) => {
|
|
18
|
+
if (!state || state === "default") return "";
|
|
19
|
+
|
|
20
|
+
const stateMap: Record<string, string> = {
|
|
21
|
+
hover: "border-border-hover",
|
|
22
|
+
focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
|
|
23
|
+
checked: "border-primary bg-primary",
|
|
24
|
+
disabled: "opacity-50 cursor-not-allowed",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return stateMap[state] || "";
|
|
28
|
+
};
|
|
29
|
+
|
|
12
30
|
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
13
|
-
({ className, label, description, id, ...props }, ref) => {
|
|
14
|
-
const
|
|
31
|
+
({ className, label, description, id, state, disabled, checked, ...props }, ref) => {
|
|
32
|
+
const uniqueId = useId();
|
|
33
|
+
const inputId = id || `checkbox-${uniqueId}`;
|
|
34
|
+
const isDisabled = disabled || state === "disabled";
|
|
35
|
+
const isChecked = checked || state === "checked";
|
|
15
36
|
|
|
16
37
|
return (
|
|
17
38
|
<div className="flex items-start gap-3">
|
|
@@ -20,18 +41,25 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
20
41
|
type="checkbox"
|
|
21
42
|
id={inputId}
|
|
22
43
|
ref={ref}
|
|
44
|
+
disabled={isDisabled}
|
|
45
|
+
checked={isChecked}
|
|
23
46
|
className={cn(
|
|
24
47
|
"peer h-5 w-5 shrink-0 appearance-none border border-border bg-input",
|
|
48
|
+
"hover:border-border-hover",
|
|
25
49
|
"checked:border-primary checked:bg-primary",
|
|
26
50
|
"focus:outline-none focus:ring-2 focus:ring-border-focus focus:ring-offset-2 focus:ring-offset-background",
|
|
27
51
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
28
52
|
"transition-colors duration-150",
|
|
53
|
+
getStateStyles(state),
|
|
29
54
|
className
|
|
30
55
|
)}
|
|
31
56
|
{...props}
|
|
32
57
|
/>
|
|
33
58
|
<Check
|
|
34
|
-
className=
|
|
59
|
+
className={cn(
|
|
60
|
+
"pointer-events-none absolute h-3.5 w-3.5 text-primary-foreground opacity-0 peer-checked:opacity-100 transition-opacity",
|
|
61
|
+
state === "checked" && "opacity-100"
|
|
62
|
+
)}
|
|
35
63
|
/>
|
|
36
64
|
</div>
|
|
37
65
|
{(label || description) && (
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
2
|
+
import { Code, CodeBlock, Snippet } from './code';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Code> = {
|
|
5
|
+
title: 'Components/Utilities/Code',
|
|
6
|
+
component: Code,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: 'Components for displaying code inline and in blocks with syntax highlighting.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
argTypes: {
|
|
16
|
+
variant: {
|
|
17
|
+
control: 'select',
|
|
18
|
+
options: ['default', 'primary'],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
type Story = StoryObj<typeof meta>;
|
|
25
|
+
|
|
26
|
+
export const InlineDefault: Story = {
|
|
27
|
+
render: () => (
|
|
28
|
+
<p className="text-foreground-secondary">
|
|
29
|
+
Use the <Code>npm install</Code> command to install dependencies.
|
|
30
|
+
</p>
|
|
31
|
+
),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const InlinePrimary: Story = {
|
|
35
|
+
render: () => (
|
|
36
|
+
<p className="text-foreground-secondary">
|
|
37
|
+
The <Code variant="primary">useState</Code> hook is used for managing state in React.
|
|
38
|
+
</p>
|
|
39
|
+
),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const Block: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<CodeBlock
|
|
45
|
+
code={`function greet(name) {
|
|
46
|
+
console.log(\`Hello, \${name}!\`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
greet('Sonance');`}
|
|
50
|
+
language="javascript"
|
|
51
|
+
/>
|
|
52
|
+
),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const BlockWithFilename: Story = {
|
|
56
|
+
render: () => (
|
|
57
|
+
<CodeBlock
|
|
58
|
+
filename="greeting.ts"
|
|
59
|
+
language="typescript"
|
|
60
|
+
code={`interface User {
|
|
61
|
+
name: string;
|
|
62
|
+
email: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function greet(user: User): string {
|
|
66
|
+
return \`Hello, \${user.name}!\`;
|
|
67
|
+
}`}
|
|
68
|
+
/>
|
|
69
|
+
),
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const BlockWithLineNumbers: Story = {
|
|
73
|
+
render: () => (
|
|
74
|
+
<CodeBlock
|
|
75
|
+
showLineNumbers
|
|
76
|
+
code={`import { useState } from 'react';
|
|
77
|
+
|
|
78
|
+
export function Counter() {
|
|
79
|
+
const [count, setCount] = useState(0);
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<button onClick={() => setCount(count + 1)}>
|
|
83
|
+
Count: {count}
|
|
84
|
+
</button>
|
|
85
|
+
);
|
|
86
|
+
}`}
|
|
87
|
+
language="tsx"
|
|
88
|
+
/>
|
|
89
|
+
),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const BlockWithHighlightedLines: Story = {
|
|
93
|
+
render: () => (
|
|
94
|
+
<CodeBlock
|
|
95
|
+
showLineNumbers
|
|
96
|
+
highlightLines={[4, 5, 6]}
|
|
97
|
+
code={`import { useState } from 'react';
|
|
98
|
+
|
|
99
|
+
export function Counter() {
|
|
100
|
+
const [count, setCount] = useState(0);
|
|
101
|
+
const increment = () => setCount(count + 1);
|
|
102
|
+
const decrement = () => setCount(count - 1);
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<div>
|
|
106
|
+
<button onClick={decrement}>-</button>
|
|
107
|
+
<span>{count}</span>
|
|
108
|
+
<button onClick={increment}>+</button>
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}`}
|
|
112
|
+
language="tsx"
|
|
113
|
+
filename="Counter.tsx"
|
|
114
|
+
/>
|
|
115
|
+
),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const SnippetDefault: Story = {
|
|
119
|
+
render: () => <Snippet text="npm install @sonance/ui" />,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const SnippetWithoutSymbol: Story = {
|
|
123
|
+
render: () => <Snippet text="pnpm add @sonance/ui" symbol="" />,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const SnippetNoCopy: Story = {
|
|
127
|
+
render: () => <Snippet text="yarn add @sonance/ui" hideCopyButton />,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const InstallCommands: Story = {
|
|
131
|
+
render: () => (
|
|
132
|
+
<div className="space-y-4">
|
|
133
|
+
<div>
|
|
134
|
+
<p className="text-xs text-foreground-muted mb-2">npm</p>
|
|
135
|
+
<Snippet text="npm install @sonance/ui" />
|
|
136
|
+
</div>
|
|
137
|
+
<div>
|
|
138
|
+
<p className="text-xs text-foreground-muted mb-2">pnpm</p>
|
|
139
|
+
<Snippet text="pnpm add @sonance/ui" />
|
|
140
|
+
</div>
|
|
141
|
+
<div>
|
|
142
|
+
<p className="text-xs text-foreground-muted mb-2">yarn</p>
|
|
143
|
+
<Snippet text="yarn add @sonance/ui" />
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
),
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const DocumentationExample: Story = {
|
|
150
|
+
render: () => (
|
|
151
|
+
<div className="max-w-2xl space-y-6">
|
|
152
|
+
<h2 className="text-xl font-semibold text-foreground">Button Component</h2>
|
|
153
|
+
|
|
154
|
+
<p className="text-foreground-secondary">
|
|
155
|
+
Import the <Code>Button</Code> component from the UI library:
|
|
156
|
+
</p>
|
|
157
|
+
|
|
158
|
+
<CodeBlock
|
|
159
|
+
filename="example.tsx"
|
|
160
|
+
language="tsx"
|
|
161
|
+
code={`import { Button } from '@sonance/ui';
|
|
162
|
+
|
|
163
|
+
export function MyComponent() {
|
|
164
|
+
return (
|
|
165
|
+
<Button variant="primary" size="lg">
|
|
166
|
+
Click me
|
|
167
|
+
</Button>
|
|
168
|
+
);
|
|
169
|
+
}`}
|
|
170
|
+
/>
|
|
171
|
+
|
|
172
|
+
<h3 className="text-lg font-medium text-foreground">Props</h3>
|
|
173
|
+
|
|
174
|
+
<p className="text-foreground-secondary">
|
|
175
|
+
The <Code variant="primary">variant</Code> prop accepts{' '}
|
|
176
|
+
<Code>primary</Code>, <Code>secondary</Code>, <Code>ghost</Code>, or{' '}
|
|
177
|
+
<Code>inverted</Code>.
|
|
178
|
+
</p>
|
|
179
|
+
</div>
|
|
180
|
+
),
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export const AllExamples: Story = {
|
|
184
|
+
render: () => (
|
|
185
|
+
<div className="space-y-8 max-w-2xl">
|
|
186
|
+
<div>
|
|
187
|
+
<h3 className="text-sm font-medium text-foreground mb-2">Inline Code</h3>
|
|
188
|
+
<p className="text-foreground-secondary">
|
|
189
|
+
Default: <Code>const x = 1</Code> | Primary: <Code variant="primary">useState</Code>
|
|
190
|
+
</p>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div>
|
|
194
|
+
<h3 className="text-sm font-medium text-foreground mb-2">Code Block</h3>
|
|
195
|
+
<CodeBlock
|
|
196
|
+
code={`const greeting = "Hello, World!";
|
|
197
|
+
console.log(greeting);`}
|
|
198
|
+
/>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<div>
|
|
202
|
+
<h3 className="text-sm font-medium text-foreground mb-2">Snippet</h3>
|
|
203
|
+
<Snippet text="npm install @sonance/ui" />
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
),
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Responsive Matrix - Mobile, Tablet, Desktop
|
|
210
|
+
export const ResponsiveMatrix: Story = {
|
|
211
|
+
render: () => (
|
|
212
|
+
<div className="space-y-8">
|
|
213
|
+
{/* Mobile */}
|
|
214
|
+
<div>
|
|
215
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
216
|
+
<div className="w-[375px] border border-dashed border-border p-4 space-y-4">
|
|
217
|
+
<p className="text-foreground-secondary text-sm">
|
|
218
|
+
Use <Code>npm install</Code> to install.
|
|
219
|
+
</p>
|
|
220
|
+
<Snippet text="npm install @sonance/ui" />
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
{/* Tablet */}
|
|
224
|
+
<div>
|
|
225
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
226
|
+
<div className="w-[768px] border border-dashed border-border p-4">
|
|
227
|
+
<CodeBlock
|
|
228
|
+
code={`import { Button } from '@sonance/ui';
|
|
229
|
+
|
|
230
|
+
export function App() {
|
|
231
|
+
return <Button>Click me</Button>;
|
|
232
|
+
}`}
|
|
233
|
+
language="tsx"
|
|
234
|
+
/>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
{/* Desktop */}
|
|
238
|
+
<div>
|
|
239
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
240
|
+
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
241
|
+
<CodeBlock
|
|
242
|
+
filename="component.tsx"
|
|
243
|
+
showLineNumbers
|
|
244
|
+
code={`import { useState } from 'react';
|
|
245
|
+
import { Button, Card, Input } from '@sonance/ui';
|
|
246
|
+
|
|
247
|
+
export function ContactForm() {
|
|
248
|
+
const [name, setName] = useState('');
|
|
249
|
+
const [email, setEmail] = useState('');
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<Card>
|
|
253
|
+
<Input label="Name" value={name} onChange={(e) => setName(e.target.value)} />
|
|
254
|
+
<Input label="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
|
|
255
|
+
<Button>Submit</Button>
|
|
256
|
+
</Card>
|
|
257
|
+
);
|
|
258
|
+
}`}
|
|
259
|
+
language="tsx"
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
),
|
|
265
|
+
};
|