demarches-normaliennes/app/javascript/components/MapEditor/SearchInput.js
2020-05-11 11:36:36 +02:00

99 lines
2.6 KiB
JavaScript

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 = {};
const useAddressSearch = searchTerm => {
const [addresses, setAddresses] = useState([]);
useEffect(() => {
if (searchTerm.trim() !== '') {
let isFresh = true;
fetchAddresses(searchTerm).then(addresses => {
if (isFresh) setAddresses(addresses);
});
return () => (isFresh = false);
}
}, [searchTerm]);
return addresses;
};
const fetchAddresses = value => {
if (cache[value]) {
return Promise.resolve(cache[value]);
}
const url = `https://api-adresse.data.gouv.fr/search/`;
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);
const handleSearchTermChange = event => {
setSearchTerm(event.target.value);
};
return (
<Combobox aria-label="addresses">
<ComboboxInput
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
style={{
borderTopColor: '#ddd',
marginTop: '-1px',
boxShadow: '0 2px 4px rgba(0,0,0,.15)',
position: 'absolute',
width: '400px',
left: '351px',
top: '5562px'
}}
className="shadow-popup"
>
{addresses.features.length > 0 ? (
<ComboboxList>
{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;