
3D Extruded Buildings & Urban Footprints
Real-world 3D building extrusions with dynamic sunlight shadows, terrain DEM elevations, and pitch/bearing camera controls.
Live fleet map on free OpenStreetMap/Esri tiles — no API key. Select a unit to fly the camera and read status.
Also available for Vue ->$pnpm dlx shadcn@latest add https://uipkge.dev/r/react/leaflet-fleet-vehicle-map.json$npx shadcn@latest add https://uipkge.dev/r/react/leaflet-fleet-vehicle-map.json$yarn dlx shadcn@latest add https://uipkge.dev/r/react/leaflet-fleet-vehicle-map.json$bunx shadcn@latest add https://uipkge.dev/r/react/leaflet-fleet-vehicle-map.jsonnpx shadcn@latest add @uipkge-react/leaflet-fleet-vehicle-mapInstalls to:components/blocks/| Name | Type / Values | Default | Required |
|---|---|---|---|
vehicles | FleetVehicle[] | — | optional |
Type aliases exported from this item's source. Use these to shape the data you pass in.
FleetVehicleinterface FleetVehicle {
id: string
identifier: string
model: string
driver: string
status: VehicleStatus
speed: number
lat: number
lng: number
}'use client'
import * as React from 'react'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { LeafletMap, LeafletMarker, type LeafletMapRef } from '@/components/ui/leaflet-map'
export type VehicleStatus = 'moving' | 'idling' | 'parked'
export interface FleetVehicle {
id: string
identifier: string
model: string
driver: string
status: VehicleStatus
speed: number
lat: number
lng: number
}
export interface LeafletFleetVehicleMapProps extends React.HTMLAttributes<HTMLDivElement> {
vehicles?: FleetVehicle[]
}
const DEFAULT_VEHICLES: FleetVehicle[] = [
{
id: 'v-104',
identifier: 'Truck #104',
model: 'Volvo VNL 860',
driver: 'Marcus Vance',
status: 'moving',
speed: 64,
lat: 41.5868,
lng: -93.625,
},
{
id: 'v-208',
identifier: 'Van #208',
model: 'Ford E-Transit 350',
driver: 'Elena Rostova',
status: 'moving',
speed: 48,
lat: 41.6005,
lng: -93.712,
},
{
id: 'v-109',
identifier: 'Truck #109',
model: 'Freightliner Cascadia',
driver: 'Derrick Hayes',
status: 'idling',
speed: 0,
lat: 41.984,
lng: -93.582,
},
{
id: 'v-212',
identifier: 'Van #212',
model: 'Mercedes Sprinter',
driver: 'Aaliyah Patel',
status: 'moving',
speed: 52,
lat: 41.591,
lng: -93.604,
},
]
function statusVariant(status: VehicleStatus) {
if (status === 'moving') return 'info' as const
if (status === 'idling') return 'warning' as const
return 'secondary' as const
}
export function LeafletFleetVehicleMap({
className,
vehicles = DEFAULT_VEHICLES,
...props
}: LeafletFleetVehicleMapProps) {
const [selectedId, setSelectedId] = React.useState(vehicles[0]?.id ?? '')
const mapRef = React.useRef<LeafletMapRef>(null)
const selected = vehicles.find((v) => v.id === selectedId) ?? vehicles[0]
const selectVehicle = (vehicle: FleetVehicle) => {
setSelectedId(vehicle.id)
mapRef.current?.flyTo?.({
center: [vehicle.lng, vehicle.lat],
zoom: 12,
duration: 800,
})
}
return (
<div
data-slot="leaflet-fleet-vehicle-map"
className={cn('flex h-full min-h-0 flex-col gap-4', className)}
{...props}
>
<div className="flex flex-wrap items-center justify-between gap-3">
<h2 className="text-foreground text-lg font-semibold tracking-tight">Fleet</h2>
<p className="text-muted-foreground text-xs">{vehicles.length} units</p>
</div>
<div className="grid min-h-0 flex-1 grid-cols-1 gap-4 lg:grid-cols-12">
<Card className="border-border flex min-h-0 flex-col overflow-hidden shadow-xs lg:col-span-8">
<div className="relative min-h-[360px] flex-1 overflow-hidden">
<LeafletMap
ref={mapRef}
variant="dark"
center={selected ? [selected.lng, selected.lat] : [-93.625, 41.59]}
zoom={11}
className="absolute inset-0 size-full"
>
{vehicles.map((vehicle) => (
<LeafletMarker key={vehicle.id} lngLat={[vehicle.lng, vehicle.lat]} anchor="center">
<button
type="button"
className={
selectedId === vehicle.id
? 'border-primary bg-primary text-primary-foreground rounded-full border px-2 py-0.5 font-mono text-xs font-semibold shadow-xs'
: 'border-border bg-card text-foreground rounded-full border px-2 py-0.5 font-mono text-xs font-semibold shadow-xs'
}
onClick={() => selectVehicle(vehicle)}
>
{vehicle.identifier.replace('Truck ', '').replace('Van ', '')}
</button>
</LeafletMarker>
))}
</LeafletMap>
</div>
</Card>
<Card className="border-border flex min-h-0 flex-col overflow-hidden shadow-xs lg:col-span-4">
<CardHeader className="border-border border-b p-4">
<CardTitle className="text-sm font-semibold">Vehicles</CardTitle>
</CardHeader>
<CardContent className="divide-border min-h-0 flex-1 divide-y overflow-auto p-0">
{vehicles.map((vehicle) => (
<button
key={vehicle.id}
type="button"
className={cn(
'hover:bg-accent/50 flex w-full items-center justify-between gap-3 px-4 py-3 text-left transition-colors',
selectedId === vehicle.id && 'bg-accent/60',
)}
onClick={() => selectVehicle(vehicle)}
>
<div className="min-w-0">
<p className="text-foreground truncate text-sm font-medium">{vehicle.identifier}</p>
<p className="text-muted-foreground truncate text-xs">
{vehicle.driver} · {vehicle.model}
</p>
</div>
<Badge variant={statusVariant(vehicle.status)} className="shrink-0 text-xs capitalize">
{vehicle.status === 'moving' ? `${vehicle.speed} mph` : vehicle.status}
</Badge>
</button>
))}
</CardContent>
</Card>
</div>
</div>
)
}
export default LeafletFleetVehicleMap
Raw manifest:https://uipkge.dev/r/react/leaflet-fleet-vehicle-map.json