1 "use client"
2
3 import * as React from "react"
4 import * as SelectPrimitive from "@radix-ui/react-select"
5 import { Check, ChevronDown, ChevronUp } from "lucide-react"
6
7 import { cn } from "@/lib/utils"
8
9 const Select = SelectPrimitive.Root
10
11 const SelectGroup = SelectPrimitive.Group
12
13 const SelectValue = SelectPrimitive.Value
14
15 const SelectTrigger = React.forwardRef<
16 React.ElementRef<typeof SelectPrimitive.Trigger>,
17 React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
18 >(({ className, children, ...props }, ref) => (
19 <SelectPrimitive.Trigger
20 ref={ref}
21 className={cn(
22 "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
23 className
24 )}
25 {...props}
26 >
27 {children}
28 <SelectPrimitive.Icon asChild>
29 <ChevronDown className="h-4 w-4 opacity-50" />
30 </SelectPrimitive.Icon>
31 </SelectPrimitive.Trigger>
32 ))
33 SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
34
35 const SelectScrollUpButton = React.forwardRef<
36 React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
37 React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
38 >(({ className, ...props }, ref) => (
39 <SelectPrimitive.ScrollUpButton
40 ref={ref}
41 className={cn(
42 "flex cursor-default items-center justify-center py-1",
43 className
44 )}
45 {...props}
46 >
47 <ChevronUp className="h-4 w-4" />
48 </SelectPrimitive.ScrollUpButton>
49 ))
50 SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
51
52 const SelectScrollDownButton = React.forwardRef<
53 React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
54 React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
55 >(({ className, ...props }, ref) => (
56 <SelectPrimitive.ScrollDownButton
57 ref={ref}
58 className={cn(
59 "flex cursor-default items-center justify-center py-1",
60 className
61 )}
62 {...props}
63 >
64 <ChevronDown className="h-4 w-4" />
65 </SelectPrimitive.ScrollDownButton>
66 ))
67 SelectScrollDownButton.displayName =
68 SelectPrimitive.ScrollDownButton.displayName
69
70 const SelectContent = React.forwardRef<
71 React.ElementRef<typeof SelectPrimitive.Content>,
72 React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
73 >(({ className, children, position = "popper", ...props }, ref) => (
74 <SelectPrimitive.Portal>
75 <SelectPrimitive.Content
76 ref={ref}
77 className={cn(
78 "relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover 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 origin-[--radix-select-content-transform-origin]",
79 position === "popper" &&
80 "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
81 className
82 )}
83 position={position}
84 {...props}
85 >
86 <SelectScrollUpButton />
87 <SelectPrimitive.Viewport
88 className={cn(
89 "p-1",
90 position === "popper" &&
91 "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
92 )}
93 >
94 {children}
95 </SelectPrimitive.Viewport>
96 <SelectScrollDownButton />
97 </SelectPrimitive.Content>
98 </SelectPrimitive.Portal>
99 ))
100 SelectContent.displayName = SelectPrimitive.Content.displayName
101
102 const SelectLabel = React.forwardRef<
103 React.ElementRef<typeof SelectPrimitive.Label>,
104 React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
105 >(({ className, ...props }, ref) => (
106 <SelectPrimitive.Label
107 ref={ref}
108 className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
109 {...props}
110 />
111 ))
112 SelectLabel.displayName = SelectPrimitive.Label.displayName
113
114 const SelectItem = React.forwardRef<
115 React.ElementRef<typeof SelectPrimitive.Item>,
116 React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
117 >(({ className, children, ...props }, ref) => (
118 <SelectPrimitive.Item
119 ref={ref}
120 className={cn(
121 "relative flex w-full 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",
122 className
123 )}
124 {...props}
125 >
126 <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
127 <SelectPrimitive.ItemIndicator>
128 <Check className="h-4 w-4" />
129 </SelectPrimitive.ItemIndicator>
130 </span>
131
132 <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
133 </SelectPrimitive.Item>
134 ))
135 SelectItem.displayName = SelectPrimitive.Item.displayName
136
137 const SelectSeparator = React.forwardRef<
138 React.ElementRef<typeof SelectPrimitive.Separator>,
139 React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
140 >(({ className, ...props }, ref) => (
141 <SelectPrimitive.Separator
142 ref={ref}
143 className={cn("-mx-1 my-1 h-px bg-muted", className)}
144 {...props}
145 />
146 ))
147 SelectSeparator.displayName = SelectPrimitive.Separator.displayName
148
149 export {
150 Select,
151 SelectGroup,
152 SelectValue,
153 SelectTrigger,
154 SelectContent,
155 SelectLabel,
156 SelectItem,
157 SelectSeparator,
158 SelectScrollUpButton,
159 SelectScrollDownButton,
160 }