npm package: @htmlbricks/hb-map
Description: Interactive map: `center`, `zoom`, `source` (OSM or CARTO vector styles), `options` (e.g. `centerFromGeometries`, marker text layout), and `data` with markers (lng/lat, icon, popup HTML, text). CARTO vector uses `source.style` in light mode; in dark mode 
Latest version: 0.71.18

# hb-map

## Description

Interactive map: `center`, `zoom`, `source` (OSM or CARTO vector styles), `options` (e.g. `centerFromGeometries`, marker text layout), and `data` with markers (lng/lat, icon, popup HTML, text). For CARTO vector (`source.type: "carto_vector"`), `source.style` (`positron`, `dark_matter`, `voyager`) applies when the page is in a **light** color scheme. When the map detects a **dark** scheme (`data-theme="dark"` / `.theme-dark` on `hb-map`, `html`, or `body`, or `prefers-color-scheme: dark`), the vector basemap always uses the **dark_matter** palette regardless of `style`. Set `boundaries_only` to `true` to draw only administrative boundaries. Set `national_boundaries_only` to `true` to hide internal regional boundaries and keep only OSM `admin_level` 2 (country borders); those lines are drawn solid, while other levels stay dashed when they are shown. In serialized `source` JSON, `yes` / `no` strings are still accepted for those flags. Only country names (`place` layer, `class: country`) are drawn from vector labels — no cities, regions, or provinces. Optionally set `boundary_admin_levels` to a JSON array string such as `"[2,4]"` to filter levels; with `national_boundaries_only`, the effective set is the intersection with level 2. OSM basemap tiles use a dark (inverted) treatment when the page is dark: `data-theme="dark"` or `.theme-dark` on `hb-map`, `html`, or `body` (checked in that order), else when `prefers-color-scheme: dark`. Set `screenshot` to capture; emits map clicks, marker clicks, and screenshot payloads.

## Types

```typescript
export type Component = {
  id?: string;
  style?: string;
  zoom: number;
  center: number[];
  data: {
    marker?: {
      lngLat: number[];
      icon?: {
        uri: string;
        scale?: number;
        anchor?: number[];
        opacity?: number;
        color?: string;
      };
      id?: string;
      popupHtml?: string;
      text?: string;
      text_position?: "top" | "right" | "bottom" | "left";
      text_offset?: number;
    };
    point?: {
      lngLat: number[];
      icon?: {
        uri: string;
        scale?: number;
        anchor?: number[];
        opacity?: number;
        color?: string;
      };
      id?: string;
      popupHtml?: string;
    };
    line?: {
      lngLat: number[];
      icon?: {
        uri: string;
        scale?: number;
        anchor?: number[];
        opacity?: number;
        color?: string;
      };
      id?: string;
      popupHtml?: string;
    }[];
  }[];
  source: {
    type: string;
    url?: string;
    style?: "positron" | "dark_matter" | "voyager";
    boundaries_only?: boolean;
    boundary_admin_levels?: string;
    national_boundaries_only?: boolean;
  };
  options: {
    centerFromGeometries?: boolean;
    text_position?: "top" | "right" | "bottom" | "left";
    text_offset?: number;
    text_scale?: number;
  };
  screenshot?: string;
};

export type Events = {
  pointClickCoordinates: {
    coordinates: { latitude: number; longitude: number };
    zoom: number;
    center: number[];
  };
  markerClick: {
    coordinates: { latitude: number; longitude: number };
    id: string;
  };
  screenshotTaken: {
    base64: string;
  };
};
```