Leaflet Delivery Tracking Map
blocklogisticsLive order delivery route on free OpenStreetMap tiles — no API key. Courier position, dropoff destination, and ETA telemetry.
Installation
$pnpm dlx uipkge-ng@latest add leaflet-delivery-tracking-map$npx uipkge-ng@latest add leaflet-delivery-tracking-map$yarn dlx uipkge-ng@latest add leaflet-delivery-tracking-map$bunx uipkge-ng@latest add leaflet-delivery-tracking-mapManifest:
https://uipkge.dev/r/angular/leaflet-delivery-tracking-map.jsonInstalls to:src/app/components/blocks/leaflet-delivery-tracking-map/Variants
Loading interactive previews…
Loading interactive previews…
Includes
Files installed (2)
src/app/components/blocks/leaflet-delivery-tracking-map/leaflet-delivery-tracking-map.component.ts7 kB
// Live order delivery route on free OpenStreetMap tiles — no API key. Courier position, // dropoff destination, and ETA telemetry. Port of the React block 1:1. import { ChangeDetectionStrategy, Component, Input, ViewChild } from '@angular/core' import { cn } from '@/lib/utils' import { UiBadgeComponent } from '@/ui/badge/badge.component' import { UiButtonComponent } from '@/ui/button/button.component' import { UiCardComponent, UiCardContentComponent, UiCardDescriptionComponent, UiCardHeaderComponent, UiCardTitleComponent, } from '@/ui/card/card.component' import { UiLeafletMapComponent, UiLeafletMarkerComponent, UiLeafletPolylineComponent, } from '@/ui/leaflet-map/leaflet-map.component' const ORIGIN: [number, number] = [-122.4194, 37.7749] const DESTINATION: [number, number] = [-122.392, 37.7915] const COURIER_POSITION: [number, number] = [-122.405, 37.783] const ROUTE_COORDS: [number, number][] = [ [-122.4194, 37.7749], [-122.414, 37.778], [-122.405, 37.783], [-122.399, 37.787], [-122.392, 37.7915], ] @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-leaflet-delivery-tracking-map, [ui-leaflet-delivery-tracking-map]', standalone: true, imports: [ UiBadgeComponent, UiButtonComponent, UiCardComponent, UiCardContentComponent, UiCardDescriptionComponent, UiCardHeaderComponent, UiCardTitleComponent, UiLeafletMapComponent, UiLeafletMarkerComponent, UiLeafletPolylineComponent, ], host: { 'data-slot': 'leaflet-delivery-tracking-map', '[class]': 'hostClass', }, template: ` <div class="border-border bg-card relative h-[480px] overflow-hidden rounded-xl border"> <ui-leaflet-map variant="dark" [center]="courierPosition" [zoom]="13.5" class="h-full w-full"> <ui-leaflet-polyline [lngLatPath]="routeCoords" color="#2563eb" [weight]="4" lineCap="round" lineJoin="round" /> <!-- Restaurant / Merchant --> <ui-leaflet-marker [lngLat]="origin" anchor="bottom"> <div class="flex flex-col items-center"> <span class="bg-muted-foreground ring-muted size-3 rounded-full ring-4"></span> <span class="border-border bg-background/90 mt-1 rounded border px-1.5 py-0.5 font-mono text-xs"> Merchant </span> </div> </ui-leaflet-marker> <!-- Live Courier --> <ui-leaflet-marker [lngLat]="courierPosition" anchor="center"> <div class="relative flex cursor-pointer items-center justify-center" (click)="focusCourier()" (keydown.enter)="focusCourier()" (keydown.space)="focusCourierKey($event)" role="button" tabindex="0" aria-label="Track courier" > <span class="bg-primary/25 absolute size-7 animate-ping rounded-full"></span> <div class="bg-primary text-primary-foreground ring-background flex size-7 items-center justify-center rounded-full shadow-md ring-2" > 🛵 </div> </div> </ui-leaflet-marker> <!-- Destination --> <ui-leaflet-marker [lngLat]="destination" anchor="bottom"> <div class="flex cursor-pointer flex-col items-center" (click)="focusDestination()" (keydown.enter)="focusDestination()" (keydown.space)="focusDestinationKey($event)" role="button" tabindex="0" aria-label="Dropoff point" > <span class="bg-success ring-success/20 size-3 rounded-full ring-4"></span> <span class="border-border bg-background/90 text-success mt-1 rounded border px-1.5 py-0.5 font-mono text-xs font-semibold" > Delivery Dropoff </span> </div> </ui-leaflet-marker> </ui-leaflet-map> </div> <!-- Telemetry & Order Status --> <ui-card class="flex flex-col justify-between"> <ui-card-header> <div class="flex items-center justify-between"> <span ui-badge variant="outline" class="font-mono text-xs"> ORDER #8924 </span> <span ui-badge class="border-success/20 bg-success/10 text-success">Approaching</span> </div> <ui-card-title class="mt-2 text-lg">Express Courier</ui-card-title> <ui-card-description> Estimated delivery in <strong class="text-foreground">8 mins</strong> (0.8 mi away) </ui-card-description> </ui-card-header> <ui-card-content class="space-y-4"> <div class="border-border space-y-2 border-t pt-3"> <div class="flex items-center justify-between text-xs"> <span class="text-muted-foreground">Driver</span> <span class="text-foreground font-medium">Carlos M. (★ 4.98)</span> </div> <div class="flex items-center justify-between text-xs"> <span class="text-muted-foreground">Vehicle</span> <span class="text-foreground font-mono">E-Scooter #412</span> </div> <div class="flex items-center justify-between text-xs"> <span class="text-muted-foreground">Destination</span> <span class="text-foreground max-w-[170px] truncate font-medium">Market St & 2nd Ave</span> </div> </div> <div class="border-border space-y-1.5 border-t pt-3 font-mono text-xs"> <div class="text-muted-foreground flex items-center gap-2"> <span class="bg-success size-1.5 rounded-full"></span> <span>12:42 PM — Order picked up</span> </div> <div class="text-foreground flex items-center gap-2 font-medium"> <span class="bg-primary size-1.5 animate-pulse rounded-full"></span> <span>12:51 PM — Approaching building</span> </div> </div> <div class="flex gap-2 pt-2"> <button ui-button variant="outline" size="sm" class="flex-1" (click)="focusCourier()">Track Courier</button> <button ui-button variant="outline" size="sm" class="flex-1" (click)="focusDestination()"> Dropoff Point </button> </div> </ui-card-content> </ui-card> `, }) export class UiLeafletDeliveryTrackingMapComponent { @Input('class') className?: string @ViewChild(UiLeafletMapComponent) map?: UiLeafletMapComponent protected readonly origin = ORIGIN protected readonly destination = DESTINATION protected readonly courierPosition = COURIER_POSITION protected readonly routeCoords = ROUTE_COORDS get hostClass(): string { return cn('grid gap-4 lg:grid-cols-[1fr_320px]', this.className) } focusCourier(): void { this.map?.flyTo({ center: COURIER_POSITION, zoom: 14.5, duration: 800 }) } focusDestination(): void { this.map?.flyTo({ center: DESTINATION, zoom: 15, duration: 800 }) } focusCourierKey(e: KeyboardEvent): void { e.preventDefault() this.focusCourier() } focusDestinationKey(e: KeyboardEvent): void { e.preventDefault() this.focusDestination() } }src/app/components/blocks/leaflet-delivery-tracking-map/index.ts0.1 kB
export { UiLeafletDeliveryTrackingMapComponent } from './leaflet-delivery-tracking-map.component'
Raw manifest:https://uipkge.dev/r/angular/leaflet-delivery-tracking-map.json