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
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
5
|
+
import { Search } from "lucide-react";
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
import {
|
|
8
|
+
Dialog,
|
|
9
|
+
DialogContent,
|
|
10
|
+
DialogTitle,
|
|
11
|
+
} from "@/components/ui/dialog";
|
|
12
|
+
|
|
13
|
+
const Command = React.forwardRef<
|
|
14
|
+
React.ElementRef<typeof CommandPrimitive>,
|
|
15
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
|
16
|
+
>(({ className, ...props }, ref) => (
|
|
17
|
+
<CommandPrimitive
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn(
|
|
20
|
+
"flex h-full w-full flex-col overflow-hidden rounded-sm bg-card text-foreground",
|
|
21
|
+
className
|
|
22
|
+
)} data-sonance-name="command"
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
));
|
|
26
|
+
Command.displayName = CommandPrimitive.displayName;
|
|
27
|
+
|
|
28
|
+
interface CommandDialogProps {
|
|
29
|
+
open?: boolean;
|
|
30
|
+
onOpenChange?: (open: boolean) => void;
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const CommandDialog = ({ children, open, onOpenChange }: CommandDialogProps) => {
|
|
35
|
+
const handleClose = React.useCallback(() => {
|
|
36
|
+
onOpenChange?.(false);
|
|
37
|
+
}, [onOpenChange]);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Dialog data-sonance-name="command" open={open ?? false} onClose={handleClose}>
|
|
41
|
+
<DialogContent className="overflow-hidden p-0 shadow-lg" showClose={false}>
|
|
42
|
+
<DialogTitle className="sr-only">Command Menu</DialogTitle>
|
|
43
|
+
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-foreground-muted [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
|
44
|
+
{children}
|
|
45
|
+
</Command>
|
|
46
|
+
</DialogContent>
|
|
47
|
+
</Dialog>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const CommandInput = React.forwardRef<
|
|
52
|
+
React.ElementRef<typeof CommandPrimitive.Input>,
|
|
53
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
|
54
|
+
>(({ className, ...props }, ref) => (
|
|
55
|
+
<div className="flex items-center border-b border-border px-3" cmdk-input-wrapper="">
|
|
56
|
+
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
|
57
|
+
<CommandPrimitive.Input
|
|
58
|
+
ref={ref}
|
|
59
|
+
className={cn(
|
|
60
|
+
"flex h-11 w-full rounded-sm bg-transparent py-3 text-sm outline-none placeholder:text-foreground-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
61
|
+
className
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
));
|
|
67
|
+
|
|
68
|
+
CommandInput.displayName = CommandPrimitive.Input.displayName;
|
|
69
|
+
|
|
70
|
+
const CommandList = React.forwardRef<
|
|
71
|
+
React.ElementRef<typeof CommandPrimitive.List>,
|
|
72
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
|
73
|
+
>(({ className, ...props }, ref) => (
|
|
74
|
+
<CommandPrimitive.List
|
|
75
|
+
ref={ref}
|
|
76
|
+
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
));
|
|
80
|
+
|
|
81
|
+
CommandList.displayName = CommandPrimitive.List.displayName;
|
|
82
|
+
|
|
83
|
+
const CommandEmpty = React.forwardRef<
|
|
84
|
+
React.ElementRef<typeof CommandPrimitive.Empty>,
|
|
85
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
|
86
|
+
>((props, ref) => (
|
|
87
|
+
<CommandPrimitive.Empty
|
|
88
|
+
ref={ref}
|
|
89
|
+
className="py-6 text-center text-sm text-foreground-muted"
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
));
|
|
93
|
+
|
|
94
|
+
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
|
|
95
|
+
|
|
96
|
+
const CommandGroup = React.forwardRef<
|
|
97
|
+
React.ElementRef<typeof CommandPrimitive.Group>,
|
|
98
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
|
99
|
+
>(({ className, ...props }, ref) => (
|
|
100
|
+
<CommandPrimitive.Group
|
|
101
|
+
ref={ref}
|
|
102
|
+
className={cn(
|
|
103
|
+
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-widest [&_[cmdk-group-heading]]:text-foreground-muted",
|
|
104
|
+
className
|
|
105
|
+
)}
|
|
106
|
+
{...props}
|
|
107
|
+
/>
|
|
108
|
+
));
|
|
109
|
+
|
|
110
|
+
CommandGroup.displayName = CommandPrimitive.Group.displayName;
|
|
111
|
+
|
|
112
|
+
const CommandSeparator = React.forwardRef<
|
|
113
|
+
React.ElementRef<typeof CommandPrimitive.Separator>,
|
|
114
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
|
115
|
+
>(({ className, ...props }, ref) => (
|
|
116
|
+
<CommandPrimitive.Separator
|
|
117
|
+
ref={ref}
|
|
118
|
+
className={cn("-mx-1 h-px bg-border", className)}
|
|
119
|
+
{...props}
|
|
120
|
+
/>
|
|
121
|
+
));
|
|
122
|
+
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
|
|
123
|
+
|
|
124
|
+
const CommandItem = React.forwardRef<
|
|
125
|
+
React.ElementRef<typeof CommandPrimitive.Item>,
|
|
126
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
|
127
|
+
>(({ className, ...props }, ref) => (
|
|
128
|
+
<CommandPrimitive.Item
|
|
129
|
+
ref={ref}
|
|
130
|
+
className={cn(
|
|
131
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
|
|
132
|
+
"data-[selected=true]:bg-secondary-hover data-[selected=true]:text-foreground",
|
|
133
|
+
"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
|
|
134
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
135
|
+
className
|
|
136
|
+
)}
|
|
137
|
+
{...props}
|
|
138
|
+
/>
|
|
139
|
+
));
|
|
140
|
+
|
|
141
|
+
CommandItem.displayName = CommandPrimitive.Item.displayName;
|
|
142
|
+
|
|
143
|
+
const CommandShortcut = ({
|
|
144
|
+
className,
|
|
145
|
+
...props
|
|
146
|
+
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
147
|
+
return (
|
|
148
|
+
<span
|
|
149
|
+
id="command-shortcut-span"
|
|
150
|
+
className={cn(
|
|
151
|
+
"ml-auto text-xs tracking-widest text-foreground-muted",
|
|
152
|
+
className
|
|
153
|
+
)} data-sonance-name="command"
|
|
154
|
+
{...props}
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
CommandShortcut.displayName = "CommandShortcut";
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
Command,
|
|
162
|
+
CommandDialog,
|
|
163
|
+
CommandInput,
|
|
164
|
+
CommandList,
|
|
165
|
+
CommandEmpty,
|
|
166
|
+
CommandGroup,
|
|
167
|
+
CommandItem,
|
|
168
|
+
CommandShortcut,
|
|
169
|
+
CommandSeparator,
|
|
170
|
+
};
|
|
171
|
+
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import {
|
|
6
|
+
ContextMenu,
|
|
7
|
+
ContextMenuCheckboxItem,
|
|
8
|
+
ContextMenuContent,
|
|
9
|
+
ContextMenuItem,
|
|
10
|
+
ContextMenuLabel,
|
|
11
|
+
ContextMenuRadioGroup,
|
|
12
|
+
ContextMenuRadioItem,
|
|
13
|
+
ContextMenuSeparator,
|
|
14
|
+
ContextMenuShortcut,
|
|
15
|
+
ContextMenuSub,
|
|
16
|
+
ContextMenuSubContent,
|
|
17
|
+
ContextMenuSubTrigger,
|
|
18
|
+
ContextMenuTrigger,
|
|
19
|
+
} from "./context-menu";
|
|
20
|
+
|
|
21
|
+
const meta: Meta<typeof ContextMenu> = {
|
|
22
|
+
title: "Components/Navigation/ContextMenu",
|
|
23
|
+
component: ContextMenu,
|
|
24
|
+
parameters: {
|
|
25
|
+
layout: "centered",
|
|
26
|
+
},
|
|
27
|
+
tags: ["autodocs"],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default meta;
|
|
31
|
+
type Story = StoryObj<typeof ContextMenu>;
|
|
32
|
+
|
|
33
|
+
export const Default: Story = {
|
|
34
|
+
render: () => (
|
|
35
|
+
<ContextMenu>
|
|
36
|
+
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-sm border border-dashed border-border text-sm text-foreground-muted">
|
|
37
|
+
Right click here
|
|
38
|
+
</ContextMenuTrigger>
|
|
39
|
+
<ContextMenuContent className="w-64">
|
|
40
|
+
<ContextMenuItem>
|
|
41
|
+
Back
|
|
42
|
+
<ContextMenuShortcut>⌘[</ContextMenuShortcut>
|
|
43
|
+
</ContextMenuItem>
|
|
44
|
+
<ContextMenuItem disabled>
|
|
45
|
+
Forward
|
|
46
|
+
<ContextMenuShortcut>⌘]</ContextMenuShortcut>
|
|
47
|
+
</ContextMenuItem>
|
|
48
|
+
<ContextMenuItem>
|
|
49
|
+
Reload
|
|
50
|
+
<ContextMenuShortcut>⌘R</ContextMenuShortcut>
|
|
51
|
+
</ContextMenuItem>
|
|
52
|
+
<ContextMenuSub>
|
|
53
|
+
<ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
|
|
54
|
+
<ContextMenuSubContent className="w-48">
|
|
55
|
+
<ContextMenuItem>
|
|
56
|
+
Save Page As...
|
|
57
|
+
<ContextMenuShortcut>⇧⌘S</ContextMenuShortcut>
|
|
58
|
+
</ContextMenuItem>
|
|
59
|
+
<ContextMenuItem>Create Shortcut...</ContextMenuItem>
|
|
60
|
+
<ContextMenuItem>Name Window...</ContextMenuItem>
|
|
61
|
+
<ContextMenuSeparator />
|
|
62
|
+
<ContextMenuItem>Developer Tools</ContextMenuItem>
|
|
63
|
+
</ContextMenuSubContent>
|
|
64
|
+
</ContextMenuSub>
|
|
65
|
+
<ContextMenuSeparator />
|
|
66
|
+
<ContextMenuCheckboxItem checked>
|
|
67
|
+
Show Bookmarks Bar
|
|
68
|
+
<ContextMenuShortcut>⌘⇧B</ContextMenuShortcut>
|
|
69
|
+
</ContextMenuCheckboxItem>
|
|
70
|
+
<ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
|
|
71
|
+
<ContextMenuSeparator />
|
|
72
|
+
<ContextMenuRadioGroup value="pedro">
|
|
73
|
+
<ContextMenuLabel inset>People</ContextMenuLabel>
|
|
74
|
+
<ContextMenuRadioItem value="pedro">
|
|
75
|
+
Pedro Duarte
|
|
76
|
+
</ContextMenuRadioItem>
|
|
77
|
+
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
|
|
78
|
+
</ContextMenuRadioGroup>
|
|
79
|
+
</ContextMenuContent>
|
|
80
|
+
</ContextMenu>
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function ContextMenuWithStateDemo() {
|
|
85
|
+
const [bookmarksChecked, setBookmarksChecked] = useState(true);
|
|
86
|
+
const [urlsChecked, setUrlsChecked] = useState(false);
|
|
87
|
+
const [person, setPerson] = useState("pedro");
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<ContextMenu>
|
|
91
|
+
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-sm border border-dashed border-border text-sm text-foreground-muted">
|
|
92
|
+
Right click here
|
|
93
|
+
</ContextMenuTrigger>
|
|
94
|
+
<ContextMenuContent className="w-64">
|
|
95
|
+
<ContextMenuItem>New Tab</ContextMenuItem>
|
|
96
|
+
<ContextMenuItem>New Window</ContextMenuItem>
|
|
97
|
+
<ContextMenuSeparator />
|
|
98
|
+
<ContextMenuCheckboxItem
|
|
99
|
+
checked={bookmarksChecked}
|
|
100
|
+
onCheckedChange={setBookmarksChecked}
|
|
101
|
+
>
|
|
102
|
+
Show Bookmarks
|
|
103
|
+
</ContextMenuCheckboxItem>
|
|
104
|
+
<ContextMenuCheckboxItem
|
|
105
|
+
checked={urlsChecked}
|
|
106
|
+
onCheckedChange={setUrlsChecked}
|
|
107
|
+
>
|
|
108
|
+
Show Full URLs
|
|
109
|
+
</ContextMenuCheckboxItem>
|
|
110
|
+
<ContextMenuSeparator />
|
|
111
|
+
<ContextMenuLabel>Switch User</ContextMenuLabel>
|
|
112
|
+
<ContextMenuRadioGroup value={person} onValueChange={setPerson}>
|
|
113
|
+
<ContextMenuRadioItem value="pedro">Pedro</ContextMenuRadioItem>
|
|
114
|
+
<ContextMenuRadioItem value="colm">Colm</ContextMenuRadioItem>
|
|
115
|
+
<ContextMenuRadioItem value="guest">Guest</ContextMenuRadioItem>
|
|
116
|
+
</ContextMenuRadioGroup>
|
|
117
|
+
</ContextMenuContent>
|
|
118
|
+
</ContextMenu>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const WithState: Story = {
|
|
123
|
+
render: () => <ContextMenuWithStateDemo />,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const FileContextMenu: Story = {
|
|
127
|
+
render: () => (
|
|
128
|
+
<ContextMenu>
|
|
129
|
+
<ContextMenuTrigger className="flex h-[100px] w-[200px] flex-col items-center justify-center gap-2 rounded-sm border border-border bg-card p-4">
|
|
130
|
+
<div className="h-12 w-12 rounded-sm bg-secondary-hover" />
|
|
131
|
+
<span id="file-context-menu-span-documentpdf" className="text-sm text-foreground">Document.pdf</span>
|
|
132
|
+
</ContextMenuTrigger>
|
|
133
|
+
<ContextMenuContent className="w-48">
|
|
134
|
+
<ContextMenuItem>
|
|
135
|
+
Open
|
|
136
|
+
<ContextMenuShortcut>⌘O</ContextMenuShortcut>
|
|
137
|
+
</ContextMenuItem>
|
|
138
|
+
<ContextMenuItem>Open With...</ContextMenuItem>
|
|
139
|
+
<ContextMenuSeparator />
|
|
140
|
+
<ContextMenuItem>
|
|
141
|
+
Copy
|
|
142
|
+
<ContextMenuShortcut>⌘C</ContextMenuShortcut>
|
|
143
|
+
</ContextMenuItem>
|
|
144
|
+
<ContextMenuItem>
|
|
145
|
+
Cut
|
|
146
|
+
<ContextMenuShortcut>⌘X</ContextMenuShortcut>
|
|
147
|
+
</ContextMenuItem>
|
|
148
|
+
<ContextMenuItem>Rename</ContextMenuItem>
|
|
149
|
+
<ContextMenuSeparator />
|
|
150
|
+
<ContextMenuItem>Share...</ContextMenuItem>
|
|
151
|
+
<ContextMenuItem className="text-error">
|
|
152
|
+
Delete
|
|
153
|
+
<ContextMenuShortcut>⌘⌫</ContextMenuShortcut>
|
|
154
|
+
</ContextMenuItem>
|
|
155
|
+
</ContextMenuContent>
|
|
156
|
+
</ContextMenu>
|
|
157
|
+
),
|
|
158
|
+
};
|
|
159
|
+
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
|
5
|
+
import { Check, ChevronRight, Circle } from "lucide-react";
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
const ContextMenu = ContextMenuPrimitive.Root;
|
|
9
|
+
const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
10
|
+
const ContextMenuGroup = ContextMenuPrimitive.Group;
|
|
11
|
+
const ContextMenuPortal = ContextMenuPrimitive.Portal;
|
|
12
|
+
const ContextMenuSub = ContextMenuPrimitive.Sub;
|
|
13
|
+
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
|
14
|
+
|
|
15
|
+
const ContextMenuSubTrigger = React.forwardRef<
|
|
16
|
+
React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
|
|
17
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
|
|
18
|
+
inset?: boolean;
|
|
19
|
+
}
|
|
20
|
+
>(({ className, inset, children, ...props }, ref) => (
|
|
21
|
+
<ContextMenuPrimitive.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
|
+
</ContextMenuPrimitive.SubTrigger>
|
|
35
|
+
));
|
|
36
|
+
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
|
|
37
|
+
|
|
38
|
+
const ContextMenuSubContent = React.forwardRef<
|
|
39
|
+
React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
|
|
40
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
|
|
41
|
+
>(({ className, ...props }, ref) => (
|
|
42
|
+
<ContextMenuPrimitive.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-md",
|
|
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
|
+
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
|
|
59
|
+
|
|
60
|
+
const ContextMenuContent = React.forwardRef<
|
|
61
|
+
React.ElementRef<typeof ContextMenuPrimitive.Content>,
|
|
62
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
|
|
63
|
+
>(({ className, ...props }, ref) => (
|
|
64
|
+
<ContextMenuPrimitive.Portal>
|
|
65
|
+
<ContextMenuPrimitive.Content
|
|
66
|
+
ref={ref}
|
|
67
|
+
className={cn(
|
|
68
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-sm border border-border bg-card p-1 text-foreground shadow-md",
|
|
69
|
+
"animate-in fade-in-80",
|
|
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
|
+
</ContextMenuPrimitive.Portal>
|
|
82
|
+
));
|
|
83
|
+
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
|
|
84
|
+
|
|
85
|
+
const ContextMenuItem = React.forwardRef<
|
|
86
|
+
React.ElementRef<typeof ContextMenuPrimitive.Item>,
|
|
87
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
|
|
88
|
+
inset?: boolean;
|
|
89
|
+
}
|
|
90
|
+
>(({ className, inset, ...props }, ref) => (
|
|
91
|
+
<ContextMenuPrimitive.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",
|
|
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
|
+
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
|
|
104
|
+
|
|
105
|
+
const ContextMenuCheckboxItem = React.forwardRef<
|
|
106
|
+
React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
|
|
107
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
|
|
108
|
+
>(({ className, children, checked, ...props }, ref) => (
|
|
109
|
+
<ContextMenuPrimitive.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",
|
|
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="context-menu-checkbox-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
121
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
122
|
+
<Check className="h-4 w-4" />
|
|
123
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
124
|
+
</span>
|
|
125
|
+
{children}
|
|
126
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
127
|
+
));
|
|
128
|
+
ContextMenuCheckboxItem.displayName =
|
|
129
|
+
ContextMenuPrimitive.CheckboxItem.displayName;
|
|
130
|
+
|
|
131
|
+
const ContextMenuRadioItem = React.forwardRef<
|
|
132
|
+
React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
|
|
133
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
|
|
134
|
+
>(({ className, children, ...props }, ref) => (
|
|
135
|
+
<ContextMenuPrimitive.RadioItem
|
|
136
|
+
ref={ref}
|
|
137
|
+
className={cn(
|
|
138
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
|
|
139
|
+
"focus:bg-secondary-hover focus:text-foreground",
|
|
140
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
141
|
+
className
|
|
142
|
+
)}
|
|
143
|
+
{...props}
|
|
144
|
+
>
|
|
145
|
+
<span id="context-menu-radio-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
146
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
147
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
148
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
149
|
+
</span>
|
|
150
|
+
{children}
|
|
151
|
+
</ContextMenuPrimitive.RadioItem>
|
|
152
|
+
));
|
|
153
|
+
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
|
|
154
|
+
|
|
155
|
+
const ContextMenuLabel = React.forwardRef<
|
|
156
|
+
React.ElementRef<typeof ContextMenuPrimitive.Label>,
|
|
157
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
|
|
158
|
+
inset?: boolean;
|
|
159
|
+
}
|
|
160
|
+
>(({ className, inset, ...props }, ref) => (
|
|
161
|
+
<ContextMenuPrimitive.Label
|
|
162
|
+
ref={ref}
|
|
163
|
+
className={cn(
|
|
164
|
+
"px-2 py-1.5 text-xs font-medium uppercase tracking-widest text-foreground-muted",
|
|
165
|
+
inset && "pl-8",
|
|
166
|
+
className
|
|
167
|
+
)}
|
|
168
|
+
{...props}
|
|
169
|
+
/>
|
|
170
|
+
));
|
|
171
|
+
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
|
|
172
|
+
|
|
173
|
+
const ContextMenuSeparator = React.forwardRef<
|
|
174
|
+
React.ElementRef<typeof ContextMenuPrimitive.Separator>,
|
|
175
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
|
|
176
|
+
>(({ className, ...props }, ref) => (
|
|
177
|
+
<ContextMenuPrimitive.Separator
|
|
178
|
+
ref={ref}
|
|
179
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
180
|
+
{...props}
|
|
181
|
+
/>
|
|
182
|
+
));
|
|
183
|
+
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
|
|
184
|
+
|
|
185
|
+
const ContextMenuShortcut = ({
|
|
186
|
+
className,
|
|
187
|
+
...props
|
|
188
|
+
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
189
|
+
return (
|
|
190
|
+
<span id="context-menu-shortcut-span" data-sonance-name="context-menu"
|
|
191
|
+
{...props}
|
|
192
|
+
/>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
ContextMenuShortcut.displayName = "ContextMenuShortcut";
|
|
196
|
+
|
|
197
|
+
export {
|
|
198
|
+
ContextMenu,
|
|
199
|
+
ContextMenuTrigger,
|
|
200
|
+
ContextMenuContent,
|
|
201
|
+
ContextMenuItem,
|
|
202
|
+
ContextMenuCheckboxItem,
|
|
203
|
+
ContextMenuRadioItem,
|
|
204
|
+
ContextMenuLabel,
|
|
205
|
+
ContextMenuSeparator,
|
|
206
|
+
ContextMenuShortcut,
|
|
207
|
+
ContextMenuGroup,
|
|
208
|
+
ContextMenuPortal,
|
|
209
|
+
ContextMenuSub,
|
|
210
|
+
ContextMenuSubContent,
|
|
211
|
+
ContextMenuSubTrigger,
|
|
212
|
+
ContextMenuRadioGroup,
|
|
213
|
+
};
|
|
214
|
+
|
|
@@ -59,13 +59,13 @@ export const Default: Story = {
|
|
|
59
59
|
render: () => {
|
|
60
60
|
const [date, setDate] = useState<Date | undefined>(undefined);
|
|
61
61
|
return (
|
|
62
|
-
<div className="w-64">
|
|
62
|
+
<div data-sonance-name="date-input.stories" className="w-64">
|
|
63
63
|
<DateInput
|
|
64
64
|
value={date}
|
|
65
65
|
onValueChange={setDate}
|
|
66
66
|
/>
|
|
67
67
|
{date && (
|
|
68
|
-
<p className="mt-2 text-sm text-foreground-muted">
|
|
68
|
+
<p id="default-p-selected-datetolocal" className="mt-2 text-sm text-foreground-muted">
|
|
69
69
|
Selected: {date.toLocaleDateString()}
|
|
70
70
|
</p>
|
|
71
71
|
)}
|
|
@@ -196,8 +196,8 @@ export const FormExample: Story = {
|
|
|
196
196
|
error={hasError ? "End date must be after start date" : undefined}
|
|
197
197
|
/>
|
|
198
198
|
<div className="text-sm text-foreground-muted">
|
|
199
|
-
{startDate && <p>Start: {startDate.toLocaleDateString()}</p>}
|
|
200
|
-
{endDate && <p>End: {endDate.toLocaleDateString()}</p>}
|
|
199
|
+
{startDate && <p id="form-example-p-start-startdatetoloc">Start: {startDate.toLocaleDateString()}</p>}
|
|
200
|
+
{endDate && <p id="form-example-p-end-enddatetolocaled">End: {endDate.toLocaleDateString()}</p>}
|
|
201
201
|
</div>
|
|
202
202
|
</div>
|
|
203
203
|
);
|
|
@@ -222,11 +222,11 @@ export const StateMatrix: Story = {
|
|
|
222
222
|
const states: DateInputState[] = ['default', 'hover', 'focus', 'error', 'disabled'];
|
|
223
223
|
return (
|
|
224
224
|
<div className="space-y-6 w-64">
|
|
225
|
-
<h3 className="text-sm font-medium text-foreground-muted">DateInput States</h3>
|
|
225
|
+
<h3 id="state-matrix-h3-dateinput-states" className="text-sm font-medium text-foreground-muted">DateInput States</h3>
|
|
226
226
|
<div className="space-y-4">
|
|
227
227
|
{states.map((state) => (
|
|
228
228
|
<div key={state}>
|
|
229
|
-
<span className="text-xs font-medium text-foreground-muted uppercase">{state}</span>
|
|
229
|
+
<span id="state-matrix-span-state" className="text-xs font-medium text-foreground-muted uppercase">{state}</span>
|
|
230
230
|
<DateInput
|
|
231
231
|
state={state}
|
|
232
232
|
placeholder="MM/DD/YYYY"
|
|
@@ -246,14 +246,14 @@ export const ResponsiveMatrix: Story = {
|
|
|
246
246
|
<div className="space-y-8">
|
|
247
247
|
{/* Mobile */}
|
|
248
248
|
<div>
|
|
249
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
249
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
250
250
|
<div className="w-[375px] border border-dashed border-border p-4">
|
|
251
251
|
<DateInput label="Date of Birth" placeholder="MM/DD/YYYY" />
|
|
252
252
|
</div>
|
|
253
253
|
</div>
|
|
254
254
|
{/* Tablet */}
|
|
255
255
|
<div>
|
|
256
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
256
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
257
257
|
<div className="w-[768px] border border-dashed border-border p-4">
|
|
258
258
|
<div className="grid grid-cols-2 gap-4">
|
|
259
259
|
<DateInput label="Start Date" placeholder="MM/DD/YYYY" />
|
|
@@ -263,7 +263,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
263
263
|
</div>
|
|
264
264
|
{/* Desktop */}
|
|
265
265
|
<div>
|
|
266
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
266
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
267
267
|
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
268
268
|
<div className="grid grid-cols-4 gap-4">
|
|
269
269
|
<DateInput label="Default" placeholder="MM/DD/YYYY" />
|
|
@@ -98,7 +98,7 @@ export const DateInput = forwardRef<HTMLInputElement, DateInputProps>(
|
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
return (
|
|
101
|
-
<div className={cn("w-full", className)}>
|
|
101
|
+
<div data-sonance-name="date-input" className={cn("w-full", className)}>
|
|
102
102
|
{label && (
|
|
103
103
|
<label className="mb-2 block text-xs font-medium uppercase tracking-widest text-foreground-muted">
|
|
104
104
|
{label}
|
|
@@ -125,7 +125,7 @@ export const DateInput = forwardRef<HTMLInputElement, DateInputProps>(
|
|
|
125
125
|
/>
|
|
126
126
|
<CalendarIcon className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-foreground-muted" />
|
|
127
127
|
</div>
|
|
128
|
-
{error && <p className="mt-1 text-sm text-error">{error}</p>}
|
|
128
|
+
{error && <p id="p-error" className="mt-1 text-sm text-error">{error}</p>}
|
|
129
129
|
</div>
|
|
130
130
|
);
|
|
131
131
|
}
|