-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathusePlaceKit.js
78 lines (68 loc) · 2.06 KB
/
usePlaceKit.js
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
import placekitAutocomplete from '@placekit/autocomplete-js';
import { useEffect, useRef, useState } from 'react';
import { useStableValue } from './useStableValue';
export const usePlaceKit = (apiKey, options = {}) => {
// throw error if invalid options
if (typeof options !== 'object' || Array.isArray(options) || options === null) {
throw Error('PlaceKit: `options` parameter is invalid, expected an object.');
}
// init states
const stableOptions = useStableValue(options);
const target = useRef(null);
const [client, setClient] = useState();
const [state, setState] = useState({
dirty: false,
empty: true,
freeForm: true,
geolocation: false,
countryMode: false,
});
// mount PlaceKit Autocomplete JS
useEffect(() => {
if (!target.current) {
return;
}
const pka = placekitAutocomplete(apiKey, {
target: target.current,
});
setClient(pka);
return () => {
pka.destroy();
setClient();
};
}, [apiKey, target.current]);
// run `pka.configure()` when options update
useEffect(() => {
if (!client) {
return;
}
const { handlers, ...opts } = stableOptions || {};
client
.on('open', handlers?.onOpen)
.on('close', handlers?.onClose)
.on('results', handlers?.onResults)
.on('pick', handlers?.onPick)
.on('error', handlers?.onError)
.on('countryChange', handlers?.onCountryChange)
.on('dirty', handlers?.onDirty)
.on('empty', handlers?.onEmpty)
.on('freeForm', handlers?.onFreeForm)
.on('geolocation', handlers?.onGeolocation)
.on('countryMode', handlers?.onCountryMode)
.on('state', ({ ...newState }) => {
// spread to remove `client.state` reference
setState(newState);
if (handlers?.onState) {
handlers.onState(newState);
}
})
.configure(opts);
// inject initial state from client (spread to remove `client.state` reference)
setState({ ...client.state });
}, [client, stableOptions]);
return {
target,
client,
state,
};
};