or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcontrols.mdevents.mdgeographic-utilities.mdindex.mdmap-core.mdui-components.md
tile.json

ui-components.mddocs/

UI Components

Interactive overlay components including markers and popups for displaying information and providing user interaction points on the map.

Capabilities

Marker Class

Point marker overlay that can display custom elements and bind popups for user interaction.

/**
 * Creates a new Marker instance
 * @param options - Configuration options for the marker
 */
class Marker extends Evented {
  constructor(options?: MarkerOptions);
  
  // Map management
  addTo(map: Map): Marker;
  remove(): Marker;
  
  // Position management
  setLngLat(lnglat: LngLatLike): Marker;
  getLngLat(): LngLat;
  
  // Styling and positioning
  setOffset(offset: PointLike): Marker;
  getOffset(): Point;
  setRotation(rotation: number): Marker;
  getRotation(): number;
  setAltitude(altitude: number): Marker;
  getAltitude(): number;
  
  // Alignment properties
  setRotationAlignment(alignment: 'auto' | 'map' | 'viewport' | 'horizon'): Marker;
  getRotationAlignment(): string;
  setPitchAlignment(alignment: 'auto' | 'map' | 'viewport'): Marker;
  getPitchAlignment(): string;
  
  // Occlusion handling
  setOccludedOpacity(opacity: number): Marker;
  getOccludedOpacity(): number;
  
  // Interaction
  setDraggable(draggable: boolean): Marker;
  isDraggable(): boolean;
  
  // CSS class management
  addClassName(className: string): Marker;
  removeClassName(className: string): Marker;
  toggleClassName(className: string): boolean;
  
  // Popup integration
  setPopup(popup?: Popup): Marker;
  getPopup(): Popup | undefined;
  togglePopup(): Marker;
  
  // DOM access
  getElement(): HTMLElement;
}

interface MarkerOptions {
  element?: HTMLElement;
  offset?: PointLike;
  anchor?: Anchor;
  color?: string;
  scale?: number;
  draggable?: boolean;
  clickTolerance?: number;
  rotation?: number;
  rotationAlignment?: 'map' | 'viewport' | 'auto';
  pitchAlignment?: 'map' | 'viewport' | 'auto';
  occludedOpacity?: number;
  className?: string;
  altitude?: number;
}

Usage Examples:

import mapboxgl from 'mapbox-gl';

// Basic marker
const marker = new mapboxgl.Marker()
  .setLngLat([-74.006, 40.7128])
  .addTo(map);

// Custom colored marker
const redMarker = new mapboxgl.Marker({ color: '#ff0000' })
  .setLngLat([-74.006, 40.7128])
  .addTo(map);

// Custom HTML element marker
const el = document.createElement('div');
el.className = 'custom-marker';
el.style.backgroundImage = 'url(marker-icon.png)';
el.style.width = '32px';
el.style.height = '32px';

const customMarker = new mapboxgl.Marker(el)
  .setLngLat([-74.006, 40.7128])
  .addTo(map);

// Draggable marker with event handling
const draggableMarker = new mapboxgl.Marker({ draggable: true })
  .setLngLat([-74.006, 40.7128])
  .addTo(map);

draggableMarker.on('dragend', () => {
  const lngLat = draggableMarker.getLngLat();
  console.log(`Marker moved to: ${lngLat.lng}, ${lngLat.lat}`);
});

// Marker with popup
const popup = new mapboxgl.Popup({ offset: 25 })
  .setHTML('<h3>Hello World!</h3><p>This is a popup.</p>');

const markerWithPopup = new mapboxgl.Marker()
  .setLngLat([-74.006, 40.7128])
  .setPopup(popup)
  .addTo(map);

Popup Class

Information popup overlay with HTML content that can be attached to markers or displayed at specific coordinates.

/**
 * Creates a new Popup instance
 * @param options - Configuration options for the popup
 */
class Popup extends Evented {
  constructor(options?: PopupOptions);
  
  // Map management
  addTo(map: Map): Popup;
  remove(): Popup;
  
  // State management
  isOpen(): boolean;
  
  // Position management
  setLngLat(lnglat: LngLatLike): Popup;
  getLngLat(): LngLat | undefined;
  setAltitude(altitude: number): Popup;
  getAltitude(): number;
  trackPointer(): Popup;
  
  // Content management
  setHTML(html: string): Popup;
  setText(text: string): Popup;
  setDOMContent(htmlNode: Node): Popup;
  
  // Styling and positioning
  setOffset(offset: Offset): Popup;
  setMaxWidth(maxWidth: string): Popup;
  getMaxWidth(): string | undefined;
  
  // CSS class management
  addClassName(className: string): Popup;
  removeClassName(className: string): Popup;
  toggleClassName(className: string): Popup;
}

interface PopupOptions {
  closeButton?: boolean;
  closeOnClick?: boolean;
  closeOnMove?: boolean;
  focusAfterOpen?: boolean;
  anchor?: Anchor;
  offset?: Offset;
  className?: string;
  maxWidth?: string;
  altitude?: number;
}

