Finder component

Map

Interactive map component powered by Leaflet plugin.

The Map component relies on the Leaflet plugin. To use a map, make sure to include the required reference to the plugin's .css and .js files.

CSS file is linked in the <head> section and above theme.min.css reference in your document:

<link rel="stylesheet" href="assets/vendor/leaflet/dist/leaflet.css">

JavaScript file is linked before the closing </body> tag and above theme.min.js reference in your document:

<script src="assets/vendor/leaflet/dist/leaflet.js"></script>

Example of usage in JavaScript

import Map from './map/map-core'

const canvas = document.querySelector('[data-map]')
const map = new Map(canvas, options)
map.render(features)

Options

You can apply virtually any Leaflet option by specifying it within the data-map="{}" attribute in JSON format.

Option Type Defaults Description
center [LatLng] [51.509865, -0.118092] https://leafletjs.com/reference.html#map-center
By default coordinates of London. Also works as a fallback in case you don't specify any features (coordinates).
zoom Number 10 https://leafletjs.com/reference.html#map-zoom
minZoom Number 1 https://leafletjs.com/reference.html#map-minzoom
maxZoom Number 22 https://leafletjs.com/reference.html#map-maxzoom
tileLayer String https://tile.openstreetmap.org/{z}/{x}/{y}.png https://leafletjs.com/reference.html#tilelayer
tileSize Number 256 Specify the size of map tile. Should be supported by your tiles provider.
setViewStrategy String bounds Set bounds or center. This will determine what will be the view of the map after calling the render method.
zoomOffset Number 0 https://leafletjs.com/reference.html#tilelayer-zoomoffset
plugins Array [] List of plugins.
templates.marker String <div class="map-marker"><i class="fi-map-pin-filled text-primary fs-4"></i></div> Default template for markers. Can be overridden per-feature (markerTemplate) or through the plugin.
templates.popup String Default template for popups. Can be overridden per-feature (popupTemplate) or through the plugin.

Methods

Method Returns Description
render(<Array> features) Renders features (markers) on the map.
getOptions() Object Returns options.
registerPlugin(<Object> plugin) Registers the plugin.

Features (markers)

Feature is a normal JavaScript object. You are free to put any props inside of the feature, however there are some properties that will be used by the plugin in a certain way.

let feature = {
  markerTemplate: '<div class="marker"></div>', // override marker template per feature, allowed any HTML
  popupTemplate: '<div class="popup"></div>', // override popup template per feature, set to empty string to disable popup per feature, allowed any HTML
  geometryType: 'Point', // Point or Polygon
  coordinates: {
    lat: 51.505,
    lng: -0.09,
  }
}
Features/markers can be set in a 3 different ways:
  1. Specify the path/URL to a .json file in data-map-markers attribute.
  2. Pass a JSON array in data-map-markers.
  3. Use API to render the features, but in this case it is expected that you will create the Map instance and call the map.render() method.
Note: data-map-markers must be set on the same HTML element where you set data-map.

Plugins

Plugins allows you to modify the certain aspect of the `Map`. Plugin can be a JavaScript object or class with methods:

Method Should return Description
features(<Array> features) <Array> Handle features before they will be rendered on the map. Suitable for filtering, modifying, or processing features before they are rendered on the map.
marker(<L.Marker> marker, <Object> feature) <L.Marker> Handle the marker instance. Suitable for modifying the marker instance before it is added to the map. Note: `feature` here is in the GeoJSON format.
popup(<String> template, <Object> feature) <String> Register the pluginHandle the popup content. Suitable for modifying the popup content before it binds to the marker. By returning an empty string from the plugin method, you can prevent the popup from being displayed.
Example:
// Define a very basic "logger" plugin
let logger = {
  features: function (features) {
    console.log('Features:', features)
  },
  marker: function (marker, feature) {
    console.log('Marker:', marker)
    console.log('Feature:', feature)
  },
  popup: function (popup, feature) {
    console.log('Popup:', popup)
    console.log('Feature:', feature)
  }
}

