import { useCallback, type ButtonHTMLAttributes, type ChangeEvent, type InputHTMLAttributes, type SelectHTMLAttributes, } from "react"; import { usePrimitives } from "../theme/hooks.js"; import { emptyArray } from "../utils.js"; export const ButtonView = (props: ButtonHTMLAttributes) => { const ButtonPrimitive = usePrimitives("button"); return ; }; export const InputView = ({ onChange, ...props }: Omit, "onChange"> & { onChange?: (value: string) => void; }) => { const InputPrimitive = usePrimitives("input"); const handleChange = useCallback( (e: ChangeEvent) => { onChange?.(e.target.value); }, [onChange], ); return ; }; export type SingleSelectProps = Omit< SelectHTMLAttributes, "value" | "onChange" | "children" | "multiple" > & { value?: T | undefined; options?: { value: T; label: string }[] | undefined; onChange?: (value: T) => void; }; export type MultiSelectProps = Omit< SelectHTMLAttributes, "value" | "onChange" | "children" | "multiple" > & { value?: T[] | undefined; options?: { value: T; label: string }[] | undefined; onChange?: (value: T[]) => void; }; export const SingleSelectView = ({ options = emptyArray, value, onChange, ...props }: SingleSelectProps) => { const SelectPrimitive = usePrimitives("select"); const OptionPrimitive = usePrimitives("option"); const selectedIdx = options.findIndex((option) => option.value === value); const handleChange = useCallback( (e: ChangeEvent) => { const index = Number(e.target.value); const selectedOption = options[index]; if (!selectedOption) return; onChange?.(selectedOption.value); }, [options, onChange], ); return ( {options.map(({ label }, index) => ( {label} ))} ); }; export const MultiSelectView = ({ options = emptyArray, value = emptyArray, onChange, ...props }: MultiSelectProps) => { const SelectPrimitive = usePrimitives("select"); const OptionPrimitive = usePrimitives("option"); const selectedIndices = value.map((val) => String(options.findIndex((option) => option.value === val)), ); const handleChange = useCallback( (e: ChangeEvent) => { const selectedOptions = Array.from(e.target.selectedOptions, (option) => { const index = Number(option.value); const selectedOption = options[index]; if (!selectedOption) return; return selectedOption.value; }).filter((i) => i !== undefined); onChange?.(selectedOptions); }, [options, onChange], ); return ( {options.map(({ label }, index) => ( {label} ))} ); };