diff --git a/core/libs.json b/core/libs.json
index 77ef71cb1..5d0e423d9 100644
--- a/core/libs.json
+++ b/core/libs.json
@@ -57,8 +57,9 @@
},
"maplibre-gl": {
"npm": "maplibre-gl",
- "js": ["dist/maplibre-gl.js"],
- "css": ["dist/maplibre-gl.css"]
+ "module": { "file": "dist/maplibre-gl.mjs", "global": "maplibregl" },
+ "css": ["dist/maplibre-gl.css"],
+ "extra": ["dist/maplibre-gl.mjs", "dist/maplibre-gl-shared.mjs", "dist/maplibre-gl-worker.mjs"]
},
"jsvectormap": {
"npm": "jsvectormap",
diff --git a/core/package.json b/core/package.json
index 7b5aece3d..d4945725e 100644
--- a/core/package.json
+++ b/core/package.json
@@ -276,7 +276,7 @@
"jsvectormap": "^1.7.0",
"list.js": "^2.3.1",
"litepicker": "^2.0.12",
- "maplibre-gl": "^5.24.0",
+ "maplibre-gl": "^6.11.2",
"nouislider": "^15.8.1",
"playwright": "1.62.1",
"plyr": "^3.8.4",
diff --git a/docs/content/ui/components/map.mdx b/docs/content/ui/components/map.mdx
index 609d1bf27..b40d110eb 100644
--- a/docs/content/ui/components/map.mdx
+++ b/docs/content/ui/components/map.mdx
@@ -48,20 +48,38 @@ The demos load their map tiles from [OpenFreeMap](https://openfreemap.org/). It
## Installation
-Install MapLibre GL JS with npm. Tabler uses version 5, the last one that ships a classic script file:
-
-```bash
-npm install maplibre-gl@5
-```
-
-Or include it from a CDN. You need two files: the stylesheet and the library.
+MapLibre GL JS is published as an ES module. Tabler uses version 6. Load the stylesheet, then import the library in a module script:
-`}
+`}
/>
+A module script runs before the `DOMContentLoaded` event, so the code examples on this page can use the `maplibregl` global. The library loads two more files from the same folder, `maplibre-gl-shared.mjs` and `maplibre-gl-worker.mjs`, so keep the three together when you host them yourself.
+
+With a bundler, install the package and import it in your code:
+
+```bash
+npm install maplibre-gl
+```
+
+```js
+import * as maplibregl from 'maplibre-gl'
+import 'maplibre-gl/dist/maplibre-gl.css'
+```
+
+
+ Older versions, including all of version 5, have a known security issue in the code that cleans the attribution text.
+
+
+Browsers do not load ES modules from a page opened straight from the disk. Use a local server to see the maps while you work.
+
Tabler styles the map controls, popups and attribution to match the interface, in light and dark mode. These styles are in `tabler-vendors.css`, so load it after the MapLibre stylesheet:
);
const libUrl = (lib: Lib, file: string) =>
isExternal(file)
@@ -151,6 +151,9 @@ const libUrl = (lib: Lib, file: string) =>
const docsLibCss = libEntries
.filter(([name]) => docsLibs.includes(name))
.flatMap(([, lib]) => (lib.css ?? []).map((file) => libUrl(lib, file)));
+const docsLibModules = libEntries
+ .filter(([name]) => docsLibs.includes(name))
+ .flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libUrl(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : []));
const docsLibJs = libEntries
.filter(([name]) => docsLibs.includes(name))
.flatMap(([, lib]) => (lib.js ?? []).map((file) => libUrl(lib, file)));
@@ -517,6 +520,7 @@ const relatedPages = await Promise.all(
)
}
+ {docsLibModules.map((code) => ${code}`} />)}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 24aa05a44..ae82392ad 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -199,8 +199,8 @@ importers:
specifier: ^2.0.12
version: 2.0.12
maplibre-gl:
- specifier: ^5.24.0
- version: 5.24.0
+ specifier: ^6.11.2
+ version: 6.11.2
nouislider:
specifier: ^15.8.1
version: 15.8.1
@@ -1289,24 +1289,17 @@ packages:
'@mapbox/tiny-sdf@2.2.0':
resolution: {integrity: sha512-LVL4wgI9YAum5V+LNVQO6QgFBPw7/MIIY4XJPNsPDMrjEwcE+JfKk1LuIl8GnF197ejVdC9QdPaxrx5gfgdGXg==}
- '@mapbox/unitbezier@0.0.1':
- resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==}
-
'@mapbox/unitbezier@1.0.0':
resolution: {integrity: sha512-fqd515fjBmANKGGsQ286E2Wvj/XvDFpGzwJxq4CI6jMQue6Oy04uCKp+JWKF00xRTmk6cEu1jPJ9p3xqH8YWqQ==}
- '@mapbox/vector-tile@2.0.5':
- resolution: {integrity: sha512-pXj8m7KTsqZt+1jsE0xIpGvqTSbblfkuEJL/NJmNePMtEwxO8V3XMDo9WMSfDeqHvCtBI9Lmt4mGcGR10zecmw==}
-
- '@mapbox/whoots-js@3.1.0':
- resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==}
- engines: {node: '>=6.0.0'}
+ '@mapbox/vector-tile@3.0.0':
+ resolution: {integrity: sha512-Qf10S1uIHMk20ri/IVBnpS+esUEkVaR5Hftmz88jTInrpmWgPGJfPe3LVjjlE77trLx8tH6qjTG7uWH9hIq/0Q==}
'@maplibre/geojson-vt@6.1.1':
resolution: {integrity: sha512-FVMOcmSP/yqol45t7StApEyTL5/vmqBCuFhH9n+fFuINenhaX+YgHHIt1yJ86S8kln3uJLcMvmEU2cfn6E2eCQ==}
- '@maplibre/maplibre-gl-style-spec@24.10.0':
- resolution: {integrity: sha512-lichxSiagMEBBrqHF0trtMQH9RKh+9jUlIJl0qW0QHvt2H/tbvUWdE+ZzI2Jd0/pT7j/iavLonlPu7EQ/ixTOw==}
+ '@maplibre/maplibre-gl-style-spec@26.4.4':
+ resolution: {integrity: sha512-hG4RZR4PBd/+6A3ODdZ3AnQRF106ZQk1y3bhwDg8bH/A4Oz2tnRUJVVWs9BZa6gXZ1d3UKe89C+Mm+olGBELvA==}
hasBin: true
'@maplibre/mlt@1.3.0':
@@ -2210,6 +2203,9 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
+ bidi-js@1.1.0:
+ resolution: {integrity: sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==}
+
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
@@ -3498,8 +3494,8 @@ packages:
make-synchronized@0.8.0:
resolution: {integrity: sha512-DZu4lwc0ffoFz581BSQa/BJl+1ZqIkoRQ+VejMlH0VrP4E86StAODnZujZ4sepumQj8rcP7wUnUBGM8Gu+zKUA==}
- maplibre-gl@5.24.0:
- resolution: {integrity: sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A==}
+ maplibre-gl@6.11.2:
+ resolution: {integrity: sha512-Xh06pxoipjX/Ad1sUPGhiNh9go9naCNGZZ1IJm3sIeqK1kYGuMaMDSTIGDQ2igOLfVyukJU7kvEOA089VO7Z7g==}
engines: {node: '>=16.14.0', npm: '>=8.1.0'}
markdown-extensions@2.0.0:
@@ -3964,10 +3960,6 @@ packages:
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
- pbf@4.0.2:
- resolution: {integrity: sha512-J0ajxARhZfpUEebxYs1vhMGMuLSXtBe1e+fFPDrf2uA2hgo+UshKfNUWOz92HJNz6/NFEXseQPddnHkTreWRqg==}
- hasBin: true
-
pbf@5.1.2:
resolution: {integrity: sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==}
hasBin: true
@@ -6153,23 +6145,19 @@ snapshots:
'@mapbox/tiny-sdf@2.2.0': {}
- '@mapbox/unitbezier@0.0.1': {}
-
'@mapbox/unitbezier@1.0.0': {}
- '@mapbox/vector-tile@2.0.5':
+ '@mapbox/vector-tile@3.0.0':
dependencies:
'@mapbox/point-geometry': 1.1.0
'@types/geojson': 7946.0.16
- pbf: 4.0.2
-
- '@mapbox/whoots-js@3.1.0': {}
+ pbf: 5.1.2
'@maplibre/geojson-vt@6.1.1':
dependencies:
kdbush: 4.1.0
- '@maplibre/maplibre-gl-style-spec@24.10.0':
+ '@maplibre/maplibre-gl-style-spec@26.4.4':
dependencies:
'@mapbox/jsonlint-lines-primitives': 2.0.3
'@mapbox/unitbezier': 1.0.0
@@ -7133,6 +7121,10 @@ snapshots:
baseline-browser-mapping@2.11.6: {}
+ bidi-js@1.1.0:
+ dependencies:
+ require-from-string: 2.0.2
+
binary-extensions@2.3.0: {}
bindings@1.5.0:
@@ -8455,24 +8447,23 @@ snapshots:
make-synchronized@0.8.0: {}
- maplibre-gl@5.24.0:
+ maplibre-gl@6.11.2:
dependencies:
- '@mapbox/jsonlint-lines-primitives': 2.0.3
'@mapbox/point-geometry': 1.1.0
'@mapbox/tiny-sdf': 2.2.0
- '@mapbox/unitbezier': 0.0.1
- '@mapbox/vector-tile': 2.0.5
- '@mapbox/whoots-js': 3.1.0
+ '@mapbox/unitbezier': 1.0.0
+ '@mapbox/vector-tile': 3.0.0
'@maplibre/geojson-vt': 6.1.1
- '@maplibre/maplibre-gl-style-spec': 24.10.0
+ '@maplibre/maplibre-gl-style-spec': 26.4.4
'@maplibre/mlt': 1.3.0
'@maplibre/vt-pbf': 4.3.2
'@types/geojson': 7946.0.16
+ bidi-js: 1.1.0
earcut: 3.2.4
gl-matrix: 3.4.4
kdbush: 4.1.0
murmurhash-js: 1.0.0
- pbf: 4.0.2
+ pbf: 5.1.2
potpack: 2.1.0
quickselect: 3.0.0
tinyqueue: 3.0.0
@@ -9227,10 +9218,6 @@ snapshots:
pathe@2.0.3: {}
- pbf@4.0.2:
- dependencies:
- resolve-protobuf-schema: 2.1.0
-
pbf@5.1.2:
dependencies:
resolve-protobuf-schema: 2.1.0
diff --git a/screenshots/layouts/ScreenshotAppLayout.astro b/screenshots/layouts/ScreenshotAppLayout.astro
index 0792e4847..f671dfc55 100644
--- a/screenshots/layouts/ScreenshotAppLayout.astro
+++ b/screenshots/layouts/ScreenshotAppLayout.astro
@@ -73,11 +73,13 @@ const themeAttributes = themeDataAttributes({ ...theme, 'navbar-position': navba
// whatever core's own watcher last emitted, which is unminified.
const min = import.meta.env.DEV ? '' : '.min'
-type Lib = { npm?: string; js?: string[]; css?: string[] }
+type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string } }
const pageLibEntries = Object.entries(libs as Record).filter(([name]) => pageLibs.includes(name))
const libHref = (lib: Lib, file: string) => `/dist/libs/${lib.npm}/${file}`
const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file)))
const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file)))
+// ES-module-only libraries: imported in a module script and exposed as a global (see BaseLayout)
+const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : []))
---
@@ -177,6 +179,7 @@ const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file)
{libJsFiles.map((src) => )}
+ {libModules.map((code) => ${code}`} />)}
diff --git a/screenshots/layouts/ScreenshotLayout.astro b/screenshots/layouts/ScreenshotLayout.astro
index bcf3e618e..1dbcef68b 100644
--- a/screenshots/layouts/ScreenshotLayout.astro
+++ b/screenshots/layouts/ScreenshotLayout.astro
@@ -45,11 +45,13 @@ const rtlSuffix = rtl ? '.rtl' : ''
// build instead of hardcoding one variant.
const min = import.meta.env.DEV ? '' : '.min'
-type Lib = { npm?: string; js?: string[]; css?: string[] }
+type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string } }
const pageLibEntries = Object.entries(libs as Record).filter(([name]) => pageLibs.includes(name))
const libHref = (lib: Lib, file: string) => `/dist/libs/${lib.npm}/${file}`
const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file)))
const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file)))
+// ES-module-only libraries: imported in a module script and exposed as a global (see BaseLayout)
+const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : []))
---
@@ -168,6 +170,7 @@ const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file)
{libJsFiles.map((src) => )}
+ {libModules.map((code) => ${code}`} />)}