const canvas = document.querySelector('[data-map]')
const map = new Map(canvas, options)
map.registerPlugin(logger)
map.render()

Basic example (no options passed)

<!-- Default map example without any options passed. The OpenStreetMap tiles (layers) are used by default. -->
<div class="ratio ratio-16x9 bg-body-tertiary border rounded" data-map></div>

Different map layers and markers

<!-- IMPORTANT! These map styles require generating MapTiler API Key. -->
<!-- Example #1 -->
<div class="ratio ratio-16x9 bg-body-tertiary border rounded" data-map='{
  "tileLayer": "https://api.maptiler.com/maps/backdrop/{z}/{x}/{y}.png?key=YOUR_MAPTILER_API_KEY",
  "attribution": "© Maptiler © OpenStreetMap contributors",
  "zoom": 15
}'></div>

<!-- Example #2 -->
<div class="ratio ratio-16x9 bg-body-tertiary border rounded" data-map='{
  "tileLayer": "https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=YOUR_MAPTILER_API_KEY",
  "attribution": "© Maptiler © OpenStreetMap contributors",
  "zoom": 15,
  "templates": {
    "marker": "<div class=\"d-flex align-items-center justify-content-center fs-4 text-info bg-white rounded-circle shadow\" style=\"width: 48px; height: 48px; margin-left: -12px\"><i class=\"fi-camera\"></i></div>"
  }
}' data-map-markers='[{
  "coordinates": {
    "lat": 51.509865,
    "lng": -0.118092
  }
}]'></div>

Multiple markers with popups

<!-- Map example showing multiple markers with price and popup listing card. Markers are passed via external JSON file. IMPORTANT! This map style requires generating MapTiler API Key. -->
<div class="ratio ratio-16x9 bg-body-tertiary border rounded" data-map='{
  "tileLayer": "https://api.maptiler.com/maps/pastel/{z}/{x}/{y}.png?key=YOUR_MAPTILER_API_KEY",
  "attribution": "© Maptiler © OpenStreetMap contributors",
  "zoom": 15,
  "tileSize": 512,
  "zoomOffset": -1,
  "templates": {
    "marker": "<div class=\"map-marker\"><i class=\"fi-map-pin-filled text-primary fs-4\"></i><span class=\"map-marker-price\">${{price}}</span></div>",
    "popup": "<div class=\"card bg-transparent border-0\" data-bs-theme=\"light\"><div class=\"card-img-top position-relative bg-body-tertiary overflow-hidden\"><div class=\"ratio d-block\" style=\"--fn-aspect-ratio: calc(248 / 362 * 100%)\"><img src=\"{{image}}\" alt=\"Image\"></div></div><div class=\"card-body p-3\"><div class=\"h5 mb-2\">${{price}}</div><h3 class=\"fs-sm fw-normal text-body mb-2\"><a class=\"stretched-link text-body\" href=\"#\">{{address}}</a></h3><div class=\"h6 fs-sm mb-0\">{{area}} sq.m</div></div><div class=\"card-footer d-flex gap-2 border-0 bg-transparent pt-0 pb-3 px-3 mt-n1\"><div class=\"d-flex align-items-center fs-sm gap-1 me-1\">{{bedrooms}}<i class=\"fi-bed-single fs-base text-secondary-emphasis\"></i></div><div class=\"d-flex align-items-center fs-sm gap-1 me-1\">{{bathrooms}}<i class=\"fi-shower fs-base text-secondary-emphasis\"></i></div><div class=\"d-flex align-items-center fs-sm gap-1 me-1\">{{garage}}<i class=\"fi-car-garage fs-base text-secondary-emphasis\"></i></div></div></div>"
  }
}' data-map-markers="assets/json/map-real-estate.json"></div>
                      
Top