or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

carto.mdcore-engine.mdeffects.mdextensions.mdindex.mdjson-config.mdlayers.mdmap-integration.mdreact.mdviews.mdwidgets.md
tile.json

widgets.mddocs/

Widgets

Pre-built UI controls for common visualization interactions including zoom controls, compass navigation, fullscreen toggle, screenshot capture, and view reset functionality.

Capabilities

Widget Base Interface

All widgets implement a common interface for consistent behavior and integration.

interface Widget {
  /** Widget identifier */
  id: string;
  /** Widget placement on screen */
  placement: WidgetPlacement;
  /** Get widget DOM element */
  getElement(): HTMLElement;
  /** Set widget properties */
  setProps(props: any): void;
  /** Clean up widget resources */
  finalize(): void;
}

type WidgetPlacement = 
  | 'top-left'
  | 'top-right' 
  | 'bottom-left'
  | 'bottom-right'
  | 'fill';

ZoomWidget

Provides zoom in and zoom out controls for map navigation.

/**
 * Zoom control widget with in/out buttons
 * Provides standard zoom functionality for map views
 */
class ZoomWidget {
  constructor(props?: ZoomWidgetProps);
  /** Set widget properties */
  setProps(props: Partial<ZoomWidgetProps>): void;
  /** Clean up widget */
  finalize(): void;
}

interface ZoomWidgetProps {
  /** Unique widget identifier */
  id?: string;
  /** Widget placement position */
  placement?: WidgetPlacement;
  /** View ID for multi-view setups */
  viewId?: string;
  /** Custom CSS styles */
  style?: React.CSSProperties;
  /** Custom CSS class name */
  className?: string;
  /** Zoom in button label */
  zoomInLabel?: string;
  /** Zoom out button label */
  zoomOutLabel?: string;
  /** Transition duration for zoom animations */
  transitionDuration?: number;
  /** Zoom step size */
  zoomStep?: number;
}

Usage Example:

import { Deck, ZoomWidget } from "deck.gl";

const deck = new Deck({
  container: 'map-container',
  initialViewState: {
    longitude: -122.4,
    latitude: 37.8,
    zoom: 10
  },
  controller: true,
  layers: []
});

const zoomWidget = new ZoomWidget({
  placement: 'top-left',
  zoomInLabel: '+',
  zoomOutLabel: '-',
  transitionDuration: 200
});

// Add widget to deck
deck.setProps({
  widgets: [zoomWidget]
});

CompassWidget

Navigation compass showing current bearing with click-to-reset functionality.

/**
 * Compass navigation widget
 * Shows current bearing and provides click-to-reset functionality
 */
class CompassWidget {
  constructor(props?: CompassWidgetProps);
  /** Set widget properties */
  setProps(props: Partial<CompassWidgetProps>): void;
  /** Clean up widget */
  finalize(): void;
}

interface CompassWidgetProps {
  /** Unique widget identifier */
  id?: string;
  /** Widget placement position */
  placement?: WidgetPlacement;
  /** View ID for multi-view setups */
  viewId?: string;
  /** Custom CSS styles */
  style?: React.CSSProperties;
  /** Custom CSS class name */
  className?: string;
  /** Transition duration for bearing reset */
  transitionDuration?: number;
  /** Label for compass (accessibility) */
  label?: string;
}

FullscreenWidget

Toggle fullscreen mode for the visualization container.

/**
 * Fullscreen toggle widget
 * Enables entering and exiting fullscreen mode
 */
class FullscreenWidget {
  constructor(props?: FullscreenWidgetProps);
  /** Set widget properties */
  setProps(props: Partial<FullscreenWidgetProps>): void;
  /** Clean up widget */
  finalize(): void;
}

interface FullscreenWidgetProps {
  /** Unique widget identifier */
  id?: string;
  /** Widget placement position */
  placement?: WidgetPlacement;
  /** Custom CSS styles */
  style?: React.CSSProperties;
  /** Custom CSS class name */
  className?: string;
  /** Enter fullscreen button label */
  enterLabel?: string;
  /** Exit fullscreen button label */
  exitLabel?: string;
  /** Fullscreen container element */
  container?: HTMLElement;
}

