gitscope
← marzneshin / v0.7.1 / dashboard/src/common/components/ui/dropdown-menu.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/common/components/ui/dropdown-menu.tsx · TypeScript
Blame Raw
  1import * as React from "react"
  2import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
  3import { Check, ChevronLeft, ChevronRight, Circle } from "lucide-react"
  4
  5import { cn } from "@marzneshin/common/utils"
  6
  7const DropdownMenu = DropdownMenuPrimitive.Root
  8
  9const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
 10
 11const DropdownMenuGroup = DropdownMenuPrimitive.Group
 12
 13const DropdownMenuPortal = DropdownMenuPrimitive.Portal
 14
 15const DropdownMenuSub = DropdownMenuPrimitive.Sub
 16
 17const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
 18
 19const DropdownMenuSubTrigger = React.forwardRef<
 20    React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
 21    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
 22        inset?: boolean
 23        arrowDir?: "right" | "left"
 24    }
 25>(({ className, inset, children, arrowDir = "right", ...props }, ref) => (
 26    <DropdownMenuPrimitive.SubTrigger
 27        ref={ref}
 28        className={cn(
 29            "flex flex-row cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
 30            inset && "pl-8",
 31            arrowDir === "left" && "flex-row-reverse",
 32            className
 33        )}
 34        {...props}
 35    >
 36        {children}
 37        {arrowDir === "right" ?
 38            <ChevronRight className="ml-auto size-4" /> :
 39            <ChevronLeft className="mr-auto size-4" />}
 40    </DropdownMenuPrimitive.SubTrigger>
 41))
 42DropdownMenuSubTrigger.displayName =
 43    DropdownMenuPrimitive.SubTrigger.displayName
 44
 45const DropdownMenuSubContent = React.forwardRef<
 46    React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
 47    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
 48>(({ className, ...props }, ref) => (
 49    <DropdownMenuPrimitive.SubContent
 50        ref={ref}
 51        className={cn(
 52            "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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",
 53            className
 54        )}
 55        {...props}
 56    />
 57))
 58DropdownMenuSubContent.displayName =
 59    DropdownMenuPrimitive.SubContent.displayName
 60
 61const DropdownMenuContent = React.forwardRef<
 62    React.ElementRef<typeof DropdownMenuPrimitive.Content>,
 63    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
 64>(({ className, sideOffset = 4, ...props }, ref) => (
 65    <DropdownMenuPrimitive.Portal>
 66        <DropdownMenuPrimitive.Content
 67            ref={ref}
 68            sideOffset={sideOffset}
 69            className={cn(
 70                "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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",
 71                className
 72            )}
 73            {...props}
 74        />
 75    </DropdownMenuPrimitive.Portal>
 76))
 77DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
 78
 79const DropdownMenuItem = React.forwardRef<
 80    React.ElementRef<typeof DropdownMenuPrimitive.Item>,
 81    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
 82        inset?: boolean
 83    }
 84>(({ className, inset, ...props }, ref) => (
 85    <DropdownMenuPrimitive.Item
 86        ref={ref}
 87        className={cn(
 88            "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 89            inset && "pl-8",
 90            className
 91        )}
 92        {...props}
 93    />
 94))
 95DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
 96
 97const DropdownMenuCheckboxItem = React.forwardRef<
 98    React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
 99    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
100>(({ className, children, checked, ...props }, ref) => (
101    <DropdownMenuPrimitive.CheckboxItem
102        ref={ref}
103        className={cn(
104            "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
105            className
106        )}
107        checked={checked}
108        {...props}
109    >
110        <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
111            <DropdownMenuPrimitive.ItemIndicator>
112                <Check className="h-4 w-4" />
113            </DropdownMenuPrimitive.ItemIndicator>
114        </span>
115        {children}
116    </DropdownMenuPrimitive.CheckboxItem>
117))
118DropdownMenuCheckboxItem.displayName =
119    DropdownMenuPrimitive.CheckboxItem.displayName
120
121const DropdownMenuRadioItem = React.forwardRef<
122    React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
123    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
124>(({ className, children, ...props }, ref) => (
125    <DropdownMenuPrimitive.RadioItem
126        ref={ref}
127        className={cn(
128            "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
129            className
130        )}
131        {...props}
132    >
133        <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
134            <DropdownMenuPrimitive.ItemIndicator>
135                <Circle className="h-2 w-2 fill-current" />
136            </DropdownMenuPrimitive.ItemIndicator>
137        </span>
138        {children}
139    </DropdownMenuPrimitive.RadioItem>
140))
141DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
142
143const DropdownMenuLabel = React.forwardRef<
144    React.ElementRef<typeof DropdownMenuPrimitive.Label>,
145    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
146        inset?: boolean
147    }
148>(({ className, inset, ...props }, ref) => (
149    <DropdownMenuPrimitive.Label
150        ref={ref}
151        className={cn(
152            "px-2 py-1.5 text-sm font-semibold",
153            inset && "pl-8",
154            className
155        )}
156        {...props}
157    />
158))
159DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
160
161const DropdownMenuSeparator = React.forwardRef<
162    React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
163    React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
164>(({ className, ...props }, ref) => (
165    <DropdownMenuPrimitive.Separator
166        ref={ref}
167        className={cn("-mx-1 my-1 h-px bg-muted", className)}
168        {...props}
169    />
170))
171DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
172
173const DropdownMenuShortcut = ({
174    className,
175    ...props
176}: React.HTMLAttributes<HTMLSpanElement>) => {
177    return (
178        <span
179            className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
180            {...props}
181        />
182    )
183}
184DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
185
186export {
187    DropdownMenu,
188    DropdownMenuTrigger,
189    DropdownMenuContent,
190    DropdownMenuItem,
191    DropdownMenuCheckboxItem,
192    DropdownMenuRadioItem,
193    DropdownMenuLabel,
194    DropdownMenuSeparator,
195    DropdownMenuShortcut,
196    DropdownMenuGroup,
197    DropdownMenuPortal,
198    DropdownMenuSub,
199    DropdownMenuSubContent,
200    DropdownMenuSubTrigger,
201    DropdownMenuRadioGroup,
202}