diff --git a/components/package.json b/components/package.json
index e517735a..84331440 100644
--- a/components/package.json
+++ b/components/package.json
@@ -33,6 +33,7 @@
"dependencies": {
"@maplibre/maplibre-gl-geocoder": "^1.9.1",
"@maplibre/maplibre-gl-inspect": "^1.7.1",
+ "bitmap-sdf": "^1.0.4",
"maplibre-gl": "^5.7.0",
"svelte-select": "^5.8.3"
},
diff --git a/components/src/index.js b/components/src/index.js
index b93bed42..ca214faa 100644
--- a/components/src/index.js
+++ b/components/src/index.js
@@ -30,6 +30,8 @@ export { default as ScaleControl } from './maplibre/ScaleControl/ScaleControl.sv
export { default as VectorLayer } from './maplibre/VectorLayer/VectorLayer.svelte';
export { default as VectorTileSource } from './maplibre/VectorTileSource/VectorTileSource.svelte';
export { default as GeoJSONSource } from './maplibre/GeoJSONSource/GeoJSONSource.svelte';
+export { default as ArrowSource } from './maplibre/ArrowSource/ArrowSource.svelte';
+export { default as MapSource } from './maplibre/Source/MapSource.svelte';
export { default as Tooltip } from './maplibre/Tooltip/Tooltip.svelte';
export { default as WithLinkLocation } from './maplibre/WithLinkLocation/WithLinkLocation.svelte';
diff --git a/components/src/maplibre/ArrowSource/ArrowSource.mdx b/components/src/maplibre/ArrowSource/ArrowSource.mdx
new file mode 100644
index 00000000..a755dbe8
--- /dev/null
+++ b/components/src/maplibre/ArrowSource/ArrowSource.mdx
@@ -0,0 +1,66 @@
+import { Story, Meta, Primary, Controls, Stories } from '@storybook/addon-docs/blocks';
+
+import * as ArrowSourceStories from './ArrowSource.stories.svelte';
+
+
+
+# ArrowSource
+
+Source component for creating smooth ([quadratic bezier](https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Quadratic_B%C3%A9zier_curves)) vector arrows [like these](https://www.nytimes.com/interactive/2025/10/09/world/americas/drug-trafficking-venezuela.html?searchResultPosition=4).
+
+
+
+## Usage
+
+ArrowSource takes an `arrow` prop of shape `ArrowSpec[]`:
+
+```js
+interface ArrowSpec {
+ a: [number, number]; // Start point
+ b: [number, number]; // End point
+ c: [number, number]; // Control point
+ width?: number;
+}
+
+```
+
+Use regular VectorLayers to render the arrows:
+
+```jsx
+
+```
+
+## Notes
+- [https://github.com/dy/bitmap-sdf](https://github.com/dy/bitmap-sdf)
+- [https://github.com/maplibre/maplibre-gl-js/issues/5037](https://github.com/maplibre/maplibre-gl-js/issues/5037)
diff --git a/components/src/maplibre/ArrowSource/ArrowSource.stories.svelte b/components/src/maplibre/ArrowSource/ArrowSource.stories.svelte
new file mode 100644
index 00000000..ec4f23e8
--- /dev/null
+++ b/components/src/maplibre/ArrowSource/ArrowSource.stories.svelte
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/src/maplibre/ArrowSource/ArrowSource.svelte b/components/src/maplibre/ArrowSource/ArrowSource.svelte
new file mode 100644
index 00000000..4068e88b
--- /dev/null
+++ b/components/src/maplibre/ArrowSource/ArrowSource.svelte
@@ -0,0 +1,142 @@
+
+
+
diff --git a/components/src/maplibre/ArrowSource/index.js b/components/src/maplibre/ArrowSource/index.js
new file mode 100644
index 00000000..cadb874e
--- /dev/null
+++ b/components/src/maplibre/ArrowSource/index.js
@@ -0,0 +1,2 @@
+import ArrowSource from './ArrowSource.svelte';
+export default ArrowSource;
diff --git a/package-lock.json b/package-lock.json
index 1ff684bb..bff0924b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
"dependencies": {
"@maplibre/maplibre-gl-geocoder": "^1.9.1",
"@maplibre/maplibre-gl-inspect": "^1.7.1",
+ "bitmap-sdf": "^1.0.4",
"maplibre-gl": "^5.7.0",
"svelte-select": "^5.8.3"
},
@@ -6537,6 +6538,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/bitmap-sdf": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz",
+ "integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==",
+ "license": "MIT"
+ },
"node_modules/bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",