ScreenshotWidget

Capture screenshots of the current visualization.

/**
 * Screenshot capture widget
 * Enables downloading visualization as image
 */
class ScreenshotWidget {
  constructor(props?: ScreenshotWidgetProps);
  /** Set widget properties */
  setProps(props: Partial<ScreenshotWidgetProps>): void;
  /** Clean up widget */
  finalize(): void;
}

interface ScreenshotWidgetProps {
  /** Unique widget identifier */
  id?: string;
  /** Widget placement position */
  placement?: WidgetPlacement;
  /** Custom CSS styles */
  style?: React.CSSProperties;
  /** Custom CSS class name */
  className?: string;
  /** Screenshot button label */
  label?: string;
  /** Image format for screenshot */
  format?: 'png' | 'jpeg';
  /** Image quality (0-1, for JPEG) */
  quality?: number;
  /** Filename for downloaded image */
  filename?: string;
}

ResetViewWidget

Reset the view to initial state or a predefined view state.

/**
 * View reset widget
 * Resets view to initial or specified state
 */
class ResetViewWidget {
  constructor(props?: ResetViewWidgetProps);
  /** Set widget properties */
  setProps(props: Partial<ResetViewWidgetProps>): void;
  /** Clean up widget */
  finalize(): void;
}

interface ResetViewWidgetProps {
  /** Unique widget identifier */
  id?: string;
  /** Widget placement position */
  placement?: WidgetPlacement;
  /** View ID for multi-view setups */
  viewId?: string;
  /** Custom CSS styles */
  style?: React.CSSProperties;
  /** Custom CSS class name */
  className?: string;
  /** Reset button label */
  label?: string;
  /** Transition duration for reset animation */
  transitionDuration?: number;
  /** Target view state (defaults to initial) */
  viewState?: ViewState;
}

Widget Integration

Basic Widget Setup

import { Deck, ZoomWidget, CompassWidget, FullscreenWidget } from "deck.gl";

const deck = new Deck({
  container: 'map-container',
  initialViewState: {
    longitude: -122.4,
    latitude: 37.8,
    zoom: 10
  },
  controller: true,
  layers: myLayers,
  
  // Add widgets
  widgets: [
    new ZoomWidget({
      id: 'zoom',
      placement: 'top-left'
    }),
    new CompassWidget({
      id: 'compass', 
      placement: 'top-right'
    }),
    new FullscreenWidget({
      id: 'fullscreen',
      placement: 'bottom-right'
    })
  ]
});

React Integration

Use widgets within React components:

import React from 'react';
import DeckGL, { ZoomWidget, CompassWidget } from '@deck.gl/react';

function MapWithWidgets() {
  return (
    <div style={{ position: 'relative', width: '100%', height: '600px' }}>
      <DeckGL
        initialViewState={{
          longitude: -122.4,
          latitude: 37.8,
          zoom: 10
        }}
        controller={true}
        layers={layers}
        style={{ width: '100%', height: '100%' }}
      />
      
      {/* React widget components */}
      <ZoomWidget placement="top-left" />
      <CompassWidget placement="top-right" />
    </div>
  );
}

Custom Widget Styling

Customize widget appearance with CSS:

const styledZoomWidget = new ZoomWidget({
  placement: 'top-left',
  className: 'custom-zoom-widget',
  style: {
    backgroundColor: 'rgba(0, 0, 0, 0.8)',
    borderRadius: '8px',
    padding: '8px'
  },
  zoomInLabel: '⬆',
  zoomOutLabel: '⬇'
});

Multi-View Widget Configuration

Configure widgets for specific views in multi-view setups:

import { Deck, MapView, OrbitView, ZoomWidget, CompassWidget } from "deck.gl";

