react-bkoi-gl 2.0.1 → 2.1.0

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
@@ -11,240 +11,1484 @@
11
11
 
12
12
  ## Description
13
13
 
14
- `react-bkoi-gl` is a suite of [React](http://facebook.github.io/react/) components designed to provide a API for [Barikoi Maps](https://docs.barikoi.com/docs/maps-api). More information in the online documentation.
14
+ `react-bkoi-gl` is a suite of [React](http://facebook.github.io/react/) components that provides a React API for [Barikoi Maps](https://docs.barikoi.com/docs/maps-api). Built on top of [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/), it offers high-performance, customizable map rendering with full TypeScript support.
15
+
16
+ Powered by <a href="https://barikoi.com/">Barikoi - Maps for Businesses</a>
17
+
18
+ ## Features
19
+
20
+ - High-performance map rendering using WebGL
21
+ - Easy integration with React and Next.js
22
+ - Customizable map controls and interactions
23
+ - Drawing tools for polygons, lines, and points
24
+ - Minimap control for navigation
25
+ - Support for GeoJSON, vector tiles, and raster sources
26
+ - Full TypeScript support
27
+ - Lightweight and optimized for production
15
28
 
16
29
  ## Installation
17
30
 
18
31
  Using `react-bkoi-gl` requires `react >= 16.3`.
19
32
 
20
- To install the package via npm, run the following command:
21
33
  ```bash
22
34
  npm install react-bkoi-gl
23
35
  ```
36
+
24
37
  Or via yarn:
38
+
25
39
  ```bash
26
40
  yarn add react-bkoi-gl
27
41
  ```
28
42
 
29
- ## Example
43
+ Import styles in your application:
30
44
 
31
- ### JavaScript (`js`) Example
32
- ```jsx
33
- import { useRef } from 'react';
34
- import {
35
- Map,
36
- Marker,
37
- Popup,
38
- Layer,
39
- Source,
40
- NavigationControl,
41
- FullscreenControl,
42
- GeolocateControl,
43
- ScaleControl,
44
- } from 'react-bkoi-gl';
45
+ ```javascript
46
+ import "react-bkoi-gl/styles";
47
+ ```
48
+
49
+ ## Get Barikoi API Key
50
+
51
+ To access Barikoi's API services, you need to:
52
+
53
+ 1. Register on [Barikoi Developer Dashboard](https://developer.barikoi.com/register)
54
+ 2. Verify with your phone number
55
+ 3. Claim your API key
56
+
57
+ ## Quick Start
45
58
 
46
- // Import Styles
59
+ ```tsx
60
+ import { Map, Marker, Popup, NavigationControl } from 'react-bkoi-gl';
47
61
  import "react-bkoi-gl/styles";
48
62
 
49
- const App = () => {
50
- const BARIKOI_API_KEY = 'YOUR_BARIKOI_API_KEY_HERE';
51
- const mapStyle = `https://map.barikoi.com/styles/osm-liberty/style.json?key=${BARIKOI_API_KEY}`;
52
- const mapContainer = useRef(null);
53
- const mapRef = useRef(null);
54
- const initialViewState = {
55
- longitude: 90.36402,
56
- latitude: 23.823731,
57
- minZoom: 4,
58
- maxZoom: 22,
59
- zoom: 13,
60
- bearing: 0,
61
- pitch: 0,
62
- antialias: true,
63
- };
63
+ const BARIKOI_API_KEY = 'YOUR_BARIKOI_API_KEY';
64
64
 
65
+ function App() {
65
66
  return (
66
- <div ref={mapContainer} style={containerStyles}>
67
+ <div style={{ width: '100%', height: '100vh' }}>
67
68
  <Map
68
- ref={mapRef}
69
- mapStyle={mapStyle}
70
- style={{ width: "100%", height: "100%" }}
71
- initialViewState={initialViewState}
72
- doubleClickZoom={false}
73
- dragRotate={false}
69
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${BARIKOI_API_KEY}`}
70
+ initialViewState={{
71
+ longitude: 90.3938010872331,
72
+ latitude: 23.821600277500405,
73
+ zoom: 12
74
+ }}
74
75
  >
75
- <Marker longitude={90.36402} latitude={23.823731} color="red" />
76
- <Popup longitude={90.36402} latitude={23.823731}>
77
- <div>Hello, Barikoi!</div>
76
+ <Marker longitude={90.3938010872331} latitude={23.821600277500405} color="red" />
77
+ <Popup longitude={90.3938010872331} latitude={23.821600277500405}>
78
+ Hello, Barikoi!
78
79
  </Popup>
79
- <Source
80
- id="points"
81
- type="geojson"
82
- data={{
83
- type: 'FeatureCollection',
84
- features: [
85
- {
86
- type: 'Feature',
87
- properties: {},
88
- geometry: { type: 'Point', coordinates: [90.36402, 23.823731] }
89
- }
90
- ]
91
- }}
92
- />
93
- <Layer
94
- id="points-layer"
95
- type="circle"
96
- source="points"
97
- paint={{ 'circle-radius': 10, 'circle-color': '#ff0000' }}
98
- />
99
80
  <NavigationControl position="top-right" />
100
- <FullscreenControl position="top-right" />
101
- <GeolocateControl position="top-right" />
102
- <ScaleControl position="bottom-right" />
103
81
  </Map>
104
82
  </div>
105
83
  );
106
- };
84
+ }
85
+ ```
107
86
 
108
- // JSX Styles
109
- const containerStyles = {
110
- width: "100%",
111
- height: "100vh",
112
- minHeight: "400px",
113
- overflow: "hidden",
114
- };
87
+ ---
115
88
 
116
- export default App;
117
- ```
89
+ ## Components
90
+
91
+ Build maps by composing the `Map` component with layers, sources, UI controls, and hooks.
92
+
93
+ ### Quick Index
94
+
95
+ #### Core
96
+
97
+ - [`Map`](#map-component): Core map component. Parent of all other components.
98
+ - [`Marker`](#marker-component): Marker at a coordinate (supports custom children).
99
+ - [`Popup`](#popup-component): Popup UI at a coordinate or attached to a marker.
100
+
101
+ #### Data & Rendering
102
+
103
+ - [`Source`](#source-component): Data source (GeoJSON, vector, raster, image, video, etc.).
104
+ - [`CanvasSource`](#canvas-source): Render a custom HTML canvas as a source.
105
+ - [`Layer`](#layer-component): Render MapLibre layers from a source (supports events).
106
+
107
+ #### Controls
108
+
109
+ - [`NavigationControl`](#navigation-control): Zoom/compass controls.
110
+ - [`FullscreenControl`](#fullscreen-control): Fullscreen toggle.
111
+ - [`GeolocateControl`](#geolocate-control): Locate and track the user.
112
+ - [`ScaleControl`](#scale-control): Scale bar.
113
+ - [`TerrainControl`](#terrain-control): Terrain visualization.
114
+ - [`DrawControl`](#draw-control): Draw/edit polygons, lines, points.
115
+ - [`GlobeControl`](#globe-control): Toggle globe projection (MapLibre 3.x+).
116
+ - [`MinimapControl`](#minimap-control): Overview minimap (toggleable, responsive).
117
+
118
+ #### Hooks
119
+
120
+ - [`useMap`](#usemap-hook): Access map instances via `MapProvider`.
121
+ - [`useControl`](#usecontrol-hook): Create custom controls.
122
+
123
+ ---
124
+
125
+ ### Map Component
126
+
127
+ The core component that renders a Barikoi map. All other components must be children of `Map`.
128
+
129
+ <details>
130
+ <summary><strong>Props</strong></summary>
131
+
132
+ | Prop | Type | Default | Description |
133
+ |------|------|---------|-------------|
134
+ | `mapStyle` | `string \| StyleSpecification` | Required | Map style URL or style object |
135
+ | `initialViewState` | `object` | - | Initial view state (longitude, latitude, zoom, etc.) |
136
+ | `viewState` | `object` | - | Controlled view state |
137
+ | `mapLib` | `MapLib \| Promise<MapLib>` | - | Custom map library instance |
138
+ | `reuseMaps` | `boolean` | `false` | Reuse map instances for performance |
139
+ | `id` | `string` | - | Container element ID |
140
+ | `style` | `CSSProperties` | - | Container CSS styles |
141
+ | `children` | `ReactNode` | - | Child components |
142
+ | `onClick` | `(e: MapLayerMouseEvent) => void` | - | Click handler |
143
+ | `onLoad` | `(e: MapLibreEvent) => void` | - | Map load handler |
144
+ | `onMoveEnd` | `(e: ViewStateChangeEvent) => void` | - | Move end handler |
145
+ | `onZoomEnd` | `(e: ViewStateChangeEvent) => void` | - | Zoom end handler |
146
+ | `onError` | `(e: ErrorEvent) => void` | - | Error handler |
147
+
148
+ And all [MapLibre Map options](https://maplibre.org/maplibre-gl-js/docs/API/types/MapOptions/).
149
+
150
+ </details>
151
+
152
+ #### Example
118
153
 
119
- ### TypeScript (`ts`) Example
120
154
  ```tsx
155
+ import { Map, MapRef } from 'react-bkoi-gl';
156
+ import "react-bkoi-gl/styles";
121
157
  import { useRef } from 'react';
122
- import {
123
- Map,
124
- Marker,
125
- Popup,
126
- Layer,
127
- Source,
128
- NavigationControl,
129
- FullscreenControl,
130
- GeolocateControl,
131
- ScaleControl,
132
- MapRef
133
- } from 'react-bkoi-gl';
134
158
 
135
- // Import Styles
159
+ function MapExample() {
160
+ const mapRef = useRef<MapRef>(null);
161
+
162
+ const handleMoveEnd = (e) => {
163
+ const map = mapRef.current?.getMap();
164
+ if (map) {
165
+ console.log('Center:', map.getCenter());
166
+ console.log('Zoom:', map.getZoom());
167
+ }
168
+ };
169
+
170
+ return (
171
+ <Map
172
+ ref={mapRef}
173
+ mapStyle="https://map.barikoi.com/styles/osm-liberty/style.json?key=YOUR_API_KEY"
174
+ initialViewState={{
175
+ longitude: 90.3938,
176
+ latitude: 23.8216,
177
+ zoom: 12,
178
+ pitch: 0,
179
+ bearing: 0
180
+ }}
181
+ style={{ width: '100%', height: '100vh' }}
182
+ doubleClickZoom={false}
183
+ dragRotate={true}
184
+ onMoveEnd={handleMoveEnd}
185
+ >
186
+ {/* Child components go here */}
187
+ </Map>
188
+ );
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ### Marker Component
195
+
196
+ Displays a marker on the map at specified coordinates.
197
+
198
+ <details>
199
+ <summary><strong>Props</strong></summary>
200
+
201
+ | Prop | Type | Default | Description |
202
+ |------|------|---------|-------------|
203
+ | `longitude` | `number` | Required | Longitude of the marker |
204
+ | `latitude` | `number` | Required | Latitude of the marker |
205
+ | `color` | `string` | - | Marker color |
206
+ | `draggable` | `boolean` | `false` | Enable dragging |
207
+ | `offset` | `[number, number]` | - | Pixel offset |
208
+ | `anchor` | `string` | `'center'` | Marker anchor position |
209
+ | `scale` | `number` | `1` | Marker scale |
210
+ | `rotation` | `number` | `0` | Rotation in degrees |
211
+ | `rotationAlignment` | `string` | `'auto'` | Rotation alignment mode |
212
+ | `pitchAlignment` | `string` | `'auto'` | Pitch alignment mode |
213
+ | `popup` | `Popup` | - | Popup to show on click |
214
+ | `onClick` | `(e: MarkerEvent) => void` | - | Click handler |
215
+ | `onDragStart` | `(e: MarkerDragEvent) => void` | - | Drag start handler |
216
+ | `onDrag` | `(e: MarkerDragEvent) => void` | - | Drag handler |
217
+ | `onDragEnd` | `(e: MarkerDragEvent) => void` | - | Drag end handler |
218
+
219
+ </details>
220
+
221
+ #### Example
222
+
223
+ ```tsx
224
+ import { Map, Marker } from 'react-bkoi-gl';
136
225
  import "react-bkoi-gl/styles";
226
+ import { useState } from 'react';
227
+
228
+ function MarkerExample() {
229
+ const [marker, setMarker] = useState({
230
+ lng: 90.3938,
231
+ lat: 23.8216
232
+ });
233
+
234
+ const onDragEnd = (e) => {
235
+ setMarker({
236
+ lng: e.lngLat.lng,
237
+ lat: e.lngLat.lat
238
+ });
239
+ };
240
+
241
+ return (
242
+ <Map
243
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
244
+ initialViewState={{
245
+ longitude: 90.3938,
246
+ latitude: 23.8216,
247
+ zoom: 12
248
+ }}
249
+ style={{ width: '100%', height: '100vh' }}
250
+ >
251
+ {/* Simple marker */}
252
+ <Marker longitude={90.3938} latitude={23.8216} color="red" />
137
253
 
138
- interface MapProps {
139
- longitude: number;
140
- latitude: number;
254
+ {/* Draggable marker */}
255
+ <Marker
256
+ longitude={marker.lng}
257
+ latitude={marker.lat}
258
+ color="blue"
259
+ draggable
260
+ onDragEnd={onDragEnd}
261
+ />
262
+
263
+ {/* Custom marker with React children */}
264
+ <Marker longitude={90.40} latitude={23.83}>
265
+ <div style={{
266
+ backgroundColor: '#fff',
267
+ padding: '5px 10px',
268
+ borderRadius: '5px',
269
+ boxShadow: '0 2px 5px rgba(0,0,0,0.3)'
270
+ }}>
271
+ Custom Marker
272
+ </div>
273
+ </Marker>
274
+ </Map>
275
+ );
141
276
  }
277
+ ```
142
278
 
143
- const App: React.FC = () => {
144
- const BARIKOI_API_KEY = 'YOUR_BARIKOI_API_KEY_HERE';
145
- const mapStyle = `https://map.barikoi.com/styles/osm-liberty/style.json?key=${BARIKOI_API_KEY}`;
146
- const mapContainer = useRef<HTMLDivElement>(null);
147
- const mapRef = useRef<MapRef>(null);
148
- const initialViewState = {
149
- longitude: 90.36402,
150
- latitude: 23.823731,
151
- minZoom: 4,
152
- maxZoom: 22,
153
- zoom: 13,
154
- bearing: 0,
155
- pitch: 0,
156
- antialias: true,
279
+ ---
280
+
281
+ ### Popup Component
282
+
283
+ Displays a popup with custom content at specified coordinates.
284
+
285
+ <details>
286
+ <summary><strong>Props</strong></summary>
287
+
288
+ | Prop | Type | Default | Description |
289
+ |------|------|---------|-------------|
290
+ | `longitude` | `number` | Required | Longitude of the popup |
291
+ | `latitude` | `number` | Required | Latitude of the popup |
292
+ | `anchor` | `string` | - | Popup anchor position |
293
+ | `offset` | `number \| [number, number]` | - | Pixel offset |
294
+ | `className` | `string` | - | CSS class name |
295
+ | `maxWidth` | `string` | `'240px'` | Maximum width |
296
+ | `closeButton` | `boolean` | `true` | Show close button |
297
+ | `closeOnClick` | `boolean` | `true` | Close on map click |
298
+ | `onOpen` | `() => void` | - | Open handler |
299
+ | `onClose` | `() => void` | - | Close handler |
300
+ | `children` | `ReactNode` | - | Popup content |
301
+
302
+ </details>
303
+
304
+ #### Example
305
+
306
+ ```tsx
307
+ import { Map, Marker, Popup } from 'react-bkoi-gl';
308
+ import "react-bkoi-gl/styles";
309
+ import { useState } from 'react';
310
+
311
+ function PopupExample() {
312
+ const [showPopup, setShowPopup] = useState(true);
313
+
314
+ return (
315
+ <Map
316
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
317
+ initialViewState={{
318
+ longitude: 90.3938,
319
+ latitude: 23.8216,
320
+ zoom: 12
321
+ }}
322
+ style={{ width: '100%', height: '100vh' }}
323
+ >
324
+ {/* Standalone popup */}
325
+ {showPopup && (
326
+ <Popup
327
+ longitude={90.3938}
328
+ latitude={23.8216}
329
+ anchor="bottom"
330
+ onClose={() => setShowPopup(false)}
331
+ >
332
+ <div>
333
+ <h3>Dhaka</h3>
334
+ <p>Capital of Bangladesh</p>
335
+ </div>
336
+ </Popup>
337
+ )}
338
+
339
+ {/* Marker with attached popup */}
340
+ <Marker longitude={90.40} latitude={23.83} color="red">
341
+ <Popup>
342
+ <div>Popup attached to marker</div>
343
+ </Popup>
344
+ </Marker>
345
+ </Map>
346
+ );
347
+ }
348
+ ```
349
+
350
+ ---
351
+
352
+ ### Source Component
353
+
354
+ Defines a data source for the map. Supports GeoJSON, vector tiles, raster tiles, image, and video sources.
355
+
356
+ <details>
357
+ <summary><strong>Props</strong></summary>
358
+
359
+ | Prop | Type | Description |
360
+ |------|------|-------------|
361
+ | `id` | `string` | Unique source identifier |
362
+ | `type` | `string` | Source type: `'geojson'`, `'vector'`, `'raster'`, `'image'`, `'video'` |
363
+ | `data` | `object \| string` | GeoJSON data or URL (for geojson type) |
364
+ | `url` | `string` | Tile URL (for vector/raster) |
365
+ | `tiles` | `string[]` | Tile URLs array |
366
+ | `tileSize` | `number` | Tile size in pixels |
367
+ | `coordinates` | `array` | Image coordinates (for image type) |
368
+ | `children` | `ReactNode` | Layer components using this source |
369
+
370
+ </details>
371
+
372
+ #### Example
373
+
374
+ ```tsx
375
+ import { Map, Source, Layer } from 'react-bkoi-gl';
376
+ import "react-bkoi-gl/styles";
377
+
378
+ function SourceExample() {
379
+ const geojsonData = {
380
+ type: 'FeatureCollection',
381
+ features: [
382
+ {
383
+ type: 'Feature',
384
+ properties: { name: 'Point A' },
385
+ geometry: {
386
+ type: 'Point',
387
+ coordinates: [90.3938, 23.8216]
388
+ }
389
+ },
390
+ {
391
+ type: 'Feature',
392
+ properties: { name: 'Point B' },
393
+ geometry: {
394
+ type: 'Point',
395
+ coordinates: [90.40, 23.83]
396
+ }
397
+ }
398
+ ]
399
+ };
400
+
401
+ const lineData = {
402
+ type: 'Feature',
403
+ properties: {},
404
+ geometry: {
405
+ type: 'LineString',
406
+ coordinates: [
407
+ [90.3938, 23.8216],
408
+ [90.40, 23.83],
409
+ [90.41, 23.84]
410
+ ]
411
+ }
412
+ };
413
+
414
+ const polygonData = {
415
+ type: 'Feature',
416
+ properties: { name: 'Polygon Area' },
417
+ geometry: {
418
+ type: 'Polygon',
419
+ coordinates: [[
420
+ [90.39, 23.82],
421
+ [90.41, 23.82],
422
+ [90.41, 23.84],
423
+ [90.39, 23.84],
424
+ [90.39, 23.82]
425
+ ]]
426
+ }
157
427
  };
158
428
 
159
429
  return (
160
- <div ref={mapContainer} style={containerStyles}>
161
- <Map
162
- ref={mapRef}
163
- mapStyle={mapStyle}
164
- style={{ width: "100%", height: "100%" }}
165
- initialViewState={initialViewState}
166
- doubleClickZoom={false}
167
- dragRotate={false}
430
+ <Map
431
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
432
+ initialViewState={{
433
+ longitude: 90.40,
434
+ latitude: 23.83,
435
+ zoom: 12
436
+ }}
437
+ style={{ width: '100%', height: '100vh' }}
438
+ >
439
+ {/* GeoJSON point source */}
440
+ <Source id="points" type="geojson" data={geojsonData}>
441
+ <Layer
442
+ id="points-layer"
443
+ type="circle"
444
+ paint={{
445
+ 'circle-radius': 10,
446
+ 'circle-color': '#007cbf'
447
+ }}
448
+ />
449
+ </Source>
450
+
451
+ {/* GeoJSON line source */}
452
+ <Source id="line" type="geojson" data={lineData}>
453
+ <Layer
454
+ id="line-layer"
455
+ type="line"
456
+ paint={{
457
+ 'line-width': 3,
458
+ 'line-color': '#ff0000'
459
+ }}
460
+ />
461
+ </Source>
462
+
463
+ {/* GeoJSON polygon source */}
464
+ <Source id="polygon" type="geojson" data={polygonData}>
465
+ <Layer
466
+ id="polygon-fill"
467
+ type="fill"
468
+ paint={{
469
+ 'fill-color': '#088',
470
+ 'fill-opacity': 0.4
471
+ }}
472
+ />
473
+ <Layer
474
+ id="polygon-outline"
475
+ type="line"
476
+ paint={{
477
+ 'line-color': '#000',
478
+ 'line-width': 2
479
+ }}
480
+ />
481
+ </Source>
482
+
483
+ {/* Raster tile source */}
484
+ <Source
485
+ id="satellite"
486
+ type="raster"
487
+ tiles={['https://example.com/tiles/{z}/{x}/{y}.png']}
488
+ tileSize={256}
168
489
  >
169
- <Marker longitude={90.36402} latitude={23.823731} color="red" />
170
- <Popup longitude={90.36402} latitude={23.823731}>
171
- <div>Hello, Barikoi!</div>
172
- </Popup>
173
- <Source
174
- id="points"
175
- type="geojson"
176
- data={{
177
- type: 'FeatureCollection',
178
- features: [
179
- {
180
- type: 'Feature',
181
- properties: {},
182
- geometry: { type: 'Point', coordinates: [90.36402, 23.823731] }
183
- }
184
- ]
490
+ <Layer id="satellite-layer" type="raster" />
491
+ </Source>
492
+ </Map>
493
+ );
494
+ }
495
+ ```
496
+
497
+ ---
498
+
499
+ ### Layer Component
500
+
501
+ Renders data from a source on the map. Supports all MapLibre layer types.
502
+
503
+ <details>
504
+ <summary><strong>Props</strong></summary>
505
+
506
+ | Prop | Type | Description |
507
+ |------|------|-------------|
508
+ | `id` | `string` | Unique layer identifier |
509
+ | `type` | `string` | Layer type: `'fill'`, `'line'`, `'circle'`, `'symbol'`, `'raster'`, `'heatmap'`, `'hillshade'`, `'background'` |
510
+ | `source` | `string` | Source ID (inherited from parent Source) |
511
+ | `source-layer` | `string` | Source layer (for vector sources) |
512
+ | `paint` | `object` | Paint properties |
513
+ | `layout` | `object` | Layout properties |
514
+ | `filter` | `array` | Filter expression |
515
+ | `minzoom` | `number` | Minimum zoom level |
516
+ | `maxzoom` | `number` | Maximum zoom level |
517
+ | `beforeId` | `string` | Insert before this layer ID |
518
+
519
+ </details>
520
+
521
+ #### Example
522
+
523
+ ```tsx
524
+ import { Map, Source, Layer } from 'react-bkoi-gl';
525
+ import "react-bkoi-gl/styles";
526
+
527
+ function LayerExample() {
528
+ const cities = {
529
+ type: 'FeatureCollection',
530
+ features: [
531
+ { type: 'Feature', properties: { name: 'Dhaka', population: 21000000 }, geometry: { type: 'Point', coordinates: [90.3938, 23.8216] } },
532
+ { type: 'Feature', properties: { name: 'Chittagong', population: 4000000 }, geometry: { type: 'Point', coordinates: [91.8317, 22.3569] } },
533
+ { type: 'Feature', properties: { name: 'Khulna', population: 1500000 }, geometry: { type: 'Point', coordinates: [89.5555, 22.8456] } }
534
+ ]
535
+ };
536
+
537
+ return (
538
+ <Map
539
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
540
+ initialViewState={{
541
+ longitude: 90.3938,
542
+ latitude: 23.8216,
543
+ zoom: 6
544
+ }}
545
+ style={{ width: '100%', height: '100vh' }}
546
+ >
547
+ <Source id="cities" type="geojson" data={cities}>
548
+ {/* Circle layer with data-driven styling */}
549
+ <Layer
550
+ id="cities-circles"
551
+ type="circle"
552
+ paint={{
553
+ 'circle-radius': ['*', 0.000001, ['get', 'population']],
554
+ 'circle-color': [
555
+ 'interpolate',
556
+ ['linear'],
557
+ ['get', 'population'],
558
+ 1000000, '#51bbd6',
559
+ 5000000, '#f1f075',
560
+ 20000000, '#f28cb1'
561
+ ],
562
+ 'circle-opacity': 0.8
185
563
  }}
186
564
  />
565
+
566
+ {/* Symbol layer for labels */}
187
567
  <Layer
188
- id="points-layer"
568
+ id="cities-labels"
569
+ type="symbol"
570
+ layout={{
571
+ 'text-field': ['get', 'name'],
572
+ 'text-font': ['Open Sans Regular'],
573
+ 'text-offset': [0, 2],
574
+ 'text-anchor': 'top'
575
+ }}
576
+ paint={{
577
+ 'text-color': '#000',
578
+ 'text-halo-color': '#fff',
579
+ 'text-halo-width': 1
580
+ }}
581
+ />
582
+
583
+ {/* Filtered layer */}
584
+ <Layer
585
+ id="large-cities"
189
586
  type="circle"
190
- source="points"
191
- paint={{ 'circle-radius': 10, 'circle-color': '#ff0000' }}
587
+ filter={['>', ['get', 'population'], 5000000]}
588
+ paint={{
589
+ 'circle-radius': 20,
590
+ 'circle-color': '#ff0000',
591
+ 'circle-stroke-width': 2,
592
+ 'circle-stroke-color': '#fff'
593
+ }}
192
594
  />
193
- <NavigationControl position="top-right" />
194
- <FullscreenControl position="top-right" />
195
- <GeolocateControl position="top-right" />
196
- <ScaleControl position="bottom-right" />
197
- </Map>
595
+ </Source>
596
+ </Map>
597
+ );
598
+ }
599
+ ```
600
+
601
+ ---
602
+
603
+ ### Navigation Control
604
+
605
+ Adds zoom and rotation controls to the map.
606
+
607
+ <details>
608
+ <summary><strong>Props</strong></summary>
609
+
610
+ | Prop | Type | Default | Description |
611
+ |------|------|---------|-------------|
612
+ | `position` | `string` | `'top-right'` | Control position |
613
+ | `showCompass` | `boolean` | `true` | Show compass button |
614
+ | `showZoom` | `boolean` | `true` | Show zoom buttons |
615
+ | `visualizePitch` | `boolean` | `false` | Visualize pitch in compass |
616
+
617
+ </details>
618
+
619
+ #### Example
620
+
621
+ ```tsx
622
+ import { Map, NavigationControl } from 'react-bkoi-gl';
623
+ import "react-bkoi-gl/styles";
624
+
625
+ function NavigationExample() {
626
+ return (
627
+ <Map
628
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
629
+ initialViewState={{
630
+ longitude: 90.3938,
631
+ latitude: 23.8216,
632
+ zoom: 12
633
+ }}
634
+ style={{ width: '100%', height: '100vh' }}
635
+ >
636
+ <NavigationControl position="top-right" showCompass showZoom visualizePitch />
637
+ </Map>
638
+ );
639
+ }
640
+ ```
641
+
642
+ ---
643
+
644
+ ### Fullscreen Control
645
+
646
+ Adds a button to toggle fullscreen mode.
647
+
648
+ <details>
649
+ <summary><strong>Props</strong></summary>
650
+
651
+ | Prop | Type | Default | Description |
652
+ |------|------|---------|-------------|
653
+ | `position` | `string` | `'top-right'` | Control position |
654
+ | `container` | `HTMLElement` | - | Custom fullscreen container |
655
+
656
+ </details>
657
+
658
+ #### Example
659
+
660
+ ```tsx
661
+ import { Map, FullscreenControl } from 'react-bkoi-gl';
662
+ import "react-bkoi-gl/styles";
663
+
664
+ function FullscreenExample() {
665
+ return (
666
+ <Map
667
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
668
+ initialViewState={{
669
+ longitude: 90.3938,
670
+ latitude: 23.8216,
671
+ zoom: 12
672
+ }}
673
+ style={{ width: '100%', height: '100vh' }}
674
+ >
675
+ <FullscreenControl position="top-right" />
676
+ </Map>
677
+ );
678
+ }
679
+ ```
680
+
681
+ ---
682
+
683
+ ### Geolocate Control
684
+
685
+ Centers the map on the user's current location.
686
+
687
+ <details>
688
+ <summary><strong>Props</strong></summary>
689
+
690
+ | Prop | Type | Default | Description |
691
+ |------|------|---------|-------------|
692
+ | `position` | `string` | `'top-right'` | Control position |
693
+ | `positionOptions` | `object` | `{ enableHighAccuracy: true }` | Geolocation options |
694
+ | `fitBoundsOptions` | `object` | `{ maxZoom: 15 }` | Fit bounds options |
695
+ | `trackUserLocation` | `boolean` | `false` | Track user location |
696
+ | `showAccuracyCircle` | `boolean` | `true` | Show accuracy circle |
697
+ | `showUserLocation` | `boolean` | `true` | Show user location marker |
698
+ | `onGeolocate` | `(e: GeolocateResultEvent) => void` | - | Geolocate success handler |
699
+ | `onError` | `(e: GeolocateErrorEvent) => void` | - | Error handler |
700
+
701
+ </details>
702
+
703
+ #### Example
704
+
705
+ ```tsx
706
+ import { Map, GeolocateControl } from 'react-bkoi-gl';
707
+ import "react-bkoi-gl/styles";
708
+
709
+ function GeolocateExample() {
710
+ const onGeolocate = (e) => {
711
+ console.log('User location:', e.coords);
712
+ };
713
+
714
+ return (
715
+ <Map
716
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
717
+ initialViewState={{
718
+ longitude: 90.3938,
719
+ latitude: 23.8216,
720
+ zoom: 12
721
+ }}
722
+ style={{ width: '100%', height: '100vh' }}
723
+ >
724
+ <GeolocateControl
725
+ position="top-right"
726
+ trackUserLocation
727
+ showAccuracyCircle
728
+ onGeolocate={onGeolocate}
729
+ />
730
+ </Map>
731
+ );
732
+ }
733
+ ```
734
+
735
+ ---
736
+
737
+ ### Scale Control
738
+
739
+ Displays a scale bar on the map.
740
+
741
+ <details>
742
+ <summary><strong>Props</strong></summary>
743
+
744
+ | Prop | Type | Default | Description |
745
+ |------|------|---------|-------------|
746
+ | `position` | `string` | `'bottom-left'` | Control position |
747
+ | `maxWidth` | `number` | `100` | Maximum width in pixels |
748
+ | `unit` | `string` | `'metric'` | Unit: `'imperial'`, `'metric'`, or `'nautical'` |
749
+
750
+ </details>
751
+
752
+ #### Example
753
+
754
+ ```tsx
755
+ import { Map, ScaleControl } from 'react-bkoi-gl';
756
+ import "react-bkoi-gl/styles";
757
+
758
+ function ScaleExample() {
759
+ return (
760
+ <Map
761
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
762
+ initialViewState={{
763
+ longitude: 90.3938,
764
+ latitude: 23.8216,
765
+ zoom: 12
766
+ }}
767
+ style={{ width: '100%', height: '100vh' }}
768
+ >
769
+ <ScaleControl position="bottom-left" unit="metric" maxWidth={150} />
770
+ </Map>
771
+ );
772
+ }
773
+ ```
774
+
775
+ ---
776
+
777
+ ### Terrain Control
778
+
779
+ Adds terrain visualization to the map.
780
+
781
+ <details>
782
+ <summary><strong>Props</strong></summary>
783
+
784
+ | Prop | Type | Default | Description |
785
+ |------|------|---------|-------------|
786
+ | `position` | `string` | `'top-right'` | Control position |
787
+ | `source` | `string \| object` | - | Terrain source |
788
+
789
+ </details>
790
+
791
+ #### Example
792
+
793
+ ```tsx
794
+ import { Map, TerrainControl, Source, Layer } from 'react-bkoi-gl';
795
+ import "react-bkoi-gl/styles";
796
+
797
+ function TerrainExample() {
798
+ return (
799
+ <Map
800
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
801
+ initialViewState={{
802
+ longitude: 90.3938,
803
+ latitude: 23.8216,
804
+ zoom: 12,
805
+ pitch: 60
806
+ }}
807
+ style={{ width: '100%', height: '100vh' }}
808
+ >
809
+ <Source
810
+ id="terrain"
811
+ type="raster-dem"
812
+ url="mapbox://mapbox.mapbox-terrain-dem-v1"
813
+ tileSize={512}
814
+ maxzoom={14}
815
+ />
816
+ <TerrainControl source="terrain" />
817
+ </Map>
818
+ );
819
+ }
820
+ ```
821
+
822
+ ---
823
+
824
+ ### Draw Control
825
+
826
+ Adds drawing tools for creating and editing polygons, lines, and points.
827
+
828
+ <details>
829
+ <summary><strong>Props</strong></summary>
830
+
831
+ | Prop | Type | Default | Description |
832
+ |------|------|---------|-------------|
833
+ | `position` | `string` | `'top-left'` | Control position |
834
+ | `displayControlsDefault` | `boolean` | `false` | Show all controls by default |
835
+ | `controls` | `object` | `{ polygon: true, trash: true }` | Control visibility |
836
+ | `styles` | `array` | - | Custom draw styles |
837
+ | `modes` | `object` | - | Custom draw modes |
838
+ | `defaultMode` | `string` | `'simple_select'` | Default drawing mode |
839
+ | `onDrawCreate` | `(e: DrawEvent) => void` | - | Feature created handler |
840
+ | `onDrawDelete` | `(e: DrawEvent) => void` | - | Feature deleted handler |
841
+ | `onDrawUpdate` | `(e: DrawEvent) => void` | - | Feature updated handler |
842
+ | `onDrawSelectionChange` | `(e: DrawEvent) => void` | - | Selection change handler |
843
+ | `onDrawModeChange` | `(e: DrawEvent) => void` | - | Mode change handler |
844
+
845
+ </details>
846
+
847
+ #### Example
848
+
849
+ ```tsx
850
+ import { Map, DrawControl } from 'react-bkoi-gl';
851
+ import "react-bkoi-gl/styles";
852
+ import { useState } from 'react';
853
+
854
+ function DrawExample() {
855
+ const [features, setFeatures] = useState([]);
856
+
857
+ const onDrawCreate = (e) => {
858
+ console.log('Created features:', e.features);
859
+ setFeatures(e.features);
860
+ };
861
+
862
+ const onDrawUpdate = (e) => {
863
+ console.log('Updated features:', e.features);
864
+ setFeatures(e.features);
865
+ };
866
+
867
+ const onDrawDelete = (e) => {
868
+ console.log('Deleted features:', e.features);
869
+ };
870
+
871
+ return (
872
+ <Map
873
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
874
+ initialViewState={{
875
+ longitude: 90.3938,
876
+ latitude: 23.8216,
877
+ zoom: 12
878
+ }}
879
+ style={{ width: '100%', height: '100vh' }}
880
+ >
881
+ <DrawControl
882
+ position="top-left"
883
+ controls={{
884
+ polygon: true,
885
+ line_string: true,
886
+ point: true,
887
+ trash: true,
888
+ combine_features: false,
889
+ uncombine_features: false
890
+ }}
891
+ onDrawCreate={onDrawCreate}
892
+ onDrawUpdate={onDrawUpdate}
893
+ onDrawDelete={onDrawDelete}
894
+ />
895
+ </Map>
896
+ );
897
+ }
898
+ ```
899
+
900
+ ---
901
+
902
+ ### Minimap Control
903
+
904
+ Displays a small overview map for navigation.
905
+
906
+ <details>
907
+ <summary><strong>Props</strong></summary>
908
+
909
+ | Prop | Type | Default | Description |
910
+ |------|------|---------|-------------|
911
+ | `position` | `string` | `'top-right'` | Control position |
912
+ | `center` | `[number, number]` | - | Initial center coordinates |
913
+ | `zoomAdjust` | `number` | `-4` | Zoom offset from parent |
914
+ | `lockZoom` | `number` | - | Lock to specific zoom level |
915
+ | `pitchAdjust` | `boolean` | `false` | Sync pitch with parent |
916
+ | `style` | `string \| StyleSpecification` | - | Custom minimap style |
917
+ | `containerStyle` | `object` | - | Custom container styles |
918
+ | `toggleable` | `boolean` | `true` | Allow toggling minimap |
919
+ | `initialMinimized` | `boolean` | `false` | Start minimized |
920
+ | `responsive` | `boolean` | `true` | Enable responsive sizing |
921
+ | `interactions` | `object` | - | Interaction configuration |
922
+ | `parentRect` | `object` | - | Parent rectangle styling |
923
+ | `onToggle` | `(isMinimized: boolean) => void` | - | Toggle callback |
924
+
925
+ </details>
926
+
927
+ #### Example
928
+
929
+ ```tsx
930
+ import { Map, MinimapControl } from 'react-bkoi-gl';
931
+ import "react-bkoi-gl/styles";
932
+
933
+ function MinimapExample() {
934
+ const onToggle = (isMinimized) => {
935
+ console.log('Minimap minimized:', isMinimized);
936
+ };
937
+
938
+ return (
939
+ <Map
940
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
941
+ initialViewState={{
942
+ longitude: 90.3938,
943
+ latitude: 23.8216,
944
+ zoom: 12
945
+ }}
946
+ style={{ width: '100%', height: '100vh' }}
947
+ >
948
+ <MinimapControl
949
+ position="bottom-right"
950
+ zoomAdjust={-5}
951
+ toggleable
952
+ initialMinimized={false}
953
+ containerStyle={{
954
+ width: '200px',
955
+ height: '150px'
956
+ }}
957
+ parentRect={{
958
+ linePaint: {
959
+ 'line-color': '#FF0000',
960
+ 'line-width': 2
961
+ },
962
+ fillPaint: {
963
+ 'fill-color': '#0000FF',
964
+ 'fill-opacity': 0.1
965
+ }
966
+ }}
967
+ interactions={{
968
+ dragPan: true,
969
+ scrollZoom: false
970
+ }}
971
+ onToggle={onToggle}
972
+ />
973
+ </Map>
974
+ );
975
+ }
976
+ ```
977
+
978
+ ---
979
+
980
+ ### Globe Control
981
+
982
+ Toggle between 2D map and 3D globe view (requires MapLibre GL 3.x+).
983
+
984
+ <details>
985
+ <summary><strong>Props</strong></summary>
986
+
987
+ | Prop | Type | Default | Description |
988
+ |------|------|---------|-------------|
989
+ | `position` | `string` | `'top-right'` | Control position |
990
+ | `buttonClassName` | `string` | `'maplibregl-ctrl-globe'` | Button CSS class |
991
+ | `buttonTitle` | `string` | `'Toggle Globe View'` | Button tooltip |
992
+ | `buttonStyle` | `CSSProperties` | - | Custom button styles |
993
+ | `onProjectionChange` | `(isGlobe: boolean) => void` | - | Projection change handler |
994
+
995
+ </details>
996
+
997
+ #### Example
998
+
999
+ ```tsx
1000
+ import { Map, GlobeControl } from 'react-bkoi-gl';
1001
+ import "react-bkoi-gl/styles";
1002
+
1003
+ function GlobeExample() {
1004
+ const handleProjectionChange = (isGlobe) => {
1005
+ console.log('Globe view:', isGlobe);
1006
+ };
1007
+
1008
+ return (
1009
+ <Map
1010
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
1011
+ initialViewState={{
1012
+ longitude: 90.3938,
1013
+ latitude: 23.8216,
1014
+ zoom: 12
1015
+ }}
1016
+ style={{ width: '100%', height: '100vh' }}
1017
+ >
1018
+ <GlobeControl
1019
+ position="top-right"
1020
+ onProjectionChange={handleProjectionChange}
1021
+ />
1022
+ </Map>
1023
+ );
1024
+ }
1025
+ ```
1026
+
1027
+ ---
1028
+
1029
+ ### Canvas Source
1030
+
1031
+ Render custom HTML canvas elements as map layers.
1032
+
1033
+ <details>
1034
+ <summary><strong>Props</strong></summary>
1035
+
1036
+ | Prop | Type | Description |
1037
+ |------|------|-------------|
1038
+ | `id` | `string` | Unique source identifier |
1039
+ | `coordinates` | `[[lng,lat], [lng,lat], [lng,lat], [lng,lat]]` | Corner coordinates (top-left, top-right, bottom-right, bottom-left) |
1040
+ | `canvas` | `HTMLCanvasElement` | The canvas element to render |
1041
+ | `animate` | `boolean` | Whether to animate the canvas |
1042
+ | `children` | `ReactNode` | Child Layer components |
1043
+
1044
+ </details>
1045
+
1046
+ #### Example
1047
+
1048
+ ```tsx
1049
+ import { Map, CanvasSource, Layer } from 'react-bkoi-gl';
1050
+ import "react-bkoi-gl/styles";
1051
+ import { useRef, useEffect, useState } from 'react';
1052
+
1053
+ function CanvasExample() {
1054
+ const canvasRef = useRef<HTMLCanvasElement>(null);
1055
+ const [canvasEl, setCanvasEl] = useState<HTMLCanvasElement | null>(null);
1056
+
1057
+ useEffect(() => {
1058
+ const canvas = canvasRef.current;
1059
+ if (!canvas) return;
1060
+
1061
+ const ctx = canvas.getContext('2d');
1062
+ if (ctx) {
1063
+ ctx.fillStyle = 'rgba(0, 100, 255, 0.5)';
1064
+ ctx.fillRect(0, 0, 256, 256);
1065
+ ctx.fillStyle = 'rgba(255, 0, 0, 0.8)';
1066
+ ctx.beginPath();
1067
+ ctx.arc(128, 128, 50, 0, 2 * Math.PI);
1068
+ ctx.fill();
1069
+ }
1070
+
1071
+ setCanvasEl(canvas);
1072
+ }, []);
1073
+
1074
+ return (
1075
+ <Map
1076
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
1077
+ initialViewState={{
1078
+ longitude: 90.3938,
1079
+ latitude: 23.8216,
1080
+ zoom: 12
1081
+ }}
1082
+ style={{ width: '100%', height: '100vh' }}
1083
+ >
1084
+ <canvas ref={canvasRef} width={256} height={256} style={{ display: 'none' }} />
1085
+ {canvasEl && (
1086
+ <CanvasSource
1087
+ id="my-canvas"
1088
+ coordinates={[
1089
+ [90.38, 23.83],
1090
+ [90.41, 23.83],
1091
+ [90.41, 23.81],
1092
+ [90.38, 23.81]
1093
+ ]}
1094
+ canvas={canvasEl}
1095
+ animate={true}
1096
+ >
1097
+ <Layer type="raster" paint={{ 'raster-opacity': 0.8 }} />
1098
+ </CanvasSource>
1099
+ )}
1100
+ </Map>
1101
+ );
1102
+ }
1103
+ ```
1104
+
1105
+ ---
1106
+
1107
+ ## Layer Events
1108
+
1109
+ The Layer component supports interactive mouse events:
1110
+
1111
+ <details>
1112
+ <summary><strong>Available Events</strong></summary>
1113
+
1114
+ | Prop | Type | Description |
1115
+ |------|------|-------------|
1116
+ | `onClick` | `(e: MapLayerMouseEvent) => void` | Fired when layer is clicked |
1117
+ | `onMouseEnter` | `(e: MapLayerMouseEvent) => void` | Fired when mouse enters layer |
1118
+ | `onMouseLeave` | `() => void` | Fired when mouse leaves layer |
1119
+ | `onMouseMove` | `(e: MapLayerMouseEvent) => void` | Fired when mouse moves over layer |
1120
+ | `onMouseDown` | `(e: MapLayerMouseEvent) => void` | Fired on mouse button press |
1121
+ | `onMouseUp` | `(e: MapLayerMouseEvent) => void` | Fired on mouse button release |
1122
+ | `onContextMenu` | `(e: MapLayerMouseEvent) => void` | Fired on right-click |
1123
+ | `onDoubleClick` | `(e: MapLayerMouseEvent) => void` | Fired on double-click |
1124
+
1125
+ </details>
1126
+
1127
+ #### Example
1128
+
1129
+ ```tsx
1130
+ import { Map, Source, Layer } from 'react-bkoi-gl';
1131
+ import "react-bkoi-gl/styles";
1132
+ import { useState } from 'react';
1133
+
1134
+ function InteractiveLayerExample() {
1135
+ const [hoveredFeature, setHoveredFeature] = useState(null);
1136
+
1137
+ const geojsonData = {
1138
+ type: 'FeatureCollection',
1139
+ features: [
1140
+ { type: 'Feature', properties: { name: 'Dhaka' }, geometry: { type: 'Point', coordinates: [90.3938, 23.8216] } }
1141
+ ]
1142
+ };
1143
+
1144
+ return (
1145
+ <Map
1146
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
1147
+ initialViewState={{
1148
+ longitude: 90.3938,
1149
+ latitude: 23.8216,
1150
+ zoom: 12
1151
+ }}
1152
+ style={{ width: '100%', height: '100vh' }}
1153
+ >
1154
+ <Source id="places" type="geojson" data={geojsonData}>
1155
+ <Layer
1156
+ id="places-layer"
1157
+ type="circle"
1158
+ paint={{
1159
+ 'circle-radius': hoveredFeature ? 12 : 8,
1160
+ 'circle-color': hoveredFeature ? '#FF0000' : '#007cbf'
1161
+ }}
1162
+ onClick={(e) => {
1163
+ console.log('Clicked:', e.features[0].properties.name);
1164
+ }}
1165
+ onMouseEnter={(e) => {
1166
+ setHoveredFeature(e.features[0]);
1167
+ }}
1168
+ onMouseLeave={() => {
1169
+ setHoveredFeature(null);
1170
+ }}
1171
+ />
1172
+ </Source>
1173
+ </Map>
1174
+ );
1175
+ }
1176
+ ```
1177
+
1178
+ ---
1179
+
1180
+ ## Hooks
1181
+
1182
+ ### useMap Hook
1183
+
1184
+ Access map instances from any component within the MapProvider.
1185
+
1186
+ #### Example
1187
+
1188
+ ```tsx
1189
+ import { Map, useMap, MapProvider } from 'react-bkoi-gl';
1190
+ import "react-bkoi-gl/styles";
1191
+
1192
+ function MapButtons() {
1193
+ const { current: map } = useMap();
1194
+
1195
+ const zoomIn = () => {
1196
+ map?.zoomIn();
1197
+ };
1198
+
1199
+ const zoomOut = () => {
1200
+ map?.zoomOut();
1201
+ };
1202
+
1203
+ const flyTo = () => {
1204
+ map?.flyTo({
1205
+ center: [90.40, 23.83],
1206
+ zoom: 15,
1207
+ duration: 2000
1208
+ });
1209
+ };
1210
+
1211
+ return (
1212
+ <div style={{ position: 'absolute', top: 10, left: 10, zIndex: 1 }}>
1213
+ <button onClick={zoomIn}>Zoom In</button>
1214
+ <button onClick={zoomOut}>Zoom Out</button>
1215
+ <button onClick={flyTo}>Fly to Location</button>
198
1216
  </div>
199
1217
  );
200
- };
1218
+ }
1219
+
1220
+ function App() {
1221
+ return (
1222
+ <MapProvider>
1223
+ <Map
1224
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
1225
+ initialViewState={{
1226
+ longitude: 90.3938,
1227
+ latitude: 23.8216,
1228
+ zoom: 12
1229
+ }}
1230
+ style={{ width: '100%', height: '100vh' }}
1231
+ />
1232
+ <MapButtons />
1233
+ </MapProvider>
1234
+ );
1235
+ }
1236
+ ```
1237
+
1238
+ ---
201
1239
 
202
- // JSX Styles
203
- const containerStyles: React.CSSProperties = {
204
- width: "100%",
205
- height: "100vh",
206
- minHeight: "400px",
207
- overflow: "hidden",
208
- };
1240
+ ### useControl Hook
209
1241
 
210
- export default App;
1242
+ Create custom map controls.
1243
+
1244
+ #### Example
1245
+
1246
+ ```tsx
1247
+ import { Map, useControl } from 'react-bkoi-gl';
1248
+ import { useControl as useMapControl } from 'react-bkoi-gl';
1249
+ import "react-bkoi-gl/styles";
1250
+
1251
+ class CustomControl {
1252
+ onAdd(map) {
1253
+ this.map = map;
1254
+ this.container = document.createElement('div');
1255
+ this.container.className = 'custom-control';
1256
+ this.container.textContent = 'Custom Control';
1257
+ this.container.style.cssText = `
1258
+ background: white;
1259
+ padding: 10px;
1260
+ border-radius: 4px;
1261
+ box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
1262
+ `;
1263
+ return this.container;
1264
+ }
1265
+
1266
+ onRemove() {
1267
+ this.container.remove();
1268
+ }
1269
+ }
1270
+
1271
+ function CustomControlComponent() {
1272
+ useControl(() => new CustomControl(), { position: 'top-left' });
1273
+ return null;
1274
+ }
1275
+
1276
+ function App() {
1277
+ return (
1278
+ <Map
1279
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
1280
+ initialViewState={{
1281
+ longitude: 90.3938,
1282
+ latitude: 23.8216,
1283
+ zoom: 12
1284
+ }}
1285
+ style={{ width: '100%', height: '100vh' }}
1286
+ >
1287
+ <CustomControlComponent />
1288
+ </Map>
1289
+ );
1290
+ }
211
1291
  ```
212
1292
 
213
- ## Components
1293
+ ---
214
1294
 
215
- Here is a list of all available components in `react-bkoi-gl`:
216
-
217
- | Component | Description |
218
- |---------------------|-----------------------------------------------------------------------------|
219
- | `Map` | The core component for rendering a Barikoi map. Must be the parent of all other components. |
220
- | `Marker` | Displays a marker on the map at specified coordinates. |
221
- | `Popup` | Displays a popup with custom content at specified coordinates. |
222
- | `Layer` | Adds a custom layer to the map. |
223
- | `Source` | Defines a data source for the map. |
224
- | `NavigationControl` | Adds zoom and rotation controls. |
225
- | `FullscreenControl` | Adds a button to toggle fullscreen mode. |
226
- | `GeolocateControl` | Centers the map on the user's location. |
227
- | `ScaleControl` | Displays a scale bar. |
228
- | `TerrainControl` | Adds terrain control to the map. |
229
- | `useMap` | Custom hook for managing the map instance. |
230
- | `useControl` | Custom hook for managing map controls. |
231
-
232
- ## Get Barikoi API key
1295
+ ## Events
233
1296
 
234
- To access Barikoi's API services, you need to:
235
- 1. Register on [Barikoi Developer Dashboard](https://developer.barikoi.com/register).
236
- 2. Verify with your phone number.
237
- 3. Claim your API key.
1297
+ The Map component supports various event callbacks:
1298
+
1299
+ <details>
1300
+ <summary><strong>Available Events</strong></summary>
1301
+
1302
+ ### Mouse Events
1303
+ - `onClick` - Map click
1304
+ - `onDblClick` - Double click
1305
+ - `onMouseDown` - Mouse down
1306
+ - `onMouseUp` - Mouse up
1307
+ - `onMouseMove` - Mouse move
1308
+ - `onMouseEnter` - Mouse enter
1309
+ - `onMouseLeave` - Mouse leave
1310
+ - `onMouseOver` - Mouse over
1311
+ - `onMouseOut` - Mouse out
1312
+ - `onContextMenu` - Right click
1313
+
1314
+ ### Touch Events
1315
+ - `onTouchStart` - Touch start
1316
+ - `onTouchEnd` - Touch end
1317
+ - `onTouchMove` - Touch move
1318
+ - `onTouchCancel` - Touch cancel
1319
+
1320
+ ### Movement Events
1321
+ - `onMoveStart` - Movement start
1322
+ - `onMove` - Movement
1323
+ - `onMoveEnd` - Movement end
1324
+ - `onDragStart` - Drag start
1325
+ - `onDrag` - Drag
1326
+ - `onDragEnd` - Drag end
1327
+ - `onZoomStart` - Zoom start
1328
+ - `onZoom` - Zoom
1329
+ - `onZoomEnd` - Zoom end
1330
+ - `onRotateStart` - Rotation start
1331
+ - `onRotate` - Rotation
1332
+ - `onRotateEnd` - Rotation end
1333
+ - `onPitchStart` - Pitch start
1334
+ - `onPitch` - Pitch
1335
+ - `onPitchEnd` - Pitch end
1336
+
1337
+ ### Map State Events
1338
+ - `onLoad` - Map loaded
1339
+ - `onRender` - Frame rendered
1340
+ - `onIdle` - Map idle
1341
+ - `onError` - Error occurred
1342
+ - `onResize` - Map resized
1343
+ - `onRemove` - Map removed
1344
+ - `onData` - Data loaded
1345
+ - `onStyleData` - Style data loaded
1346
+ - `onSourceData` - Source data loaded
238
1347
 
239
- Once registered, you'll be able to access the full suite of Barikoi API services. If you exceed the free usage limits, you'll need to subscribe to a paid plan.
1348
+ </details>
240
1349
 
241
- ## Learning Resources
242
- * [Barikoi API Documentation](https://docs.barikoi.com/docs/maps-api)
1350
+ ### Event Example
1351
+
1352
+ ```tsx
1353
+ import { Map, Marker } from 'react-bkoi-gl';
1354
+ import "react-bkoi-gl/styles";
1355
+ import { useState } from 'react';
1356
+
1357
+ function EventExample() {
1358
+ const [center, setCenter] = useState({ lng: 90.3938, lat: 23.8216 });
1359
+
1360
+ const onClick = (e) => {
1361
+ console.log('Clicked at:', e.lngLat);
1362
+ setCenter({ lng: e.lngLat.lng, lat: e.lngLat.lat });
1363
+ };
1364
+
1365
+ const onMoveEnd = (e) => {
1366
+ console.log('Move ended, viewState:', e.viewState);
1367
+ };
1368
+
1369
+ const onLoad = (e) => {
1370
+ console.log('Map loaded!');
1371
+ };
1372
+
1373
+ return (
1374
+ <Map
1375
+ mapStyle={`https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`}
1376
+ initialViewState={{
1377
+ longitude: 90.3938,
1378
+ latitude: 23.8216,
1379
+ zoom: 12
1380
+ }}
1381
+ style={{ width: '100%', height: '100vh' }}
1382
+ onClick={onClick}
1383
+ onMoveEnd={onMoveEnd}
1384
+ onLoad={onLoad}
1385
+ >
1386
+ <Marker longitude={center.lng} latitude={center.lat} color="red" />
1387
+ </Map>
1388
+ );
1389
+ }
1390
+ ```
1391
+
1392
+ ---
1393
+
1394
+ ## MapRef Methods
1395
+
1396
+ Access the underlying map instance through the ref:
1397
+
1398
+ <details>
1399
+ <summary><strong>Available Methods</strong></summary>
1400
+
1401
+ ```tsx
1402
+ const mapRef = useRef<MapRef>(null);
1403
+
1404
+ // Get the underlying MapLibre instance
1405
+ const map = mapRef.current?.getMap();
1406
+
1407
+ // Common methods:
1408
+ map.getCenter() // Get map center
1409
+ map.getZoom() // Get zoom level
1410
+ map.getBearing() // Get bearing
1411
+ map.getPitch() // Get pitch
1412
+ map.getBounds() // Get bounds
1413
+
1414
+ map.setCenter([lng, lat]) // Set center
1415
+ map.setZoom(zoom) // Set zoom
1416
+ map.setBearing(bearing) // Set bearing
1417
+ map.setPitch(pitch) // Set pitch
1418
+
1419
+ map.flyTo(options) // Fly to location
1420
+ map.jumpTo(options) // Jump to location
1421
+ map.easeTo(options) // Ease to location
1422
+
1423
+ map.zoomIn() // Zoom in
1424
+ map.zoomOut() // Zoom out
1425
+
1426
+ map.resize() // Resize map
1427
+ map.remove() // Remove map
1428
+ ```
1429
+
1430
+ </details>
1431
+
1432
+ ---
1433
+
1434
+ ## Styling
1435
+
1436
+ The library uses MapLibre GL JS styles. Import the styles in your application:
1437
+
1438
+ ```tsx
1439
+ import "react-bkoi-gl/styles";
1440
+ ```
1441
+
1442
+ ### Available Map Styles
1443
+
1444
+ - `osm-liberty` - Default street style
1445
+ - `osm_barikoi_v2` - Barikoi street style
1446
+
1447
+ ```tsx
1448
+ const mapStyle = `https://map.barikoi.com/styles/osm-liberty/style.json?key=${API_KEY}`;
1449
+ const mapStyle = `https://map.barikoi.com/styles/osm_barikoi_v2/style.json?key=${API_KEY}`;
1450
+ ```
1451
+
1452
+ ---
1453
+
1454
+ ## TypeScript
1455
+
1456
+ Full TypeScript support is included. All types are exported:
1457
+
1458
+ ```tsx
1459
+ import type {
1460
+ MapProps,
1461
+ MapRef,
1462
+ MarkerProps,
1463
+ PopupProps,
1464
+ SourceProps,
1465
+ CanvasSourceProps,
1466
+ LayerProps,
1467
+ MapLayerMouseEvent,
1468
+ ViewStateChangeEvent,
1469
+ DrawControlProps,
1470
+ GlobeControlProps,
1471
+ MinimapControlOptions
1472
+ } from 'react-bkoi-gl';
1473
+ ```
1474
+
1475
+ ---
1476
+
1477
+ ## Documentation & Resources
1478
+
1479
+ - [Barikoi API Documentation](https://docs.barikoi.com/docs/maps-api)
1480
+ - [Barikoi Business API](https://docs.barikoi.com/api)
1481
+ - [MapLibre GL JS Docs](https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre/)
1482
+ - [Interactive Examples](https://docs.barikoi.com/examples)
1483
+
1484
+ ---
243
1485
 
244
1486
  ## License
245
- This library is licensed under the MIT License. See the [LICENSE](https://www.npmjs.com/package/LICENSE) file for details.
1487
+
1488
+ This library is licensed under the MIT License. See the [LICENSE](https://github.com/barikoi/react-bkoi-gl/blob/master/LICENSE) file for details.
246
1489
 
247
1490
  ## Support
248
- For any issues or questions, please contact [support@barikoi.com](mailto:support@barikoi.com).
1491
+
1492
+ For issues or questions, contact [support@barikoi.com](mailto:support@barikoi.com).
249
1493
 
250
1494
  <img src="https://docs.barikoi.com/img/barikoi-logo-black.svg" height="30" />