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