Jake Vanderwerf
2026-09-09 8318f60480aedd4aa1e64dc35468247dfbba9316
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { useState } from '@wordpress/element';
import { TextControl, Spinner, Button } from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import { useDebounce } from '@wordpress/compose';
 
const LocationField = ({field, value, onChange }) => {
    const address = value || {};
 
    const [query, setQuery] = useState(address.address || '');
    const [results, setResults] = useState([]);
    const [loading, setLoading] = useState(false);
 
    const search = useDebounce((search) => {
        if (!search) return setResults([]);
        setLoading(true);
 
        apiFetch({path: `jvb/v1/geocode?q=${encodeURIComponent(search)}`})
            .then(setResults)
            .finally(()=>setLoading(false));
 
    }, 400);
 
    const onSelect = (result) => {
        const a = result.address || {};
 
        const newAddress = {
            address:    [a.house_number, a.road].filter(Boolean).join(' '),
            city:       a.city||a.town||a.village||'',
            province:   a.state || '',
            postal_code:a.postcode||'',
            country:    a.country||'',
            lat:        parseFloat(result.lat),
            lng:        parseFloat(result.lng),
        };
        onChange(newAddress);
        setQuery(newAddress.address);
        setResults([]);
    };
 
    const onClear = () => {
        onChange({});
        setQuery('');
        setResults([]);
    }
 
    return (
        <div className="jvb-location-field" id={field.name}>
            <TextControl
                label={field.label}
                value={query}
                onChange={(newQuery) => {
                    setQuery(newQuery);
                    search(newQuery)
                }}
            />
            {loading && <Spinner />}
            {!!results.length && (
                <div className="jvb-location-results">
                    {results.map((result) => (
 
                        <Button
                            key={result.place_id}
                            variant="tertiary"
                            onClick={()=>onSelect(result)}
                            style={{display:'block', textAlign:'left'}}
                        >
                            {result.display_name}
                        </Button>
                    ))}
                    {!!address.lat && (
                        <p className="jvb-location-summary">
                            {address.address}, {address.city}, {address.province}{' '}
                            {address.postal_code}, {address.country}
                            <br />
                            <Button variant="link" isDestructive onClick={onClear}>Clear</Button>
                        </p>
                    )}
                </div>
            )}
        </div>
    );
};
 
export default LocationField;