This is the documentation of version 1.0.0-rc.2. Go to the latest version, 1.0.0-rc.5.
TomTom Maps for JavaScript
    Preparing search index...

    Class UserEventsWithStates<T>

    A named events scope of a module that draws its own data, with the UserEvents and event states of one part of what the module shows.

    The module's own setEventState, clearEventState, clearEventStates and getEventStates act on the features its show takes. A scope's act on its features alone, by the ids its handlers receive. For example, routing.events.waypoints acts on the waypoints, custom.events.<source> on one source. A UserEvents.where narrowing returns plain UserEvents, since a state belongs to a feature, not to a predicate over features.

    routing.events.waypoints.setEventState({ id: waypoint.id, state: 'click' });
    const { hover: hoveredStops = [] } = routing.events.waypoints.getEventStates();

    Type Parameters

    Hierarchy (View Summary)

    Index
    • Removes all event handlers for an event type.

      This stops further event notifications for that type. Clean up this way to prevent memory leaks and unwanted behaviour.

      Parameters

      • type: EventType

        The event type to stop listening for.

      Returns void

      It removes all handlers for the event type. To remove a single handler, call the unsubscribe function on returns. Other event types and other modules' handlers stay active. It also resets this module's cursor behaviour, and you can safely call it more than once, even when no handler exists.

      Always call it when a component unmounts, ideally from a framework lifecycle hook. Also use it to switch between interaction modes, to disable interactions temporarily, or to replace a handler by calling off() and then on(). Remove handlers before you remove features from the map.

      // Remove click handlers
      module.events.off('click');

      // Remove all handlers
      module.events.off('click');
      module.events.off('hover');
      module.events.off('long-hover');
      module.events.off('contextmenu');
      // React component cleanup, with `pois` from `await POIsModule.get(map)`
      useEffect(() => {
      pois.events.on('click', handlePoiClick);
      pois.events.on('hover', handlePoiHover);

      return () => {
      // Cleanup on unmount
      pois.events.off('click');
      pois.events.off('hover');
      };
      }, [pois]);
      // Replace handler
      module.events.off('click'); // Remove old handler
      module.events.on('click', newHandler); // Add new handler

      // Disable interactions temporarily
      const savedHandler = currentHandler;
      module.events.off('click'); // Disable
      // ... later ...
      module.events.on('click', savedHandler); // Re-enable
    • Registers a handler for user interactions with this module's features, such as clicking a POI or hovering over a route.

      Parameters

      • type: EventType

        The event type to listen for (click, contextmenu, hover, long-hover).

      • handler: UserEventHandler<T>

        The function called when the event occurs.

      Returns () => void

      An unsubscribe function that removes the handler registered by this call.

      The handler receives:

      • feature - The primary feature that triggered the event.
      • lngLat - The geographic coordinates [longitude, latitude] of the event.
      • features - This module's features at the event location, de-duplicated for overlapping features within the module. To inspect features across all modules, query map.mapLibreMap.queryRenderedFeatures(...) directly, as UserEventHandler shows.

      Note that:

      • Each on() adds a handler and does not replace existing ones, so all of them fire. To remove one, call the unsubscribe function this returns. To clear them all, use off(type).
      • Handlers survive map style changes.
      • The cursor changes to a pointer on hover.
      • Hidden features don't trigger events, since events respect module visibility.
      • Hover events use spatial indexing for fast lookup.
      • Long-hover has a configurable delay to prevent accidental triggers.
      • Keep handlers lightweight to maintain smooth interaction.
      // Basic click handler
      module.events.on('click', (feature, lngLat, features) => {
      console.log('Clicked feature:', feature.properties);
      console.log('Location:', lngLat);
      console.log('All features here:', features.length);
      });

      // Hover with tooltip
      module.events.on('hover', (feature) => {
      const name = feature.properties.name || 'Unnamed';
      tooltip.show(name);
      });

      // Long-hover for detailed preview
      module.events.on('long-hover', (feature) => {
      // Only triggered after hovering for 300-800ms
      loadPreview(feature.properties.id);
      });

      // Right-click context menu
      module.events.on('contextmenu', (feature, lngLat) => {
      showCustomMenu(lngLat, feature);
      });
      // Route-specific handlers
      const routing = await RoutingModule.create(map);

      // Handle route line clicks
      routing.events.mainLines.on('click', (route) => {
      highlightRoute(route.properties.index);
      showRouteSummary(route.properties.summary);
      });

      // Handle waypoint interactions
      routing.events.waypoints.on('hover', (waypoint) => {
      const index = waypoint.properties.index;
      showTooltip(`Stop ${index + 1}`);
      });
    • Narrows these events to part of what they cover, and returns a UserEvents over just that part.

      You can narrow in two ways. A feature predicate keeps only the features you care about. Every module offers it, since only the module's own data can tell a major incident from a minor one. A layer scope keeps only part of the map's layers. The SDK offers it where a stable, typed vocabulary for those layers exists, which today means BaseMapModule's layer groups.

      It returns a new instance rather than narrowing this one in place. Callers narrow events more than once, and mutating would make the second where() mean "first AND second". It would also leave the surface it came from silently scoped, with its config overridden.

      Narrowing on both axes takes one call, since BaseMapModule's scope object takes a features predicate alongside its layerGroups. A further where() does intersect with this one, but two feature predicates read better as a single a(f) && b(f).

      Parameters

      • scope: (feature: T) => boolean

        A predicate over this scope's feature type or, where the module supports one, a scope object such as { layerGroups }. See EventScope.

      • Optionalconfig: EventHandlerConfig

        The event configuration for handlers registered through the returned instance. Each scope can carry its own, which is how two parts of one module get different hover cursors. Defaults to the configuration this instance already uses.

      Returns UserEvents<T, never>

      // Feature scope: only major incidents are clickable.
      trafficIncidents.events.where((incident) => incident.properties.magnitudeOfDelay === 'major')
      .on('click', showIncidentDetails);

      // Layer scope with its own cursor, on the base map.
      baseMap.events
      .where({ layerGroups: { show: 'only', values: ['roadLabels'] } }, { cursorOnHover: 'pointer' })
      .on('click', showRoadName);

      // A named scope, narrowed by a predicate.
      routing.events.tunnels.where((section) => section.properties.routeState === 'selected')
      .on('click', showTunnel);