Map Component

Display interactive maps with custom markers and popups

Map Component

Overview

The Map component creates an interactive map interface using Mapbox, supporting custom markers, popups, and view controls. It's perfect for displaying location-based data, routes, or geographic information.

Usage

To use the Map component in your tool handler, follow these steps:

  1. Import the MapUIBuilder and DainResponse from the @dainprotocol/utils package:
import { MapUIBuilder, DainResponse } from "@dainprotocol/utils";
  1. Create a MapUIBuilder instance and configure it:
const mapUI = new MapUIBuilder()
  .setInitialView(40.7128, -74.0060, 11)  // Mandatory: lat, lng, zoom
  .addMarker({                            // Optional
    latitude: 40.7128,
    longitude: -74.0060,
    text: "🗽",
    title: "New York City",
    description: "The Big Apple"
  })
  .setMapStyle("mapbox://styles/mapbox/streets-v12")  // Optional
  .setZoomRange(9, 18)                    // Optional: min, max zoom
  .build();
  1. Return the MapUIBuilder instance in a DainResponse object:
return new DainResponse({
  text: "Generated map view",
  data: { /* Your data */ },
  ui: mapUI
});

Configuration

Mandatory Props

  • initialView: Object containing:
    • latitude (number): Initial center latitude
    • longitude (number): Initial center longitude
    • zoom (number): Initial zoom level

Optional Props

  • markers (MapMarker[]): Array of map markers
  • mapStyle (string): Mapbox style URL
  • maxZoom (number): Maximum zoom level
  • minZoom (number): Minimum zoom level

MapMarker Interface

Each marker is defined using this interface:

interface MapMarker {
    latitude: number;       // Mandatory: marker latitude
    longitude: number;      // Mandatory: marker longitude
    text: string;          // Mandatory: emoji or text for marker
    title?: string;        // Optional: popup title
    description?: string;  // Optional: popup description
}

Actions

The Map component supports marker click actions:

mapUI.onMarkerClick({
  tool: "locationViewer",
  params: {
    // Predefined parameters
    source: "map"
  },
  paramSchema: {
    source: { type: "string" }
  }
});

Action Arguments

  • tool (string): The name of the tool to be called when a marker is clicked
  • params (object): Pre-defined parameters that will be included with the action:
    • These values are set at build time
    • Will be passed to the tool when a marker is clicked

Examples

Basic Location Map

const basicMap = new MapUIBuilder()
  .setInitialView(51.5074, -0.1278, 13)
  .addMarker({
    latitude: 51.5074,
    longitude: -0.1278,
    text: "📍",
    title: "London",
    description: "Capital of England"
  })
  .build();

return new DainResponse({
  text: "London Map",
  data: {},
  ui: basicMap
});

Multiple Points of Interest

const poiMap = new MapUIBuilder()
  .setInitialView(48.8566, 2.3522, 12)
  .setMapStyle("mapbox://styles/mapbox/light-v11")
  .setZoomRange(10, 16)
  .addMarkers([
    {
      latitude: 48.8584,
      longitude: 2.2945,
      text: "🗼",
      title: "Eiffel Tower"
    },
    {
      latitude: 48.8606,
      longitude: 2.3376,
      text: "🏛️",
      title: "Louvre Museum"
    }
  ])
  .onMarkerClick({
    tool: "poiViewer",
    params: {
      city: "paris"
    }
  })
  .build();

return new DainResponse({
  text: "Paris Attractions",
  data: {},
  ui: poiMap
});

Interactive Store Locations

const storeMap = new MapUIBuilder()
  .setInitialView(34.0522, -118.2437, 10)
  .setMapStyle("mapbox://styles/mapbox/streets-v12")
  .setZoomRange(8, 18)
  .addMarkers(storeLocations.map(store => ({
    latitude: store.lat,
    longitude: store.lng,
    text: "🏪",
    title: store.name,
    description: `Open: ${store.hours}`
  })))
  .onMarkerClick({
    tool: "storeDetails",
    params: {
      view: "full"
    }
  })
  .build();

return new DainResponse({
  text: "Store Locations",
  data: {},
  ui: storeMap
});