71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
import { useId, useState } from 'react';
|
|
import TerritorySearchSelect from './territory-search-select';
|
|
import { matchesChoice } from '@/lib/catalogue-choice';
|
|
|
|
export type CatalogueChoice = {
|
|
value: string;
|
|
label: string;
|
|
keywords?: string[];
|
|
};
|
|
export default function CatalogueChoiceSelect({
|
|
options,
|
|
value,
|
|
onChange,
|
|
label,
|
|
id,
|
|
disabled = false,
|
|
required = false,
|
|
error,
|
|
className,
|
|
}: {
|
|
options: CatalogueChoice[];
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
label: string;
|
|
id?: string;
|
|
disabled?: boolean;
|
|
required?: boolean;
|
|
error?: string;
|
|
className?: string;
|
|
}) {
|
|
const generated = useId();
|
|
const [search, setSearch] = useState('');
|
|
const selected = options.find((o) => o.value === value);
|
|
return (
|
|
<TerritorySearchSelect
|
|
id={id ?? generated}
|
|
label={label}
|
|
search={search}
|
|
onSearch={setSearch}
|
|
selected={
|
|
value
|
|
? {
|
|
id: value,
|
|
name:
|
|
selected?.label ??
|
|
`${value} — valor anterior; confirme a selecção`,
|
|
}
|
|
: undefined
|
|
}
|
|
options={options
|
|
.filter((o) =>
|
|
matchesChoice(search, [
|
|
o.value,
|
|
o.label,
|
|
...(o.keywords ?? []),
|
|
]),
|
|
)
|
|
.map((o) => ({ id: o.value, name: o.label }))}
|
|
onChange={(o) => onChange(o?.id ?? '')}
|
|
disabled={disabled}
|
|
required={required}
|
|
error={error}
|
|
className={
|
|
className ??
|
|
'bg-background text-foreground w-full rounded border p-2'
|
|
}
|
|
placeholder={`Seleccionar ou pesquisar ${label.toLowerCase()}`}
|
|
/>
|
|
);
|
|
}
|