85 lines
2.0 KiB
TypeScript
85 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
import { useId } from "react";
|
|
import Typography from "../Typography/Typography";
|
|
|
|
type Option = {
|
|
value: string | number;
|
|
label: string;
|
|
};
|
|
|
|
export interface SelectInputProps extends React.ComponentProps<"select"> {
|
|
error?: boolean;
|
|
options: Option[];
|
|
placeholder?: string;
|
|
label?: string;
|
|
labelProps?: React.ComponentProps<"label">;
|
|
errorProps?: React.ComponentProps<typeof Typography>;
|
|
}
|
|
|
|
export default function SelectInput({
|
|
error,
|
|
options,
|
|
placeholder,
|
|
label,
|
|
labelProps,
|
|
errorProps,
|
|
...props
|
|
}: SelectInputProps) {
|
|
const id = useId();
|
|
|
|
return (
|
|
<div className={cn("w-full flex flex-col gap-2")}>
|
|
{label && (
|
|
<label
|
|
htmlFor={id}
|
|
className={cn(
|
|
"text-muted-foreground font-inter font-medium text-base",
|
|
labelProps?.className
|
|
)}
|
|
{...labelProps}
|
|
>
|
|
{label}
|
|
</label>
|
|
)}
|
|
<select
|
|
id={id}
|
|
className={cn(
|
|
"cursor-pointer",
|
|
"appearance-none",
|
|
"w-full min-w-[106px] h-fit! min-h-14",
|
|
"px-4 py-3.5",
|
|
"font-inter text-[18px]/[28px] font-medium text-placeholder-foreground",
|
|
"rounded-2xl outline-2 outline-primary/30",
|
|
"duration-200",
|
|
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
error &&
|
|
"outline-destructive focus-visible:shadow-destructive focus-visible:ring-destructive/30"
|
|
)}
|
|
{...props}
|
|
>
|
|
{placeholder && (
|
|
<option value="" hidden>
|
|
{placeholder}
|
|
</option>
|
|
)}
|
|
{options.map((option) => (
|
|
<option
|
|
key={option.value}
|
|
value={option.value}
|
|
className="text-foreground"
|
|
>
|
|
{option.label}
|
|
</option>
|
|
))}
|
|
</select>
|
|
{error && (
|
|
<Typography size="xs" color="destructive" {...errorProps}>
|
|
{errorProps?.children}
|
|
</Typography>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|