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