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}
))}
);
};