@chaosity/location-client-react 0.1.9 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -32
- package/package.json +7 -4
- package/dist/hooks/useLocationClient.d.ts +0 -10
- package/dist/hooks/useLocationClient.js +0 -21
package/README.md
CHANGED
|
@@ -66,6 +66,42 @@ function SearchComponent() {
|
|
|
66
66
|
}
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
## Map Utilities
|
|
70
|
+
|
|
71
|
+
### useMapLanguage
|
|
72
|
+
|
|
73
|
+
React hook that keeps map label language in sync. Automatically reapplies after `map.setStyle()` calls (e.g. when switching color schemes or terrain).
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { useMapLanguage } from '@chaosity/location-client-react'
|
|
77
|
+
|
|
78
|
+
function MapComponent() {
|
|
79
|
+
const [mapInstance, setMapInstance] = useState<maplibregl.Map | null>(null)
|
|
80
|
+
const [language, setLanguage] = useState('en')
|
|
81
|
+
|
|
82
|
+
// Keeps labels in sync — zero API calls for language changes
|
|
83
|
+
useMapLanguage(mapInstance, language)
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const map = new maplibregl.Map({ /* ... */ })
|
|
87
|
+
map.once('load', () => setMapInstance(map))
|
|
88
|
+
return () => map.remove()
|
|
89
|
+
}, [])
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<>
|
|
93
|
+
<select value={language} onChange={(e) => setLanguage(e.target.value)}>
|
|
94
|
+
<option value="en">English</option>
|
|
95
|
+
<option value="fr">Français</option>
|
|
96
|
+
<option value="de">Deutsch</option>
|
|
97
|
+
<option value="ja">日本語</option>
|
|
98
|
+
</select>
|
|
99
|
+
<div ref={mapContainer} />
|
|
100
|
+
</>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
69
105
|
## API Reference
|
|
70
106
|
|
|
71
107
|
### LocationClientProvider
|
|
@@ -118,9 +154,13 @@ No manual token management needed. The `client` always uses a valid token.
|
|
|
118
154
|
```tsx
|
|
119
155
|
'use client'
|
|
120
156
|
|
|
121
|
-
import { useEffect, useRef } from 'react'
|
|
122
|
-
import { useLocationClient } from '@chaosity/location-client-react'
|
|
123
|
-
import {
|
|
157
|
+
import { useEffect, useRef, useState } from 'react'
|
|
158
|
+
import { useLocationClient, useMapLanguage } from '@chaosity/location-client-react'
|
|
159
|
+
import {
|
|
160
|
+
GeoPlaces,
|
|
161
|
+
fetchMapStyle,
|
|
162
|
+
createTransformRequest,
|
|
163
|
+
} from '@chaosity/location-client'
|
|
124
164
|
import maplibregl from 'maplibre-gl'
|
|
125
165
|
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder'
|
|
126
166
|
|
|
@@ -129,45 +169,54 @@ const API_URL = process.env.NEXT_PUBLIC_LOCATION_API_URL!
|
|
|
129
169
|
export default function MapComponent() {
|
|
130
170
|
const mapContainer = useRef<HTMLDivElement>(null)
|
|
131
171
|
const map = useRef<maplibregl.Map | null>(null)
|
|
172
|
+
const [mapInstance, setMapInstance] = useState<maplibregl.Map | null>(null)
|
|
173
|
+
const [language, setLanguage] = useState('en')
|
|
132
174
|
const { client, getToken, loading, error } = useLocationClient()
|
|
133
175
|
|
|
176
|
+
// Keeps map labels in sync with language — reapplies after every setStyle() call
|
|
177
|
+
useMapLanguage(mapInstance, language)
|
|
178
|
+
|
|
134
179
|
useEffect(() => {
|
|
135
180
|
if (!mapContainer.current || map.current || loading || !client) return
|
|
136
181
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
182
|
+
;(async () => {
|
|
183
|
+
// Fetch style with terrain, 3D buildings, and language baked into the descriptor
|
|
184
|
+
const style = await fetchMapStyle(API_URL, 'Standard', getToken, {
|
|
185
|
+
colorScheme: 'Light',
|
|
186
|
+
terrain: 'Terrain3D',
|
|
187
|
+
buildings: 'Buildings3D',
|
|
188
|
+
language,
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
const instance = new maplibregl.Map({
|
|
192
|
+
container: mapContainer.current!,
|
|
193
|
+
style,
|
|
194
|
+
center: [-123.12, 49.28],
|
|
195
|
+
zoom: 10,
|
|
196
|
+
maxPitch: 85,
|
|
197
|
+
transformRequest: createTransformRequest(API_URL, getToken),
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
instance.addControl(new maplibregl.NavigationControl({ visualizePitch: true }), 'top-right')
|
|
201
|
+
instance.addControl(new maplibregl.TerrainControl({ source: 'amazon' }), 'top-right')
|
|
202
|
+
|
|
203
|
+
const geoPlaces = new GeoPlaces(client, instance)
|
|
204
|
+
const geocoder = new MaplibreGeocoder(geoPlaces, {
|
|
205
|
+
maplibregl,
|
|
206
|
+
showResultsWhileTyping: true,
|
|
207
|
+
limit: 30,
|
|
208
|
+
})
|
|
209
|
+
instance.addControl(geocoder, 'top-left')
|
|
210
|
+
|
|
211
|
+
map.current = instance
|
|
212
|
+
setMapInstance(instance)
|
|
213
|
+
})()
|
|
166
214
|
|
|
167
215
|
return () => {
|
|
168
216
|
if (map.current) {
|
|
169
217
|
map.current.remove()
|
|
170
218
|
map.current = null
|
|
219
|
+
setMapInstance(null)
|
|
171
220
|
}
|
|
172
221
|
}
|
|
173
222
|
}, [client, getToken, loading])
|
|
@@ -179,6 +228,18 @@ export default function MapComponent() {
|
|
|
179
228
|
}
|
|
180
229
|
```
|
|
181
230
|
|
|
231
|
+
### useMapLanguage
|
|
232
|
+
|
|
233
|
+
Hook that keeps map labels in the specified language. Registers a persistent `style.load` listener so language is automatically reapplied after `map.setStyle()` calls.
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
useMapLanguage(map: MapLike | null, language: string): void
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Parameters:**
|
|
240
|
+
- `map` — MapLibre Map instance, or `null` while the map is initializing.
|
|
241
|
+
- `language` — ISO 639-1 language code (e.g. `'en'`, `'fr'`, `'de'`, `'ja'`, `'zh'`, `'ar'`).
|
|
242
|
+
|
|
182
243
|
## Available Commands
|
|
183
244
|
|
|
184
245
|
All AWS Location Service commands are available through the client:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaosity/location-client-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "React bindings for Chaosity Location Service client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsc",
|
|
10
10
|
"dev": "tsc --watch",
|
|
11
|
-
"test": "vitest run",
|
|
11
|
+
"test": "vitest run --passWithNoTests",
|
|
12
12
|
"test:watch": "vitest",
|
|
13
|
-
"prepublishOnly": "npm run build"
|
|
13
|
+
"prepublishOnly": "npm run build",
|
|
14
|
+
"prepare": "husky"
|
|
14
15
|
},
|
|
15
16
|
"keywords": [
|
|
16
17
|
"react",
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
"url": "https://github.com/chaosity-io/location-service-client-react/issues"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@chaosity/location-client": "
|
|
34
|
+
"@chaosity/location-client": "^0.1.0",
|
|
34
35
|
"debug": "^4.4.3"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
@@ -47,7 +48,9 @@
|
|
|
47
48
|
"@testing-library/user-event": "^14.0.0",
|
|
48
49
|
"@types/debug": "^4.1.12",
|
|
49
50
|
"@types/react": "^19.0.0",
|
|
51
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
50
52
|
"happy-dom": "^17.0.0",
|
|
53
|
+
"husky": "^9.0.0",
|
|
51
54
|
"maplibre-gl": "^5.0.0",
|
|
52
55
|
"react": "^19.0.0",
|
|
53
56
|
"typescript": "^5.0.0",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { GeoPlacesClient, ClientConfig } from '@chaosity/location-client';
|
|
2
|
-
export interface UseLocationClientOptions {
|
|
3
|
-
getConfig: () => Promise<ClientConfig>;
|
|
4
|
-
}
|
|
5
|
-
export declare function useLocationClient(options: UseLocationClientOptions): {
|
|
6
|
-
config: ClientConfig | null;
|
|
7
|
-
client: GeoPlacesClient | null;
|
|
8
|
-
loading: boolean;
|
|
9
|
-
error: string | null;
|
|
10
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { GeoPlacesClient } from '@chaosity/location-client';
|
|
3
|
-
export function useLocationClient(options) {
|
|
4
|
-
const [config, setConfig] = useState(null);
|
|
5
|
-
const [client, setClient] = useState(null);
|
|
6
|
-
const [loading, setLoading] = useState(true);
|
|
7
|
-
const [error, setError] = useState(null);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
options.getConfig()
|
|
10
|
-
.then((cfg) => {
|
|
11
|
-
setConfig(cfg);
|
|
12
|
-
setClient(new GeoPlacesClient(cfg));
|
|
13
|
-
setLoading(false);
|
|
14
|
-
})
|
|
15
|
-
.catch((err) => {
|
|
16
|
-
setError(err instanceof Error ? err.message : 'Failed to initialize client');
|
|
17
|
-
setLoading(false);
|
|
18
|
-
});
|
|
19
|
-
}, []);
|
|
20
|
-
return { config, client, loading, error };
|
|
21
|
-
}
|