-
+
+
+
+ {(data.markers ?? []).map((marker) => )}
+
+
+
)
}
-{
- data && mapboxKey && (
-
-
-
-
-
- )
-}
diff --git a/shared/components/demo/MapVector.astro b/shared/components/demo/MapVector.astro
index aed8de681..d170de8ab 100644
--- a/shared/components/demo/MapVector.astro
+++ b/shared/components/demo/MapVector.astro
@@ -54,7 +54,7 @@ const mapOptions = data
initial: {
fill: 'var(--tblr-bg-surface-secondary)',
stroke: data.filled ? '#fff' : 'var(--tblr-border-color)',
- strokeWidth: data.filled ? 1 : 2,
+ strokeWidth: 1,
},
},
zoomOnScroll: Boolean(data.zoom),
diff --git a/shared/data/maps.json b/shared/data/maps.json
index df1d2254d..d8e88b2ee 100644
--- a/shared/data/maps.json
+++ b/shared/data/maps.json
@@ -1,24 +1,25 @@
{
"simple": {
- "title": "Simple map"
+ "title": "Simple map",
+ "controls": true
},
"light": {
- "title": "Light map style",
+ "title": "Street map style",
"center": [
51.5285582,
-0.2416782
],
"zoom": 11,
- "style": "light-v10"
+ "style": "liberty"
},
"markers": {
- "title": "Light map style",
+ "title": "Map with markers",
"center": [
0,
0
],
"zoom": 1,
- "style": "light-v10",
+ "style": "positron",
"card": true,
"markers": [
{
@@ -72,7 +73,8 @@
0
],
"zoom": 1,
- "style": "satellite-v9",
+ "style": "bright",
+ "darkStyle": "fiord",
"card": true
}
}
\ No newline at end of file
diff --git a/shared/data/menu.json b/shared/data/menu.json
index 6c339fd18..2cdbc163d 100644
--- a/shared/data/menu.json
+++ b/shared/data/menu.json
@@ -588,6 +588,11 @@
"url": "map-fullsize.html",
"title": "Map fullsize"
},
+ "map-blocks": {
+ "url": "map-blocks.html",
+ "title": "Map blocks",
+ "badge": "New"
+ },
"maps-vector": {
"url": "maps-vector.html",
"title": "Map vector"
diff --git a/shared/data/open-source.json b/shared/data/open-source.json
index 13a01c780..bd134e951 100644
--- a/shared/data/open-source.json
+++ b/shared/data/open-source.json
@@ -103,6 +103,13 @@
"description": "Lightweight, no-dependency date range picker. Kept in dist/libs for older projects; use the Datepicker plugin instead.",
"license": "MIT"
},
+ {
+ "name": "MapLibre GL JS",
+ "npm": "maplibre-gl",
+ "url": "https://maplibre.org/maplibre-gl-js/docs/",
+ "description": "Open-source JavaScript library for interactive vector maps on the web, with no access token.",
+ "license": "BSD-3-Clause"
+ },
{
"name": "Mapbox GL JS",
"lib": "mapbox",
diff --git a/shared/layouts/BaseLayout.astro b/shared/layouts/BaseLayout.astro
index 4dba0eb35..8352c7d4e 100644
--- a/shared/layouts/BaseLayout.astro
+++ b/shared/layouts/BaseLayout.astro
@@ -39,19 +39,21 @@ const isProduction = process.env.VERCEL_ENV === 'production'
// RTL swaps tabler/plugin stylesheets for their .rtl.css variants (demo stays LTR)
const rtlSuffix = rtl ? '.rtl' : ''
-type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean }
+type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean; module?: { file: string; global: string }; addon?: string }
const unknownLibs = pageLibs.filter((name) => !(name in libs))
if (unknownLibs.length > 0) {
throw new Error(`BaseLayout: unknown pageLibs ${unknownLibs.map((name) => `"${name}"`).join(', ')} — use a key from core/libs.json`)
}
const pageLibEntries = Object.entries(libs as Record
).filter(([name]) => pageLibs.includes(name))
-// Google Maps API key comes from the environment (GOOGLE_MAPS_KEY in .env or the
-// host's settings), never from the source. Without it the script loads keyless.
-const googleMapsKey = import.meta.env.GOOGLE_MAPS_KEY ?? process.env.GOOGLE_MAPS_KEY ?? ''
-// External URLs (http/https) are emitted verbatim (with the maps-key placeholder
-// replaced); local files as ./dist/libs/{npm}/{file}.
-const libHref = (lib: Lib, file: string) => (/^https?:\/\//.test(file) ? file.replace(googleMapsKey ? 'GOOGLE_MAPS_KEY' : '?key=GOOGLE_MAPS_KEY', googleMapsKey) : `${base}/dist/libs/${lib.npm}/${file}`)
+// External URLs (http/https) are emitted verbatim; local files as ./dist/libs/{npm}/{file}.
+const libHref = (lib: Lib, file: string) => (/^https?:\/\//.test(file) ? file : `${base}/dist/libs/${lib.npm}/${file}`)
const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file)))
+// Libraries published as ES modules only: imported in a module script and
+// handed to the classic page scripts as a global. Module scripts are deferred,
+// so the global is set before DOMContentLoaded.
+const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'\n window.${lib.module.global} = lib`] : []))
+// Tabler add-on bundles (dist/js) that a library needs, loaded after tabler.js
+const libAddons = pageLibEntries.flatMap(([, lib]) => (lib.addon ? [lib.addon] : []))
const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean(lib.head) === head).flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file)))
---
@@ -133,9 +135,11 @@ const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean
)
}
+ {libModules.map((code) => \n ${code}\n `} />)}
+ {libAddons.map((addon) => )}
diff --git a/shared/static/maps/berlin-places.geojson b/shared/static/maps/berlin-places.geojson
new file mode 100644
index 000000000..f1d5e516f
--- /dev/null
+++ b/shared/static/maps/berlin-places.geojson
@@ -0,0 +1,24 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": { "name": "Tiergarten" },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [[[13.336, 52.5165], [13.3445, 52.5195], [13.3755, 52.5165], [13.3765, 52.5115], [13.3625, 52.5085], [13.3385, 52.5095], [13.336, 52.5165]]]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "Riverside walk" },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [[13.3765, 52.5195], [13.3885, 52.5205], [13.3975, 52.5215], [13.4035, 52.5185], [13.4115, 52.5145], [13.4255, 52.5115], [13.4395, 52.5055]]
+ }
+ },
+ { "type": "Feature", "properties": { "name": "Brandenburg Gate" }, "geometry": { "type": "Point", "coordinates": [13.3777, 52.5163] } },
+ { "type": "Feature", "properties": { "name": "Museum Island" }, "geometry": { "type": "Point", "coordinates": [13.4019, 52.5169] } },
+ { "type": "Feature", "properties": { "name": "East Side Gallery" }, "geometry": { "type": "Point", "coordinates": [13.4397, 52.505] } }
+ ]
+}
diff --git a/turbo.json b/turbo.json
index 20500967e..ad61a723a 100644
--- a/turbo.json
+++ b/turbo.json
@@ -1,6 +1,6 @@
{
"$schema": "https://turbo.build/schema.json",
- "globalEnv": ["NODE_ENV", "VERCEL_ENV", "POSTHOG_KEY", "DOCSEARCH_API_KEY", "DOCSEARCH_APP_ID", "DOCSEARCH_INDEX_NAME", "GOOGLE_MAPS_KEY", "MAPBOX_KEY"],
+ "globalEnv": ["NODE_ENV", "VERCEL_ENV", "POSTHOG_KEY", "DOCSEARCH_API_KEY", "DOCSEARCH_APP_ID", "DOCSEARCH_INDEX_NAME"],
"tasks": {
"build": {
"dependsOn": ["^build"],