"use client" import { useRef } from "react" import type { AsyncOption, BaseFieldControlProps } from "../types" import { Loader2 } from "lucide-react" import { Combobox, ComboboxInput, ComboboxContent, ComboboxList, ComboboxItem, ComboboxEmpty, } from "@/shared/components/ui/combobox" const defaultGetOptionValue = (opt: any) => opt.value const defaultGetOptionLabel = (opt: any) => opt.label function defaultGetOptionKey(opt: any): string { const v = defaultGetOptionValue(opt) if (typeof v === "string" || typeof v === "number") return String(v) return String(opt.id ?? JSON.stringify(v)) } // ── Single-select ── export type AsyncSelectFieldProps = BaseFieldControlProps & { options: TOption[] loading?: boolean onInputValueChange?: (value: string) => void placeholder?: string getOptionValue?: (option: TOption) => any getOptionLabel?: (option: TOption) => string getOptionKey?: (option: TOption) => string } export function AsyncSelectField({ value, onChange, onBlur, disabled, invalid, options, loading, onInputValueChange, placeholder = "Search...", getOptionValue = defaultGetOptionValue, getOptionLabel = defaultGetOptionLabel, getOptionKey = defaultGetOptionKey, }: AsyncSelectFieldProps) { const anchorRef = useRef(null) return (
onChange(val)} disabled={disabled} onInputValueChange={(val, { reason }) => { if (reason === "input-change") { onInputValueChange?.(val) } }} > {loading && (
)} {!loading && options.map((opt) => ( {getOptionLabel(opt)} ))} {!loading && options.length === 0 && ( No results found )}
) } // ── Multi-select ── export type AsyncMultiSelectFieldProps = BaseFieldControlProps & { options: TOption[] loading?: boolean onInputValueChange?: (value: string) => void placeholder?: string getOptionValue?: (option: TOption) => any getOptionLabel?: (option: TOption) => string getOptionKey?: (option: TOption) => string } export function AsyncMultiSelectField({ value, onChange, onBlur, disabled, invalid, options, loading, onInputValueChange, placeholder = "Search...", getOptionValue = defaultGetOptionValue, getOptionLabel = defaultGetOptionLabel, getOptionKey = defaultGetOptionKey, }: AsyncMultiSelectFieldProps) { const anchorRef = useRef(null) return (
onChange(val as any[])} disabled={disabled} onInputValueChange={(val, { reason }) => { if (reason === "input-change") { onInputValueChange?.(val) } }} > 0} onBlur={onBlur} aria-invalid={invalid || undefined} /> {loading && (
)} {!loading && options.map((opt) => ( {getOptionLabel(opt)} ))} {!loading && options.length === 0 && ( No results found )}
) }