type Offset = number | PointLike | Partial<Record<Anchor, PointLike>>;

Usage Examples:

import mapboxgl from 'mapbox-gl';

// Basic popup
const popup = new mapboxgl.Popup()
  .setLngLat([-74.006, 40.7128])
  .setHTML('<h3>New York City</h3><p>The most populous city in the United States.</p>')
  .addTo(map);

// Popup with custom styling
const styledPopup = new mapboxgl.Popup({
  closeButton: false,
  closeOnClick: false,
  className: 'custom-popup',
  maxWidth: '300px',
  offset: 25
})
  .setLngLat([-74.006, 40.7128])
  .setHTML('<div class="popup-content"><h3>Custom Popup</h3></div>')
  .addTo(map);

// Popup with DOM content
const contentDiv = document.createElement('div');
contentDiv.innerHTML = '<h3>Dynamic Content</h3><button onclick="handleClick()">Click Me</button>';

const domPopup = new mapboxgl.Popup()
  .setLngLat([-74.006, 40.7128])
  .setDOMContent(contentDiv)
  .addTo(map);

// Popup that appears on map click
map.on('click', (e) => {
  new mapboxgl.Popup()
    .setLngLat(e.lngLat)
    .setHTML(`<h3>Clicked Location</h3><p>Coordinates: ${e.lngLat.lng.toFixed(4)}, ${e.lngLat.lat.toFixed(4)}</p>`)
    .addTo(map);
});

// Popup with conditional anchor positioning
const smartPopup = new mapboxgl.Popup({
  offset: {
    'top': [0, 0],
    'top-left': [0, 0],
    'top-right': [0, 0],
    'bottom': [0, -40],
    'bottom-left': [25, -40],
    'bottom-right': [-25, -40],
    'left': [25, -20],
    'right': [-25, -20]
  }
})
  .setLngLat([-74.006, 40.7128])
  .setHTML('<h3>Smart Positioned Popup</h3>')
  .addTo(map);

Event Handling

Both Marker and Popup classes extend Evented and support event listeners for user interactions.

// Marker events
interface MarkerEvents {
  'dragstart': void;
  'drag': void; 
  'dragend': void;
}

// Popup events  
interface PopupEvents {
  'open': void;
  'close': void;
}

Usage Examples:

// Marker event handling
const marker = new mapboxgl.Marker({ draggable: true })
  .setLngLat([-74.006, 40.7128])
  .addTo(map);

marker.on('dragstart', () => {
  console.log('Marker drag started');
});

marker.on('drag', () => {
  console.log('Marker is being dragged');
});

marker.on('dragend', () => {
  const lngLat = marker.getLngLat();
  console.log(`Marker drag ended at: ${lngLat.lng}, ${lngLat.lat}`);
});

// Popup event handling
const popup = new mapboxgl.Popup()
  .setLngLat([-74.006, 40.7128])
  .setHTML('<h3>Event Popup</h3>')
  .addTo(map);

popup.on('open', () => {
  console.log('Popup opened');
});

popup.on('close', () => {
  console.log('Popup closed');
});

Advanced Usage Patterns

Dynamic Marker Management

// Create a marker manager for handling multiple markers
class MarkerManager {
  private markers: Map<string, mapboxgl.Marker> = new Map();
  
  addMarker(id: string, lngLat: [number, number], options?: MarkerOptions) {
    if (this.markers.has(id)) {
      this.removeMarker(id);
    }
    
    const marker = new mapboxgl.Marker(options)
      .setLngLat(lngLat)
      .addTo(map);
      
    this.markers.set(id, marker);
    return marker;
  }
  
  removeMarker(id: string) {
    const marker = this.markers.get(id);
    if (marker) {
      marker.remove();
      this.markers.delete(id);
    }
  }
  
  clearAll() {
    this.markers.forEach(marker => marker.remove());
    this.markers.clear();
  }
}

const markerManager = new MarkerManager();

Interactive Popup Content

// Create popups with interactive content
function createInteractivePopup(feature: any) {
  const popup = new mapboxgl.Popup({ offset: 25 });
  
  // Create interactive content
  const content = document.createElement('div');
  content.className = 'interactive-popup';
  
  const title = document.createElement('h3');
  title.textContent = feature.properties.name;
  content.appendChild(title);
  
  const button = document.createElement('button');
  button.textContent = 'View Details';
  button.onclick = () => {
    // Handle button click
    showDetails(feature.properties.id);
    popup.remove();
  };
  content.appendChild(button);
  
  return popup.setDOMContent(content);
}

Types

// Anchor positioning for popups and markers
type Anchor = 
  | 'center' 
  | 'top' 
  | 'bottom' 
  | 'left' 
  | 'right' 
  | 'top-left' 
  | 'top-right' 
  | 'bottom-left' 
  | 'bottom-right';

// Point-like coordinate representation
type PointLike = Point | [number, number];

// Geographic coordinate representation
type LngLatLike = LngLat | [number, number] | { lng: number; lat: number } | { lon: number; lat: number };