1 "use client"
2
3 import * as React from "react"
4 import * as MenubarPrimitive from "@radix-ui/react-menubar"
5 import { Check, ChevronRight, Circle } from "lucide-react"
6
7 import { cn } from "@/lib/utils"
8
9 function MenubarMenu({
10 ...props
11 }: React.ComponentProps<typeof MenubarPrimitive.Menu>) {
12 return <MenubarPrimitive.Menu {...props} />
13 }
14
15 function MenubarGroup({
16 ...props
17 }: React.ComponentProps<typeof MenubarPrimitive.Group>) {
18 return <MenubarPrimitive.Group {...props} />
19 }
20
21 function MenubarPortal({
22 ...props
23 }: React.ComponentProps<typeof MenubarPrimitive.Portal>) {
24 return <MenubarPrimitive.Portal {...props} />
25 }
26
27 function MenubarRadioGroup({
28 ...props
29 }: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {
30 return <MenubarPrimitive.RadioGroup {...props} />
31 }
32
33 function MenubarSub({
34 ...props
35 }: React.ComponentProps<typeof MenubarPrimitive.Sub>) {
36 return <MenubarPrimitive.Sub data-slot="menubar-sub" {...props} />
37 }
38
39 const Menubar = React.forwardRef<
40 React.ElementRef<typeof MenubarPrimitive.Root>,
41 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
42 >(({ className, ...props }, ref) => (
43 <MenubarPrimitive.Root
44 ref={ref}
45 className={cn(
46 "flex h-10 items-center space-x-1 rounded-md border bg-background p-1",
47 className
48 )}
49 {...props}
50 />
51 ))
52 Menubar.displayName = MenubarPrimitive.Root.displayName
53
54 const MenubarTrigger = React.forwardRef<
55 React.ElementRef<typeof MenubarPrimitive.Trigger>,
56 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
57 >(({ className, ...props }, ref) => (
58 <MenubarPrimitive.Trigger
59 ref={ref}
60 className={cn(
61 "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
62 className
63 )}
64 {...props}
65 />
66 ))
67 MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName
68
69 const MenubarSubTrigger = React.forwardRef<
70 React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
71 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
72 inset?: boolean
73 }
74 >(({ className, inset, children, ...props }, ref) => (
75 <MenubarPrimitive.SubTrigger
76 ref={ref}
77 className={cn(
78 "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
79 inset && "pl-8",
80 className
81 )}
82 {...props}
83 >
84 {children}
85 <ChevronRight className="ml-auto h-4 w-4" />
86 </MenubarPrimitive.SubTrigger>
87 ))
88 MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName
89
90 const MenubarSubContent = React.forwardRef<
91 React.ElementRef<typeof MenubarPrimitive.SubContent>,
92 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
93 >(({ className, ...props }, ref) => (
94 <MenubarPrimitive.SubContent
95 ref={ref}
96 className={cn(
97 "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-menubar-content-transform-origin]",
98 className
99 )}
100 {...props}
101 />
102 ))
103 MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName
104
105 const MenubarContent = React.forwardRef<
106 React.ElementRef<typeof MenubarPrimitive.Content>,
107 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
108 >(
109 (
110 { className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
111 ref
112 ) => (
113 <MenubarPrimitive.Portal>
114 <MenubarPrimitive.Content
115 ref={ref}
116 align={align}
117 alignOffset={alignOffset}
118 sideOffset={sideOffset}
119 className={cn(
120 "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-menubar-content-transform-origin]",
121 className
122 )}
123 {...props}
124 />
125 </MenubarPrimitive.Portal>
126 )
127 )
128 MenubarContent.displayName = MenubarPrimitive.Content.displayName
129
130 const MenubarItem = React.forwardRef<
131 React.ElementRef<typeof MenubarPrimitive.Item>,
132 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
133 inset?: boolean
134 }
135 >(({ className, inset, ...props }, ref) => (
136 <MenubarPrimitive.Item
137 ref={ref}
138 className={cn(
139 "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
140 inset && "pl-8",
141 className
142 )}
143 {...props}
144 />
145 ))
146 MenubarItem.displayName = MenubarPrimitive.Item.displayName
147
148 const MenubarCheckboxItem = React.forwardRef<
149 React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
150 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
151 >(({ className, children, checked, ...props }, ref) => (
152 <MenubarPrimitive.CheckboxItem
153 ref={ref}
154 className={cn(
155 "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
156 className
157 )}
158 checked={checked}
159 {...props}
160 >
161 <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
162 <MenubarPrimitive.ItemIndicator>
163 <Check className="h-4 w-4" />
164 </MenubarPrimitive.ItemIndicator>
165 </span>
166 {children}
167 </MenubarPrimitive.CheckboxItem>
168 ))
169 MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName
170
171 const MenubarRadioItem = React.forwardRef<
172 React.ElementRef<typeof MenubarPrimitive.RadioItem>,
173 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
174 >(({ className, children, ...props }, ref) => (
175 <MenubarPrimitive.RadioItem
176 ref={ref}
177 className={cn(
178 "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
179 className
180 )}
181 {...props}
182 >
183 <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
184 <MenubarPrimitive.ItemIndicator>
185 <Circle className="h-2 w-2 fill-current" />
186 </MenubarPrimitive.ItemIndicator>
187 </span>
188 {children}
189 </MenubarPrimitive.RadioItem>
190 ))
191 MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName
192
193 const MenubarLabel = React.forwardRef<
194 React.ElementRef<typeof MenubarPrimitive.Label>,
195 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
196 inset?: boolean
197 }
198 >(({ className, inset, ...props }, ref) => (
199 <MenubarPrimitive.Label
200 ref={ref}
201 className={cn(
202 "px-2 py-1.5 text-sm font-semibold",
203 inset && "pl-8",
204 className
205 )}
206 {...props}
207 />
208 ))
209 MenubarLabel.displayName = MenubarPrimitive.Label.displayName
210
211 const MenubarSeparator = React.forwardRef<
212 React.ElementRef<typeof MenubarPrimitive.Separator>,
213 React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
214 >(({ className, ...props }, ref) => (
215 <MenubarPrimitive.Separator
216 ref={ref}
217 className={cn("-mx-1 my-1 h-px bg-muted", className)}
218 {...props}
219 />
220 ))
221 MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName
222
223 const MenubarShortcut = ({
224 className,
225 ...props
226 }: React.HTMLAttributes<HTMLSpanElement>) => {
227 return (
228 <span
229 className={cn(
230 "ml-auto text-xs tracking-widest text-muted-foreground",
231 className
232 )}
233 {...props}
234 />
235 )
236 }
237 MenubarShortcut.displayname = "MenubarShortcut"
238
239 export {
240 Menubar,
241 MenubarMenu,
242 MenubarTrigger,
243 MenubarContent,
244 MenubarItem,
245 MenubarSeparator,
246 MenubarLabel,
247 MenubarCheckboxItem,
248 MenubarRadioGroup,
249 MenubarRadioItem,
250 MenubarPortal,
251 MenubarSubContent,
252 MenubarSubTrigger,
253 MenubarGroup,
254 MenubarSub,
255 MenubarShortcut,
256 }