Close on select option
Example of closeOnSelect
being set to false.
If a region such as "North America" new options are display.
import { useEffect, useState } from 'react';
import { ComboBox, tokenSearcher } from '@citizensadvice/react-combo-boxes';
import countries from '../../data/countries.json';
const regions = countries
.map(({ region }) => ({ name: region, isRegion: true }))
.filter(
(item, i, ar) =>
item.name && ar.findIndex((sub) => sub.name === item.name) === i,
);
const countriesAndRegions = [...countries, ...regions].sort((a, b) =>
a.name.localeCompare(b.name),
);
function mapOption({ name }) {
return name;
}
const tokenSearch = tokenSearcher(countriesAndRegions, { index: mapOption });
function searcher(query, value) {
if (value?.isRegion && value?.name === query) {
return countries.filter((c) => c.region === value?.name);
}
return tokenSearch(query);
}
function useDelaySearch(search, value) {
const [results, setResults] = useState(null);
const [busy, setBusy] = useState(false);
useEffect(() => {
const controller = new AbortController();
const run = async () => {
await new Promise((resolve) => {
setTimeout(resolve, 200);
});
setBusy(true);
await new Promise((resolve) => {
setTimeout(resolve, 2000);
});
if (!controller.signal.aborted) {
setResults(searcher(search, value));
setBusy(false);
}
};
run();
return () => controller.abort();
}, [search, value]);
return [results, busy];
}
export function Example() {
const [value, setValue] = useState(null);
const [search, setSearch] = useState(null);
const [closeOnSelect, setCloseOnSelect] = useState(false);
const [filteredOptions, busy] = useDelaySearch(search, value);
return (
<>
<label
id="select-label"
htmlFor="select"
>
Select
</label>
<ComboBox
id="select"
aria-labelledby="select-label"
value={value}
onValue={setValue}
onSearch={setSearch}
options={filteredOptions}
mapOption={mapOption}
closeOnSelect={closeOnSelect}
busy={busy}
/>
<label>
<input
type="checkbox"
checked={closeOnSelect}
onChange={({ target: { checked } }) => {
setCloseOnSelect(checked);
}}
/>{' '}
<code>closeOnSelect</code>
</label>
<label htmlFor="output">Current value</label>
<output
htmlFor="select"
id="output"
>
{JSON.stringify(value, undefined, ' ')}
</output>
</>
);
}