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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component, createRef } from '@wordpress/element';
import { BaseControl, TextControl } from '@wordpress/components';
/**
* Internal dependencies
*/
import Lookup from '../lookup';
const placeholderText = __( 'Add a marker…', 'jetpack' );
export class LocationSearch extends Component {
constructor() {
super( ...arguments );
this.textRef = createRef();
this.containerRef = createRef();
this.state = {
isEmpty: true,
};
this.autocompleter = {
name: 'placeSearch',
options: this.search,
isDebounced: true,
getOptionLabel: option => <span>{ option.place_name }</span>,
getOptionKeywords: option => [ option.place_name ],
getOptionCompletion: this.getOptionCompletion,
};
}
componentDidMount() {
setTimeout( () => {
this.containerRef.current.querySelector( 'input' ).focus();
}, 50 );
}
getOptionCompletion = option => {
const { value } = option;
const point = {
placeTitle: value.text,
title: value.text,
caption: value.place_name,
id: value.id,
coordinates: {
longitude: value.geometry.coordinates[ 0 ],
latitude: value.geometry.coordinates[ 1 ],
},
};
this.props.onAddPoint( point );
return value.text;
};
search = value => {
const { apiKey, onError } = this.props;
const url =
'https://api.mapbox.com/geocoding/v5/mapbox.places/' +
encodeURI( value ) +
'.json?access_token=' +
apiKey;
return new Promise( function( resolve, reject ) {
const xhr = new XMLHttpRequest();
xhr.open( 'GET', url );
xhr.onload = function() {
if ( xhr.status === 200 ) {
const res = JSON.parse( xhr.responseText );
resolve( res.features );
} else {
const res = JSON.parse( xhr.responseText );
onError( res.statusText, res.responseJSON.message );
reject( new Error( 'Mapbox Places Error' ) );
}
};
xhr.send();
} );
};
onReset = () => {
this.textRef.current.value = null;
};
render() {
const { label } = this.props;
return (
<div ref={ this.containerRef }>
<BaseControl label={ label } className="components-location-search">
<Lookup completer={ this.autocompleter } onReset={ this.onReset }>
{ ( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) => (
<TextControl
placeholder={ placeholderText }
ref={ this.textRef }
onChange={ onChange }
aria-expanded={ isExpanded }
aria-owns={ listBoxId }
aria-activedescendant={ activeId }
onKeyDown={ onKeyDown }
/>
) }
</Lookup>
</BaseControl>
</div>
);
}
}
LocationSearch.defaultProps = {
onError: () => {},
};
export default LocationSearch;
|