sonance-brand-mcp 1.2.5 → 1.3.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/api/sonance-analyze/route.ts +1116 -0
- package/dist/assets/api/sonance-assets/route.ts +113 -0
- package/dist/assets/api/sonance-components/route.ts +41 -0
- package/dist/assets/api/sonance-inject-id/route.ts +363 -0
- package/dist/assets/api/sonance-save-logo/route.ts +426 -0
- package/dist/assets/api/sonance-theme/route.ts +106 -0
- package/dist/assets/brand-system.ts +1265 -0
- package/dist/assets/components/accordion.stories.tsx +26 -26
- package/dist/assets/components/accordion.tsx +3 -3
- package/dist/assets/components/alert-dialog.stories.tsx +142 -0
- package/dist/assets/components/alert-dialog.tsx +143 -0
- package/dist/assets/components/alert.stories.tsx +3 -3
- package/dist/assets/components/alert.tsx +4 -3
- package/dist/assets/components/aspect-ratio.stories.tsx +70 -0
- package/dist/assets/components/aspect-ratio.tsx +8 -0
- package/dist/assets/components/autocomplete.stories.tsx +9 -9
- package/dist/assets/components/autocomplete.tsx +3 -3
- package/dist/assets/components/avatar.stories.tsx +5 -5
- package/dist/assets/components/avatar.tsx +67 -23
- package/dist/assets/components/badge.stories.tsx +10 -10
- package/dist/assets/components/badge.tsx +3 -3
- package/dist/assets/components/breadcrumbs.stories.tsx +7 -7
- package/dist/assets/components/breadcrumbs.tsx +13 -8
- package/dist/assets/components/button.stories.tsx +74 -74
- package/dist/assets/components/button.tsx +2 -0
- package/dist/assets/components/calendar.stories.tsx +11 -11
- package/dist/assets/components/calendar.tsx +4 -4
- package/dist/assets/components/card.stories.tsx +22 -22
- package/dist/assets/components/card.tsx +7 -3
- package/dist/assets/components/carousel.stories.tsx +158 -0
- package/dist/assets/components/carousel.tsx +264 -0
- package/dist/assets/components/chart.stories.tsx +376 -0
- package/dist/assets/components/chart.tsx +384 -0
- package/dist/assets/components/checkbox-group.stories.tsx +6 -6
- package/dist/assets/components/checkbox-group.tsx +3 -3
- package/dist/assets/components/checkbox.stories.tsx +23 -20
- package/dist/assets/components/checkbox.tsx +13 -6
- package/dist/assets/components/code.stories.tsx +24 -24
- package/dist/assets/components/code.tsx +22 -27
- package/dist/assets/components/collapsible.stories.tsx +128 -0
- package/dist/assets/components/collapsible.tsx +10 -0
- package/dist/assets/components/command.stories.tsx +183 -0
- package/dist/assets/components/command.tsx +171 -0
- package/dist/assets/components/context-menu.stories.tsx +159 -0
- package/dist/assets/components/context-menu.tsx +214 -0
- package/dist/assets/components/date-input.stories.tsx +9 -9
- package/dist/assets/components/date-input.tsx +2 -2
- package/dist/assets/components/date-picker.stories.tsx +9 -9
- package/dist/assets/components/date-picker.tsx +3 -3
- package/dist/assets/components/date-range-picker.stories.tsx +12 -12
- package/dist/assets/components/date-range-picker.tsx +3 -3
- package/dist/assets/components/dialog.stories.tsx +40 -40
- package/dist/assets/components/dialog.tsx +8 -12
- package/dist/assets/components/divider.stories.tsx +30 -30
- package/dist/assets/components/divider.tsx +34 -35
- package/dist/assets/components/drawer.stories.tsx +32 -31
- package/dist/assets/components/drawer.tsx +7 -6
- package/dist/assets/components/dropdown-menu.tsx +213 -0
- package/dist/assets/components/dropdown.stories.tsx +12 -12
- package/dist/assets/components/dropdown.tsx +5 -5
- package/dist/assets/components/form.stories.tsx +30 -29
- package/dist/assets/components/form.tsx +5 -5
- package/dist/assets/components/hover-card.stories.tsx +115 -0
- package/dist/assets/components/hover-card.tsx +35 -0
- package/dist/assets/components/image.stories.tsx +48 -25
- package/dist/assets/components/image.tsx +8 -5
- package/dist/assets/components/input-otp.stories.tsx +15 -15
- package/dist/assets/components/input-otp.tsx +5 -5
- package/dist/assets/components/input.stories.tsx +30 -25
- package/dist/assets/components/input.tsx +7 -4
- package/dist/assets/components/kbd.stories.tsx +34 -34
- package/dist/assets/components/kbd.tsx +9 -9
- package/dist/assets/components/link.stories.tsx +36 -36
- package/dist/assets/components/link.tsx +4 -0
- package/dist/assets/components/listbox.stories.tsx +5 -5
- package/dist/assets/components/listbox.tsx +4 -4
- package/dist/assets/components/menubar.stories.tsx +208 -0
- package/dist/assets/components/menubar.tsx +247 -0
- package/dist/assets/components/navbar.stories.tsx +24 -24
- package/dist/assets/components/navbar.tsx +8 -14
- package/dist/assets/components/navigation-menu.stories.tsx +239 -0
- package/dist/assets/components/navigation-menu.tsx +135 -0
- package/dist/assets/components/number-input.stories.tsx +11 -11
- package/dist/assets/components/number-input.tsx +3 -3
- package/dist/assets/components/pagination.stories.tsx +13 -13
- package/dist/assets/components/pagination.tsx +6 -6
- package/dist/assets/components/popover.stories.tsx +35 -35
- package/dist/assets/components/popover.tsx +98 -15
- package/dist/assets/components/progress.stories.tsx +5 -5
- package/dist/assets/components/progress.tsx +5 -5
- package/dist/assets/components/radio-group.stories.tsx +7 -7
- package/dist/assets/components/radio-group.tsx +3 -3
- package/dist/assets/components/range-calendar.stories.tsx +18 -18
- package/dist/assets/components/range-calendar.tsx +3 -3
- package/dist/assets/components/resizable.stories.tsx +197 -0
- package/dist/assets/components/resizable.tsx +47 -0
- package/dist/assets/components/scroll-area.stories.tsx +123 -0
- package/dist/assets/components/scroll-area.tsx +48 -0
- package/dist/assets/components/scroll-shadow.stories.tsx +17 -17
- package/dist/assets/components/scroll-shadow.tsx +31 -9
- package/dist/assets/components/select.stories.tsx +20 -19
- package/dist/assets/components/select.tsx +10 -6
- package/dist/assets/components/separator.tsx +32 -0
- package/dist/assets/components/sheet.tsx +137 -0
- package/dist/assets/components/sidebar.stories.tsx +351 -0
- package/dist/assets/components/sidebar.tsx +757 -0
- package/dist/assets/components/skeleton.stories.tsx +3 -3
- package/dist/assets/components/skeleton.tsx +2 -2
- package/dist/assets/components/slider.stories.tsx +6 -6
- package/dist/assets/components/slider.tsx +3 -3
- package/dist/assets/components/spacer.stories.tsx +11 -11
- package/dist/assets/components/spacer.tsx +2 -2
- package/dist/assets/components/spinner.stories.tsx +8 -8
- package/dist/assets/components/spinner.tsx +5 -5
- package/dist/assets/components/switch.stories.tsx +24 -20
- package/dist/assets/components/switch.tsx +14 -6
- package/dist/assets/components/table.stories.tsx +7 -7
- package/dist/assets/components/table.tsx +8 -8
- package/dist/assets/components/tabs.stories.tsx +37 -37
- package/dist/assets/components/tabs.tsx +3 -3
- package/dist/assets/components/textarea.stories.tsx +13 -12
- package/dist/assets/components/textarea.tsx +3 -3
- package/dist/assets/components/theme-toggle.stories.tsx +31 -30
- package/dist/assets/components/theme-toggle.tsx +2 -2
- package/dist/assets/components/time-input.stories.tsx +16 -16
- package/dist/assets/components/time-input.tsx +2 -2
- package/dist/assets/components/toast.stories.tsx +8 -5
- package/dist/assets/components/toast.tsx +6 -6
- package/dist/assets/components/toggle-group.stories.tsx +153 -0
- package/dist/assets/components/toggle-group.tsx +61 -0
- package/dist/assets/components/toggle.stories.tsx +77 -0
- package/dist/assets/components/toggle.tsx +46 -0
- package/dist/assets/components/tooltip.stories.tsx +49 -27
- package/dist/assets/components/tooltip.tsx +23 -90
- package/dist/assets/components/user.stories.tsx +23 -23
- package/dist/assets/components/user.tsx +7 -4
- package/dist/assets/dev-tools/SonanceDevTools.tsx +4201 -0
- package/dist/assets/dev-tools/index.ts +10 -0
- package/dist/assets/globals.css +39 -0
- package/dist/assets/logos/40th-anniversary/Sonance_40_Logo_CMYK_BEAM_BLUE_40_AND_BEAM_DARK.png +0 -0
- package/dist/assets/logos/Sonance logo dark mode.png +0 -0
- package/dist/assets/logos/Sonance logo light mode.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_White_RGB_05162025.png +0 -0
- package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Black_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_LtGray_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_LtGray_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Polished_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Reverse_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_White_CMYK.png +0 -0
- package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Dark_RGB.png +0 -0
- package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Light_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Grayscale_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Dark_CMYK.png +0 -0
- package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Light_CMYK.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Dark_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Light_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Black_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Grayscale_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Dark.png +0 -0
- package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Light.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Dark.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Light.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Dark.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Light.png +0 -0
- package/dist/assets/logos/trufig/TrufigLogo_Black.png +0 -0
- package/dist/assets/logos/trufig/TrufigLogo_Light.png +0 -0
- package/dist/assets/logos/trufig/TrufigWatermark_Black.png +0 -0
- package/dist/assets/logos/trufig/TrufigWatermark_Light.png +0 -0
- package/dist/assets/styles/brand-overrides.css +37 -0
- package/dist/index.js +2055 -15
- package/package.json +1 -1
|
@@ -1,50 +1,49 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
1
2
|
import { cn } from "@/lib/utils";
|
|
2
3
|
|
|
3
|
-
interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
export interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
5
|
orientation?: "horizontal" | "vertical";
|
|
5
6
|
label?: string;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
export
|
|
9
|
-
orientation = "horizontal",
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
export const Divider = forwardRef<HTMLDivElement, DividerProps>(
|
|
10
|
+
({ orientation = "horizontal", label, className, ...props }, ref) => {
|
|
11
|
+
if (orientation === "vertical") {
|
|
12
|
+
return (
|
|
13
|
+
<div data-sonance-name="divider"
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (label) {
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
ref={ref}
|
|
23
|
+
role="separator"
|
|
24
|
+
className={cn("flex items-center gap-4", className)} data-sonance-name="divider"
|
|
25
|
+
{...props}
|
|
26
|
+
>
|
|
27
|
+
<div className="h-px flex-1 bg-border" />
|
|
28
|
+
<span id="divider-span-label" className="text-xs font-medium uppercase tracking-widest text-foreground-muted">
|
|
29
|
+
{label}
|
|
30
|
+
</span>
|
|
31
|
+
<div className="h-px flex-1 bg-border" />
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
24
35
|
|
|
25
|
-
if (label) {
|
|
26
36
|
return (
|
|
27
37
|
<div
|
|
38
|
+
ref={ref}
|
|
28
39
|
role="separator"
|
|
29
|
-
|
|
40
|
+
aria-orientation="horizontal"
|
|
41
|
+
className={cn("h-px w-full bg-border", className)} data-sonance-name="divider"
|
|
30
42
|
{...props}
|
|
31
|
-
|
|
32
|
-
<div className="h-px flex-1 bg-border" />
|
|
33
|
-
<span className="text-xs font-medium uppercase tracking-widest text-foreground-muted">
|
|
34
|
-
{label}
|
|
35
|
-
</span>
|
|
36
|
-
<div className="h-px flex-1 bg-border" />
|
|
37
|
-
</div>
|
|
43
|
+
/>
|
|
38
44
|
);
|
|
39
45
|
}
|
|
46
|
+
);
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
<div
|
|
43
|
-
role="separator"
|
|
44
|
-
aria-orientation="horizontal"
|
|
45
|
-
className={cn("h-px w-full bg-border", className)}
|
|
46
|
-
{...props}
|
|
47
|
-
/>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
48
|
+
Divider.displayName = "Divider";
|
|
50
49
|
|
|
@@ -26,19 +26,19 @@ export const Default: Story = {
|
|
|
26
26
|
const [open, setOpen] = useState(false);
|
|
27
27
|
return (
|
|
28
28
|
<>
|
|
29
|
-
<Button onClick={() => setOpen(true)}>Open Drawer</Button>
|
|
29
|
+
<Button id="default-button" onClick={() => setOpen(true)}>Open Drawer</Button>
|
|
30
30
|
<Drawer open={open} onClose={() => setOpen(false)}>
|
|
31
31
|
<DrawerHeader onClose={() => setOpen(false)}>
|
|
32
32
|
<DrawerTitle>Drawer Title</DrawerTitle>
|
|
33
33
|
</DrawerHeader>
|
|
34
34
|
<DrawerBody>
|
|
35
|
-
<p className="text-foreground-secondary">
|
|
35
|
+
<p id="default-p-this-is-the-drawer-c" className="text-foreground-secondary">
|
|
36
36
|
This is the drawer content area. You can add any content here.
|
|
37
37
|
</p>
|
|
38
38
|
</DrawerBody>
|
|
39
39
|
<DrawerFooter>
|
|
40
|
-
<Button variant="secondary" onClick={() => setOpen(false)}>Cancel</Button>
|
|
41
|
-
<Button onClick={() => setOpen(false)}>Save</Button>
|
|
40
|
+
<Button id="default-button-secondary" variant="secondary" onClick={() => setOpen(false)}>Cancel</Button>
|
|
41
|
+
<Button id="default-button" onClick={() => setOpen(false)}>Save</Button>
|
|
42
42
|
</DrawerFooter>
|
|
43
43
|
</Drawer>
|
|
44
44
|
</>
|
|
@@ -51,7 +51,7 @@ export const LeftPosition: Story = {
|
|
|
51
51
|
const [open, setOpen] = useState(false);
|
|
52
52
|
return (
|
|
53
53
|
<>
|
|
54
|
-
<Button onClick={() => setOpen(true)}>Open Left Drawer</Button>
|
|
54
|
+
<Button id="left-position-button" onClick={() => setOpen(true)}>Open Left Drawer</Button>
|
|
55
55
|
<Drawer open={open} onClose={() => setOpen(false)} position="left">
|
|
56
56
|
<DrawerHeader onClose={() => setOpen(false)}>
|
|
57
57
|
<DrawerTitle>Navigation</DrawerTitle>
|
|
@@ -60,6 +60,7 @@ export const LeftPosition: Story = {
|
|
|
60
60
|
<nav className="space-y-2">
|
|
61
61
|
{['Dashboard', 'Products', 'Orders', 'Customers', 'Settings'].map((item) => (
|
|
62
62
|
<a
|
|
63
|
+
id="nav-a"
|
|
63
64
|
key={item}
|
|
64
65
|
href="#"
|
|
65
66
|
className="block px-4 py-2 text-foreground hover:bg-secondary-hover rounded transition-colors"
|
|
@@ -80,13 +81,13 @@ export const TopPosition: Story = {
|
|
|
80
81
|
const [open, setOpen] = useState(false);
|
|
81
82
|
return (
|
|
82
83
|
<>
|
|
83
|
-
<Button onClick={() => setOpen(true)}>Open Top Drawer</Button>
|
|
84
|
+
<Button id="top-position-button" onClick={() => setOpen(true)}>Open Top Drawer</Button>
|
|
84
85
|
<Drawer open={open} onClose={() => setOpen(false)} position="top">
|
|
85
86
|
<DrawerHeader onClose={() => setOpen(false)}>
|
|
86
87
|
<DrawerTitle>Notifications</DrawerTitle>
|
|
87
88
|
</DrawerHeader>
|
|
88
89
|
<DrawerBody>
|
|
89
|
-
<p className="text-foreground-secondary">
|
|
90
|
+
<p id="top-position-p-top-drawer-content-a" className="text-foreground-secondary">
|
|
90
91
|
Top drawer content appears from the top of the screen.
|
|
91
92
|
</p>
|
|
92
93
|
</DrawerBody>
|
|
@@ -101,7 +102,7 @@ export const BottomPosition: Story = {
|
|
|
101
102
|
const [open, setOpen] = useState(false);
|
|
102
103
|
return (
|
|
103
104
|
<>
|
|
104
|
-
<Button onClick={() => setOpen(true)}>Open Bottom Drawer</Button>
|
|
105
|
+
<Button id="bottom-position-button" onClick={() => setOpen(true)}>Open Bottom Drawer</Button>
|
|
105
106
|
<Drawer open={open} onClose={() => setOpen(false)} position="bottom">
|
|
106
107
|
<DrawerHeader onClose={() => setOpen(false)}>
|
|
107
108
|
<DrawerTitle>Quick Actions</DrawerTitle>
|
|
@@ -114,7 +115,7 @@ export const BottomPosition: Story = {
|
|
|
114
115
|
className="flex flex-col items-center gap-2 p-4 hover:bg-secondary-hover rounded transition-colors"
|
|
115
116
|
>
|
|
116
117
|
<div className="w-10 h-10 rounded-full bg-primary" />
|
|
117
|
-
<span className="text-sm text-foreground">{action}</span>
|
|
118
|
+
<span id="bottom-position-span-action" className="text-sm text-foreground">{action}</span>
|
|
118
119
|
</button>
|
|
119
120
|
))}
|
|
120
121
|
</div>
|
|
@@ -130,21 +131,21 @@ export const FormDrawer: Story = {
|
|
|
130
131
|
const [open, setOpen] = useState(false);
|
|
131
132
|
return (
|
|
132
133
|
<>
|
|
133
|
-
<Button onClick={() => setOpen(true)}>Edit Profile</Button>
|
|
134
|
+
<Button id="form-drawer-button" onClick={() => setOpen(true)}>Edit Profile</Button>
|
|
134
135
|
<Drawer open={open} onClose={() => setOpen(false)}>
|
|
135
136
|
<DrawerHeader onClose={() => setOpen(false)}>
|
|
136
137
|
<DrawerTitle>Edit Profile</DrawerTitle>
|
|
137
138
|
</DrawerHeader>
|
|
138
139
|
<DrawerBody>
|
|
139
140
|
<form className="space-y-4">
|
|
140
|
-
<Input label="Full Name" placeholder="John Doe" />
|
|
141
|
-
<Input label="Email" type="email" placeholder="john@example.com" />
|
|
142
|
-
<Input label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
141
|
+
<Input id="form-drawer-input-john-doe" label="Full Name" placeholder="John Doe" />
|
|
142
|
+
<Input id="form-drawer-input-johnexamplecom" label="Email" type="email" placeholder="john@example.com" />
|
|
143
|
+
<Input id="form-drawer-input-1-555-0000000" label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
143
144
|
</form>
|
|
144
145
|
</DrawerBody>
|
|
145
146
|
<DrawerFooter>
|
|
146
|
-
<Button variant="secondary" onClick={() => setOpen(false)}>Cancel</Button>
|
|
147
|
-
<Button onClick={() => setOpen(false)}>Save Changes</Button>
|
|
147
|
+
<Button id="form-drawer-button-secondary" variant="secondary" onClick={() => setOpen(false)}>Cancel</Button>
|
|
148
|
+
<Button id="form-drawer-button" onClick={() => setOpen(false)}>Save Changes</Button>
|
|
148
149
|
</DrawerFooter>
|
|
149
150
|
</Drawer>
|
|
150
151
|
</>
|
|
@@ -158,16 +159,16 @@ export const ResponsiveMatrix: Story = {
|
|
|
158
159
|
<div className="space-y-8">
|
|
159
160
|
{/* Mobile */}
|
|
160
161
|
<div>
|
|
161
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
162
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
162
163
|
<div className="w-[375px] h-[400px] border border-dashed border-border relative overflow-hidden">
|
|
163
164
|
<div className="absolute right-0 top-0 bottom-0 w-[280px] bg-background border-l border-border shadow-lg">
|
|
164
165
|
<div className="p-4 border-b border-border">
|
|
165
|
-
<h3 className="font-semibold">Drawer Title</h3>
|
|
166
|
+
<h3 id="responsive-matrix-h3-drawer-title" className="font-semibold">Drawer Title</h3>
|
|
166
167
|
</div>
|
|
167
168
|
<div className="p-4">
|
|
168
|
-
<p className="text-sm text-foreground-secondary">Full-height drawer on mobile.</p>
|
|
169
|
+
<p id="responsive-matrix-p-fullheight-drawer-on" className="text-sm text-foreground-secondary">Full-height drawer on mobile.</p>
|
|
169
170
|
<div className="mt-4 space-y-4">
|
|
170
|
-
<Input label="Name" placeholder="Enter name" />
|
|
171
|
+
<Input id="responsive-matrix-input-enter-name" label="Name" placeholder="Enter name" />
|
|
171
172
|
</div>
|
|
172
173
|
</div>
|
|
173
174
|
</div>
|
|
@@ -175,38 +176,38 @@ export const ResponsiveMatrix: Story = {
|
|
|
175
176
|
</div>
|
|
176
177
|
{/* Tablet */}
|
|
177
178
|
<div>
|
|
178
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
179
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
179
180
|
<div className="w-[768px] h-[300px] border border-dashed border-border relative overflow-hidden">
|
|
180
181
|
<div className="absolute right-0 top-0 bottom-0 w-[400px] bg-background border-l border-border shadow-lg">
|
|
181
182
|
<div className="p-4 border-b border-border">
|
|
182
|
-
<h3 className="font-semibold">Edit Profile</h3>
|
|
183
|
+
<h3 id="responsive-matrix-h3-edit-profile" className="font-semibold">Edit Profile</h3>
|
|
183
184
|
</div>
|
|
184
185
|
<div className="p-4 space-y-4">
|
|
185
|
-
<Input label="Name" placeholder="John Doe" />
|
|
186
|
-
<Input label="Email" placeholder="john@example.com" />
|
|
186
|
+
<Input id="responsive-matrix-input-john-doe" label="Name" placeholder="John Doe" />
|
|
187
|
+
<Input id="responsive-matrix-input-johnexamplecom" label="Email" placeholder="john@example.com" />
|
|
187
188
|
</div>
|
|
188
189
|
<div className="absolute bottom-0 left-0 right-0 p-4 border-t border-border flex justify-end gap-2">
|
|
189
|
-
<Button variant="secondary" size="sm">Cancel</Button>
|
|
190
|
-
<Button size="sm">Save</Button>
|
|
190
|
+
<Button id="responsive-matrix-button-secondary" variant="secondary" size="sm">Cancel</Button>
|
|
191
|
+
<Button id="responsive-matrix-button" size="sm">Save</Button>
|
|
191
192
|
</div>
|
|
192
193
|
</div>
|
|
193
194
|
</div>
|
|
194
195
|
</div>
|
|
195
196
|
{/* Desktop */}
|
|
196
197
|
<div>
|
|
197
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
198
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
198
199
|
<div className="w-[1280px] h-[300px] border border-dashed border-border relative overflow-hidden bg-black/20">
|
|
199
200
|
<div className="absolute right-0 top-0 bottom-0 w-[480px] bg-background border-l border-border shadow-lg">
|
|
200
201
|
<div className="p-6 border-b border-border">
|
|
201
|
-
<h3 className="text-lg font-semibold">Settings Panel</h3>
|
|
202
|
+
<h3 id="responsive-matrix-h3-settings-panel" className="text-lg font-semibold">Settings Panel</h3>
|
|
202
203
|
</div>
|
|
203
204
|
<div className="p-6 space-y-4">
|
|
204
|
-
<Input label="Display Name" placeholder="Enter display name" />
|
|
205
|
-
<Input label="Email" type="email" placeholder="email@example.com" />
|
|
205
|
+
<Input id="responsive-matrix-input-enter-display-n" label="Display Name" placeholder="Enter display name" />
|
|
206
|
+
<Input id="responsive-matrix-input-emailexamplecom" label="Email" type="email" placeholder="email@example.com" />
|
|
206
207
|
</div>
|
|
207
208
|
<div className="absolute bottom-0 left-0 right-0 p-6 border-t border-border flex justify-end gap-2">
|
|
208
|
-
<Button variant="secondary">Cancel</Button>
|
|
209
|
-
<Button>Save Changes</Button>
|
|
209
|
+
<Button id="responsive-matrix-button-secondary" variant="secondary">Cancel</Button>
|
|
210
|
+
<Button id="responsive-matrix-button">Save Changes</Button>
|
|
210
211
|
</div>
|
|
211
212
|
</div>
|
|
212
213
|
</div>
|
|
@@ -54,14 +54,14 @@ export function Drawer({
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
return (
|
|
57
|
-
<div className="fixed inset-0 z-50">
|
|
57
|
+
<div data-sonance-name="drawer" className="fixed inset-0 z-50">
|
|
58
58
|
{/* Backdrop */}
|
|
59
59
|
<div
|
|
60
60
|
className="absolute inset-0 bg-overlay animate-in fade-in duration-200"
|
|
61
61
|
onClick={onClose}
|
|
62
62
|
/>
|
|
63
63
|
{/* Drawer panel */}
|
|
64
|
-
<div
|
|
64
|
+
<div data-sonance-name="drawer"
|
|
65
65
|
className={cn(
|
|
66
66
|
"absolute bg-background border-border shadow-xl",
|
|
67
67
|
position === "left" && "border-r",
|
|
@@ -87,7 +87,7 @@ export const DrawerHeader = forwardRef<
|
|
|
87
87
|
className={cn(
|
|
88
88
|
"flex items-center justify-between px-6 py-4 border-b border-border",
|
|
89
89
|
className
|
|
90
|
-
)}
|
|
90
|
+
)} data-sonance-name="drawer"
|
|
91
91
|
{...props}
|
|
92
92
|
>
|
|
93
93
|
<div>{children}</div>
|
|
@@ -97,7 +97,7 @@ export const DrawerHeader = forwardRef<
|
|
|
97
97
|
className="p-1 text-foreground-muted hover:text-foreground transition-colors"
|
|
98
98
|
>
|
|
99
99
|
<X className="h-5 w-5" />
|
|
100
|
-
<span className="sr-only">Close</span>
|
|
100
|
+
<span id="drawer-header-span-close" className="sr-only">Close</span>
|
|
101
101
|
</button>
|
|
102
102
|
)}
|
|
103
103
|
</div>
|
|
@@ -110,6 +110,7 @@ export const DrawerTitle = forwardRef<
|
|
|
110
110
|
React.HTMLAttributes<HTMLHeadingElement>
|
|
111
111
|
>(({ className, ...props }, ref) => (
|
|
112
112
|
<h2
|
|
113
|
+
id="drawer-title-h2"
|
|
113
114
|
ref={ref}
|
|
114
115
|
className={cn("text-lg font-medium text-foreground", className)}
|
|
115
116
|
{...props}
|
|
@@ -124,7 +125,7 @@ export const DrawerBody = forwardRef<
|
|
|
124
125
|
>(({ className, ...props }, ref) => (
|
|
125
126
|
<div
|
|
126
127
|
ref={ref}
|
|
127
|
-
className={cn("flex-1 overflow-auto p-6", className)}
|
|
128
|
+
className={cn("flex-1 overflow-auto p-6", className)} data-sonance-name="drawer"
|
|
128
129
|
{...props}
|
|
129
130
|
/>
|
|
130
131
|
));
|
|
@@ -140,7 +141,7 @@ export const DrawerFooter = forwardRef<
|
|
|
140
141
|
className={cn(
|
|
141
142
|
"flex items-center justify-end gap-3 px-6 py-4 border-t border-border",
|
|
142
143
|
className
|
|
143
|
-
)}
|
|
144
|
+
)} data-sonance-name="drawer"
|
|
144
145
|
{...props}
|
|
145
146
|
/>
|
|
146
147
|
));
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
5
|
+
import { Check, ChevronRight, Circle } from "lucide-react";
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
9
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
10
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
11
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
12
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
13
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
14
|
+
|
|
15
|
+
const DropdownMenuSubTrigger = React.forwardRef<
|
|
16
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
17
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
18
|
+
inset?: boolean;
|
|
19
|
+
}
|
|
20
|
+
>(({ className, inset, children, ...props }, ref) => (
|
|
21
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={cn(
|
|
24
|
+
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
|
|
25
|
+
"focus:bg-secondary-hover focus:text-foreground",
|
|
26
|
+
"data-[state=open]:bg-secondary-hover data-[state=open]:text-foreground",
|
|
27
|
+
inset && "pl-8",
|
|
28
|
+
className
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
<ChevronRight className="ml-auto h-4 w-4" />
|
|
34
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
35
|
+
));
|
|
36
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
37
|
+
|
|
38
|
+
const DropdownMenuSubContent = React.forwardRef<
|
|
39
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
40
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
41
|
+
>(({ className, ...props }, ref) => (
|
|
42
|
+
<DropdownMenuPrimitive.SubContent
|
|
43
|
+
ref={ref}
|
|
44
|
+
className={cn(
|
|
45
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-sm border border-border bg-card p-1 text-foreground shadow-lg",
|
|
46
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
47
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
48
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
49
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
50
|
+
"data-[side=left]:slide-in-from-right-2",
|
|
51
|
+
"data-[side=right]:slide-in-from-left-2",
|
|
52
|
+
"data-[side=top]:slide-in-from-bottom-2",
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
));
|
|
58
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
59
|
+
|
|
60
|
+
const DropdownMenuContent = React.forwardRef<
|
|
61
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
62
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
63
|
+
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
64
|
+
<DropdownMenuPrimitive.Portal>
|
|
65
|
+
<DropdownMenuPrimitive.Content
|
|
66
|
+
ref={ref}
|
|
67
|
+
sideOffset={sideOffset}
|
|
68
|
+
className={cn(
|
|
69
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-sm border border-border bg-card p-1 text-foreground shadow-md",
|
|
70
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
71
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
72
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
73
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
74
|
+
"data-[side=left]:slide-in-from-right-2",
|
|
75
|
+
"data-[side=right]:slide-in-from-left-2",
|
|
76
|
+
"data-[side=top]:slide-in-from-bottom-2",
|
|
77
|
+
className
|
|
78
|
+
)}
|
|
79
|
+
{...props}
|
|
80
|
+
/>
|
|
81
|
+
</DropdownMenuPrimitive.Portal>
|
|
82
|
+
));
|
|
83
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
84
|
+
|
|
85
|
+
const DropdownMenuItem = React.forwardRef<
|
|
86
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
87
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
|
88
|
+
inset?: boolean;
|
|
89
|
+
}
|
|
90
|
+
>(({ className, inset, ...props }, ref) => (
|
|
91
|
+
<DropdownMenuPrimitive.Item
|
|
92
|
+
ref={ref}
|
|
93
|
+
className={cn(
|
|
94
|
+
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors",
|
|
95
|
+
"focus:bg-secondary-hover focus:text-foreground",
|
|
96
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
97
|
+
inset && "pl-8",
|
|
98
|
+
className
|
|
99
|
+
)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
));
|
|
103
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
104
|
+
|
|
105
|
+
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
106
|
+
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
107
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
108
|
+
>(({ className, children, checked, ...props }, ref) => (
|
|
109
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
110
|
+
ref={ref}
|
|
111
|
+
className={cn(
|
|
112
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors",
|
|
113
|
+
"focus:bg-secondary-hover focus:text-foreground",
|
|
114
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
115
|
+
className
|
|
116
|
+
)}
|
|
117
|
+
checked={checked}
|
|
118
|
+
{...props}
|
|
119
|
+
>
|
|
120
|
+
<span id="dropdown-menu-checkbox-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
121
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
122
|
+
<Check className="h-4 w-4" />
|
|
123
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
124
|
+
</span>
|
|
125
|
+
{children}
|
|
126
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
127
|
+
));
|
|
128
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
129
|
+
|
|
130
|
+
const DropdownMenuRadioItem = React.forwardRef<
|
|
131
|
+
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
132
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
133
|
+
>(({ className, children, ...props }, ref) => (
|
|
134
|
+
<DropdownMenuPrimitive.RadioItem
|
|
135
|
+
ref={ref}
|
|
136
|
+
className={cn(
|
|
137
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors",
|
|
138
|
+
"focus:bg-secondary-hover focus:text-foreground",
|
|
139
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
140
|
+
className
|
|
141
|
+
)}
|
|
142
|
+
{...props}
|
|
143
|
+
>
|
|
144
|
+
<span id="dropdown-menu-radio-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
145
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
146
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
147
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
148
|
+
</span>
|
|
149
|
+
{children}
|
|
150
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
151
|
+
));
|
|
152
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
153
|
+
|
|
154
|
+
const DropdownMenuLabel = React.forwardRef<
|
|
155
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
156
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
157
|
+
inset?: boolean;
|
|
158
|
+
}
|
|
159
|
+
>(({ className, inset, ...props }, ref) => (
|
|
160
|
+
<DropdownMenuPrimitive.Label
|
|
161
|
+
ref={ref}
|
|
162
|
+
className={cn(
|
|
163
|
+
"px-2 py-1.5 text-xs font-medium uppercase tracking-widest text-foreground-muted",
|
|
164
|
+
inset && "pl-8",
|
|
165
|
+
className
|
|
166
|
+
)}
|
|
167
|
+
{...props}
|
|
168
|
+
/>
|
|
169
|
+
));
|
|
170
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
171
|
+
|
|
172
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
173
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
174
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
175
|
+
>(({ className, ...props }, ref) => (
|
|
176
|
+
<DropdownMenuPrimitive.Separator
|
|
177
|
+
ref={ref}
|
|
178
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
179
|
+
{...props}
|
|
180
|
+
/>
|
|
181
|
+
));
|
|
182
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
183
|
+
|
|
184
|
+
const DropdownMenuShortcut = ({
|
|
185
|
+
className,
|
|
186
|
+
...props
|
|
187
|
+
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
188
|
+
return (
|
|
189
|
+
<span id="dropdown-menu-shortcut-span" data-sonance-name="dropdown-menu"
|
|
190
|
+
{...props}
|
|
191
|
+
/>
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
195
|
+
|
|
196
|
+
export {
|
|
197
|
+
DropdownMenu,
|
|
198
|
+
DropdownMenuTrigger,
|
|
199
|
+
DropdownMenuContent,
|
|
200
|
+
DropdownMenuItem,
|
|
201
|
+
DropdownMenuCheckboxItem,
|
|
202
|
+
DropdownMenuRadioItem,
|
|
203
|
+
DropdownMenuLabel,
|
|
204
|
+
DropdownMenuSeparator,
|
|
205
|
+
DropdownMenuShortcut,
|
|
206
|
+
DropdownMenuGroup,
|
|
207
|
+
DropdownMenuPortal,
|
|
208
|
+
DropdownMenuSub,
|
|
209
|
+
DropdownMenuSubContent,
|
|
210
|
+
DropdownMenuSubTrigger,
|
|
211
|
+
DropdownMenuRadioGroup,
|
|
212
|
+
};
|
|
213
|
+
|
|
@@ -178,7 +178,7 @@ export const CustomTrigger: Story = {
|
|
|
178
178
|
render: () => (
|
|
179
179
|
<Dropdown>
|
|
180
180
|
<DropdownTrigger asChild>
|
|
181
|
-
<Button variant="secondary">Custom Button Trigger</Button>
|
|
181
|
+
<Button id="custom-trigger-button-secondary" variant="secondary">Custom Button Trigger</Button>
|
|
182
182
|
</DropdownTrigger>
|
|
183
183
|
<DropdownMenu>
|
|
184
184
|
<DropdownItem>Action 1</DropdownItem>
|
|
@@ -197,13 +197,13 @@ export const UserMenu: Story = {
|
|
|
197
197
|
<div className="w-8 h-8 rounded-full bg-primary flex items-center justify-center text-primary-foreground text-sm font-medium">
|
|
198
198
|
JD
|
|
199
199
|
</div>
|
|
200
|
-
<span className="text-sm font-medium text-foreground">John Doe</span>
|
|
200
|
+
<span id="user-menu-span-john-doe" className="text-sm font-medium text-foreground">John Doe</span>
|
|
201
201
|
</button>
|
|
202
202
|
</DropdownTrigger>
|
|
203
203
|
<DropdownMenu align="end">
|
|
204
204
|
<div className="px-3 py-2 border-b border-border">
|
|
205
|
-
<p className="text-sm font-medium text-foreground">John Doe</p>
|
|
206
|
-
<p className="text-xs text-foreground-muted">john@sonance.com</p>
|
|
205
|
+
<p id="user-menu-p-john-doe" className="text-sm font-medium text-foreground">John Doe</p>
|
|
206
|
+
<p id="user-menu-p-johnsonancecom" className="text-xs text-foreground-muted">john@sonance.com</p>
|
|
207
207
|
</div>
|
|
208
208
|
<DropdownItem icon={<User className="h-4 w-4" />}>Profile</DropdownItem>
|
|
209
209
|
<DropdownItem icon={<Settings className="h-4 w-4" />}>Settings</DropdownItem>
|
|
@@ -222,13 +222,13 @@ export const StateMatrix: Story = {
|
|
|
222
222
|
const triggerStates: DropdownTriggerState[] = ['default', 'hover', 'focus', 'open', 'disabled'];
|
|
223
223
|
const itemStates: DropdownItemState[] = ['default', 'hover', 'focus', 'selected', 'disabled'];
|
|
224
224
|
return (
|
|
225
|
-
<div className="space-y-8">
|
|
225
|
+
<div data-sonance-name="dropdown.stories" className="space-y-8">
|
|
226
226
|
<div>
|
|
227
|
-
<h3 className="text-sm font-medium text-foreground-muted mb-4">DropdownTrigger States</h3>
|
|
227
|
+
<h3 id="state-matrix-h3-dropdowntrigger-stat" className="text-sm font-medium text-foreground-muted mb-4">DropdownTrigger States</h3>
|
|
228
228
|
<div className="flex flex-wrap gap-4">
|
|
229
229
|
{triggerStates.map((state) => (
|
|
230
230
|
<div key={state} className="flex flex-col items-center gap-2">
|
|
231
|
-
<span className="text-xs font-medium text-foreground-muted uppercase">{state}</span>
|
|
231
|
+
<span id="state-matrix-span-state" className="text-xs font-medium text-foreground-muted uppercase">{state}</span>
|
|
232
232
|
<Dropdown>
|
|
233
233
|
<DropdownTrigger state={state}>{state}</DropdownTrigger>
|
|
234
234
|
<DropdownMenu>
|
|
@@ -240,7 +240,7 @@ export const StateMatrix: Story = {
|
|
|
240
240
|
</div>
|
|
241
241
|
</div>
|
|
242
242
|
<div>
|
|
243
|
-
<h3 className="text-sm font-medium text-foreground-muted mb-4">DropdownItem States (Open menu to see)</h3>
|
|
243
|
+
<h3 id="state-matrix-h3-dropdownitem-states-" className="text-sm font-medium text-foreground-muted mb-4">DropdownItem States (Open menu to see)</h3>
|
|
244
244
|
<Dropdown>
|
|
245
245
|
<DropdownTrigger state="open">View Item States</DropdownTrigger>
|
|
246
246
|
<DropdownMenu>
|
|
@@ -263,7 +263,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
263
263
|
<div className="space-y-8">
|
|
264
264
|
{/* Mobile */}
|
|
265
265
|
<div>
|
|
266
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
266
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
267
267
|
<div className="w-[375px] border border-dashed border-border p-4 flex justify-center">
|
|
268
268
|
<Dropdown>
|
|
269
269
|
<DropdownTrigger>Actions</DropdownTrigger>
|
|
@@ -278,7 +278,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
278
278
|
</div>
|
|
279
279
|
{/* Tablet */}
|
|
280
280
|
<div>
|
|
281
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
281
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
282
282
|
<div className="w-[768px] border border-dashed border-border p-4 flex justify-between">
|
|
283
283
|
<Dropdown>
|
|
284
284
|
<DropdownTrigger>File</DropdownTrigger>
|
|
@@ -301,7 +301,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
301
301
|
</div>
|
|
302
302
|
{/* Desktop */}
|
|
303
303
|
<div>
|
|
304
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
304
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
305
305
|
<div className="w-[1280px] border border-dashed border-border p-4 flex justify-between items-center">
|
|
306
306
|
<div className="flex gap-4">
|
|
307
307
|
<Dropdown>
|
|
@@ -325,7 +325,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
325
325
|
<DropdownTrigger asChild>
|
|
326
326
|
<button className="flex items-center gap-2 p-2 hover:bg-secondary-hover rounded">
|
|
327
327
|
<div className="w-8 h-8 rounded-full bg-primary flex items-center justify-center text-primary-foreground text-sm font-medium">JD</div>
|
|
328
|
-
<span className="text-sm font-medium">John Doe</span>
|
|
328
|
+
<span id="responsive-matrix-span-john-doe" className="text-sm font-medium">John Doe</span>
|
|
329
329
|
</button>
|
|
330
330
|
</DropdownTrigger>
|
|
331
331
|
<DropdownMenu align="end">
|
|
@@ -106,14 +106,14 @@ export function DropdownTrigger({ children, className, asChild, disabled, state
|
|
|
106
106
|
|
|
107
107
|
if (asChild) {
|
|
108
108
|
return (
|
|
109
|
-
<span onClick={() => !isDisabled && setIsOpen(!isOpen)} className={className}>
|
|
109
|
+
<span id="dropdown-trigger-span-children" data-sonance-name="dropdown" onClick={() => !isDisabled && setIsOpen(!isOpen)} className={className}>
|
|
110
110
|
{children}
|
|
111
111
|
</span>
|
|
112
112
|
);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
return (
|
|
116
|
-
<button
|
|
116
|
+
<button data-sonance-name="dropdown"
|
|
117
117
|
type="button"
|
|
118
118
|
onClick={() => !isDisabled && setIsOpen(!isOpen)}
|
|
119
119
|
disabled={isDisabled}
|
|
@@ -234,11 +234,11 @@ export function DropdownItem({
|
|
|
234
234
|
className
|
|
235
235
|
)}
|
|
236
236
|
>
|
|
237
|
-
{icon && <span className="w-4 h-4 shrink-0">{icon}</span>}
|
|
238
|
-
<span className="flex-1">{children}</span>
|
|
237
|
+
{icon && <span id="dropdown-item-span-icon" className="w-4 h-4 shrink-0">{icon}</span>}
|
|
238
|
+
<span id="dropdown-item-span-children" className="flex-1">{children}</span>
|
|
239
239
|
{isSelected && !icon && <Check className="h-4 w-4 ml-auto" />}
|
|
240
240
|
{shortcut && (
|
|
241
|
-
<span className="ml-auto text-xs text-foreground-muted">{shortcut}</span>
|
|
241
|
+
<span id="dropdown-item-span-shortcut" className="ml-auto text-xs text-foreground-muted">{shortcut}</span>
|
|
242
242
|
)}
|
|
243
243
|
</button>
|
|
244
244
|
);
|