@chaosity/location-client-react 0.1.8 → 0.1.10

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 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 { GeoPlaces, createTransformRequest } from '@chaosity/location-client'
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
- const token = getToken()
138
- if (!token) return
139
-
140
- const mapInstance = new maplibregl.Map({
141
- container: mapContainer.current,
142
- style: `${API_URL}/maps/Standard/descriptor`,
143
- center: [-123.12, 49.28],
144
- zoom: 10,
145
- transformRequest: createTransformRequest(API_URL, getToken),
146
- })
147
-
148
- mapInstance.addControl(new maplibregl.NavigationControl(), 'top-right')
149
-
150
- // GeoPlaces adapter takes the client instance (not raw apiUrl/token)
151
- const geoPlaces = new GeoPlaces(client, mapInstance)
152
- const geocoder = new MaplibreGeocoder(geoPlaces, {
153
- maplibregl,
154
- showResultsWhileTyping: true,
155
- limit: 30,
156
- })
157
- mapInstance.addControl(geocoder, 'top-left')
158
-
159
- // The geocoder resolves places internally via searchByPlaceId.
160
- // The 'result' event fires with the resolved place feature.
161
- geocoder.on('result', (event: any) => {
162
- console.log('Selected place:', event.result)
163
- })
164
-
165
- map.current = mapInstance
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:
@@ -3,7 +3,7 @@
3
3
  * Using a structural type avoids maplibre-gl version conflicts between packages.
4
4
  */
5
5
  interface MapLike {
6
- isStyleLoaded(): boolean;
6
+ isStyleLoaded(): boolean | void;
7
7
  on(event: string, listener: (...args: unknown[]) => void): void;
8
8
  off(event: string, listener: (...args: unknown[]) => void): void;
9
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chaosity/location-client-react",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "React bindings for Chaosity Location Service client",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "license": "MIT",
24
24
  "repository": {
25
25
  "type": "git",
26
- "url": "https://github.com/chaosity-io/location-service-client-react.git"
26
+ "url": "git+https://github.com/chaosity-io/location-service-client-react.git"
27
27
  },
28
28
  "homepage": "https://github.com/chaosity-io/location-service-client-react",
29
29
  "bugs": {