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