61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import * as React from "react";
|
|
import { Select as KumoSelect } from "@cloudflare/kumo/components/select";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export type SelectOption = {
|
|
value: string;
|
|
label: React.ReactNode;
|
|
disabled?: boolean;
|
|
};
|
|
|
|
type SelectProps = {
|
|
"aria-label"?: string;
|
|
className?: string;
|
|
defaultValue?: string;
|
|
disabled?: boolean;
|
|
label?: React.ReactNode;
|
|
name?: string;
|
|
onValueChange?: (value: string) => void;
|
|
options: SelectOption[];
|
|
placeholder?: string;
|
|
required?: boolean;
|
|
value?: string;
|
|
};
|
|
|
|
export function Select({
|
|
className,
|
|
onValueChange,
|
|
options,
|
|
placeholder,
|
|
value,
|
|
defaultValue,
|
|
...props
|
|
}: SelectProps): React.ReactElement {
|
|
return (
|
|
<KumoSelect<string>
|
|
className={cn(
|
|
"min-h-10 w-full rounded-md border border-input bg-card px-3 py-2 text-left text-sm font-medium text-foreground shadow-sm",
|
|
"transition-colors hover:border-primary/45 hover:bg-secondary/35",
|
|
"focus-visible:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/25",
|
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
"[&_[data-placeholder]]:text-muted-foreground [&_svg]:text-primary",
|
|
className,
|
|
)}
|
|
defaultValue={defaultValue}
|
|
onValueChange={(nextValue) => onValueChange?.(String(nextValue))}
|
|
placeholder={placeholder}
|
|
value={value}
|
|
{...props}
|
|
>
|
|
{options.map((option) => (
|
|
<KumoSelect.Option key={option.value} disabled={option.disabled} value={option.value}>
|
|
{option.label}
|
|
</KumoSelect.Option>
|
|
))}
|
|
</KumoSelect>
|
|
);
|
|
}
|