const deck = new Deck({
  views: [
    new MapView({ id: 'map', x: '0%', width: '50%' }),
    new OrbitView({ id: 'orbit', x: '50%', width: '50%' })
  ],
  
  widgets: [
    // Zoom widget for map view only
    new ZoomWidget({
      id: 'map-zoom',
      placement: 'top-left',
      viewId: 'map'
    }),
    
    // Compass for both views
    new CompassWidget({
      id: 'map-compass',
      placement: 'top-right',
      viewId: 'map'
    }),
    new CompassWidget({
      id: 'orbit-compass', 
      placement: 'top-right',
      viewId: 'orbit'
    })
  ]
});

Widget Themes

Customize widget appearance with predefined themes:

interface WidgetTheme {
  /** Primary color */
  primary?: string;
  /** Secondary color */
  secondary?: string;
  /** Background color */
  background?: string;
  /** Text color */
  text?: string;
  /** Border radius */
  borderRadius?: string;
  /** Font family */
  fontFamily?: string;
  /** Font size */
  fontSize?: string;
}

/** Apply theme to all widgets */
function applyWidgetTheme(theme: WidgetTheme): void;

/** Built-in themes */
const WIDGET_THEMES: {
  light: WidgetTheme;
  dark: WidgetTheme;
  minimal: WidgetTheme;
};

Usage Example:

import { applyWidgetTheme, WIDGET_THEMES } from "deck.gl";

// Apply dark theme
applyWidgetTheme(WIDGET_THEMES.dark);

// Custom theme
applyWidgetTheme({
  primary: '#2196F3',
  secondary: '#FFC107',
  background: 'rgba(255, 255, 255, 0.9)',
  text: '#333333',
  borderRadius: '6px'
});

Advanced Widget Usage

Programmatic Widget Control

Control widgets programmatically:

const zoomWidget = new ZoomWidget({
  placement: 'top-left'
});

// Update widget properties
zoomWidget.setProps({
  zoomStep: 0.5,
  transitionDuration: 500
});

// Listen for widget events (if supported)
zoomWidget.on('zoom', (event) => {
  console.log('Zoom level changed:', event.zoom);
});

Custom Widget Implementation

Create custom widgets by implementing the Widget interface:

import { Widget } from "deck.gl";

class CustomInfoWidget implements Widget {
  id: string;
  placement: WidgetPlacement;
  private element: HTMLElement;
  
  constructor(props: CustomInfoWidgetProps) {
    this.id = props.id || 'info-widget';
    this.placement = props.placement || 'bottom-left';
    this.element = this.createElement(props);
  }
  
  private createElement(props: CustomInfoWidgetProps): HTMLElement {
    const div = document.createElement('div');
    div.className = 'custom-info-widget';
    div.innerHTML = `
      <div class="info-content">
        <h3>${props.title}</h3>
        <p>${props.content}</p>
      </div>
    `;
    return div;
  }
  
  getElement(): HTMLElement {
    return this.element;
  }
  
  setProps(props: Partial<CustomInfoWidgetProps>): void {
    if (props.title || props.content) {
      this.element.innerHTML = `
        <div class="info-content">
          <h3>${props.title}</h3>
          <p>${props.content}</p>
        </div>
      `;
    }
  }
  
  finalize(): void {
    this.element.remove();
  }
}

interface CustomInfoWidgetProps {
  id?: string;
  placement?: WidgetPlacement;
  title: string;
  content: string;
}

Widget Event Handling

Handle widget interactions and state changes:

const zoomWidget = new ZoomWidget({
  placement: 'top-left',
  onZoomIn: (viewState) => {
    console.log('Zooming in, new zoom:', viewState.zoom);
  },
  onZoomOut: (viewState) => {
    console.log('Zooming out, new zoom:', viewState.zoom);
  }
});

const compassWidget = new CompassWidget({
  placement: 'top-right',
  onReset: (viewState) => {
    console.log('Bearing reset, new bearing:', viewState.bearing);
  }
});