diff --git a/examples/filter/package.json b/examples/filter/package.json deleted file mode 100644 index 677adc0fb..000000000 --- a/examples/filter/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "mapbox-gl": "^2.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/geojson-animation/package.json b/examples/geojson-animation/package.json deleted file mode 100644 index 6e5a6c29d..000000000 --- a/examples/geojson-animation/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/get-started/basic/app.jsx b/examples/get-started/basic/app.jsx index 4ca4270ab..92c54ad4c 100644 --- a/examples/get-started/basic/app.jsx +++ b/examples/get-started/basic/app.jsx @@ -1,7 +1,7 @@ /* global document */ import * as React from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {Marker} from 'react-map-gl'; +import Map, {Marker} from 'react-map-gl/mapbox'; import 'mapbox-gl/dist/mapbox-gl.css'; diff --git a/examples/get-started/basic/package.json b/examples/get-started/basic/package.json index c0922fbc1..9d134f9a0 100644 --- a/examples/get-started/basic/package.json +++ b/examples/get-started/basic/package.json @@ -6,8 +6,8 @@ "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/get-started/controlled/README.md b/examples/get-started/controlled/README.md index e639d04bf..307a47405 100644 --- a/examples/get-started/controlled/README.md +++ b/examples/get-started/controlled/README.md @@ -6,7 +6,7 @@ This example shows a minimal app configuration to use react-map-gl's Map compone To run this example, you need a [Mapbox token](http://visgl.github.io/react-map-gl/docs/get-started/mapbox-tokens). You can either set it as `MAPBOX_TOKEN` in `app.js`, or set a `MapboxAccessToken` environment variable in the command line. -Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. +Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl/mapbox'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. ```bash npm i diff --git a/examples/get-started/controlled/app.jsx b/examples/get-started/controlled/app.jsx index 98be80e03..4896423f3 100644 --- a/examples/get-started/controlled/app.jsx +++ b/examples/get-started/controlled/app.jsx @@ -1,7 +1,7 @@ /* global document */ import * as React from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {Marker} from 'react-map-gl'; +import Map, {Marker} from 'react-map-gl/mapbox'; import 'mapbox-gl/dist/mapbox-gl.css'; diff --git a/examples/get-started/controlled/package.json b/examples/get-started/controlled/package.json index c0922fbc1..9d134f9a0 100644 --- a/examples/get-started/controlled/package.json +++ b/examples/get-started/controlled/package.json @@ -6,8 +6,8 @@ "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/get-started/hook/README.md b/examples/get-started/hook/README.md index 1917f13c1..aaee070e6 100644 --- a/examples/get-started/hook/README.md +++ b/examples/get-started/hook/README.md @@ -6,7 +6,7 @@ This example shows how to use react-map-gl's Map component with the `useMap` hoo To run this example, you need a [Mapbox token](http://visgl.github.io/react-map-gl/docs/get-started/mapbox-tokens). You can either set it as `MAPBOX_TOKEN` in `map.js`, or set a `MapboxAccessToken` environment variable in the command line. -Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. +Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl/mapbox'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. ```bash npm i diff --git a/examples/get-started/hook/app.jsx b/examples/get-started/hook/app.jsx index 66425cc73..fa2027202 100644 --- a/examples/get-started/hook/app.jsx +++ b/examples/get-started/hook/app.jsx @@ -1,7 +1,7 @@ /* global document */ import * as React from 'react'; import {createRoot} from 'react-dom/client'; -import {MapProvider} from 'react-map-gl'; +import {MapProvider} from 'react-map-gl/mapbox'; import Map from './map'; import Controls from './controls'; diff --git a/examples/get-started/hook/controls.jsx b/examples/get-started/hook/controls.jsx index c1e23baef..4f7404897 100644 --- a/examples/get-started/hook/controls.jsx +++ b/examples/get-started/hook/controls.jsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useCallback, useState, useEffect} from 'react'; -import {useMap} from 'react-map-gl'; +import {useMap} from 'react-map-gl/mapbox'; export default function Controls() { /** diff --git a/examples/get-started/hook/controls2.jsx b/examples/get-started/hook/controls2.jsx index 139ac5a35..a3f68dde8 100644 --- a/examples/get-started/hook/controls2.jsx +++ b/examples/get-started/hook/controls2.jsx @@ -1,4 +1,4 @@ -// import {useMap} from 'react-map-gl'; +// import {useMap} from 'react-map-gl/mapbox'; export default function Controls2() { /** diff --git a/examples/get-started/hook/map.jsx b/examples/get-started/hook/map.jsx index dad4e6cd7..ce214e553 100644 --- a/examples/get-started/hook/map.jsx +++ b/examples/get-started/hook/map.jsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import Map from 'react-map-gl'; -// import {useMap} from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; +// import {useMap} from 'react-map-gl/mapbox'; import 'mapbox-gl/dist/mapbox-gl.css'; import Controls2 from './controls2'; diff --git a/examples/get-started/hook/package.json b/examples/get-started/hook/package.json index c0922fbc1..9d134f9a0 100644 --- a/examples/get-started/hook/package.json +++ b/examples/get-started/hook/package.json @@ -6,8 +6,8 @@ "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/get-started/maplibre/package.json b/examples/get-started/maplibre/package.json index 0ae46a204..ba1967f9d 100644 --- a/examples/get-started/maplibre/package.json +++ b/examples/get-started/maplibre/package.json @@ -4,10 +4,10 @@ "build": "vite build" }, "dependencies": { - "maplibre-gl": "^2.0.0", + "maplibre-gl": "^5.0.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" + "react-map-gl": "^8.0.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/get-started/nextjs/README.md b/examples/get-started/nextjs/README.md index 5ec7538c6..9dbcece99 100644 --- a/examples/get-started/nextjs/README.md +++ b/examples/get-started/nextjs/README.md @@ -4,7 +4,7 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next To run this example, you need a [Mapbox token](http://visgl.github.io/react-map-gl/docs/get-started/mapbox-tokens). You can either set it as `MAPBOX_TOKEN` in `pages/index.js`, or set a `MapboxAccessToken` environment variable in the command line. -Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. +Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl/mapbox'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. ## Getting Started diff --git a/examples/get-started/nextjs/package.json b/examples/get-started/nextjs/package.json index 5859f15a8..cd91424cf 100644 --- a/examples/get-started/nextjs/package.json +++ b/examples/get-started/nextjs/package.json @@ -9,8 +9,8 @@ "next": "12.0.7", "react": "17.0.2", "react-dom": "17.0.2", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "eslint": "8.5.0", diff --git a/examples/get-started/nextjs/pages/index.js b/examples/get-started/nextjs/pages/index.js index 3ca9a3254..6586105b1 100644 --- a/examples/get-started/nextjs/pages/index.js +++ b/examples/get-started/nextjs/pages/index.js @@ -1,6 +1,6 @@ import * as React from 'react'; import Head from 'next/head'; -import Map, {Marker} from 'react-map-gl'; +import Map, {Marker} from 'react-map-gl/mapbox'; import 'mapbox-gl/dist/mapbox-gl.css'; diff --git a/examples/get-started/redux/README.md b/examples/get-started/redux/README.md index 93afdc03e..d2bb5b3f8 100644 --- a/examples/get-started/redux/README.md +++ b/examples/get-started/redux/README.md @@ -6,7 +6,7 @@ This example shows how to use react-map-gl's Map component with react-redux. To run this example, you need a [Mapbox token](http://visgl.github.io/react-map-gl/docs/get-started/mapbox-tokens). You can either set it as `MAPBOX_TOKEN` in `map.js`, or set a `MapboxAccessToken` environment variable in the command line. -Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. +Alternative to acquiring a Mapbox token, you can install `maplibre-gl` and change all `import from 'react-map-gl/mapbox'` to `import from 'react-map-gl/maplibre'`. You also need to supply a third-party or self-hosted `mapStyle` URL. ```bash npm i diff --git a/examples/get-started/redux/map.jsx b/examples/get-started/redux/map.jsx index 6eed6b06a..294763017 100644 --- a/examples/get-started/redux/map.jsx +++ b/examples/get-started/redux/map.jsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import {useCallback} from 'react'; import {useSelector, useDispatch} from 'react-redux'; diff --git a/examples/get-started/redux/package.json b/examples/get-started/redux/package.json index 97ece787e..4cd66dc25 100644 --- a/examples/get-started/redux/package.json +++ b/examples/get-started/redux/package.json @@ -6,9 +6,9 @@ "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", + "react-map-gl": "^8.0.0", "react-redux": "^7.0.0", - "mapbox-gl": "^2.0.0" + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/heatmap/package.json b/examples/heatmap/package.json deleted file mode 100644 index 6e5a6c29d..000000000 --- a/examples/heatmap/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/interaction/package.json b/examples/interaction/package.json deleted file mode 100644 index 6e5a6c29d..000000000 --- a/examples/interaction/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/clusters/README.md b/examples/mapbox/clusters/README.md similarity index 86% rename from examples/clusters/README.md rename to examples/mapbox/clusters/README.md index 8866b9722..85c47bff2 100644 --- a/examples/clusters/README.md +++ b/examples/mapbox/clusters/README.md @@ -15,5 +15,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/clusters/index.html b/examples/mapbox/clusters/index.html similarity index 100% rename from examples/clusters/index.html rename to examples/mapbox/clusters/index.html diff --git a/examples/controls/package.json b/examples/mapbox/clusters/package.json similarity index 66% rename from examples/controls/package.json rename to examples/mapbox/clusters/package.json index 6e5a6c29d..d25a4764a 100644 --- a/examples/controls/package.json +++ b/examples/mapbox/clusters/package.json @@ -1,14 +1,14 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/clusters/src/app.tsx b/examples/mapbox/clusters/src/app.tsx similarity index 94% rename from examples/clusters/src/app.tsx rename to examples/mapbox/clusters/src/app.tsx index 9da34af4e..e3c2132d1 100644 --- a/examples/clusters/src/app.tsx +++ b/examples/mapbox/clusters/src/app.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import {useRef} from 'react'; import {createRoot} from 'react-dom/client'; -import {Map, Source, Layer} from 'react-map-gl'; +import {Map, Source, Layer} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; import {clusterLayer, clusterCountLayer, unclusteredPointLayer} from './layers'; -import type {MapRef} from 'react-map-gl'; +import type {MapRef} from 'react-map-gl/mapbox'; import type {GeoJSONSource} from 'mapbox-gl'; const MAPBOX_TOKEN = ''; // Set your mapbox token here diff --git a/examples/clusters/src/control-panel.tsx b/examples/mapbox/clusters/src/control-panel.tsx similarity index 100% rename from examples/clusters/src/control-panel.tsx rename to examples/mapbox/clusters/src/control-panel.tsx diff --git a/examples/clusters/src/layers.ts b/examples/mapbox/clusters/src/layers.ts similarity index 94% rename from examples/clusters/src/layers.ts rename to examples/mapbox/clusters/src/layers.ts index b4c060aa2..eac7355ad 100644 --- a/examples/clusters/src/layers.ts +++ b/examples/mapbox/clusters/src/layers.ts @@ -1,4 +1,4 @@ -import type {LayerProps} from 'react-map-gl'; +import type {LayerProps} from 'react-map-gl/mapbox'; export const clusterLayer: LayerProps = { id: 'clusters', diff --git a/examples/clusters/tsconfig.json b/examples/mapbox/clusters/tsconfig.json similarity index 100% rename from examples/clusters/tsconfig.json rename to examples/mapbox/clusters/tsconfig.json diff --git a/examples/clusters/vite.config.js b/examples/mapbox/clusters/vite.config.js similarity index 100% rename from examples/clusters/vite.config.js rename to examples/mapbox/clusters/vite.config.js diff --git a/examples/controls/README.md b/examples/mapbox/controls/README.md similarity index 84% rename from examples/controls/README.md rename to examples/mapbox/controls/README.md index 77b134510..7b94d20eb 100644 --- a/examples/controls/README.md +++ b/examples/mapbox/controls/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/controls/index.html b/examples/mapbox/controls/index.html similarity index 100% rename from examples/controls/index.html rename to examples/mapbox/controls/index.html diff --git a/examples/clusters/package.json b/examples/mapbox/controls/package.json similarity index 66% rename from examples/clusters/package.json rename to examples/mapbox/controls/package.json index 6e5a6c29d..d25a4764a 100644 --- a/examples/clusters/package.json +++ b/examples/mapbox/controls/package.json @@ -1,14 +1,14 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/controls/src/app.tsx b/examples/mapbox/controls/src/app.tsx similarity index 96% rename from examples/controls/src/app.tsx rename to examples/mapbox/controls/src/app.tsx index 25d8f6a7d..6e26a4ed6 100644 --- a/examples/controls/src/app.tsx +++ b/examples/mapbox/controls/src/app.tsx @@ -8,12 +8,12 @@ import Map, { FullscreenControl, ScaleControl, GeolocateControl -} from 'react-map-gl'; +} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; import Pin from './pin'; -import CITIES from '../../.data/cities.json'; +import CITIES from '../../../.data/cities.json'; const TOKEN = ''; // Set your mapbox token here diff --git a/examples/controls/src/control-panel.tsx b/examples/mapbox/controls/src/control-panel.tsx similarity index 100% rename from examples/controls/src/control-panel.tsx rename to examples/mapbox/controls/src/control-panel.tsx diff --git a/examples/controls/src/pin.tsx b/examples/mapbox/controls/src/pin.tsx similarity index 100% rename from examples/controls/src/pin.tsx rename to examples/mapbox/controls/src/pin.tsx diff --git a/examples/controls/tsconfig.json b/examples/mapbox/controls/tsconfig.json similarity index 100% rename from examples/controls/tsconfig.json rename to examples/mapbox/controls/tsconfig.json diff --git a/examples/controls/vite.config.js b/examples/mapbox/controls/vite.config.js similarity index 100% rename from examples/controls/vite.config.js rename to examples/mapbox/controls/vite.config.js diff --git a/examples/custom-cursor/README.md b/examples/mapbox/custom-cursor/README.md similarity index 85% rename from examples/custom-cursor/README.md rename to examples/mapbox/custom-cursor/README.md index ff3ebe89b..beb1b07bb 100644 --- a/examples/custom-cursor/README.md +++ b/examples/mapbox/custom-cursor/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/custom-cursor/index.html b/examples/mapbox/custom-cursor/index.html similarity index 100% rename from examples/custom-cursor/index.html rename to examples/mapbox/custom-cursor/index.html diff --git a/examples/custom-cursor/package.json b/examples/mapbox/custom-cursor/package.json similarity index 66% rename from examples/custom-cursor/package.json rename to examples/mapbox/custom-cursor/package.json index 6e5a6c29d..d25a4764a 100644 --- a/examples/custom-cursor/package.json +++ b/examples/mapbox/custom-cursor/package.json @@ -1,14 +1,14 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/custom-cursor/src/app.tsx b/examples/mapbox/custom-cursor/src/app.tsx similarity index 90% rename from examples/custom-cursor/src/app.tsx rename to examples/mapbox/custom-cursor/src/app.tsx index 8c8d2d0f0..0d07d3b25 100644 --- a/examples/custom-cursor/src/app.tsx +++ b/examples/mapbox/custom-cursor/src/app.tsx @@ -2,9 +2,9 @@ import * as React from 'react'; import {useState, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {MapboxStyle} from 'react-map-gl'; +import Map, {MapStyle} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; -import MAP_STYLE from '../../map-style-basic-v8.json'; +import MAP_STYLE from '../../../map-style-basic-v8.json'; const MAPBOX_TOKEN = ''; // Set your mapbox token here @@ -39,7 +39,7 @@ export default function App() { <> ` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/custom-overlay/index.html b/examples/mapbox/custom-overlay/index.html similarity index 100% rename from examples/custom-overlay/index.html rename to examples/mapbox/custom-overlay/index.html diff --git a/examples/custom-overlay/package.json b/examples/mapbox/custom-overlay/package.json similarity index 68% rename from examples/custom-overlay/package.json rename to examples/mapbox/custom-overlay/package.json index b759239b9..8dab89029 100644 --- a/examples/custom-overlay/package.json +++ b/examples/mapbox/custom-overlay/package.json @@ -1,15 +1,15 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "d3-shape": "^3.1.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/custom-overlay/src/app.tsx b/examples/mapbox/custom-overlay/src/app.tsx similarity index 97% rename from examples/custom-overlay/src/app.tsx rename to examples/mapbox/custom-overlay/src/app.tsx index b74dbd1b3..db3acfaa4 100644 --- a/examples/custom-overlay/src/app.tsx +++ b/examples/mapbox/custom-overlay/src/app.tsx @@ -1,13 +1,13 @@ import * as React from 'react'; import {useMemo, useState} from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import {arc, pie} from 'd3-shape'; import CustomOverlay from './custom-overlay'; import ControlPanel, {COLORS} from './control-panel'; -import electionData from '../../.data/us-election-2016.json'; +import electionData from '../../../.data/us-election-2016.json'; import type {Map as MapboxMap} from 'mapbox-gl'; diff --git a/examples/custom-overlay/src/control-panel.tsx b/examples/mapbox/custom-overlay/src/control-panel.tsx similarity index 100% rename from examples/custom-overlay/src/control-panel.tsx rename to examples/mapbox/custom-overlay/src/control-panel.tsx diff --git a/examples/custom-overlay/src/custom-overlay.tsx b/examples/mapbox/custom-overlay/src/custom-overlay.tsx similarity index 92% rename from examples/custom-overlay/src/custom-overlay.tsx rename to examples/mapbox/custom-overlay/src/custom-overlay.tsx index 82b4c22a1..63b9309b3 100644 --- a/examples/custom-overlay/src/custom-overlay.tsx +++ b/examples/mapbox/custom-overlay/src/custom-overlay.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import {useState, cloneElement} from 'react'; -import {useControl} from 'react-map-gl'; +import {useControl} from 'react-map-gl/mapbox'; import {createPortal} from 'react-dom'; -import type {IControl, MapInstance} from 'react-map-gl'; +import type {IControl, MapInstance} from 'react-map-gl/mapbox'; // Based on template in https://docs.mapbox.com/mapbox-gl-js/api/markers/#icontrol class OverlayControl implements IControl { diff --git a/examples/custom-overlay/tsconfig.json b/examples/mapbox/custom-overlay/tsconfig.json similarity index 100% rename from examples/custom-overlay/tsconfig.json rename to examples/mapbox/custom-overlay/tsconfig.json diff --git a/examples/custom-overlay/vite.config.js b/examples/mapbox/custom-overlay/vite.config.js similarity index 100% rename from examples/custom-overlay/vite.config.js rename to examples/mapbox/custom-overlay/vite.config.js diff --git a/examples/deckgl-overlay/README.md b/examples/mapbox/deckgl-overlay/README.md similarity index 85% rename from examples/deckgl-overlay/README.md rename to examples/mapbox/deckgl-overlay/README.md index 4473095c0..af0613a40 100644 --- a/examples/deckgl-overlay/README.md +++ b/examples/mapbox/deckgl-overlay/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/deckgl-overlay/index.html b/examples/mapbox/deckgl-overlay/index.html similarity index 100% rename from examples/deckgl-overlay/index.html rename to examples/mapbox/deckgl-overlay/index.html diff --git a/examples/deckgl-overlay/package.json b/examples/mapbox/deckgl-overlay/package.json similarity index 68% rename from examples/deckgl-overlay/package.json rename to examples/mapbox/deckgl-overlay/package.json index bc5904faf..412f3041e 100644 --- a/examples/deckgl-overlay/package.json +++ b/examples/mapbox/deckgl-overlay/package.json @@ -1,15 +1,15 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "deck.gl": "^8.8.0-beta.2", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/deckgl-overlay/src/app.tsx b/examples/mapbox/deckgl-overlay/src/app.tsx similarity index 95% rename from examples/deckgl-overlay/src/app.tsx rename to examples/mapbox/deckgl-overlay/src/app.tsx index 5aa865562..be25b7ca6 100644 --- a/examples/deckgl-overlay/src/app.tsx +++ b/examples/mapbox/deckgl-overlay/src/app.tsx @@ -3,7 +3,7 @@ import {createRoot} from 'react-dom/client'; import {ArcLayer} from '@deck.gl/layers/typed'; import {DeckProps, PickingInfo} from '@deck.gl/core/typed'; import {MapboxOverlay} from '@deck.gl/mapbox/typed'; -import Map, {useControl, NavigationControl} from 'react-map-gl'; +import Map, {useControl, NavigationControl} from 'react-map-gl/mapbox'; const TOKEN = ''; // Set your mapbox token here diff --git a/examples/deckgl-overlay/tsconfig.json b/examples/mapbox/deckgl-overlay/tsconfig.json similarity index 100% rename from examples/deckgl-overlay/tsconfig.json rename to examples/mapbox/deckgl-overlay/tsconfig.json diff --git a/examples/deckgl-overlay/vite.config.js b/examples/mapbox/deckgl-overlay/vite.config.js similarity index 100% rename from examples/deckgl-overlay/vite.config.js rename to examples/mapbox/deckgl-overlay/vite.config.js diff --git a/examples/draggable-markers/README.md b/examples/mapbox/draggable-markers/README.md similarity index 84% rename from examples/draggable-markers/README.md rename to examples/mapbox/draggable-markers/README.md index 7043163a0..0c0c3af09 100644 --- a/examples/draggable-markers/README.md +++ b/examples/mapbox/draggable-markers/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/draggable-markers/index.html b/examples/mapbox/draggable-markers/index.html similarity index 100% rename from examples/draggable-markers/index.html rename to examples/mapbox/draggable-markers/index.html diff --git a/examples/draggable-markers/package.json b/examples/mapbox/draggable-markers/package.json similarity index 66% rename from examples/draggable-markers/package.json rename to examples/mapbox/draggable-markers/package.json index 677adc0fb..94735163a 100644 --- a/examples/draggable-markers/package.json +++ b/examples/mapbox/draggable-markers/package.json @@ -1,14 +1,14 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { - "mapbox-gl": "^2.0.0", + "mapbox-gl": "^3.5.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" + "react-map-gl": "^8.0.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/draggable-markers/src/app.tsx b/examples/mapbox/draggable-markers/src/app.tsx similarity index 92% rename from examples/draggable-markers/src/app.tsx rename to examples/mapbox/draggable-markers/src/app.tsx index 5b0e8a8f4..3853d16ad 100644 --- a/examples/draggable-markers/src/app.tsx +++ b/examples/mapbox/draggable-markers/src/app.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import {useState, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {Marker, NavigationControl} from 'react-map-gl'; +import Map, {Marker, NavigationControl} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; import Pin from './pin'; -import type {MarkerDragEvent, LngLat} from 'react-map-gl'; +import type {MarkerDragEvent, LngLat} from 'react-map-gl/mapbox'; const TOKEN = ''; // Set your mapbox token here diff --git a/examples/draggable-markers/src/control-panel.tsx b/examples/mapbox/draggable-markers/src/control-panel.tsx similarity index 95% rename from examples/draggable-markers/src/control-panel.tsx rename to examples/mapbox/draggable-markers/src/control-panel.tsx index e3bd15d30..9ae3231cf 100644 --- a/examples/draggable-markers/src/control-panel.tsx +++ b/examples/mapbox/draggable-markers/src/control-panel.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type {LngLat} from 'react-map-gl'; +import type {LngLat} from 'react-map-gl/mapbox'; const eventNames = ['onDragStart', 'onDrag', 'onDragEnd']; diff --git a/examples/draggable-markers/src/pin.tsx b/examples/mapbox/draggable-markers/src/pin.tsx similarity index 100% rename from examples/draggable-markers/src/pin.tsx rename to examples/mapbox/draggable-markers/src/pin.tsx diff --git a/examples/draggable-markers/tsconfig.json b/examples/mapbox/draggable-markers/tsconfig.json similarity index 100% rename from examples/draggable-markers/tsconfig.json rename to examples/mapbox/draggable-markers/tsconfig.json diff --git a/examples/draggable-markers/vite.config.js b/examples/mapbox/draggable-markers/vite.config.js similarity index 100% rename from examples/draggable-markers/vite.config.js rename to examples/mapbox/draggable-markers/vite.config.js diff --git a/examples/draw-polygon/README.md b/examples/mapbox/draw-polygon/README.md similarity index 85% rename from examples/draw-polygon/README.md rename to examples/mapbox/draw-polygon/README.md index 5b31b6bd9..80853d0c6 100644 --- a/examples/draw-polygon/README.md +++ b/examples/mapbox/draw-polygon/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/draw-polygon/index.html b/examples/mapbox/draw-polygon/index.html similarity index 100% rename from examples/draw-polygon/index.html rename to examples/mapbox/draw-polygon/index.html diff --git a/examples/draw-polygon/package.json b/examples/mapbox/draw-polygon/package.json similarity index 74% rename from examples/draw-polygon/package.json rename to examples/mapbox/draw-polygon/package.json index ed673640e..1f47c9db9 100644 --- a/examples/draw-polygon/package.json +++ b/examples/mapbox/draw-polygon/package.json @@ -1,7 +1,7 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { @@ -10,8 +10,8 @@ "@turf/area": "^6.5.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/draw-polygon/src/app.tsx b/examples/mapbox/draw-polygon/src/app.tsx similarity index 97% rename from examples/draw-polygon/src/app.tsx rename to examples/mapbox/draw-polygon/src/app.tsx index 55706dceb..e81f222fd 100644 --- a/examples/draw-polygon/src/app.tsx +++ b/examples/mapbox/draw-polygon/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import DrawControl from './draw-control'; import ControlPanel from './control-panel'; diff --git a/examples/draw-polygon/src/control-panel.tsx b/examples/mapbox/draw-polygon/src/control-panel.tsx similarity index 100% rename from examples/draw-polygon/src/control-panel.tsx rename to examples/mapbox/draw-polygon/src/control-panel.tsx diff --git a/examples/draw-polygon/src/draw-control.ts b/examples/mapbox/draw-polygon/src/draw-control.ts similarity index 89% rename from examples/draw-polygon/src/draw-control.ts rename to examples/mapbox/draw-polygon/src/draw-control.ts index 42f71dd13..4e8170548 100644 --- a/examples/draw-polygon/src/draw-control.ts +++ b/examples/mapbox/draw-polygon/src/draw-control.ts @@ -1,7 +1,7 @@ import MapboxDraw from '@mapbox/mapbox-gl-draw'; -import {useControl} from 'react-map-gl'; +import {useControl} from 'react-map-gl/mapbox'; -import type {ControlPosition} from 'react-map-gl'; +import type {ControlPosition} from 'react-map-gl/mapbox'; type DrawControlProps = ConstructorParameters[0] & { position?: ControlPosition; diff --git a/examples/draw-polygon/tsconfig.json b/examples/mapbox/draw-polygon/tsconfig.json similarity index 100% rename from examples/draw-polygon/tsconfig.json rename to examples/mapbox/draw-polygon/tsconfig.json diff --git a/examples/draw-polygon/vite.config.js b/examples/mapbox/draw-polygon/vite.config.js similarity index 100% rename from examples/draw-polygon/vite.config.js rename to examples/mapbox/draw-polygon/vite.config.js diff --git a/examples/filter/README.md b/examples/mapbox/filter/README.md similarity index 87% rename from examples/filter/README.md rename to examples/mapbox/filter/README.md index 43a5c91e9..8c5101c50 100644 --- a/examples/filter/README.md +++ b/examples/mapbox/filter/README.md @@ -15,5 +15,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/filter/index.html b/examples/mapbox/filter/index.html similarity index 100% rename from examples/filter/index.html rename to examples/mapbox/filter/index.html diff --git a/examples/mapbox/filter/package.json b/examples/mapbox/filter/package.json new file mode 100644 index 000000000..94735163a --- /dev/null +++ b/examples/mapbox/filter/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "mapbox-gl": "^3.5.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/filter/src/app.tsx b/examples/mapbox/filter/src/app.tsx similarity index 96% rename from examples/filter/src/app.tsx rename to examples/mapbox/filter/src/app.tsx index 2a4aabd01..c0bba0bff 100644 --- a/examples/filter/src/app.tsx +++ b/examples/mapbox/filter/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState, useMemo, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {Popup, Source, Layer} from 'react-map-gl'; +import Map, {Popup, Source, Layer} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; import {countiesLayer, highlightLayer} from './map-style'; diff --git a/examples/filter/src/control-panel.tsx b/examples/mapbox/filter/src/control-panel.tsx similarity index 100% rename from examples/filter/src/control-panel.tsx rename to examples/mapbox/filter/src/control-panel.tsx diff --git a/examples/filter/src/map-style.ts b/examples/mapbox/filter/src/map-style.ts similarity index 90% rename from examples/filter/src/map-style.ts rename to examples/mapbox/filter/src/map-style.ts index 556c2cc1e..e2c29be98 100644 --- a/examples/filter/src/map-style.ts +++ b/examples/mapbox/filter/src/map-style.ts @@ -1,4 +1,4 @@ -import type {FillLayer} from 'react-map-gl'; +import type {FillLayer} from 'react-map-gl/mapbox'; export const countiesLayer: FillLayer = { id: 'counties', diff --git a/examples/filter/tsconfig.json b/examples/mapbox/filter/tsconfig.json similarity index 100% rename from examples/filter/tsconfig.json rename to examples/mapbox/filter/tsconfig.json diff --git a/examples/filter/vite.config.js b/examples/mapbox/filter/vite.config.js similarity index 100% rename from examples/filter/vite.config.js rename to examples/mapbox/filter/vite.config.js diff --git a/examples/geocoder/README.md b/examples/mapbox/geocoder/README.md similarity index 85% rename from examples/geocoder/README.md rename to examples/mapbox/geocoder/README.md index aa34b5329..512f4dfcd 100644 --- a/examples/geocoder/README.md +++ b/examples/mapbox/geocoder/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/geocoder/index.html b/examples/mapbox/geocoder/index.html similarity index 100% rename from examples/geocoder/index.html rename to examples/mapbox/geocoder/index.html diff --git a/examples/geocoder/package.json b/examples/mapbox/geocoder/package.json similarity index 73% rename from examples/geocoder/package.json rename to examples/mapbox/geocoder/package.json index 7f93f4e55..52eb3ee07 100644 --- a/examples/geocoder/package.json +++ b/examples/mapbox/geocoder/package.json @@ -1,7 +1,7 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { @@ -9,8 +9,8 @@ "@types/mapbox__mapbox-gl-geocoder": "^4.7.2", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/geocoder/src/app.tsx b/examples/mapbox/geocoder/src/app.tsx similarity index 95% rename from examples/geocoder/src/app.tsx rename to examples/mapbox/geocoder/src/app.tsx index b294e2817..1a9be93c8 100644 --- a/examples/geocoder/src/app.tsx +++ b/examples/mapbox/geocoder/src/app.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import GeocoderControl from './geocoder-control'; import ControlPanel from './control-panel'; diff --git a/examples/geocoder/src/control-panel.tsx b/examples/mapbox/geocoder/src/control-panel.tsx similarity index 100% rename from examples/geocoder/src/control-panel.tsx rename to examples/mapbox/geocoder/src/control-panel.tsx diff --git a/examples/geocoder/src/geocoder-control.tsx b/examples/mapbox/geocoder/src/geocoder-control.tsx similarity index 99% rename from examples/geocoder/src/geocoder-control.tsx rename to examples/mapbox/geocoder/src/geocoder-control.tsx index ddb5421a7..540136f52 100644 --- a/examples/geocoder/src/geocoder-control.tsx +++ b/examples/mapbox/geocoder/src/geocoder-control.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import {useState} from 'react'; -import {useControl, Marker, MarkerProps, ControlPosition} from 'react-map-gl'; +import {useControl, Marker, MarkerProps, ControlPosition} from 'react-map-gl/mapbox'; import MapboxGeocoder, {GeocoderOptions} from '@mapbox/mapbox-gl-geocoder'; type GeocoderControlProps = Omit & { diff --git a/examples/geocoder/tsconfig.json b/examples/mapbox/geocoder/tsconfig.json similarity index 100% rename from examples/geocoder/tsconfig.json rename to examples/mapbox/geocoder/tsconfig.json diff --git a/examples/geocoder/vite.config.js b/examples/mapbox/geocoder/vite.config.js similarity index 100% rename from examples/geocoder/vite.config.js rename to examples/mapbox/geocoder/vite.config.js diff --git a/examples/geojson-animation/README.md b/examples/mapbox/geojson-animation/README.md similarity index 87% rename from examples/geojson-animation/README.md rename to examples/mapbox/geojson-animation/README.md index 081940af5..e9235318f 100644 --- a/examples/geojson-animation/README.md +++ b/examples/mapbox/geojson-animation/README.md @@ -15,5 +15,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/geojson-animation/index.html b/examples/mapbox/geojson-animation/index.html similarity index 100% rename from examples/geojson-animation/index.html rename to examples/mapbox/geojson-animation/index.html diff --git a/examples/mapbox/geojson-animation/package.json b/examples/mapbox/geojson-animation/package.json new file mode 100644 index 000000000..d25a4764a --- /dev/null +++ b/examples/mapbox/geojson-animation/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/geojson-animation/src/app.tsx b/examples/mapbox/geojson-animation/src/app.tsx similarity index 92% rename from examples/geojson-animation/src/app.tsx rename to examples/mapbox/geojson-animation/src/app.tsx index fefe30e9f..d2fea86a5 100644 --- a/examples/geojson-animation/src/app.tsx +++ b/examples/mapbox/geojson-animation/src/app.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import {useState, useEffect} from 'react'; import {createRoot} from 'react-dom/client'; -import {Map, Source, Layer} from 'react-map-gl'; -import type {LayerProps} from 'react-map-gl'; +import {Map, Source, Layer} from 'react-map-gl/mapbox'; +import type {LayerProps} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; diff --git a/examples/geojson-animation/src/control-panel.tsx b/examples/mapbox/geojson-animation/src/control-panel.tsx similarity index 100% rename from examples/geojson-animation/src/control-panel.tsx rename to examples/mapbox/geojson-animation/src/control-panel.tsx diff --git a/examples/geojson-animation/tsconfig.json b/examples/mapbox/geojson-animation/tsconfig.json similarity index 100% rename from examples/geojson-animation/tsconfig.json rename to examples/mapbox/geojson-animation/tsconfig.json diff --git a/examples/geojson-animation/vite.config.js b/examples/mapbox/geojson-animation/vite.config.js similarity index 100% rename from examples/geojson-animation/vite.config.js rename to examples/mapbox/geojson-animation/vite.config.js diff --git a/examples/geojson/README.md b/examples/mapbox/geojson/README.md similarity index 84% rename from examples/geojson/README.md rename to examples/mapbox/geojson/README.md index 6fe1be0be..bf213e563 100644 --- a/examples/geojson/README.md +++ b/examples/mapbox/geojson/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/geojson/index.html b/examples/mapbox/geojson/index.html similarity index 100% rename from examples/geojson/index.html rename to examples/mapbox/geojson/index.html diff --git a/examples/geojson/package.json b/examples/mapbox/geojson/package.json similarity index 70% rename from examples/geojson/package.json rename to examples/mapbox/geojson/package.json index 161908acb..fa6e6855c 100644 --- a/examples/geojson/package.json +++ b/examples/mapbox/geojson/package.json @@ -1,16 +1,16 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "d3-array": "^3.1.1", "d3-scale": "^4.0.2", - "mapbox-gl": "^2.0.0", + "mapbox-gl": "^3.5.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" + "react-map-gl": "^8.0.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/geojson/src/app.tsx b/examples/mapbox/geojson/src/app.tsx similarity index 97% rename from examples/geojson/src/app.tsx rename to examples/mapbox/geojson/src/app.tsx index f8cf5f049..1f5f44cf8 100644 --- a/examples/geojson/src/app.tsx +++ b/examples/mapbox/geojson/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState, useEffect, useMemo, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {Source, Layer} from 'react-map-gl'; +import Map, {Source, Layer} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; import {dataLayer} from './map-style'; diff --git a/examples/geojson/src/control-panel.tsx b/examples/mapbox/geojson/src/control-panel.tsx similarity index 100% rename from examples/geojson/src/control-panel.tsx rename to examples/mapbox/geojson/src/control-panel.tsx diff --git a/examples/geojson/src/map-style.ts b/examples/mapbox/geojson/src/map-style.ts similarity index 90% rename from examples/geojson/src/map-style.ts rename to examples/mapbox/geojson/src/map-style.ts index cce6f9421..54aa15479 100644 --- a/examples/geojson/src/map-style.ts +++ b/examples/mapbox/geojson/src/map-style.ts @@ -1,4 +1,4 @@ -import type {LayerProps} from 'react-map-gl'; +import type {LayerProps} from 'react-map-gl/mapbox'; // For more information on data-driven styles, see https://www.mapbox.com/help/gl-dds-ref/ export const dataLayer: LayerProps = { diff --git a/examples/geojson/src/utils.ts b/examples/mapbox/geojson/src/utils.ts similarity index 100% rename from examples/geojson/src/utils.ts rename to examples/mapbox/geojson/src/utils.ts diff --git a/examples/geojson/tsconfig.json b/examples/mapbox/geojson/tsconfig.json similarity index 100% rename from examples/geojson/tsconfig.json rename to examples/mapbox/geojson/tsconfig.json diff --git a/examples/geojson/vite.config.js b/examples/mapbox/geojson/vite.config.js similarity index 100% rename from examples/geojson/vite.config.js rename to examples/mapbox/geojson/vite.config.js diff --git a/examples/heatmap/README.md b/examples/mapbox/heatmap/README.md similarity index 85% rename from examples/heatmap/README.md rename to examples/mapbox/heatmap/README.md index 1c8a0257b..952215c38 100644 --- a/examples/heatmap/README.md +++ b/examples/mapbox/heatmap/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/heatmap/index.html b/examples/mapbox/heatmap/index.html similarity index 100% rename from examples/heatmap/index.html rename to examples/mapbox/heatmap/index.html diff --git a/examples/mapbox/heatmap/package.json b/examples/mapbox/heatmap/package.json new file mode 100644 index 000000000..d25a4764a --- /dev/null +++ b/examples/mapbox/heatmap/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/heatmap/src/app.tsx b/examples/mapbox/heatmap/src/app.tsx similarity index 97% rename from examples/heatmap/src/app.tsx rename to examples/mapbox/heatmap/src/app.tsx index 7715bfb75..7cc0a6abb 100644 --- a/examples/heatmap/src/app.tsx +++ b/examples/mapbox/heatmap/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState, useEffect, useMemo} from 'react'; import {createRoot} from 'react-dom/client'; -import MapGL, {Source, Layer} from 'react-map-gl'; +import MapGL, {Source, Layer} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; import {heatmapLayer} from './map-style'; diff --git a/examples/heatmap/src/control-panel.tsx b/examples/mapbox/heatmap/src/control-panel.tsx similarity index 100% rename from examples/heatmap/src/control-panel.tsx rename to examples/mapbox/heatmap/src/control-panel.tsx diff --git a/examples/heatmap/src/map-style.ts b/examples/mapbox/heatmap/src/map-style.ts similarity index 95% rename from examples/heatmap/src/map-style.ts rename to examples/mapbox/heatmap/src/map-style.ts index 3fb22bae0..8c55d8a65 100644 --- a/examples/heatmap/src/map-style.ts +++ b/examples/mapbox/heatmap/src/map-style.ts @@ -1,4 +1,4 @@ -import type {LayerProps} from 'react-map-gl'; +import type {LayerProps} from 'react-map-gl/mapbox'; const MAX_ZOOM_LEVEL = 9; diff --git a/examples/heatmap/tsconfig.json b/examples/mapbox/heatmap/tsconfig.json similarity index 100% rename from examples/heatmap/tsconfig.json rename to examples/mapbox/heatmap/tsconfig.json diff --git a/examples/heatmap/vite.config.js b/examples/mapbox/heatmap/vite.config.js similarity index 100% rename from examples/heatmap/vite.config.js rename to examples/mapbox/heatmap/vite.config.js diff --git a/examples/interaction/README.md b/examples/mapbox/interaction/README.md similarity index 84% rename from examples/interaction/README.md rename to examples/mapbox/interaction/README.md index b3295fefc..2e1da4e67 100644 --- a/examples/interaction/README.md +++ b/examples/mapbox/interaction/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/interaction/index.html b/examples/mapbox/interaction/index.html similarity index 100% rename from examples/interaction/index.html rename to examples/mapbox/interaction/index.html diff --git a/examples/mapbox/interaction/package.json b/examples/mapbox/interaction/package.json new file mode 100644 index 000000000..d25a4764a --- /dev/null +++ b/examples/mapbox/interaction/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/interaction/src/app.tsx b/examples/mapbox/interaction/src/app.tsx similarity index 96% rename from examples/interaction/src/app.tsx rename to examples/mapbox/interaction/src/app.tsx index 13dc46e01..2c1d2f8a7 100644 --- a/examples/interaction/src/app.tsx +++ b/examples/mapbox/interaction/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; const MAPBOX_TOKEN = ''; // Set your mapbox token here diff --git a/examples/interaction/src/control-panel.tsx b/examples/mapbox/interaction/src/control-panel.tsx similarity index 100% rename from examples/interaction/src/control-panel.tsx rename to examples/mapbox/interaction/src/control-panel.tsx diff --git a/examples/interaction/tsconfig.json b/examples/mapbox/interaction/tsconfig.json similarity index 100% rename from examples/interaction/tsconfig.json rename to examples/mapbox/interaction/tsconfig.json diff --git a/examples/interaction/vite.config.js b/examples/mapbox/interaction/vite.config.js similarity index 100% rename from examples/interaction/vite.config.js rename to examples/mapbox/interaction/vite.config.js diff --git a/examples/layers/README.md b/examples/mapbox/layers/README.md similarity index 84% rename from examples/layers/README.md rename to examples/mapbox/layers/README.md index 527485004..c45e30529 100644 --- a/examples/layers/README.md +++ b/examples/mapbox/layers/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/layers/index.html b/examples/mapbox/layers/index.html similarity index 100% rename from examples/layers/index.html rename to examples/mapbox/layers/index.html diff --git a/examples/layers/package.json b/examples/mapbox/layers/package.json similarity index 68% rename from examples/layers/package.json rename to examples/mapbox/layers/package.json index c219a0eaa..a53832b61 100644 --- a/examples/layers/package.json +++ b/examples/mapbox/layers/package.json @@ -1,15 +1,15 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "immutable": "^4.0.0", - "mapbox-gl": "^2.0.0", + "mapbox-gl": "^3.5.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" + "react-map-gl": "^8.0.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/layers/src/app.tsx b/examples/mapbox/layers/src/app.tsx similarity index 94% rename from examples/layers/src/app.tsx rename to examples/mapbox/layers/src/app.tsx index fe72c4075..4c11a6af9 100644 --- a/examples/layers/src/app.tsx +++ b/examples/mapbox/layers/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState} from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; const MAPBOX_TOKEN = ''; // Set your mapbox token here diff --git a/examples/layers/src/control-panel.tsx b/examples/mapbox/layers/src/control-panel.tsx similarity index 98% rename from examples/layers/src/control-panel.tsx rename to examples/mapbox/layers/src/control-panel.tsx index 626ccbe20..3bfe2a362 100644 --- a/examples/layers/src/control-panel.tsx +++ b/examples/mapbox/layers/src/control-panel.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useState, useEffect} from 'react'; import {fromJS} from 'immutable'; -import MAP_STYLE from '../../map-style-basic-v8.json'; +import MAP_STYLE from '../../../map-style-basic-v8.json'; const defaultMapStyle: any = fromJS(MAP_STYLE); const defaultLayers = defaultMapStyle.get('layers'); diff --git a/examples/layers/tsconfig.json b/examples/mapbox/layers/tsconfig.json similarity index 100% rename from examples/layers/tsconfig.json rename to examples/mapbox/layers/tsconfig.json diff --git a/examples/layers/vite.config.js b/examples/mapbox/layers/vite.config.js similarity index 100% rename from examples/layers/vite.config.js rename to examples/mapbox/layers/vite.config.js diff --git a/examples/side-by-side/README.md b/examples/mapbox/side-by-side/README.md similarity index 84% rename from examples/side-by-side/README.md rename to examples/mapbox/side-by-side/README.md index dc16d1099..f11ec3cf8 100644 --- a/examples/side-by-side/README.md +++ b/examples/mapbox/side-by-side/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/side-by-side/index.html b/examples/mapbox/side-by-side/index.html similarity index 100% rename from examples/side-by-side/index.html rename to examples/mapbox/side-by-side/index.html diff --git a/examples/mapbox/side-by-side/package.json b/examples/mapbox/side-by-side/package.json new file mode 100644 index 000000000..94735163a --- /dev/null +++ b/examples/mapbox/side-by-side/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "mapbox-gl": "^3.5.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/side-by-side/src/app.tsx b/examples/mapbox/side-by-side/src/app.tsx similarity index 98% rename from examples/side-by-side/src/app.tsx rename to examples/mapbox/side-by-side/src/app.tsx index 7ff619331..cb1b00415 100644 --- a/examples/side-by-side/src/app.tsx +++ b/examples/mapbox/side-by-side/src/app.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import {useState, useCallback, useMemo} from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import ControlPanel, {Mode} from './control-panel'; diff --git a/examples/side-by-side/src/control-panel.tsx b/examples/mapbox/side-by-side/src/control-panel.tsx similarity index 100% rename from examples/side-by-side/src/control-panel.tsx rename to examples/mapbox/side-by-side/src/control-panel.tsx diff --git a/examples/side-by-side/tsconfig.json b/examples/mapbox/side-by-side/tsconfig.json similarity index 100% rename from examples/side-by-side/tsconfig.json rename to examples/mapbox/side-by-side/tsconfig.json diff --git a/examples/side-by-side/vite.config.js b/examples/mapbox/side-by-side/vite.config.js similarity index 100% rename from examples/side-by-side/vite.config.js rename to examples/mapbox/side-by-side/vite.config.js diff --git a/examples/terrain/README.md b/examples/mapbox/terrain/README.md similarity index 84% rename from examples/terrain/README.md rename to examples/mapbox/terrain/README.md index 83f325501..c7a18e026 100644 --- a/examples/terrain/README.md +++ b/examples/mapbox/terrain/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/terrain/index.html b/examples/mapbox/terrain/index.html similarity index 100% rename from examples/terrain/index.html rename to examples/mapbox/terrain/index.html diff --git a/examples/mapbox/terrain/package.json b/examples/mapbox/terrain/package.json new file mode 100644 index 000000000..94735163a --- /dev/null +++ b/examples/mapbox/terrain/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "mapbox-gl": "^3.5.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/terrain/src/app.tsx b/examples/mapbox/terrain/src/app.tsx similarity index 91% rename from examples/terrain/src/app.tsx rename to examples/mapbox/terrain/src/app.tsx index d3bdbe6f5..5937915ea 100644 --- a/examples/terrain/src/app.tsx +++ b/examples/mapbox/terrain/src/app.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {Source, Layer} from 'react-map-gl'; +import Map, {Source, Layer} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; -import type {SkyLayer} from 'react-map-gl'; +import type {SkyLayer} from 'react-map-gl/mapbox'; const TOKEN = ''; // Set your mapbox token here diff --git a/examples/terrain/src/control-panel.tsx b/examples/mapbox/terrain/src/control-panel.tsx similarity index 100% rename from examples/terrain/src/control-panel.tsx rename to examples/mapbox/terrain/src/control-panel.tsx diff --git a/examples/terrain/tsconfig.json b/examples/mapbox/terrain/tsconfig.json similarity index 100% rename from examples/terrain/tsconfig.json rename to examples/mapbox/terrain/tsconfig.json diff --git a/examples/terrain/vite.config.js b/examples/mapbox/terrain/vite.config.js similarity index 100% rename from examples/terrain/vite.config.js rename to examples/mapbox/terrain/vite.config.js diff --git a/examples/viewport-animation/README.md b/examples/mapbox/viewport-animation/README.md similarity index 85% rename from examples/viewport-animation/README.md rename to examples/mapbox/viewport-animation/README.md index 670da1920..9a06233e0 100644 --- a/examples/viewport-animation/README.md +++ b/examples/mapbox/viewport-animation/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/viewport-animation/index.html b/examples/mapbox/viewport-animation/index.html similarity index 100% rename from examples/viewport-animation/index.html rename to examples/mapbox/viewport-animation/index.html diff --git a/examples/mapbox/viewport-animation/package.json b/examples/mapbox/viewport-animation/package.json new file mode 100644 index 000000000..d25a4764a --- /dev/null +++ b/examples/mapbox/viewport-animation/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.5.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/viewport-animation/src/app.tsx b/examples/mapbox/viewport-animation/src/app.tsx similarity index 94% rename from examples/viewport-animation/src/app.tsx rename to examples/mapbox/viewport-animation/src/app.tsx index c03085005..70ad0f12c 100644 --- a/examples/viewport-animation/src/app.tsx +++ b/examples/mapbox/viewport-animation/src/app.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {useRef, useCallback} from 'react'; import {createRoot} from 'react-dom/client'; -import Map, {MapRef} from 'react-map-gl'; +import Map, {MapRef} from 'react-map-gl/mapbox'; import ControlPanel from './control-panel'; diff --git a/examples/viewport-animation/src/control-panel.tsx b/examples/mapbox/viewport-animation/src/control-panel.tsx similarity index 95% rename from examples/viewport-animation/src/control-panel.tsx rename to examples/mapbox/viewport-animation/src/control-panel.tsx index 9fbd3a4f8..a0b9c9fe8 100644 --- a/examples/viewport-animation/src/control-panel.tsx +++ b/examples/mapbox/viewport-animation/src/control-panel.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import CITIES from '../../.data/cities.json'; +import CITIES from '../../../.data/cities.json'; function ControlPanel(props) { return ( diff --git a/examples/viewport-animation/tsconfig.json b/examples/mapbox/viewport-animation/tsconfig.json similarity index 100% rename from examples/viewport-animation/tsconfig.json rename to examples/mapbox/viewport-animation/tsconfig.json diff --git a/examples/viewport-animation/vite.config.js b/examples/mapbox/viewport-animation/vite.config.js similarity index 100% rename from examples/viewport-animation/vite.config.js rename to examples/mapbox/viewport-animation/vite.config.js diff --git a/examples/zoom-to-bounds/README.md b/examples/mapbox/zoom-to-bounds/README.md similarity index 84% rename from examples/zoom-to-bounds/README.md rename to examples/mapbox/zoom-to-bounds/README.md index 1e4e8f063..139873088 100644 --- a/examples/zoom-to-bounds/README.md +++ b/examples/mapbox/zoom-to-bounds/README.md @@ -13,5 +13,5 @@ npm run start Alternative to acquiring a Mapbox token, you can use `maplibre-gl` instead. Follow these steps: - Run `npm install maplibre-gl` -- In the source, change all `import ... from 'react-map-gl'` to `import ... from 'react-map-gl/maplibre'` +- In the source, change all `import ... from 'react-map-gl/mapbox'` to `import ... from 'react-map-gl/maplibre'` - Change the `mapStyle` prop of `` to `"https://demotiles.maplibre.org/style.json"` or a self-hosted URL diff --git a/examples/zoom-to-bounds/index.html b/examples/mapbox/zoom-to-bounds/index.html similarity index 100% rename from examples/zoom-to-bounds/index.html rename to examples/mapbox/zoom-to-bounds/index.html diff --git a/examples/zoom-to-bounds/package.json b/examples/mapbox/zoom-to-bounds/package.json similarity index 68% rename from examples/zoom-to-bounds/package.json rename to examples/mapbox/zoom-to-bounds/package.json index 4004f5bd7..dcbc39336 100644 --- a/examples/zoom-to-bounds/package.json +++ b/examples/mapbox/zoom-to-bounds/package.json @@ -1,15 +1,15 @@ { "scripts": { "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", + "start-local": "vite --config ../../vite.config.local.js", "build": "vite build" }, "dependencies": { "@turf/bbox": "^6.5.0", - "mapbox-gl": "^2.0.0", + "mapbox-gl": "^3.5.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" + "react-map-gl": "^8.0.0" }, "devDependencies": { "typescript": "^4.0.0", diff --git a/examples/zoom-to-bounds/src/app.tsx b/examples/mapbox/zoom-to-bounds/src/app.tsx similarity index 87% rename from examples/zoom-to-bounds/src/app.tsx rename to examples/mapbox/zoom-to-bounds/src/app.tsx index 6693d694b..26c0d26ae 100644 --- a/examples/zoom-to-bounds/src/app.tsx +++ b/examples/mapbox/zoom-to-bounds/src/app.tsx @@ -1,13 +1,13 @@ import * as React from 'react'; import {useRef} from 'react'; import {createRoot} from 'react-dom/client'; -import Map from 'react-map-gl'; +import Map from 'react-map-gl/mapbox'; import bbox from '@turf/bbox'; import ControlPanel from './control-panel'; import MAP_STYLE from './map-style'; -import type {MapboxStyle, MapRef, MapLayerMouseEvent} from 'react-map-gl'; +import type {MapStyle, MapRef, MapLayerMouseEvent} from 'react-map-gl/mapbox'; const TOKEN = ''; // Set your mapbox token here @@ -39,7 +39,7 @@ export default function App() { longitude: -122.4, zoom: 11 }} - mapStyle={MAP_STYLE as MapboxStyle} + mapStyle={MAP_STYLE as MapStyle} interactiveLayerIds={['sf-neighborhoods-fill']} onClick={onClick} mapboxAccessToken={TOKEN} diff --git a/examples/zoom-to-bounds/src/control-panel.tsx b/examples/mapbox/zoom-to-bounds/src/control-panel.tsx similarity index 100% rename from examples/zoom-to-bounds/src/control-panel.tsx rename to examples/mapbox/zoom-to-bounds/src/control-panel.tsx diff --git a/examples/zoom-to-bounds/src/map-style.tsx b/examples/mapbox/zoom-to-bounds/src/map-style.tsx similarity index 80% rename from examples/zoom-to-bounds/src/map-style.tsx rename to examples/mapbox/zoom-to-bounds/src/map-style.tsx index bb47db3c8..33f899c3c 100644 --- a/examples/zoom-to-bounds/src/map-style.tsx +++ b/examples/mapbox/zoom-to-bounds/src/map-style.tsx @@ -1,8 +1,8 @@ -import type {GeoJSONSourceRaw, FillLayer, LineLayer} from 'react-map-gl'; +import type {GeoJSONSource, FillLayer, LineLayer} from 'react-map-gl/mapbox'; -import MAP_STYLE from '../../map-style-basic-v8.json'; +import MAP_STYLE from '../../../map-style-basic-v8.json'; -const sfNeighborhoods: GeoJSONSourceRaw = { +const sfNeighborhoods: GeoJSONSource = { type: 'geojson', data: 'https://raw.githubusercontent.com/uber/react-map-gl/master/examples/.data/feature-example-sf.json' }; diff --git a/examples/zoom-to-bounds/tsconfig.json b/examples/mapbox/zoom-to-bounds/tsconfig.json similarity index 100% rename from examples/zoom-to-bounds/tsconfig.json rename to examples/mapbox/zoom-to-bounds/tsconfig.json diff --git a/examples/zoom-to-bounds/vite.config.js b/examples/mapbox/zoom-to-bounds/vite.config.js similarity index 100% rename from examples/zoom-to-bounds/vite.config.js rename to examples/mapbox/zoom-to-bounds/vite.config.js diff --git a/examples/maplibre/clusters/README.md b/examples/maplibre/clusters/README.md new file mode 100644 index 000000000..c50132395 --- /dev/null +++ b/examples/maplibre/clusters/README.md @@ -0,0 +1,12 @@ +# Example: Supercluster + +This app reproduces Maplibre's [Create and style clusters](https://maplibre.org/maplibre-gl-js/docs/examples/cluster/) example. + +This example showcases how to visualize points as clusters. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/clusters/index.html b/examples/maplibre/clusters/index.html new file mode 100644 index 000000000..e310935c5 --- /dev/null +++ b/examples/maplibre/clusters/index.html @@ -0,0 +1,40 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/clusters/package.json b/examples/maplibre/clusters/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/clusters/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/clusters/src/app.tsx b/examples/maplibre/clusters/src/app.tsx new file mode 100644 index 000000000..af3e2f9ab --- /dev/null +++ b/examples/maplibre/clusters/src/app.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import {useRef} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, Source, Layer} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; +import {clusterLayer, clusterCountLayer, unclusteredPointLayer} from './layers'; + +import type {MapRef, MapMouseEvent} from 'react-map-gl/maplibre'; +import type {GeoJSONSource} from 'maplibre-gl'; + +export default function App() { + const mapRef = useRef(null); + + const onClick = async (event: MapMouseEvent) => { + const feature = event.features[0]; + if (!feature) { + return; + } + const clusterId = feature.properties.cluster_id; + + const geojsonSource: GeoJSONSource = mapRef.current.getSource('earthquakes'); + + const zoom = await geojsonSource.getClusterExpansionZoom(clusterId); + + mapRef.current.easeTo({ + center: feature.geometry.coordinates, + zoom, + duration: 500 + }); + }; + + return ( + <> + + + + + + + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/clusters/src/control-panel.tsx b/examples/maplibre/clusters/src/control-panel.tsx new file mode 100644 index 000000000..db22b89dd --- /dev/null +++ b/examples/maplibre/clusters/src/control-panel.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Create and Style Clusters

+

Use Maplibre GL JS' built-in functions to visualize points as clusters.

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/clusters/src/layers.ts b/examples/maplibre/clusters/src/layers.ts new file mode 100644 index 000000000..3a0d3a35a --- /dev/null +++ b/examples/maplibre/clusters/src/layers.ts @@ -0,0 +1,36 @@ +import type {LayerProps} from 'react-map-gl/maplibre'; + +export const clusterLayer: LayerProps = { + id: 'clusters', + type: 'circle', + source: 'earthquakes', + filter: ['has', 'point_count'], + paint: { + 'circle-color': ['step', ['get', 'point_count'], '#51bbd6', 100, '#f1f075', 750, '#f28cb1'], + 'circle-radius': ['step', ['get', 'point_count'], 20, 100, 30, 750, 40] + } +}; + +export const clusterCountLayer: LayerProps = { + id: 'cluster-count', + type: 'symbol', + source: 'earthquakes', + filter: ['has', 'point_count'], + layout: { + 'text-field': '{point_count_abbreviated}', + 'text-size': 12 + } +}; + +export const unclusteredPointLayer: LayerProps = { + id: 'unclustered-point', + type: 'circle', + source: 'earthquakes', + filter: ['!', ['has', 'point_count']], + paint: { + 'circle-color': '#11b4da', + 'circle-radius': 4, + 'circle-stroke-width': 1, + 'circle-stroke-color': '#fff' + } +}; diff --git a/examples/maplibre/clusters/tsconfig.json b/examples/maplibre/clusters/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/clusters/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/controls/README.md b/examples/maplibre/controls/README.md new file mode 100644 index 000000000..006579393 --- /dev/null +++ b/examples/maplibre/controls/README.md @@ -0,0 +1,10 @@ +# Example: Controls + +Demonstrates how various control components can be used with react-maplibre. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/controls/index.html b/examples/maplibre/controls/index.html new file mode 100644 index 000000000..e310935c5 --- /dev/null +++ b/examples/maplibre/controls/index.html @@ -0,0 +1,40 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/controls/package.json b/examples/maplibre/controls/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/controls/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/controls/src/app.tsx b/examples/maplibre/controls/src/app.tsx new file mode 100644 index 000000000..71ff81e28 --- /dev/null +++ b/examples/maplibre/controls/src/app.tsx @@ -0,0 +1,90 @@ +import * as React from 'react'; +import {useState, useMemo} from 'react'; +import {createRoot} from 'react-dom/client'; +import { + Map, + Marker, + Popup, + NavigationControl, + FullscreenControl, + ScaleControl, + GeolocateControl +} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; +import Pin from './pin'; + +import CITIES from '../../../.data/cities.json'; + +export default function App() { + const [popupInfo, setPopupInfo] = useState(null); + + const pins = useMemo( + () => + CITIES.map((city, index) => ( + { + // If we let the click event propagates to the map, it will immediately close the popup + // with `closeOnClick: true` + e.originalEvent.stopPropagation(); + setPopupInfo(city); + }} + > + + + )), + [] + ); + + return ( + <> + + + + + + + {pins} + + {popupInfo && ( + setPopupInfo(null)} + > +
+ {popupInfo.city}, {popupInfo.state} |{' '} + + Wikipedia + +
+ +
+ )} +
+ + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/controls/src/control-panel.tsx b/examples/maplibre/controls/src/control-panel.tsx new file mode 100644 index 000000000..917e35446 --- /dev/null +++ b/examples/maplibre/controls/src/control-panel.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Marker, Popup, NavigationControl and FullscreenControl

+

+ Map showing top 20 most populated cities of the United States. Click on a marker to learn + more. +

+

+ Data source:{' '} + + Wikipedia + +

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/controls/src/pin.tsx b/examples/maplibre/controls/src/pin.tsx new file mode 100644 index 000000000..c66933304 --- /dev/null +++ b/examples/maplibre/controls/src/pin.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; + +const ICON = `M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3 + c0,0,0.1,0.1,0.1,0.2c0.2,0.3,0.4,0.6,0.7,0.9c2.6,3.1,7.4,7.6,7.4,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9 + C20.1,15.8,20.2,15.8,20.2,15.7z`; + +const pinStyle = { + cursor: 'pointer', + fill: '#d00', + stroke: 'none' +}; + +function Pin({size = 20}) { + return ( + + + + ); +} + +export default React.memo(Pin); diff --git a/examples/maplibre/controls/tsconfig.json b/examples/maplibre/controls/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/controls/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/custom-cursor/README.md b/examples/maplibre/custom-cursor/README.md new file mode 100644 index 000000000..3147067b8 --- /dev/null +++ b/examples/maplibre/custom-cursor/README.md @@ -0,0 +1,10 @@ +# Example: Custom Cursor + +This example showcases how to dynamically change the cursor over the map based on interactivity. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/custom-cursor/index.html b/examples/maplibre/custom-cursor/index.html new file mode 100644 index 000000000..dda0569eb --- /dev/null +++ b/examples/maplibre/custom-cursor/index.html @@ -0,0 +1,51 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/custom-cursor/package.json b/examples/maplibre/custom-cursor/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/custom-cursor/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/custom-cursor/src/app.tsx b/examples/maplibre/custom-cursor/src/app.tsx new file mode 100644 index 000000000..80b78a600 --- /dev/null +++ b/examples/maplibre/custom-cursor/src/app.tsx @@ -0,0 +1,54 @@ +/* global window */ +import * as React from 'react'; +import {useState, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, MapStyle} from 'react-map-gl/maplibre'; +import ControlPanel from './control-panel'; +import MAP_STYLE from '../../../map-style-basic-v8.json'; + +const initialViewState = { + longitude: -122.48, + latitude: 37.78, + zoom: 15.5, + bearing: 0, + pitch: 0 +}; + +export default function App() { + const [cursor, setCursor] = useState('auto'); + const [interactiveLayerIds, setInteractiveLayerIds] = useState(['nonexist']); + + const onInteractiveLayersChange = useCallback(layerFilter => { + setInteractiveLayerIds(MAP_STYLE.layers.map(layer => layer.id).filter(layerFilter)); + }, []); + + const onClick = useCallback(event => { + const feature = event.features && event.features[0]; + + if (feature) { + window.alert(`Clicked layer ${feature.layer.id}`); // eslint-disable-line no-alert + } + }, []); + + const onMouseEnter = useCallback(() => setCursor('pointer'), []); + const onMouseLeave = useCallback(() => setCursor('auto'), []); + + return ( + <> + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/custom-cursor/src/control-panel.tsx b/examples/maplibre/custom-cursor/src/control-panel.tsx new file mode 100644 index 000000000..856aeedc2 --- /dev/null +++ b/examples/maplibre/custom-cursor/src/control-panel.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; +import {useState, useEffect} from 'react'; + +// Layer id patterns by category +const layerSelector = { + parks: /park/, + buildings: /building/, + roads: /bridge|road|tunnel/, + labels: /label|place|poi/ +}; + +function getLayerFilter(categories, layerId) { + for (const key in categories) { + if (categories[key] && layerSelector[key].test(layerId)) { + return true; + } + } + return false; +} + +function Checkbox({name, value, onChange}) { + return ( +
+ + onChange(name, evt.target.checked)} /> +
+ ); +} + +function StyleControls(props) { + const [categories, setCategories] = useState({ + parks: true, + buildings: true, + roads: true, + labels: true + }); + + useEffect(() => { + const filter = layerId => getLayerFilter(categories, layerId); + props.onChange(filter); + }, [categories]); + + const toggleLayer = (name, on) => { + setCategories({...categories, [name]: on}); + }; + + return ( +
+

Custom Cursor

+

Customize the cursor based on interactivity.

+ +
+

Clickable layers

+ {Object.keys(layerSelector).map(name => ( + + ))} +
+ ); +} + +export default React.memo(StyleControls); diff --git a/examples/maplibre/custom-cursor/tsconfig.json b/examples/maplibre/custom-cursor/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/custom-cursor/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/custom-overlay/README.md b/examples/maplibre/custom-overlay/README.md new file mode 100644 index 000000000..744e57de3 --- /dev/null +++ b/examples/maplibre/custom-overlay/README.md @@ -0,0 +1,10 @@ +# Example: SVG overlay + +This app shows how to implement a custom control that draws arbitrary React content that responds to camera updates. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/custom-overlay/index.html b/examples/maplibre/custom-overlay/index.html new file mode 100644 index 000000000..543ed88b3 --- /dev/null +++ b/examples/maplibre/custom-overlay/index.html @@ -0,0 +1,54 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/custom-overlay/package.json b/examples/maplibre/custom-overlay/package.json new file mode 100644 index 000000000..5fef98dd8 --- /dev/null +++ b/examples/maplibre/custom-overlay/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "d3-shape": "^3.1.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/custom-overlay/src/app.tsx b/examples/maplibre/custom-overlay/src/app.tsx new file mode 100644 index 000000000..4457d7318 --- /dev/null +++ b/examples/maplibre/custom-overlay/src/app.tsx @@ -0,0 +1,138 @@ +import * as React from 'react'; +import {useMemo, useState} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; +import {arc, pie} from 'd3-shape'; + +import CustomOverlay from './custom-overlay'; +import ControlPanel, {COLORS} from './control-panel'; + +import electionData from '../../../.data/us-election-2016.json'; + +import type {Map as MaplibreMap} from 'maplibre-gl'; + +// Shape of the sample data +type CountyElectionData = { + dem: number; + rep: number; + total: number; + name: string; + coordinates: [number, number]; +}; + +export default function App() { + return ( + <> + + + + + + + + ); +} + +function PieCharts({map, data}: {map?: MaplibreMap; data: any[]}) { + const [hoveredCounty, setHoveredCounty] = useState(null); + + const width = map.getContainer().clientWidth; + const height = map.getContainer().clientHeight; + + // Create pie chart shapes for each row + const pies = useMemo(() => data.map(d => makePieChart(d, setHoveredCounty)), [map, data]); + + // Position each pie chart at the map location + const [originLngLat, content] = useMemo(() => { + const scale = 2 ** Math.max(0, map.getZoom() - 6); + return [ + map.unproject([0, 0]), + data.map((d, i) => { + const centroid = map.project(d.coordinates); + return ( + + {pies[i]} + + ); + }) + ]; + }, [map.getZoom(), pies]); + + const origin = map.project(originLngLat); + + let tooltip; + if (hoveredCounty) { + const {dem = 0, rep = 0, total, coordinates, name} = hoveredCounty; + const tooltipLocation = map.project(coordinates); + tooltip = ( +
+
+ {name} +
+
+ Democrats: {dem} ({((dem / total) * 100).toPrecision(3)}%) +
+
+ Republican: {rep} ({((rep / total) * 100).toPrecision(3)}%) +
+
+ ); + } + + return ( + <> + + {content} + + {tooltip} + + ); +} + +function makePieChart(datum: CountyElectionData, onHover: (target: CountyElectionData) => void) { + const {dem = 0, rep = 0, total} = datum; + + const pathGenerator = arc(); + const arcs = pie()([dem, rep, total - dem - rep]); + const radius = Math.sqrt(total) / 60; + + return ( + onHover(datum)} + onMouseOut={() => onHover(null)} + > + {arcs.map((a, i) => ( + + ))} + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/custom-overlay/src/control-panel.tsx b/examples/maplibre/custom-overlay/src/control-panel.tsx new file mode 100644 index 000000000..c7cfef5a2 --- /dev/null +++ b/examples/maplibre/custom-overlay/src/control-panel.tsx @@ -0,0 +1,45 @@ +import * as React from 'react'; + +export const COLORS = ['#2b83ba', '#c7191c', '#c8c8cf']; + +const legendStyle = { + display: 'inline-block', + width: 16, + height: 8, + marginRight: 4 +}; + +function ControlPanel() { + return ( +
+

US Presidential Election 2016 By County

+
+
+
+ Democrat +
+
+
+ Republican +
+
+
+ Independent +
+
+

+ Data source: Harvard Dataverse +

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/custom-overlay/src/custom-overlay.tsx b/examples/maplibre/custom-overlay/src/custom-overlay.tsx new file mode 100644 index 000000000..f2debcf32 --- /dev/null +++ b/examples/maplibre/custom-overlay/src/custom-overlay.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import {useState, cloneElement} from 'react'; +import {useControl} from 'react-map-gl/maplibre'; +import {createPortal} from 'react-dom'; + +import type {IControl, MapInstance} from 'react-map-gl/maplibre'; + +class OverlayControl implements IControl { + _map: MapInstance = null; + _container: HTMLElement; + _redraw: () => void; + + constructor(redraw: () => void) { + this._redraw = redraw; + } + + onAdd(map) { + this._map = map; + map.on('move', this._redraw); + /* global document */ + this._container = document.createElement('div'); + this._redraw(); + return this._container; + } + + onRemove() { + this._container.remove(); + this._map.off('move', this._redraw); + this._map = null; + } + + getMap() { + return this._map; + } + + getElement() { + return this._container; + } +} + +/** + * A custom control that rerenders arbitrary React content whenever the camera changes + */ +function CustomOverlay(props: {children: React.ReactElement}) { + const [, setVersion] = useState(0); + + const ctrl = useControl(() => { + const forceUpdate = () => setVersion(v => v + 1); + return new OverlayControl(forceUpdate); + }); + + const map = ctrl.getMap(); + + return map && createPortal(cloneElement(props.children, {map}), ctrl.getElement()); +} + +export default React.memo(CustomOverlay); diff --git a/examples/maplibre/custom-overlay/tsconfig.json b/examples/maplibre/custom-overlay/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/custom-overlay/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/deckgl-overlay/README.md b/examples/maplibre/deckgl-overlay/README.md new file mode 100644 index 000000000..1203e8a02 --- /dev/null +++ b/examples/maplibre/deckgl-overlay/README.md @@ -0,0 +1,10 @@ +# Example: DeckGL Overlay + +This example demonstrates using [deck.gl](https://deck.gl) to render a data overlay on top of react-maplibre. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/deckgl-overlay/index.html b/examples/maplibre/deckgl-overlay/index.html new file mode 100644 index 000000000..8502d0f24 --- /dev/null +++ b/examples/maplibre/deckgl-overlay/index.html @@ -0,0 +1,26 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/deckgl-overlay/package.json b/examples/maplibre/deckgl-overlay/package.json new file mode 100644 index 000000000..fa0bbe539 --- /dev/null +++ b/examples/maplibre/deckgl-overlay/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "deck.gl": "^9.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/deckgl-overlay/src/app.tsx b/examples/maplibre/deckgl-overlay/src/app.tsx new file mode 100644 index 000000000..07020b1bd --- /dev/null +++ b/examples/maplibre/deckgl-overlay/src/app.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import {createRoot} from 'react-dom/client'; +import {ArcLayer} from '@deck.gl/layers'; +import {DeckProps, PickingInfo} from '@deck.gl/core'; +import {MapboxOverlay} from '@deck.gl/mapbox'; +import {Map, useControl, NavigationControl} from 'react-map-gl/maplibre'; + +const initialViewState = { + latitude: 37.78, + longitude: -122.45, + zoom: 12, + pitch: 45 +}; + +function DeckGLOverlay(props: DeckProps) { + const deck = useControl(() => new MapboxOverlay(props)); + + deck.setProps(props); + return null; +} + +// Type of elements in https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-segments.json +type DataT = { + inbound: number; + outbound: number; + from: { + name: string; + coordinates: [number, number]; + }; + to: { + name: string; + coordinates: [number, number]; + }; +}; + +export default function App() { + const arcLayer = new ArcLayer({ + data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-segments.json', + getSourcePosition: d => d.from.coordinates, + getTargetPosition: d => d.to.coordinates, + getSourceColor: [255, 200, 0], + getTargetColor: [0, 140, 255], + getWidth: 12, + pickable: true, + autoHighlight: true + }); + + return ( + + + + + ); +} + +function getTooltip(info: PickingInfo) { + const d = info.object as DataT; + return d && `${d.from.name} -- ${d.to.name}`; +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/deckgl-overlay/tsconfig.json b/examples/maplibre/deckgl-overlay/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/deckgl-overlay/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/draggable-markers/README.md b/examples/maplibre/draggable-markers/README.md new file mode 100644 index 000000000..b03f26bc6 --- /dev/null +++ b/examples/maplibre/draggable-markers/README.md @@ -0,0 +1,10 @@ +# Example: Draggable Marker + +Demonstrates how Marker component can be dragged with react-maplibre. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/draggable-markers/index.html b/examples/maplibre/draggable-markers/index.html new file mode 100644 index 000000000..6bd9f9d5f --- /dev/null +++ b/examples/maplibre/draggable-markers/index.html @@ -0,0 +1,41 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/draggable-markers/package.json b/examples/maplibre/draggable-markers/package.json new file mode 100644 index 000000000..767e9700a --- /dev/null +++ b/examples/maplibre/draggable-markers/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/draggable-markers/src/app.tsx b/examples/maplibre/draggable-markers/src/app.tsx new file mode 100644 index 000000000..487d551b6 --- /dev/null +++ b/examples/maplibre/draggable-markers/src/app.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; +import {useState, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, Marker, NavigationControl} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; +import Pin from './pin'; + +import type {MarkerDragEvent, LngLat} from 'react-map-gl/maplibre'; + +const initialViewState = { + latitude: 40, + longitude: -100, + zoom: 3.5 +}; + +export default function App() { + const [marker, setMarker] = useState({ + latitude: 40, + longitude: -100 + }); + const [events, logEvents] = useState>({}); + + const onMarkerDragStart = useCallback((event: MarkerDragEvent) => { + logEvents(_events => ({..._events, onDragStart: event.lngLat})); + }, []); + + const onMarkerDrag = useCallback((event: MarkerDragEvent) => { + logEvents(_events => ({..._events, onDrag: event.lngLat})); + + setMarker({ + longitude: event.lngLat.lng, + latitude: event.lngLat.lat + }); + }, []); + + const onMarkerDragEnd = useCallback((event: MarkerDragEvent) => { + logEvents(_events => ({..._events, onDragEnd: event.lngLat})); + }, []); + + return ( + <> + + + + + + + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/draggable-markers/src/control-panel.tsx b/examples/maplibre/draggable-markers/src/control-panel.tsx new file mode 100644 index 000000000..fcd1e2a12 --- /dev/null +++ b/examples/maplibre/draggable-markers/src/control-panel.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import type {LngLat} from 'react-map-gl/maplibre'; + +const eventNames = ['onDragStart', 'onDrag', 'onDragEnd']; + +function round5(value) { + return (Math.round(value * 1e5) / 1e5).toFixed(5); +} + +function ControlPanel(props: {events: Record}) { + return ( +
+

Draggable Marker

+

Try dragging the marker to another location.

+
+ {eventNames.map(eventName => { + const {events = {}} = props; + const lngLat = events[eventName]; + return ( +
+ {eventName}:{' '} + {lngLat ? `${round5(lngLat.lng)}, ${round5(lngLat.lat)}` : null} +
+ ); + })} +
+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/draggable-markers/src/pin.tsx b/examples/maplibre/draggable-markers/src/pin.tsx new file mode 100644 index 000000000..2c155a996 --- /dev/null +++ b/examples/maplibre/draggable-markers/src/pin.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; + +const ICON = `M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3 + c0,0,0.1,0.1,0.1,0.2c0.2,0.3,0.4,0.6,0.7,0.9c2.6,3.1,7.4,7.6,7.4,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9 + C20.1,15.8,20.2,15.8,20.2,15.7z`; + +const pinStyle = { + fill: '#d00', + stroke: 'none' +}; + +function Pin(props) { + const {size = 20} = props; + + return ( + + + + ); +} + +export default React.memo(Pin); diff --git a/examples/maplibre/draggable-markers/tsconfig.json b/examples/maplibre/draggable-markers/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/draggable-markers/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/draw-polygon/README.md b/examples/maplibre/draw-polygon/README.md new file mode 100644 index 000000000..33b0ebda6 --- /dev/null +++ b/examples/maplibre/draw-polygon/README.md @@ -0,0 +1,10 @@ +# Example: Draw Polygon + +This app reproduces Mapbox's [Draw a polygon and calculate its area](https://docs.mapbox.com/mapbox-gl-js/example/mapbox-gl-draw/) example. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/draw-polygon/index.html b/examples/maplibre/draw-polygon/index.html new file mode 100644 index 000000000..e310935c5 --- /dev/null +++ b/examples/maplibre/draw-polygon/index.html @@ -0,0 +1,40 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/draw-polygon/package.json b/examples/maplibre/draw-polygon/package.json new file mode 100644 index 000000000..e3d4012b7 --- /dev/null +++ b/examples/maplibre/draw-polygon/package.json @@ -0,0 +1,20 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "@mapbox/mapbox-gl-draw": "^1.3.0", + "@types/mapbox__mapbox-gl-draw": "^1.2.3", + "@turf/area": "^6.5.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/draw-polygon/src/app.tsx b/examples/maplibre/draw-polygon/src/app.tsx new file mode 100644 index 000000000..8f2b59ce6 --- /dev/null +++ b/examples/maplibre/draw-polygon/src/app.tsx @@ -0,0 +1,64 @@ +import * as React from 'react'; +import {useState, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; + +import DrawControl from './draw-control'; +import ControlPanel from './control-panel'; + +import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; + +export default function App() { + const [features, setFeatures] = useState({}); + + const onUpdate = useCallback(e => { + setFeatures(currFeatures => { + const newFeatures = {...currFeatures}; + for (const f of e.features) { + newFeatures[f.id] = f; + } + return newFeatures; + }); + }, []); + + const onDelete = useCallback(e => { + setFeatures(currFeatures => { + const newFeatures = {...currFeatures}; + for (const f of e.features) { + delete newFeatures[f.id]; + } + return newFeatures; + }); + }, []); + + return ( + <> + + + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/draw-polygon/src/control-panel.tsx b/examples/maplibre/draw-polygon/src/control-panel.tsx new file mode 100644 index 000000000..d79050faf --- /dev/null +++ b/examples/maplibre/draw-polygon/src/control-panel.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import area from '@turf/area'; + +function ControlPanel(props) { + let polygonArea = 0; + for (const polygon of props.polygons) { + polygonArea += area(polygon); + } + + return ( +
+

Draw Polygon

+ {polygonArea > 0 && ( +

+ {Math.round(polygonArea * 100) / 100}
+ square meters +

+ )} + +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/draw-polygon/src/draw-control.ts b/examples/maplibre/draw-polygon/src/draw-control.ts new file mode 100644 index 000000000..68cd57e64 --- /dev/null +++ b/examples/maplibre/draw-polygon/src/draw-control.ts @@ -0,0 +1,39 @@ +import MapboxDraw from '@mapbox/mapbox-gl-draw'; +import {useControl} from 'react-map-gl/maplibre'; + +import type {ControlPosition} from 'react-map-gl/maplibre'; + +type DrawControlProps = ConstructorParameters[0] & { + position?: ControlPosition; + + onCreate?: (evt: {features: object[]}) => void; + onUpdate?: (evt: {features: object[]; action: string}) => void; + onDelete?: (evt: {features: object[]}) => void; +}; + +export default function DrawControl(props: DrawControlProps) { + useControl( + () => new MapboxDraw(props), + ({map}) => { + map.on('draw.create', props.onCreate); + map.on('draw.update', props.onUpdate); + map.on('draw.delete', props.onDelete); + }, + ({map}) => { + map.off('draw.create', props.onCreate); + map.off('draw.update', props.onUpdate); + map.off('draw.delete', props.onDelete); + }, + { + position: props.position + } + ); + + return null; +} + +DrawControl.defaultProps = { + onCreate: () => {}, + onUpdate: () => {}, + onDelete: () => {} +}; diff --git a/examples/maplibre/draw-polygon/tsconfig.json b/examples/maplibre/draw-polygon/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/draw-polygon/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/filter/README.md b/examples/maplibre/filter/README.md new file mode 100644 index 000000000..bae62eade --- /dev/null +++ b/examples/maplibre/filter/README.md @@ -0,0 +1,12 @@ +# Example: Highlight By Filter + +This app reproduces Mapbox's [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/) example. + +This example showcases how to dynamically add/remove filters from layers. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/filter/index.html b/examples/maplibre/filter/index.html new file mode 100644 index 000000000..c73253f0a --- /dev/null +++ b/examples/maplibre/filter/index.html @@ -0,0 +1,46 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/filter/package.json b/examples/maplibre/filter/package.json new file mode 100644 index 000000000..767e9700a --- /dev/null +++ b/examples/maplibre/filter/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/filter/src/app.tsx b/examples/maplibre/filter/src/app.tsx new file mode 100644 index 000000000..8997d81d8 --- /dev/null +++ b/examples/maplibre/filter/src/app.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import {useState, useMemo, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, Popup, Source, Layer} from 'react-map-gl/maplibre'; +import ControlPanel from './control-panel'; +import {countiesLayer, highlightLayer} from './map-style'; +import type {ExpressionSpecification} from 'maplibre-gl'; + +export default function App() { + const [hoverInfo, setHoverInfo] = useState(null); + + const onHover = useCallback(event => { + const county = event.features && event.features[0]; + setHoverInfo({ + longitude: event.lngLat.lng, + latitude: event.lngLat.lat, + countyName: county && county.properties.name.split(',')[0] + }); + }, []); + + const selectedCounty = (hoverInfo && hoverInfo.countyName) || ''; + const filter: ExpressionSpecification = useMemo( + () => ['in', selectedCounty || 'N/A', ['get', 'name']], + [selectedCounty] + ); + + return ( + <> + + + + + + {selectedCounty && ( + + {selectedCounty} + + )} + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/filter/src/control-panel.tsx b/examples/maplibre/filter/src/control-panel.tsx new file mode 100644 index 000000000..6ebaeaba3 --- /dev/null +++ b/examples/maplibre/filter/src/control-panel.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Highlight Features Containing Similar Data

+

Hover over counties to highlight counties that share the same name.

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/filter/src/map-style.ts b/examples/maplibre/filter/src/map-style.ts new file mode 100644 index 000000000..de8368a6f --- /dev/null +++ b/examples/maplibre/filter/src/map-style.ts @@ -0,0 +1,22 @@ +import type {FillLayer} from 'react-map-gl/maplibre'; + +export const countiesLayer: FillLayer = { + id: 'counties', + source: '', + type: 'fill', + paint: { + 'fill-outline-color': 'rgba(0,0,0,0.1)', + 'fill-color': 'rgba(0,0,0,0.1)' + } +}; +// Highlighted county polygons +export const highlightLayer: FillLayer = { + id: 'counties-highlighted', + type: 'fill', + source: 'counties', + paint: { + 'fill-outline-color': '#484896', + 'fill-color': '#6e599f', + 'fill-opacity': 0.75 + } +}; diff --git a/examples/maplibre/filter/tsconfig.json b/examples/maplibre/filter/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/filter/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/geocoder/README.md b/examples/maplibre/geocoder/README.md new file mode 100644 index 000000000..7f2f29515 --- /dev/null +++ b/examples/maplibre/geocoder/README.md @@ -0,0 +1,10 @@ +# Example: Geocoder + +This app reproduces Maplibre's [Geocode with Nominatim](https://maplibre.org/maplibre-gl-js/docs/examples/geocoder/) example. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/geocoder/index.html b/examples/maplibre/geocoder/index.html new file mode 100644 index 000000000..e310935c5 --- /dev/null +++ b/examples/maplibre/geocoder/index.html @@ -0,0 +1,40 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/geocoder/package.json b/examples/maplibre/geocoder/package.json new file mode 100644 index 000000000..42b7eac3a --- /dev/null +++ b/examples/maplibre/geocoder/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "@maplibre/maplibre-gl-geocoder": "^1.5.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/geocoder/src/app.tsx b/examples/maplibre/geocoder/src/app.tsx new file mode 100644 index 000000000..96aaaa89f --- /dev/null +++ b/examples/maplibre/geocoder/src/app.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; + +import GeocoderControl from './geocoder-control'; +import ControlPanel from './control-panel'; + +import '@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css'; + +export default function App() { + return ( + <> + + + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/geocoder/src/control-panel.tsx b/examples/maplibre/geocoder/src/control-panel.tsx new file mode 100644 index 000000000..256634c49 --- /dev/null +++ b/examples/maplibre/geocoder/src/control-panel.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Geocoder

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/geocoder/src/geocoder-control.tsx b/examples/maplibre/geocoder/src/geocoder-control.tsx new file mode 100644 index 000000000..fb932ed46 --- /dev/null +++ b/examples/maplibre/geocoder/src/geocoder-control.tsx @@ -0,0 +1,155 @@ +/* global fetch */ +import * as React from 'react'; +import {useState} from 'react'; +import {useControl, Marker, MarkerProps, ControlPosition} from 'react-map-gl/maplibre'; +import MaplibreGeocoder, { + MaplibreGeocoderApi, + MaplibreGeocoderOptions +} from '@maplibre/maplibre-gl-geocoder'; + +type GeocoderControlProps = Omit & { + marker?: boolean | Omit; + + position: ControlPosition; + + onLoading?: (e: object) => void; + onResults?: (e: object) => void; + onResult?: (e: object) => void; + onError?: (e: object) => void; +}; + +/* eslint-disable camelcase */ +const geocoderApi: MaplibreGeocoderApi = { + forwardGeocode: async config => { + const features = []; + try { + const request = `https://nominatim.openstreetmap.org/search?q=${config.query}&format=geojson&polygon_geojson=1&addressdetails=1`; + const response = await fetch(request); + const geojson = await response.json(); + for (const feature of geojson.features) { + const center = [ + feature.bbox[0] + (feature.bbox[2] - feature.bbox[0]) / 2, + feature.bbox[1] + (feature.bbox[3] - feature.bbox[1]) / 2 + ]; + const point = { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: center + }, + place_name: feature.properties.display_name, + properties: feature.properties, + text: feature.properties.display_name, + place_type: ['place'], + center + }; + features.push(point); + } + } catch (e) { + console.error(`Failed to forwardGeocode with error: ${e}`); // eslint-disable-line + } + + return { + features + }; + } +}; + +/* eslint-disable complexity,max-statements */ +export default function GeocoderControl(props: GeocoderControlProps) { + const [marker, setMarker] = useState(null); + + const geocoder = useControl( + ({mapLib}) => { + const ctrl = new MaplibreGeocoder(geocoderApi, { + ...props, + marker: false, + maplibregl: mapLib + }); + ctrl.on('loading', props.onLoading); + ctrl.on('results', props.onResults); + ctrl.on('result', evt => { + props.onResult(evt); + + const {result} = evt; + const location = + result && + (result.center || (result.geometry?.type === 'Point' && result.geometry.coordinates)); + if (location && props.marker) { + const markerProps = typeof props.marker === 'object' ? props.marker : {}; + setMarker(); + } else { + setMarker(null); + } + }); + ctrl.on('error', props.onError); + return ctrl; + }, + { + position: props.position + } + ); + + // @ts-ignore (TS2339) private member + if (geocoder._map) { + if (geocoder.getProximity() !== props.proximity && props.proximity !== undefined) { + geocoder.setProximity(props.proximity); + } + if (geocoder.getRenderFunction() !== props.render && props.render !== undefined) { + geocoder.setRenderFunction(props.render); + } + if (geocoder.getLanguage() !== props.language && props.language !== undefined) { + geocoder.setLanguage(props.language); + } + if (geocoder.getZoom() !== props.zoom && props.zoom !== undefined) { + geocoder.setZoom(props.zoom); + } + if (geocoder.getFlyTo() !== props.flyTo && props.flyTo !== undefined) { + geocoder.setFlyTo(props.flyTo); + } + if (geocoder.getPlaceholder() !== props.placeholder && props.placeholder !== undefined) { + geocoder.setPlaceholder(props.placeholder); + } + if (geocoder.getCountries() !== props.countries && props.countries !== undefined) { + geocoder.setCountries(props.countries); + } + if (geocoder.getTypes() !== props.types && props.types !== undefined) { + geocoder.setTypes(props.types); + } + if (geocoder.getMinLength() !== props.minLength && props.minLength !== undefined) { + geocoder.setMinLength(props.minLength); + } + if (geocoder.getLimit() !== props.limit && props.limit !== undefined) { + geocoder.setLimit(props.limit); + } + if (geocoder.getFilter() !== props.filter && props.filter !== undefined) { + geocoder.setFilter(props.filter); + } + // if (geocoder.getOrigin() !== props.origin && props.origin !== undefined) { + // geocoder.setOrigin(props.origin); + // } + // if (geocoder.getAutocomplete() !== props.autocomplete && props.autocomplete !== undefined) { + // geocoder.setAutocomplete(props.autocomplete); + // } + // if (geocoder.getFuzzyMatch() !== props.fuzzyMatch && props.fuzzyMatch !== undefined) { + // geocoder.setFuzzyMatch(props.fuzzyMatch); + // } + // if (geocoder.getRouting() !== props.routing && props.routing !== undefined) { + // geocoder.setRouting(props.routing); + // } + // if (geocoder.getWorldview() !== props.worldview && props.worldview !== undefined) { + // geocoder.setWorldview(props.worldview); + // } + } + return marker; +} + +const noop = () => {}; + +GeocoderControl.defaultProps = { + marker: true, + onLoading: noop, + onResults: noop, + onResult: noop, + onError: noop +}; diff --git a/examples/maplibre/geocoder/tsconfig.json b/examples/maplibre/geocoder/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/geocoder/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/geojson-animation/README.md b/examples/maplibre/geojson-animation/README.md new file mode 100644 index 000000000..1668c9af1 --- /dev/null +++ b/examples/maplibre/geojson-animation/README.md @@ -0,0 +1,12 @@ +# Example: Animated GeoJSON + +This app reproduces Maplibre's [Animate point along line](https://maplibre.org/maplibre-gl-js/docs/examples/animate-point-along-line/) example. + +This example showcases how to dynamically add and update custom data sources. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/geojson-animation/index.html b/examples/maplibre/geojson-animation/index.html new file mode 100644 index 000000000..e310935c5 --- /dev/null +++ b/examples/maplibre/geojson-animation/index.html @@ -0,0 +1,40 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/geojson-animation/package.json b/examples/maplibre/geojson-animation/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/geojson-animation/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/geojson-animation/src/app.tsx b/examples/maplibre/geojson-animation/src/app.tsx new file mode 100644 index 000000000..e19e90a56 --- /dev/null +++ b/examples/maplibre/geojson-animation/src/app.tsx @@ -0,0 +1,59 @@ +/* global window */ +import * as React from 'react'; +import {useState, useEffect} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, Source, Layer} from 'react-map-gl/maplibre'; +import type {LayerProps} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; + +const pointLayer: LayerProps = { + id: 'point', + type: 'circle', + paint: { + 'circle-radius': 10, + 'circle-color': '#007cbf' + } +}; + +function pointOnCircle({center, angle, radius}) { + return { + type: 'Point', + coordinates: [center[0] + Math.cos(angle) * radius, center[1] + Math.sin(angle) * radius] + }; +} + +export default function App() { + const [pointData, setPointData] = useState(null); + + useEffect(() => { + const animation = window.requestAnimationFrame(() => + setPointData(pointOnCircle({center: [-100, 0], angle: Date.now() / 1000, radius: 20})) + ); + return () => window.cancelAnimationFrame(animation); + }); + + return ( + <> + + {pointData && ( + + + + )} + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/geojson-animation/src/control-panel.tsx b/examples/maplibre/geojson-animation/src/control-panel.tsx new file mode 100644 index 000000000..216140a11 --- /dev/null +++ b/examples/maplibre/geojson-animation/src/control-panel.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Animated GeoJSON

+

Render animation by updating GeoJSON data source.

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/geojson-animation/tsconfig.json b/examples/maplibre/geojson-animation/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/geojson-animation/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/geojson/README.md b/examples/maplibre/geojson/README.md new file mode 100644 index 000000000..6d94cfdca --- /dev/null +++ b/examples/maplibre/geojson/README.md @@ -0,0 +1,10 @@ +# Example: GeoJSON + +This example showcases how to dynamically add and update custom data sources. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/geojson/index.html b/examples/maplibre/geojson/index.html new file mode 100644 index 000000000..fd824a501 --- /dev/null +++ b/examples/maplibre/geojson/index.html @@ -0,0 +1,63 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/geojson/package.json b/examples/maplibre/geojson/package.json new file mode 100644 index 000000000..7fd3a8441 --- /dev/null +++ b/examples/maplibre/geojson/package.json @@ -0,0 +1,19 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "d3-array": "^3.1.1", + "d3-scale": "^4.0.2", + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/geojson/src/app.tsx b/examples/maplibre/geojson/src/app.tsx new file mode 100644 index 000000000..c04b7adc9 --- /dev/null +++ b/examples/maplibre/geojson/src/app.tsx @@ -0,0 +1,71 @@ +import * as React from 'react'; +import {useState, useEffect, useMemo, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, Source, Layer} from 'react-map-gl/maplibre'; +import ControlPanel from './control-panel'; + +import {dataLayer} from './map-style'; +import {updatePercentiles} from './utils'; + +export default function App() { + const [year, setYear] = useState(2015); + const [allData, setAllData] = useState(null); + const [hoverInfo, setHoverInfo] = useState(null); + + useEffect(() => { + /* global fetch */ + fetch( + 'https://raw.githubusercontent.com/uber/react-map-gl/master/examples/.data/us-income.geojson' + ) + .then(resp => resp.json()) + .then(json => setAllData(json)) + .catch(err => console.error('Could not load data', err)); // eslint-disable-line + }, []); + + const onHover = useCallback(event => { + const { + features, + point: {x, y} + } = event; + const hoveredFeature = features && features[0]; + + // prettier-ignore + setHoverInfo(hoveredFeature && {feature: hoveredFeature, x, y}); + }, []); + + const data = useMemo(() => { + return allData && updatePercentiles(allData, f => f.properties.income[year]); + }, [allData, year]); + + return ( + <> + + + + + {hoverInfo && ( +
+
State: {hoverInfo.feature.properties.name}
+
Median Household Income: {hoverInfo.feature.properties.value}
+
Percentile: {(hoverInfo.feature.properties.percentile / 8) * 100}
+
+ )} +
+ + setYear(value)} /> + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/geojson/src/control-panel.tsx b/examples/maplibre/geojson/src/control-panel.tsx new file mode 100644 index 000000000..a55ad6e2a --- /dev/null +++ b/examples/maplibre/geojson/src/control-panel.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; + +function ControlPanel(props) { + const {year} = props; + + return ( +
+

Interactive GeoJSON

+

+ Map showing median household income by state in year {year}. Hover over a state to + see details. +

+

+ Data source: US Census Bureau +

+ +
+ +
+ + props.onChange(evt.target.value)} + /> +
+
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/geojson/src/map-style.ts b/examples/maplibre/geojson/src/map-style.ts new file mode 100644 index 000000000..4f8c7b6e8 --- /dev/null +++ b/examples/maplibre/geojson/src/map-style.ts @@ -0,0 +1,25 @@ +import type {LayerProps} from 'react-map-gl/maplibre'; + +// For more information on data-driven styles, see https://maplibre.org/maplibre-style-spec/expressions/ +export const dataLayer: LayerProps = { + id: 'data', + type: 'fill', + paint: { + 'fill-color': { + type: 'interval', + property: 'percentile', + stops: [ + [0, '#3288bd'], + [1, '#66c2a5'], + [2, '#abdda4'], + [3, '#e6f598'], + [4, '#ffffbf'], + [5, '#fee08b'], + [6, '#fdae61'], + [7, '#f46d43'], + [8, '#d53e4f'] + ] + }, + 'fill-opacity': 0.8 + } +}; diff --git a/examples/maplibre/geojson/src/utils.ts b/examples/maplibre/geojson/src/utils.ts new file mode 100644 index 000000000..88d6a1709 --- /dev/null +++ b/examples/maplibre/geojson/src/utils.ts @@ -0,0 +1,24 @@ +import {range} from 'd3-array'; +import {scaleQuantile} from 'd3-scale'; + +import type GeoJSON from 'geojson'; + +export function updatePercentiles( + featureCollection: GeoJSON.FeatureCollection, + accessor: (f: GeoJSON.Feature) => number +): GeoJSON.FeatureCollection { + const {features} = featureCollection; + const scale = scaleQuantile().domain(features.map(accessor)).range(range(9)); + return { + type: 'FeatureCollection', + features: features.map(f => { + const value = accessor(f); + const properties = { + ...f.properties, + value, + percentile: scale(value) + }; + return {...f, properties}; + }) + }; +} diff --git a/examples/maplibre/geojson/tsconfig.json b/examples/maplibre/geojson/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/geojson/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/globe/README.md b/examples/maplibre/globe/README.md new file mode 100644 index 000000000..d4ab8ce95 --- /dev/null +++ b/examples/maplibre/globe/README.md @@ -0,0 +1,10 @@ +# Example: Globe + +This app reproduces Maplibre's [globe](https://maplibre.org/maplibre-gl-js/docs/examples/globe/) example. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/globe/index.html b/examples/maplibre/globe/index.html new file mode 100644 index 000000000..6bd9f9d5f --- /dev/null +++ b/examples/maplibre/globe/index.html @@ -0,0 +1,41 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/globe/package.json b/examples/maplibre/globe/package.json new file mode 100644 index 000000000..34a73b9f6 --- /dev/null +++ b/examples/maplibre/globe/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "maplibre-gl": "^5.0.0-pre.1", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/globe/src/app.tsx b/examples/maplibre/globe/src/app.tsx new file mode 100644 index 000000000..524cbb889 --- /dev/null +++ b/examples/maplibre/globe/src/app.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; + +export default function App() { + return ( + <> + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/globe/src/control-panel.tsx b/examples/maplibre/globe/src/control-panel.tsx new file mode 100644 index 000000000..b825b0cca --- /dev/null +++ b/examples/maplibre/globe/src/control-panel.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Globe

+

Use globe projection.

+ + +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/globe/tsconfig.json b/examples/maplibre/globe/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/globe/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/heatmap/README.md b/examples/maplibre/heatmap/README.md new file mode 100644 index 000000000..b19d9ac4b --- /dev/null +++ b/examples/maplibre/heatmap/README.md @@ -0,0 +1,10 @@ +# Example: Heatmap layer + +This app reproduces Maplibre's [Create a heatmap layer](https://maplibre.org/maplibre-gl-js/docs/examples/heatmap-layer/) example. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/heatmap/index.html b/examples/maplibre/heatmap/index.html new file mode 100644 index 000000000..63e7d7e46 --- /dev/null +++ b/examples/maplibre/heatmap/index.html @@ -0,0 +1,54 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/heatmap/package.json b/examples/maplibre/heatmap/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/heatmap/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/heatmap/src/app.tsx b/examples/maplibre/heatmap/src/app.tsx new file mode 100644 index 000000000..2493822e4 --- /dev/null +++ b/examples/maplibre/heatmap/src/app.tsx @@ -0,0 +1,82 @@ +import * as React from 'react'; +import {useState, useEffect, useMemo} from 'react'; +import {createRoot} from 'react-dom/client'; +import MapGL, {Source, Layer} from 'react-map-gl/maplibre'; +import ControlPanel from './control-panel'; +import {heatmapLayer} from './map-style'; + +function filterFeaturesByDay(featureCollection, time) { + const date = new Date(time); + const year = date.getFullYear(); + const month = date.getMonth(); + const day = date.getDate(); + const features = featureCollection.features.filter(feature => { + const featureDate = new Date(feature.properties.time); + return ( + featureDate.getFullYear() === year && + featureDate.getMonth() === month && + featureDate.getDate() === day + ); + }); + return {type: 'FeatureCollection', features}; +} + +export default function App() { + const [allDays, useAllDays] = useState(true); + const [timeRange, setTimeRange] = useState([0, 0]); + const [selectedTime, selectTime] = useState(0); + const [earthquakes, setEarthQuakes] = useState(null); + + useEffect(() => { + /* global fetch */ + fetch('https://maplibre.org/maplibre-gl-js/docs/assets/earthquakes.geojson') + .then(resp => resp.json()) + .then(json => { + // Note: In a real application you would do a validation of JSON data before doing anything with it, + // but for demonstration purposes we ingore this part here and just trying to select needed data... + const features = json.features; + const endTime = features[0].properties.time; + const startTime = features[features.length - 1].properties.time; + + setTimeRange([startTime, endTime]); + setEarthQuakes(json); + selectTime(endTime); + }) + .catch(err => console.error('Could not load data', err)); // eslint-disable-line + }, []); + + const data = useMemo(() => { + return allDays ? earthquakes : filterFeaturesByDay(earthquakes, selectedTime); + }, [earthquakes, allDays, selectedTime]); + + return ( + <> + + {data && ( + + + + )} + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/heatmap/src/control-panel.tsx b/examples/maplibre/heatmap/src/control-panel.tsx new file mode 100644 index 000000000..1221b15be --- /dev/null +++ b/examples/maplibre/heatmap/src/control-panel.tsx @@ -0,0 +1,70 @@ +import * as React from 'react'; + +function formatTime(time) { + const date = new Date(time); + return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`; +} + +function ControlPanel(props) { + const {startTime, endTime, onChangeTime, allDays, onChangeAllDays, selectedTime} = props; + const day = 24 * 60 * 60 * 1000; + const days = Math.round((endTime - startTime) / day); + const selectedDay = Math.round((selectedTime - startTime) / day); + + const onSelectDay = evt => { + const daysToAdd = evt.target.value; + // add selected days to start time to calculate new time + const newTime = startTime + daysToAdd * day; + onChangeTime(newTime); + }; + + return ( +
+

Heatmap

+

+ Map showing earthquakes +
+ from {formatTime(startTime)} to {formatTime(endTime)}. +

+
+
+ + onChangeAllDays(evt.target.checked)} + /> +
+
+ + +
+
+

+ Data source:{' '} + + earthquakes.geojson + +

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/heatmap/src/map-style.ts b/examples/maplibre/heatmap/src/map-style.ts new file mode 100644 index 000000000..fd53b1d9c --- /dev/null +++ b/examples/maplibre/heatmap/src/map-style.ts @@ -0,0 +1,40 @@ +import type {LayerProps} from 'react-map-gl/maplibre'; + +const MAX_ZOOM_LEVEL = 9; + +export const heatmapLayer: LayerProps = { + id: 'heatmap', + maxzoom: MAX_ZOOM_LEVEL, + type: 'heatmap', + paint: { + // Increase the heatmap weight based on frequency and property magnitude + 'heatmap-weight': ['interpolate', ['linear'], ['get', 'mag'], 0, 0, 6, 1], + // Increase the heatmap color weight weight by zoom level + // heatmap-intensity is a multiplier on top of heatmap-weight + 'heatmap-intensity': ['interpolate', ['linear'], ['zoom'], 0, 1, MAX_ZOOM_LEVEL, 3], + // Color ramp for heatmap. Domain is 0 (low) to 1 (high). + // Begin color ramp at 0-stop with a 0-transparancy color + // to create a blur-like effect. + 'heatmap-color': [ + 'interpolate', + ['linear'], + ['heatmap-density'], + 0, + 'rgba(33,102,172,0)', + 0.2, + 'rgb(103,169,207)', + 0.4, + 'rgb(209,229,240)', + 0.6, + 'rgb(253,219,199)', + 0.8, + 'rgb(239,138,98)', + 0.9, + 'rgb(255,201,101)' + ], + // Adjust the heatmap radius by zoom level + 'heatmap-radius': ['interpolate', ['linear'], ['zoom'], 0, 2, MAX_ZOOM_LEVEL, 20], + // Transition from heatmap to circle layer by zoom level + 'heatmap-opacity': ['interpolate', ['linear'], ['zoom'], 7, 1, 9, 0] + } +}; diff --git a/examples/maplibre/heatmap/tsconfig.json b/examples/maplibre/heatmap/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/heatmap/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/interaction/README.md b/examples/maplibre/interaction/README.md new file mode 100644 index 000000000..736bb451a --- /dev/null +++ b/examples/maplibre/interaction/README.md @@ -0,0 +1,10 @@ +# Example: Interaction + +This example showcases how to toggle/limit user interaction. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/interaction/index.html b/examples/maplibre/interaction/index.html new file mode 100644 index 000000000..cd1721e66 --- /dev/null +++ b/examples/maplibre/interaction/index.html @@ -0,0 +1,52 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/interaction/package.json b/examples/maplibre/interaction/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/interaction/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/interaction/src/app.tsx b/examples/maplibre/interaction/src/app.tsx new file mode 100644 index 000000000..029327a00 --- /dev/null +++ b/examples/maplibre/interaction/src/app.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import {useState, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; +import ControlPanel from './control-panel'; + +const initialViewState = { + latitude: 37.729, + longitude: -122.36, + zoom: 11, + bearing: 0, + pitch: 50 +}; + +export default function App() { + const [settings, setSettings] = useState({ + scrollZoom: true, + boxZoom: true, + dragRotate: true, + dragPan: true, + keyboard: true, + doubleClickZoom: true, + touchZoomRotate: true, + touchPitch: true, + minZoom: 0, + maxZoom: 20, + minPitch: 0, + maxPitch: 85 + }); + + const updateSettings = useCallback( + (name, value) => + setSettings(s => ({ + ...s, + [name]: value + })), + [] + ); + + return ( + <> + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/interaction/src/control-panel.tsx b/examples/maplibre/interaction/src/control-panel.tsx new file mode 100644 index 000000000..307f6eedf --- /dev/null +++ b/examples/maplibre/interaction/src/control-panel.tsx @@ -0,0 +1,65 @@ +import * as React from 'react'; + +const camelPattern = /(^|[A-Z])[a-z]*/g; +function formatSettingName(name) { + return name.match(camelPattern).join(' '); +} + +function Checkbox({name, value, onChange}) { + return ( +
+ + onChange(name, evt.target.checked)} /> +
+ ); +} + +function NumericInput({name, value, onChange}) { + return ( +
+ + onChange(name, Number(evt.target.value))} + /> +
+ ); +} + +function ControlPanel(props) { + const {settings, onChange} = props; + + const renderSetting = (name, value) => { + switch (typeof value) { + case 'boolean': + return ; + case 'number': + return ; + default: + return null; + } + }; + + return ( +
+

Limit Map Interaction

+

Turn interactive features off/on.

+ +
+ + {Object.keys(settings).map(name => renderSetting(name, settings[name]))} + +
+
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/interaction/tsconfig.json b/examples/maplibre/interaction/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/interaction/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/layers/README.md b/examples/maplibre/layers/README.md new file mode 100644 index 000000000..bf7162bf1 --- /dev/null +++ b/examples/maplibre/layers/README.md @@ -0,0 +1,10 @@ +# Example: Layers + +This example showcases how to dynamically change layer styles and show/hide layers. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/layers/index.html b/examples/maplibre/layers/index.html new file mode 100644 index 000000000..43d7ac2da --- /dev/null +++ b/examples/maplibre/layers/index.html @@ -0,0 +1,49 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/layers/package.json b/examples/maplibre/layers/package.json new file mode 100644 index 000000000..4adbef11f --- /dev/null +++ b/examples/maplibre/layers/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "immutable": "^4.0.0", + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/layers/src/app.tsx b/examples/maplibre/layers/src/app.tsx new file mode 100644 index 000000000..6c814df43 --- /dev/null +++ b/examples/maplibre/layers/src/app.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import {useState} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; +import ControlPanel from './control-panel'; + +export default function App() { + const [mapStyle, setMapStyle] = useState(null); + + return ( + <> + + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/layers/src/control-panel.tsx b/examples/maplibre/layers/src/control-panel.tsx new file mode 100644 index 000000000..8ac9cd5f6 --- /dev/null +++ b/examples/maplibre/layers/src/control-panel.tsx @@ -0,0 +1,112 @@ +import * as React from 'react'; +import {useState, useEffect} from 'react'; +import {fromJS} from 'immutable'; +import MAP_STYLE from '../../../map-style-basic-v8.json'; + +const defaultMapStyle: any = fromJS(MAP_STYLE); +const defaultLayers = defaultMapStyle.get('layers'); + +const categories = ['labels', 'roads', 'buildings', 'parks', 'water', 'background']; + +// Layer id patterns by category +const layerSelector = { + background: /background/, + water: /water/, + parks: /park/, + buildings: /building/, + roads: /bridge|road|tunnel/, + labels: /label|place|poi/ +}; + +// Layer color class by type +const colorClass = { + line: 'line-color', + fill: 'fill-color', + background: 'background-color', + symbol: 'text-color' +}; + +function getMapStyle({visibility, color}) { + const layers = defaultLayers + .filter(layer => { + const id = layer.get('id'); + return categories.every(name => visibility[name] || !layerSelector[name].test(id)); + }) + .map(layer => { + const id = layer.get('id'); + const type = layer.get('type'); + const category = categories.find(name => layerSelector[name].test(id)); + if (category && colorClass[type]) { + return layer.setIn(['paint', colorClass[type]], color[category]); + } + return layer; + }); + + return defaultMapStyle.set('layers', layers); +} + +function StyleControls(props) { + const [visibility, setVisibility] = useState({ + water: true, + parks: true, + buildings: true, + roads: true, + labels: true, + background: true + }); + + const [color, setColor] = useState({ + water: '#DBE2E6', + parks: '#E6EAE9', + buildings: '#c0c0c8', + roads: '#ffffff', + labels: '#78888a', + background: '#EBF0F0' + }); + + useEffect(() => { + props.onChange(getMapStyle({visibility, color})); + }, [visibility, color]); + + const onColorChange = (name, value) => { + setColor({...color, [name]: value}); + }; + + const onVisibilityChange = (name, value) => { + setVisibility({...visibility, [name]: value}); + }; + + return ( +
+

Dynamic Styling

+

Dynamically show/hide map layers and change color with Immutable map style.

+ +
+ {categories.map(name => ( +
+ + onVisibilityChange(name, evt.target.checked)} + /> + onColorChange(name, evt.target.value)} + /> +
+ ))} +
+ ); +} + +export default React.memo(StyleControls); diff --git a/examples/maplibre/layers/tsconfig.json b/examples/maplibre/layers/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/layers/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/side-by-side/README.md b/examples/maplibre/side-by-side/README.md new file mode 100644 index 000000000..13013715b --- /dev/null +++ b/examples/maplibre/side-by-side/README.md @@ -0,0 +1,10 @@ +# Example: Side By Side + +Demonstrates how to synchronize two maps with react-maplibre. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/side-by-side/index.html b/examples/maplibre/side-by-side/index.html new file mode 100644 index 000000000..6bd9f9d5f --- /dev/null +++ b/examples/maplibre/side-by-side/index.html @@ -0,0 +1,41 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/side-by-side/package.json b/examples/maplibre/side-by-side/package.json new file mode 100644 index 000000000..767e9700a --- /dev/null +++ b/examples/maplibre/side-by-side/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/side-by-side/src/app.tsx b/examples/maplibre/side-by-side/src/app.tsx new file mode 100644 index 000000000..16f42fc1c --- /dev/null +++ b/examples/maplibre/side-by-side/src/app.tsx @@ -0,0 +1,67 @@ +/* global window */ +import * as React from 'react'; +import {useState, useCallback, useMemo} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; + +import ControlPanel, {Mode} from './control-panel'; + +const LeftMapStyle: React.CSSProperties = { + position: 'absolute', + width: '50%', + height: '100%' +}; +const RightMapStyle: React.CSSProperties = { + position: 'absolute', + left: '50%', + width: '50%', + height: '100%' +}; + +export default function App() { + const [viewState, setViewState] = useState({ + longitude: -122.43, + latitude: 37.78, + zoom: 12, + pitch: 30 + }); + const [mode, setMode] = useState('side-by-side'); + + const onMove = useCallback(evt => setViewState(evt.viewState), []); + + const width = typeof window === 'undefined' ? 100 : window.innerWidth; + const leftMapPadding = useMemo(() => { + return {left: mode === 'split-screen' ? width / 2 : 0, top: 0, right: 0, bottom: 0}; + }, [width, mode]); + const rightMapPadding = useMemo(() => { + return {right: mode === 'split-screen' ? width / 2 : 0, top: 0, left: 0, bottom: 0}; + }, [width, mode]); + + return ( + <> +
+ + +
+ + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/side-by-side/src/control-panel.tsx b/examples/maplibre/side-by-side/src/control-panel.tsx new file mode 100644 index 000000000..32d180529 --- /dev/null +++ b/examples/maplibre/side-by-side/src/control-panel.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import {useCallback} from 'react'; + +export type Mode = 'side-by-side' | 'split-screen'; + +function ControlPanel(props: {mode: Mode; onModeChange: (newMode: Mode) => void}) { + const onModeChange = useCallback( + evt => { + props.onModeChange(evt.target.value as Mode); + }, + [props.onModeChange] + ); + + return ( +
+

Side by Side

+

Synchronize two maps.

+ +
+ + +
+ + +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/side-by-side/tsconfig.json b/examples/maplibre/side-by-side/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/side-by-side/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/terrain/README.md b/examples/maplibre/terrain/README.md new file mode 100644 index 000000000..27b0189f7 --- /dev/null +++ b/examples/maplibre/terrain/README.md @@ -0,0 +1,10 @@ +# Example: 3D Terrain + +This app reproduces Maplibre's [3D terrain](https://maplibre.org/maplibre-gl-js/docs/examples/3d-terrain/) example. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/terrain/index.html b/examples/maplibre/terrain/index.html new file mode 100644 index 000000000..6bd9f9d5f --- /dev/null +++ b/examples/maplibre/terrain/index.html @@ -0,0 +1,41 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/terrain/package.json b/examples/maplibre/terrain/package.json new file mode 100644 index 000000000..767e9700a --- /dev/null +++ b/examples/maplibre/terrain/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/terrain/src/app.tsx b/examples/maplibre/terrain/src/app.tsx new file mode 100644 index 000000000..ab58f5a9b --- /dev/null +++ b/examples/maplibre/terrain/src/app.tsx @@ -0,0 +1,63 @@ +import * as React from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, Source, Layer, TerrainControl} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; + +import type {Terrain, Sky} from 'react-map-gl/maplibre'; + +const sky: Sky = { + 'sky-color': '#80ccff', + 'sky-horizon-blend': 0.5, + 'horizon-color': '#ccddff', + 'horizon-fog-blend': 0.5, + 'fog-color': '#fcf0dd', + 'fog-ground-blend': 0.2 +}; + +const terrain: Terrain = {source: 'terrain-dem', exaggeration: 1.5}; + +export default function App() { + return ( + <> + + + + + + + + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/terrain/src/control-panel.tsx b/examples/maplibre/terrain/src/control-panel.tsx new file mode 100644 index 000000000..4cfdaccee --- /dev/null +++ b/examples/maplibre/terrain/src/control-panel.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

3D Terrain

+

Add 3D terrain and sky to a map.

+ + +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/terrain/tsconfig.json b/examples/maplibre/terrain/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/terrain/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/viewport-animation/README.md b/examples/maplibre/viewport-animation/README.md new file mode 100644 index 000000000..43708a616 --- /dev/null +++ b/examples/maplibre/viewport-animation/README.md @@ -0,0 +1,10 @@ +# Example: Viewport Animation + +This example showcases how to transition smoothly between one viewport to another. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/viewport-animation/index.html b/examples/maplibre/viewport-animation/index.html new file mode 100644 index 000000000..e310935c5 --- /dev/null +++ b/examples/maplibre/viewport-animation/index.html @@ -0,0 +1,40 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/viewport-animation/package.json b/examples/maplibre/viewport-animation/package.json new file mode 100644 index 000000000..2a322d8ec --- /dev/null +++ b/examples/maplibre/viewport-animation/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*", + "maplibre-gl": "^5.0.0" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/viewport-animation/src/app.tsx b/examples/maplibre/viewport-animation/src/app.tsx new file mode 100644 index 000000000..04d72e38f --- /dev/null +++ b/examples/maplibre/viewport-animation/src/app.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import {useRef, useCallback} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map, MapRef} from 'react-map-gl/maplibre'; + +import ControlPanel from './control-panel'; + +const initialViewState = { + latitude: 37.7751, + longitude: -122.4193, + zoom: 11, + bearing: 0, + pitch: 0 +}; + +export default function App() { + const mapRef = useRef(); + + const onSelectCity = useCallback(({longitude, latitude}) => { + mapRef.current?.flyTo({center: [longitude, latitude], duration: 2000}); + }, []); + + return ( + <> + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/viewport-animation/src/control-panel.tsx b/examples/maplibre/viewport-animation/src/control-panel.tsx new file mode 100644 index 000000000..27cfc0898 --- /dev/null +++ b/examples/maplibre/viewport-animation/src/control-panel.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; + +import CITIES from '../../../.data/cities.json'; + +function ControlPanel(props) { + return ( +
+

Camera Transition

+

Smooth animate of the viewport.

+ +
+ + {CITIES.filter(city => city.state === 'California').map((city, index) => ( +
+ props.onSelectCity(city)} + /> + +
+ ))} +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/viewport-animation/tsconfig.json b/examples/maplibre/viewport-animation/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/viewport-animation/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/maplibre/zoom-to-bounds/README.md b/examples/maplibre/zoom-to-bounds/README.md new file mode 100644 index 000000000..08c881507 --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/README.md @@ -0,0 +1,10 @@ +# Example: Zoom To Bounds + +Demonstrates how to zoom to a bounding box with react-maplibre. + +## Usage + +```bash +npm i +npm run start +``` diff --git a/examples/maplibre/zoom-to-bounds/index.html b/examples/maplibre/zoom-to-bounds/index.html new file mode 100644 index 000000000..6bd9f9d5f --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/index.html @@ -0,0 +1,41 @@ + + + + + react-maplibre Example + + + + +
+ + + diff --git a/examples/maplibre/zoom-to-bounds/package.json b/examples/maplibre/zoom-to-bounds/package.json new file mode 100644 index 000000000..1441e1be5 --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "start": "vite --open", + "start-local": "vite --config ../../vite.config.local.js", + "build": "vite build" + }, + "dependencies": { + "@turf/bbox": "^6.5.0", + "maplibre-gl": "^5.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "@vis.gl/react-maplibre": "*" + }, + "devDependencies": { + "typescript": "^4.0.0", + "vite": "^4.0.0" + } +} diff --git a/examples/maplibre/zoom-to-bounds/src/app.tsx b/examples/maplibre/zoom-to-bounds/src/app.tsx new file mode 100644 index 000000000..8638d6653 --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/src/app.tsx @@ -0,0 +1,51 @@ +import * as React from 'react'; +import {useRef} from 'react'; +import {createRoot} from 'react-dom/client'; +import {Map} from 'react-map-gl/maplibre'; +import bbox from '@turf/bbox'; + +import ControlPanel from './control-panel'; +import MAP_STYLE from './map-style'; + +import type {MapStyle, MapRef, MapLayerMouseEvent} from 'react-map-gl/maplibre'; + +export default function App() { + const mapRef = useRef(); + + const onClick = (event: MapLayerMouseEvent) => { + const feature = event.features[0]; + if (feature) { + // calculate the bounding box of the feature + const [minLng, minLat, maxLng, maxLat] = bbox(feature); + + mapRef.current.fitBounds( + [ + [minLng, minLat], + [maxLng, maxLat] + ], + {padding: 40, duration: 1000} + ); + } + }; + + return ( + <> + + + + ); +} + +export function renderToDom(container) { + createRoot(container).render(); +} diff --git a/examples/maplibre/zoom-to-bounds/src/control-panel.tsx b/examples/maplibre/zoom-to-bounds/src/control-panel.tsx new file mode 100644 index 000000000..ba16683fd --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/src/control-panel.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +function ControlPanel() { + return ( +
+

Zoom to Bounding Box

+

Click on a San Fransisco Neighborhood to zoom in.

+ +
+ ); +} + +export default React.memo(ControlPanel); diff --git a/examples/maplibre/zoom-to-bounds/src/map-style.tsx b/examples/maplibre/zoom-to-bounds/src/map-style.tsx new file mode 100644 index 000000000..a88503ef6 --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/src/map-style.tsx @@ -0,0 +1,39 @@ +import type {GeoJSONSource, FillLayer, LineLayer} from 'react-map-gl/maplibre'; + +import MAP_STYLE from '../../../map-style-basic-v8.json'; + +const sfNeighborhoods: GeoJSONSource = { + type: 'geojson', + data: 'https://raw.githubusercontent.com/visgl/react-map-gl/master/examples/.data/feature-example-sf.json' +}; + +const fillLayer: FillLayer = { + id: 'sf-neighborhoods-fill', + source: 'sf-neighborhoods', + type: 'fill', + paint: { + 'fill-outline-color': '#0040c8', + 'fill-color': '#fff', + 'fill-opacity': 0 + } +}; + +const lineLayer: LineLayer = { + id: 'sf-neighborhoods-outline', + source: 'sf-neighborhoods', + type: 'line', + paint: { + 'line-width': 2, + 'line-color': '#0080ef' + } +}; + +// Make a copy of the map style +export default { + ...MAP_STYLE, + sources: { + ...MAP_STYLE.sources, + ['sf-neighborhoods']: sfNeighborhoods + }, + layers: [...MAP_STYLE.layers, fillLayer, lineLayer] +}; diff --git a/examples/maplibre/zoom-to-bounds/tsconfig.json b/examples/maplibre/zoom-to-bounds/tsconfig.json new file mode 100644 index 000000000..2b37aa6c2 --- /dev/null +++ b/examples/maplibre/zoom-to-bounds/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "jsx": "react", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "module": "ES2020", + "sourceMap": true + } +} \ No newline at end of file diff --git a/examples/side-by-side/package.json b/examples/side-by-side/package.json deleted file mode 100644 index 677adc0fb..000000000 --- a/examples/side-by-side/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "mapbox-gl": "^2.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/terrain/package.json b/examples/terrain/package.json deleted file mode 100644 index 677adc0fb..000000000 --- a/examples/terrain/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "mapbox-gl": "^2.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/viewport-animation/package.json b/examples/viewport-animation/package.json deleted file mode 100644 index 6e5a6c29d..000000000 --- a/examples/viewport-animation/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "scripts": { - "start": "vite --open", - "start-local": "vite --config ../vite.config.local.js", - "build": "vite build" - }, - "dependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-map-gl": "^7.1.0", - "mapbox-gl": "^2.0.0" - }, - "devDependencies": { - "typescript": "^4.0.0", - "vite": "^4.0.0" - } -} diff --git a/examples/vite.config.local.js b/examples/vite.config.local.js index 054ea2450..d6642c298 100644 --- a/examples/vite.config.local.js +++ b/examples/vite.config.local.js @@ -9,9 +9,8 @@ export default defineConfig(async () => { resolve: { alias: { // Use root dependencies - 'react-map-gl': join(rootDir, './src/index.ts'), - 'mapbox-gl': join(rootDir, './node_modules/mapbox-gl/dist/mapbox-gl-dev.js'), - 'maplibre-gl': join(rootDir, './node_modules/maplibre-gl/dist/maplibre-gl-dev.js'), + 'react-map-gl/mapbox': join(rootDir, './modules/main/src/mapbox.ts'), + 'react-map-gl/maplibre': join(rootDir, './modules/main/src/maplibre.ts'), react: join(rootDir, './node_modules/react'), 'react-dom': join(rootDir, './node_modules/react-dom') }