demarches-normaliennes/app/javascript/components/MapEditor/SearchInput.js

89 lines
2.4 KiB
JavaScript
Raw Normal View History

import React, { useState, useEffect } from 'react';
import { getJSON } from '@utils';
import {
Combobox,
ComboboxInput,
ComboboxPopover,
ComboboxList,
ComboboxOption
} from '@reach/combobox';
import '@reach/combobox/styles.css';
import PropTypes from 'prop-types';
let cache = {};
2020-04-30 15:42:29 +02:00
const useAddressSearch = (searchTerm) => {
const [addresses, setAddresses] = useState([]);
useEffect(() => {
if (searchTerm.trim() !== '') {
let isFresh = true;
2020-04-30 15:42:29 +02:00
fetchAddresses(searchTerm).then((addresses) => {
if (isFresh) setAddresses(addresses);
});
return () => (isFresh = false);
}
}, [searchTerm]);
return addresses;
};
2020-04-30 15:42:29 +02:00
const fetchAddresses = (value) => {
if (cache[value]) {
return Promise.resolve(cache[value]);
}
const url = `https://api-adresse.data.gouv.fr/search/`;
2020-04-30 15:42:29 +02:00
return getJSON(url, { q: value, limit: 5 }, 'get').then((result) => {
if (result) {
cache[value] = result;
}
return result;
});
};
const SearchInput = ({ getCoords }) => {
const [searchTerm, setSearchTerm] = useState('');
const addresses = useAddressSearch(searchTerm);
2020-04-30 15:42:29 +02:00
const handleSearchTermChange = (event) => {
setSearchTerm(event.target.value);
};
return (
<Combobox aria-label="addresses">
<ComboboxInput
2020-05-07 18:30:19 +02:00
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
className="address-search-input"
style={{
font: 'inherit',
padding: '.25rem .5rem',
width: '100%',
minHeight: '62px'
}}
onChange={handleSearchTermChange}
/>
{addresses.features && (
<ComboboxPopover className="shadow-popup">
{addresses.features.length > 0 ? (
<ComboboxList>
2020-04-30 15:42:29 +02:00
{addresses.features.map((feature) => {
const str = `${feature.properties.name}, ${feature.properties.city}`;
return (
<ComboboxOption
onClick={() => getCoords(feature.geometry.coordinates)}
key={str}
value={str}
/>
);
})}
</ComboboxList>
) : (
<span style={{ display: 'block', margin: 8 }}>Aucun résultat</span>
)}
</ComboboxPopover>
)}
</Combobox>
);
};
SearchInput.propTypes = {
getCoords: PropTypes.func
};
export default SearchInput;