@object-ui/plugin-map 2.0.0 → 3.0.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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +20 -0
- package/dist/index.css +1 -1
- package/dist/index.js +948 -919
- package/dist/index.umd.cjs +77 -77
- package/dist/{maplibre-gl-CNsW26De.js → maplibre-gl-DSpYxujd.js} +7994 -7981
- package/dist/src/ObjectMap.d.ts +1 -0
- package/dist/src/ObjectMap.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/ObjectMap.tsx +61 -10
package/dist/src/ObjectMap.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectMap.d.ts","sourceRoot":"","sources":["../../src/ObjectMap.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ObjectMap.d.ts","sourceRoot":"","sources":["../../src/ObjectMap.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;AAM/E,OAAO,kCAAkC,CAAC;AAY1C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAClC;AAsKD,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAsT9C,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-map",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Map visualization plugin for Object UI",
|
|
@@ -24,24 +24,24 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@objectstack/spec": "^
|
|
27
|
+
"@objectstack/spec": "^3.0.2",
|
|
28
28
|
"lucide-react": "^0.563.0",
|
|
29
|
-
"maplibre-gl": "^5.
|
|
29
|
+
"maplibre-gl": "^5.18.0",
|
|
30
30
|
"react-map-gl": "^8.1.0",
|
|
31
31
|
"zod": "^4.3.6",
|
|
32
|
-
"@object-ui/components": "
|
|
33
|
-
"@object-ui/
|
|
34
|
-
"@object-ui/
|
|
35
|
-
"@object-ui/types": "
|
|
32
|
+
"@object-ui/components": "3.0.0",
|
|
33
|
+
"@object-ui/react": "3.0.0",
|
|
34
|
+
"@object-ui/core": "3.0.0",
|
|
35
|
+
"@object-ui/types": "3.0.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": "^18.0.0 || ^19.0.0",
|
|
39
39
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@types/react": "
|
|
43
|
-
"@types/react-dom": "
|
|
44
|
-
"@vitejs/plugin-react": "^5.1.
|
|
42
|
+
"@types/react": "19.2.13",
|
|
43
|
+
"@types/react-dom": "19.2.3",
|
|
44
|
+
"@vitejs/plugin-react": "^5.1.4",
|
|
45
45
|
"typescript": "^5.9.3",
|
|
46
46
|
"vite": "^7.3.1",
|
|
47
47
|
"vite-plugin-dts": "^4.5.4"
|
package/src/ObjectMap.tsx
CHANGED
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
import React, { useEffect, useState, useMemo } from 'react';
|
|
24
24
|
import type { ObjectGridSchema, DataSource, ViewData } from '@object-ui/types';
|
|
25
|
+
import { useNavigationOverlay } from '@object-ui/react';
|
|
26
|
+
import { NavigationOverlay } from '@object-ui/components';
|
|
25
27
|
import { z } from 'zod';
|
|
26
28
|
import Map, { NavigationControl, Marker, Popup } from 'react-map-gl/maplibre';
|
|
27
29
|
import maplibregl from 'maplibre-gl';
|
|
@@ -42,6 +44,7 @@ export interface ObjectMapProps {
|
|
|
42
44
|
dataSource?: DataSource;
|
|
43
45
|
className?: string;
|
|
44
46
|
onMarkerClick?: (record: any) => void;
|
|
47
|
+
onRowClick?: (record: any) => void;
|
|
45
48
|
onEdit?: (record: any) => void;
|
|
46
49
|
onDelete?: (record: any) => void;
|
|
47
50
|
}
|
|
@@ -215,6 +218,7 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
215
218
|
dataSource,
|
|
216
219
|
className,
|
|
217
220
|
onMarkerClick,
|
|
221
|
+
onRowClick,
|
|
218
222
|
onEdit,
|
|
219
223
|
onDelete,
|
|
220
224
|
...rest
|
|
@@ -224,6 +228,7 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
224
228
|
const [error, setError] = useState<Error | null>(null);
|
|
225
229
|
const [objectSchema, setObjectSchema] = useState<any>(null);
|
|
226
230
|
const [selectedMarkerId, setSelectedMarkerId] = useState<string | null>(null);
|
|
231
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
227
232
|
|
|
228
233
|
const rawDataConfig = getDataConfig(schema);
|
|
229
234
|
// Memoize dataConfig using deep comparison to prevent infinite loops
|
|
@@ -283,8 +288,8 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
283
288
|
} else if (result && typeof result === 'object') {
|
|
284
289
|
if (Array.isArray((result as any).data)) {
|
|
285
290
|
items = (result as any).data;
|
|
286
|
-
} else if (Array.isArray((result as any).
|
|
287
|
-
items = (result as any).
|
|
291
|
+
} else if (Array.isArray((result as any).records)) {
|
|
292
|
+
items = (result as any).records;
|
|
288
293
|
}
|
|
289
294
|
}
|
|
290
295
|
setData(items);
|
|
@@ -365,9 +370,24 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
365
370
|
markers.find(m => m.id === selectedMarkerId),
|
|
366
371
|
[markers, selectedMarkerId]);
|
|
367
372
|
|
|
373
|
+
const navigation = useNavigationOverlay({
|
|
374
|
+
navigation: (schema as any).navigation,
|
|
375
|
+
objectName: schema.objectName,
|
|
376
|
+
onRowClick,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
const filteredMarkers = useMemo(() => {
|
|
380
|
+
if (!searchQuery.trim()) return markers;
|
|
381
|
+
const q = searchQuery.toLowerCase();
|
|
382
|
+
return markers.filter(m =>
|
|
383
|
+
m.title?.toLowerCase().includes(q) ||
|
|
384
|
+
m.description?.toLowerCase().includes(q)
|
|
385
|
+
);
|
|
386
|
+
}, [markers, searchQuery]);
|
|
387
|
+
|
|
368
388
|
// Calculate map bounds
|
|
369
389
|
const initialViewState = useMemo(() => {
|
|
370
|
-
if (!
|
|
390
|
+
if (!filteredMarkers.length) {
|
|
371
391
|
return {
|
|
372
392
|
longitude: mapConfig.center?.[1] || 0,
|
|
373
393
|
latitude: mapConfig.center?.[0] || 0,
|
|
@@ -376,8 +396,8 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
376
396
|
}
|
|
377
397
|
|
|
378
398
|
// Simple bounds calculation
|
|
379
|
-
const lngs =
|
|
380
|
-
const lats =
|
|
399
|
+
const lngs = filteredMarkers.map(m => m.coordinates[0]);
|
|
400
|
+
const lats = filteredMarkers.map(m => m.coordinates[1]);
|
|
381
401
|
|
|
382
402
|
const minLng = Math.min(...lngs);
|
|
383
403
|
const maxLng = Math.max(...lngs);
|
|
@@ -389,7 +409,7 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
389
409
|
latitude: (minLat + maxLat) / 2,
|
|
390
410
|
zoom: mapConfig.zoom || 3, // Auto-zoom logic could be improved here
|
|
391
411
|
};
|
|
392
|
-
}, [
|
|
412
|
+
}, [filteredMarkers, mapConfig]);
|
|
393
413
|
|
|
394
414
|
if (loading) {
|
|
395
415
|
return (
|
|
@@ -418,15 +438,29 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
418
438
|
{`${invalidCount} record${invalidCount !== 1 ? 's' : ''} with missing or invalid coordinates excluded from the map.`}
|
|
419
439
|
</div>
|
|
420
440
|
)}
|
|
421
|
-
|
|
441
|
+
{markers.length > 0 && (
|
|
442
|
+
<div className="mb-2">
|
|
443
|
+
<input
|
|
444
|
+
type="text"
|
|
445
|
+
value={searchQuery}
|
|
446
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
447
|
+
placeholder="Search locations…"
|
|
448
|
+
className="w-full px-3 py-2 text-sm border rounded-md bg-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
|
449
|
+
/>
|
|
450
|
+
</div>
|
|
451
|
+
)}
|
|
452
|
+
<div className="relative border rounded-lg overflow-hidden bg-muted h-[300px] sm:h-[400px] md:h-[500px] lg:h-[600px] w-full">
|
|
422
453
|
<Map
|
|
423
454
|
initialViewState={initialViewState}
|
|
424
455
|
style={{ width: '100%', height: '100%' }}
|
|
425
456
|
mapStyle="https://demotiles.maplibre.org/style.json"
|
|
457
|
+
touchZoomRotate={true}
|
|
458
|
+
dragRotate={true}
|
|
459
|
+
touchPitch={true}
|
|
426
460
|
>
|
|
427
|
-
<NavigationControl position="top-right" />
|
|
461
|
+
<NavigationControl position="top-right" showCompass={true} showZoom={true} />
|
|
428
462
|
|
|
429
|
-
{
|
|
463
|
+
{filteredMarkers.map(marker => (
|
|
430
464
|
<Marker
|
|
431
465
|
key={marker.id}
|
|
432
466
|
longitude={marker.coordinates[0]}
|
|
@@ -435,6 +469,7 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
435
469
|
onClick={(e) => {
|
|
436
470
|
e.originalEvent.stopPropagation();
|
|
437
471
|
setSelectedMarkerId(marker.id);
|
|
472
|
+
navigation.handleClick(marker.data);
|
|
438
473
|
onMarkerClick?.(marker.data);
|
|
439
474
|
}}
|
|
440
475
|
>
|
|
@@ -452,7 +487,7 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
452
487
|
onClose={() => setSelectedMarkerId(null)}
|
|
453
488
|
closeOnClick={false}
|
|
454
489
|
>
|
|
455
|
-
<div className="p-2 min-w-[200px]">
|
|
490
|
+
<div className="p-2 min-w-[150px] sm:min-w-[200px]">
|
|
456
491
|
<h3 className="font-bold text-sm mb-1">{selectedMarker.title}</h3>
|
|
457
492
|
{selectedMarker.description && (
|
|
458
493
|
<p className="text-xs text-muted-foreground">{selectedMarker.description}</p>
|
|
@@ -470,6 +505,22 @@ export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
|
470
505
|
)}
|
|
471
506
|
</Map>
|
|
472
507
|
</div>
|
|
508
|
+
{navigation.isOverlay && (
|
|
509
|
+
<NavigationOverlay {...navigation} title="Location Details">
|
|
510
|
+
{(record) => (
|
|
511
|
+
<div className="space-y-3">
|
|
512
|
+
{Object.entries(record).map(([key, value]) => (
|
|
513
|
+
<div key={key} className="flex flex-col">
|
|
514
|
+
<span className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
515
|
+
{key.replace(/_/g, ' ')}
|
|
516
|
+
</span>
|
|
517
|
+
<span className="text-sm">{String(value ?? '—')}</span>
|
|
518
|
+
</div>
|
|
519
|
+
))}
|
|
520
|
+
</div>
|
|
521
|
+
)}
|
|
522
|
+
</NavigationOverlay>
|
|
523
|
+
)}
|
|
473
524
|
</div>
|
|
474
525
|
);
|
|
475
526
|
};
|