forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1import type { JSX } from "preact";
2import { cn } from "../../utils/cn.ts";
3import { Text } from "./Text.tsx";
4import { ChevronDown } from "lucide-preact";
5
6type SelectSize = "sm" | "md" | "lg";
7
8export interface SelectProps
9 extends Omit<JSX.IntrinsicElements['select'], 'size'> {
10 label?: string;
11 error?: string;
12 size?: SelectSize;
13}
14
15export function Select(props: SelectProps): JSX.Element {
16 const { class: classProp, label, error, size = "lg", children, ...rest } = props;
17
18 const sizeClasses = {
19 sm: "pl-2.5 pr-8 py-0.5 text-xs",
20 md: "pl-3 pr-8 py-1 text-sm",
21 lg: "pl-4 pr-9 py-2 text-sm",
22 };
23
24 const className = cn(
25 "block w-full bg-zinc-50 hover:bg-zinc-50/90 dark:bg-zinc-600 dark:hover:bg-zinc-600/90 text-zinc-900 dark:text-zinc-100 border border-zinc-200 dark:border-zinc-500/70 rounded-md cursor-pointer focus:outline-none focus:ring-0 appearance-none",
26 sizeClasses[size],
27 error
28 ? "border-red-300 dark:border-red-500"
29 : "",
30 classProp,
31 );
32
33 return (
34 <div>
35 {label && (
36 <Text as="label" size="sm" variant="label" className="block mb-2">
37 {label}
38 </Text>
39 )}
40 <div className="relative">
41 <select class={className} {...rest}>
42 {children}
43 </select>
44 <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
45 <ChevronDown size={16} className="text-zinc-500 dark:text-zinc-400" />
46 </div>
47 </div>
48 {error && (
49 <Text as="p" size="xs" variant="error" className="mt-1">
50 {error}
51 </Text>
52 )}
53 </div>
54 );
55}