├── .editorconfig ├── .env.example ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── renovate.json └── workflows │ ├── export-size.yml │ ├── publish.yml │ └── tests.yml ├── .gitignore ├── .npmignore ├── .nvmrc ├── CHANGELOG.md ├── README.md ├── eslint.config.js ├── package-lock.json ├── package.json ├── packages ├── demo │ ├── nuxt.config.ts │ ├── package.json │ ├── pages │ │ ├── index.vue │ │ ├── issue-249.vue │ │ └── issue-77.vue │ ├── plugins │ │ └── errorHandler.js │ └── public │ │ └── earthquakes.json ├── docs │ ├── .vitepress │ │ ├── assets │ │ │ └── earthquakes.json │ │ ├── components │ │ │ ├── MapboxClusterWithCustomImageDemo.vue │ │ │ ├── MapboxClusterWithPopupDemo.vue │ │ │ ├── MapboxGeocoderDemo.vue │ │ │ ├── MapboxGeocoderDemoWithoutMap.vue │ │ │ ├── MapboxGeolocateControlDemo.vue │ │ │ ├── MapboxImagesDemo.vue │ │ │ ├── MapboxMarkerCustomHtmlDemo.vue │ │ │ ├── MapboxMarkerPopupDemo.vue │ │ │ ├── MapboxNavigationControlDemo.vue │ │ │ ├── MapboxPopupDemo.vue │ │ │ ├── StoreLocatorArchitecture.vue │ │ │ ├── StoreLocatorDemo.vue │ │ │ └── index.js │ │ ├── config.js │ │ └── theme │ │ │ └── index.js │ ├── components │ │ ├── MapboxCluster │ │ │ └── index.md │ │ ├── MapboxFullscreenControl │ │ │ └── index.md │ │ ├── MapboxGeocoder │ │ │ └── index.md │ │ ├── MapboxGeolocateControl │ │ │ └── index.md │ │ ├── MapboxImage │ │ │ └── index.md │ │ ├── MapboxImages │ │ │ └── index.md │ │ ├── MapboxLayer │ │ │ └── index.md │ │ ├── MapboxMap │ │ │ └── index.md │ │ ├── MapboxMarker │ │ │ └── index.md │ │ ├── MapboxNavigationControl │ │ │ └── index.md │ │ ├── MapboxPopup │ │ │ └── index.md │ │ ├── MapboxSource │ │ │ └── index.md │ │ └── StoreLocator │ │ │ └── index.md │ ├── guide │ │ ├── installation │ │ │ └── index.md │ │ ├── introduction │ │ │ └── index.md │ │ └── usage │ │ │ └── index.md │ ├── index.md │ ├── package.json │ ├── postcss.config.cjs │ ├── public │ │ ├── earthquakes.json │ │ └── logo.png │ └── tailwind.config.js ├── tests │ ├── components │ │ └── MapboxMap.spec.ts │ ├── index.spec.ts │ ├── package.json │ └── vitest.config.ts └── vue-mapbox-gl │ ├── components │ ├── MapboxCluster.vue │ ├── MapboxFullscreenControl.vue │ ├── MapboxGeocoder.vue │ ├── MapboxGeolocateControl.vue │ ├── MapboxImage.vue │ ├── MapboxImages.vue │ ├── MapboxLayer.vue │ ├── MapboxMap.vue │ ├── MapboxMarker.vue │ ├── MapboxNavigationControl.vue │ ├── MapboxPopup.vue │ ├── MapboxSource.vue │ ├── StoreLocator │ │ ├── StoreLocator.vue │ │ ├── VueScroller.vue │ │ └── index.ts │ └── index.ts │ ├── composables │ ├── index.ts │ ├── useControl.ts │ ├── useEventsBinding.ts │ ├── useMap.ts │ └── usePropsBinding.ts │ ├── index.ts │ └── package.json ├── prettier.config.js ├── tsconfig.build.json ├── tsconfig.json ├── tsconfig.lint.json └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | MAPBOX_API_KEY='' 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | ### 🔗 Linked issue 6 | 7 | 8 | 9 | ### ❓ Type of change 10 | 11 | 12 | 13 | - [ ] 📖 Documentation (updates to the documentation, readme or JSdoc annotations) 14 | - [ ] 🐞 Bug fix (a non-breaking change that fixes an issue) 15 | - [ ] 👌 Enhancement (improving an existing functionality like performance) 16 | - [ ] ✨ New feature (a non-breaking change that adds functionality) 17 | - [ ] 🧹 Chore (updates to the build process or auxiliary tools and libraries) 18 | - [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change) 19 | 20 | ### 📚 Description 21 | 22 | 23 | 24 | 25 | 26 | ### 📝 Checklist 27 | 28 | 29 | 30 | 31 | 32 | - [ ] I have linked an issue or discussion. 33 | - [ ] I have added tests (if possible). 34 | - [ ] I have updated the documentation accordingly. 35 | - [ ] I have updated the changelog. 36 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "github>studiometa/renovate" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.github/workflows/export-size.yml: -------------------------------------------------------------------------------- 1 | name: export-size 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - develop 8 | 9 | jobs: 10 | export-size: 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | fetch-depth: '0' 16 | - uses: titouanmathis/export-size-action@main 17 | with: 18 | github_token: ${{ secrets.GITHUB_TOKEN }} 19 | build_script: npm run build 20 | paths: dist 21 | node-version: 22 22 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish-and-release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*.*.*' 7 | 8 | jobs: 9 | publish-and-release: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | id-token: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - uses: actions/setup-node@v4 18 | with: 19 | node-version: 22 20 | registry-url: https://registry.npmjs.org/ 21 | 22 | - name: Get npm cache directory 23 | id: npm-cache-dir 24 | shell: bash 25 | run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT} 26 | 27 | - uses: actions/cache@v4 28 | id: npm-cache 29 | with: 30 | path: | 31 | ${{ steps.npm-cache-dir.outputs.dir }} 32 | **/node_modules 33 | .eslintcache 34 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 35 | restore-keys: ${{ runner.os }}-node- 36 | 37 | - run: npm install --no-audit --no-fund 38 | 39 | - name: Install Playwright Dependencies 40 | run: npx playwright install chromium --with-deps 41 | 42 | - run: npm run build 43 | 44 | - name: Test 45 | run: npm run test -- -- --retry=3 --coverage.enabled 46 | 47 | - name: Upload coverage to Codecov 48 | uses: codecov/codecov-action@v4 49 | with: 50 | token: ${{ secrets.CODECOV_TOKEN }} 51 | directory: ./packages/coverage 52 | flags: unittests 53 | fail_ci_if_error: false 54 | verbose: true 55 | 56 | - run: | 57 | NPM_TAG='latest' 58 | IS_PRERELEASE=false 59 | 60 | if [[ $GITHUB_REF_NAME =~ 'alpha' || $GITHUB_REF_NAME =~ 'beta' || $GITHUB_REF_NAME =~ 'rc' ]]; then 61 | NPM_TAG='next' 62 | IS_PRERELEASE=true 63 | fi 64 | 65 | echo "NPM_TAG=$NPM_TAG" >> $GITHUB_ENV 66 | echo "IS_PRERELEASE=$IS_PRERELEASE" >> $GITHUB_ENV 67 | 68 | - uses: JS-DevTools/npm-publish@v3 69 | with: 70 | provenance: true 71 | package: dist/ 72 | tag: ${{ env.NPM_TAG }} 73 | token: ${{ secrets.NPM_TOKEN }} 74 | 75 | - uses: ncipollo/release-action@v1 76 | with: 77 | tag: ${{ github.ref }} 78 | name: v${{ github.ref_name }} 79 | body: Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/CHANGELOG.md) for details. 80 | draft: false 81 | prerelease: ${{ env.IS_PRERELEASE }} 82 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - develop 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: 22 18 | cache: npm 19 | - name: Install dependencies 20 | run: npm install 21 | - name: Build 22 | run: npm run build 23 | 24 | code-quality: 25 | runs-on: macos-latest 26 | steps: 27 | - uses: actions/checkout@v4 28 | - uses: actions/setup-node@v4 29 | with: 30 | node-version: 22 31 | cache: npm 32 | - name: Install dependencies 33 | run: npm install 34 | - name: Run code quality tests 35 | run: npm run lint 36 | 37 | unit: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v4 41 | - uses: actions/setup-node@v4 42 | with: 43 | node-version: 22 44 | cache: npm 45 | - name: Install dependencies 46 | run: npm install 47 | - name: Install Playwright Dependencies 48 | run: npx playwright install chromium --with-deps 49 | - name: Run tests 50 | run: npm run test -- -- --retry=3 --coverage.enabled 51 | - name: Upload coverage to Codecov 52 | uses: codecov/codecov-action@v4 53 | with: 54 | files: ./packages/coverage/clover.xml 55 | flags: unittests 56 | fail_ci_if_error: false 57 | verbose: true 58 | env: 59 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log* 4 | .env 5 | /dist/ 6 | /packages/docs/.vitepress/dist/ 7 | /packages/docs/.vitepress/cache/ 8 | /packages/demo/.nuxt/ 9 | /packages/demo/.output/ 10 | /packages/coverage/ 11 | .eslintcache 12 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.code-workspace 2 | *.sublime-* 3 | .env 4 | .env.example 5 | tests/ 6 | jest.config.js 7 | docs/ 8 | .github/ 9 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 4 | 5 | ## [Unreleased] 6 | 7 | ## [v2.7.2](https://github.com/studiometa/vue-mapbox-gl/compare/2.7.1...2.7.2) (2025-02-12) 8 | 9 | ### Fixed 10 | 11 | - Fix Mapbox trying to remove controls already removed ([#249](https://github.com/studiometa/vue-mapbox-gl/issues/249), [#259](https://github.com/studiometa/vue-mapbox-gl/pull/259), [0bfaea6](https://github.com/studiometa/vue-mapbox-gl/commit/0bfaea6)) 12 | 13 | ## [v2.7.1](https://github.com/studiometa/vue-mapbox-gl/compare/2.7.0...2.7.1) (2025-02-04) 14 | 15 | ### Changed 16 | 17 | - **Docs:** update mapbox token ([3de06ed](https://github.com/studiometa/vue-mapbox-gl/commit/3de06ed)) 18 | 19 | ## [v2.7.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.6.0...2.7.0) (2025-01-25) 20 | 21 | ### Added 22 | 23 | - Add initial support for types ([#107](https://github.com/studiometa/vue-mapbox-gl/issues/107), [#226](https://github.com/studiometa/vue-mapbox-gl/pull/226), [539cc32](https://github.com/studiometa/vue-mapbox-gl/commit/539cc32)) 24 | 25 | ### Changed 26 | 27 | - Update dependencies ([#243](https://github.com/studiometa/vue-mapbox-gl/pull/243), [#229](https://github.com/studiometa/vue-mapbox-gl/pull/229)) 28 | 29 | ## [v2.7.0-alpha.3](https://github.com/studiometa/vue-mapbox-gl/compare/2.7.0-alpha.2...2.7.0-alpha.3) (2025-01-24) 30 | 31 | ### Fixed 32 | 33 | - Fix build on ubuntu ([23ca250](https://github.com/studiometa/vue-mapbox-gl/commit/23ca250)) 34 | 35 | ### Changed 36 | 37 | - Update dependencies ([#243](https://github.com/studiometa/vue-mapbox-gl/pull/243)) 38 | 39 | ## [v2.7.0-alpha.2](https://github.com/studiometa/vue-mapbox-gl/compare/2.7.0-alpha.1...2.7.0-alpha.2) (2025-01-24) 40 | 41 | ### Fixed 42 | 43 | - Fix NPM publish ([8a9df54](https://github.com/studiometa/vue-mapbox-gl/commit/8a9df54)) 44 | 45 | ### Dependencies 46 | 47 | - Update dependency vue-tsc to v2.2.0 ([#229](https://github.com/studiometa/vue-mapbox-gl/pull/229), [40dce9e](https://github.com/studiometa/vue-mapbox-gl/commit/40dce9e)) 48 | 49 | ## [v2.7.0-alpha.1](https://github.com/studiometa/vue-mapbox-gl/compare/2.7.0-alpha.0...2.7.0-alpha.1) (2025-01-24) 50 | 51 | ### Fixed 52 | 53 | - Fix Mapbox event binding ([#231](https://github.com/studiometa/vue-mapbox-gl/issues/231), [#232](https://github.com/studiometa/vue-mapbox-gl/pull/232), [882baca](https://github.com/studiometa/vue-mapbox-gl/commit/882baca)) 54 | 55 | ## [v2.7.0-alpha.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.6.0...2.7.0-alpha.0) (2025-01-02) 56 | 57 | ### Added 58 | 59 | - Add types ([#107](https://github.com/studiometa/vue-mapbox-gl/issues/107), [#226](https://github.com/studiometa/vue-mapbox-gl/pull/226), [539cc32](https://github.com/studiometa/vue-mapbox-gl/commit/539cc32)) 60 | 61 | ## [v2.6.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.5.0...2.6.0) (2025-01-02) 62 | 63 | ### Added 64 | 65 | - Add a `MapboxFullscreenControl` component ([#177](https://github.com/studiometa/vue-mapbox-gl/pull/177), [36fff83](https://github.com/studiometa/vue-mapbox-gl/commit/36fff83)) 66 | - Expose the marker instance ([#195](https://github.com/studiometa/vue-mapbox-gl/pull/195), [08b1cab](https://github.com/studiometa/vue-mapbox-gl/commit/08b1cab)) 67 | - Add support for renderless marker ([#196](https://github.com/studiometa/vue-mapbox-gl/pull/196), [91cb2e3](https://github.com/studiometa/vue-mapbox-gl/commit/91cb2e3)) 68 | 69 | ### Changed 70 | 71 | - Improve performance by using shallowRef instead of ref ([#194](https://github.com/studiometa/vue-mapbox-gl/pull/194), [a34ce76](https://github.com/studiometa/vue-mapbox-gl/commit/a34ce76)) 72 | 73 | ### Fixed 74 | 75 | - Fix typo in heading of accessToken prop ([#192](https://github.com/studiometa/vue-mapbox-gl/pull/192), [f0d6587](https://github.com/studiometa/vue-mapbox-gl/commit/f0d6587)) 76 | - Fix binding of events ([#124](https://github.com/studiometa/vue-mapbox-gl/pull/124), [9d71b7e](https://github.com/studiometa/vue-mapbox-gl/commit/9d71b7e)) 77 | 78 | ## [v2.5.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.4.0...2.5.0) (2024-03-05) 79 | 80 | ### Added 81 | 82 | - **StoreLocator:** add `disableFeatureClickZoom` prop to disable the zoom on feature click ([#136](https://github.com/studiometa/vue-mapbox-gl/pull/136)) 83 | 84 | ## [v2.4.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.3.4...2.4.0) (2024-02-23) 85 | 86 | ### Added 87 | 88 | - Add support for mapbox-gl ^3.0.0 ([f8a9b21](https://github.com/studiometa/vue-mapbox-gl/commit/f8a9b21)) 89 | 90 | ### Fixed 91 | 92 | - Fix a warning when using MapboxGeocoder outside MapboxMap ([e4202ea](https://github.com/studiometa/vue-mapbox-gl/commit/e4202ea)) 93 | 94 | ## [v2.3.4](https://github.com/studiometa/vue-mapbox-gl/compare/2.3.3...2.3.4) (2024-01-30) 95 | 96 | ### Fixed 97 | 98 | - Fix Geocoder proximity props default ([#133](https://github.com/studiometa/vue-mapbox-gl/pull/133)) 99 | 100 | ## [v2.3.3](https://github.com/studiometa/vue-mapbox-gl/compare/2.3.2...2.3.3) (2024-01-12) 101 | 102 | ### Fixed 103 | 104 | - Fix NPM publication ([#131](https://github.com/studiometa/vue-mapbox-gl/pull/131)) 105 | 106 | ## [v2.3.2](https://github.com/studiometa/vue-mapbox-gl/compare/2.3.1...2.3.2) (2024-01-11) 107 | 108 | ### Fixed 109 | 110 | - Fix NPM publication 111 | 112 | ## [v2.3.1](https://github.com/studiometa/vue-mapbox-gl/compare/2.3.0...2.3.1) (2024-01-11) 113 | 114 | ### Fixed 115 | 116 | - Fix NPM critical dependencies ([#130](https://github.com/studiometa/vue-mapbox-gl/pull/130)) 117 | 118 | ## [v2.3.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.2.0...2.3.0) (2024-01-11) 119 | 120 | ### Added 121 | 122 | - Add `filterItemsCallback` props to `StoreLocator` component to enable filtering the items list ([#128](https://github.com/studiometa/vue-mapbox-gl/pull/128)) 123 | 124 | ## [v2.2.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.1.1...2.2.0) (2023-09-15) 125 | 126 | ### Added 127 | 128 | - Add support for the `clusterProperties` option ([4a55844](https://github.com/studiometa/vue-mapbox-gl/commit/4a55844), [#119](https://github.com/studiometa/vue-mapbox-gl/pull/119), fix [#117](https://github.com/studiometa/vue-mapbox-gl/issues/117)) 129 | - Add support for the `clusterMinPoints` option ([4e403c7](https://github.com/studiometa/vue-mapbox-gl/commit/4e403c7), [#119](https://github.com/studiometa/vue-mapbox-gl/pull/119)) 130 | - Add props to the `MapboxMap` component ([79d2929](https://github.com/studiometa/vue-mapbox-gl/commit/79d2929), [#121](https://github.com/studiometa/vue-mapbox-gl/pull/121), fix [#108](https://github.com/studiometa/vue-mapbox-gl/issues/108)) 131 | 132 | ### Fixed 133 | 134 | - Fix a bug where the geolocate control could be accessed before being added to the map ([3f8eaef](https://github.com/studiometa/vue-mapbox-gl/commit/3f8eaef), [#106](https://github.com/studiometa/vue-mapbox-gl/pull/106), fix [#77](https://github.com/studiometa/vue-mapbox-gl/issues/77)) 135 | 136 | ## [v2.1.1](https://github.com/studiometa/vue-mapbox-gl/compare/2.1.0...2.1.1) (2023-04-17) 137 | 138 | ### Changed 139 | 140 | - Add search to the docs (1c92956) 141 | 142 | ## [v2.1.0](https://github.com/studiometa/vue-mapbox-gl/compare/2.0.4...2.1.0) (2023-04-08) 143 | 144 | ### Added 145 | 146 | - **MapboxCluster:** add support for preventing the default behavior when clicking on a cluster ([#88](https://github.com/studiometa/vue-mapbox-gl/pull/88), fix [#87](https://github.com/studiometa/vue-mapbox-gl/issues/87), [@asanmiguel-nodrizatech](https://github.com/asanmiguel-nodrizatech)) 147 | - **MapboxGeolocateControl:** add support for the `trackUserLocation` option ([#93](https://github.com/studiometa/vue-mapbox-gl/pull/93), [@kayrunm](https://github.com/kayrunm)) 148 | 149 | ### Fixed 150 | 151 | - **MapboxGeocoder:** fix a JavaScript error when used outside of a map ([#98](https://github.com/studiometa/vue-mapbox-gl/pull/98), fix [#91](https://github.com/studiometa/vue-mapbox-gl/issues/91)) 152 | 153 | ### Changed 154 | 155 | - Update NPM dependencies ([#89](https://github.com/studiometa/vue-mapbox-gl/pull/89), [#92](https://github.com/studiometa/vue-mapbox-gl/pull/92), [#86](https://github.com/studiometa/vue-mapbox-gl/pull/86), [#80](https://github.com/studiometa/vue-mapbox-gl/pull/80), [#99](https://github.com/studiometa/vue-mapbox-gl/pull/99)) 156 | - Update docs with center as ref ([#95](https://github.com/studiometa/vue-mapbox-gl/pull/95), [@michaelklopf](https://github.com/michaelklopf)) 157 | 158 | ## [v2.0.4](https://github.com/studiometa/vue-mapbox-gl/compare/2.0.3...2.0.4) (2023-01-11) 159 | 160 | ### Fixed 161 | 162 | - Fix a bug where controls could be accessed before being added to the map ([eefaee2](https://github.com/studiometa/vue-mapbox-gl/commit/eefaee2), fix [#77](https://github.com/studiometa/vue-mapbox-gl/issues/77)) 163 | - Fix doc regarding access token ([#78](https://github.com/studiometa/vue-mapbox-gl/pull/78), fix [#67](https://github.com/studiometa/vue-mapbox-gl/issues/67)) 164 | 165 | ## [v2.0.3](https://github.com/studiometa/vue-mapbox-gl/compare/2.0.2...2.0.3) (2023-01-10) 166 | 167 | ### Fixed 168 | 169 | - Fix cluster IDs not being incremented ([#83](https://github.com/studiometa/vue-mapbox-gl/pull/83), fix [#75](https://github.com/studiometa/vue-mapbox-gl/issues/75)) 170 | - Fix a bug where controls could be accessed before being added to the map ([#82](https://github.com/studiometa/vue-mapbox-gl/pull/82), fix [#77](https://github.com/studiometa/vue-mapbox-gl/issues/77)) 171 | - Fix Node warning about package.json fields ([3b5e4e7](https://github.com/studiometa/vue-mapbox-gl/commit/3b5e4e7), fix [#74](https://github.com/studiometa/vue-mapbox-gl/issues/74)) 172 | - Fix CSS build file containing an invalid comment ([612c9e8](https://github.com/studiometa/vue-mapbox-gl/commit/612c9e8)) 173 | 174 | ### Changed 175 | 176 | - Update NPM dependencies ([#81](https://github.com/studiometa/vue-mapbox-gl/pull/81)) 177 | 178 | ## [v2.0.2](https://github.com/studiometa/vue-mapbox-gl/compare/2.0.1...2.0.2) (2022-12-05) 179 | 180 | ### Fixed 181 | 182 | - Fix links in the README.md ([#65](https://github.com/studiometa/vue-mapbox-gl/pull/65)) 183 | 184 | ### Changed 185 | 186 | - Move release notes to the [CHANGELOG.md](https://github.com/studiometa/vue-mapbox-gl/blob/develop/CHANGELOG.md) file 187 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🗺 @studiometa/vue-mapbox-gl 2 | 3 | [![NPM Version](https://img.shields.io/npm/v/@studiometa/vue-mapbox-gl.svg?style=flat&colorB=3e63dd&colorA=414853)](https://www.npmjs.com/package/@studiometa/vue-mapbox-gl/) 4 | [![Downloads](https://img.shields.io/npm/dm/@studiometa/vue-mapbox-gl?style=flat&colorB=3e63dd&colorA=414853)](https://www.npmjs.com/package/@studiometa/vue-mapbox-gl/) 5 | [![Size](https://img.shields.io/bundlephobia/minzip/@studiometa/vue-mapbox-gl?style=flat&colorB=3e63dd&colorA=414853&label=size)](https://bundlephobia.com/package/@studiometa/vue-mapbox-gl) 6 | [![Dependency Status](https://img.shields.io/librariesio/release/npm/@studiometa/vue-mapbox-gl?style=flat&colorB=3e63dd&colorA=414853)](https://david-dm.org/studiometa/vue-mapbox-gl) 7 | ![Codecov](https://img.shields.io/codecov/c/github/studiometa/vue-mapbox-gl?style=flat&colorB=3e63dd&colorA=414853) 8 | 9 | > A small components library to use Mapbox GL in Vue 3 app. 10 | 11 | ## Installation & usage 12 | 13 | Have a look at the [small guide](https://vue-mapbox-gl.studiometa.dev/guide/introduction/) for information on how to setup a simple map. 14 | 15 | ## Components 16 | 17 | The following components are available: 18 | 19 | | Component | Description | Doc. | 20 | |---------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|------| 21 | | [MapboxMap](https://vue-mapbox-gl.studiometa.dev/components/MapboxMap) | Display a map with the given style. | ✅ | 22 | | [MapboxMarker](https://vue-mapbox-gl.studiometa.dev/components/MapboxMarker) | Display a simple or custom marker. | ✅ | 23 | | [MapboxCluster](https://vue-mapbox-gl.studiometa.dev/components/MapboxCluster) | Display a GeoJSON as clusters. | ✅ | 24 | | [MapboxGeocoder](https://vue-mapbox-gl.studiometa.dev/components/MapboxGeocoder) | Display a geocoder search input with the [@mapbox/mapbox-gl-geocoder](https://github.com/mapbox/mapbox-gl-geocoder) plugin. | ✅ | 25 | | [MapboxImage](https://vue-mapbox-gl.studiometa.dev/components/MapboxImage) | Load an image to be used on the map. | ✅ | 26 | | [MapboxImages](https://vue-mapbox-gl.studiometa.dev/components/MapboxImages) | Load multiple images to be used on the map. | ✅ | 27 | | [MapboxLayer](https://vue-mapbox-gl.studiometa.dev/components/MapboxLayer) | Display a layer on the map. | ❌ | 28 | | [MapboxNavigationControl](https://vue-mapbox-gl.meta.fr/components/MapboxNavigationControl) | Display the map's navigation controls | ✅ | 29 | | [MapboxPopup](https://vue-mapbox-gl.studiometa.dev/components/MapboxPopup) | Display a popup on the map | ✅ | 30 | | [MapboxSource](https://vue-mapbox-gl.studiometa.dev/components/MapboxSource) | Load a source of data to be used on the map | ❌ | 31 | 32 | ## Contributing 33 | 34 | ### Installation 35 | 36 | ```bash 37 | # Clone the project 38 | git clone git@github.com:studiometa/vue-mapbox-gl.git 39 | # Cd in the repository 40 | cd vue-mapbox-gl 41 | # Install dependencies 42 | npm i 43 | ``` 44 | 45 | ### Useful commands 46 | 47 | ```bash 48 | # Build for deployment 49 | npm run build 50 | # Test before deployment 51 | npm run test 52 | # Lint files 53 | npm run lint 54 | # Fix linting errors 55 | npm run fix 56 | ``` 57 | 58 | ## Note 59 | 60 | This project is a rewrite of a fork of [openearth/vue2mapbox-gl](https://github.com/openearth/vue2mapbox-gl) and is published under the [GNU GPL 3](https://www.gnu.org/licenses/gpl-3.0.en.html) license. 61 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig, ts, vueTs, prettier, globals } from '@studiometa/eslint-config'; 2 | 3 | export default defineConfig( 4 | ts, 5 | vueTs, 6 | prettier, 7 | { 8 | files: ['packages/{demo,vue-mapbox-gl}/**/*.{js,vue}'], 9 | languageOptions: { 10 | globals: { 11 | ...globals.browser, 12 | }, 13 | }, 14 | rules: { 15 | 'vue/valid-define-emits': 'off', 16 | }, 17 | }, 18 | { 19 | ignores: ['**/.nuxt/**', '**/.output/**'], 20 | }, 21 | ); 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studiometa/vue-mapbox-gl-workspace", 3 | "private": true, 4 | "version": "2.7.2", 5 | "type": "module", 6 | "workspaces": [ 7 | "packages/*" 8 | ], 9 | "scripts": { 10 | "docs:dev": "npm run dev -w @studiometa/vue-mapbox-gl-docs", 11 | "docs:build": "npm run build -w @studiometa/vue-mapbox-gl-docs", 12 | "demo:dev": "npm run dev -w @studiometa/vue-mapbox-gl-demo", 13 | "demo:build": "npm run build -w @studiometa/vue-mapbox-gl-demo", 14 | "lint": "npm run lint:eslint", 15 | "lint:eslint": "eslint packages/{vue-mapbox-gl,demo} --cache", 16 | "lint:types": "vue-tsc --noEmit", 17 | "fix": "npm run lint:eslint -- --fix", 18 | "build": "rm -rf dist && npm run build:vite && npm run build:cp", 19 | "build:vite": "vite build", 20 | "build:cp": "cp packages/vue-mapbox-gl/package.json dist/ && cp README.md dist/ && npm run build:fix-extension", 21 | "build:fix-extension": "echo \"$(cat dist/package.json | sed 's/index\\.ts/index\\.js/')\" > dist/package.json && cat dist/package.json", 22 | "prepublishOnly": "npm run build", 23 | "test": "npm run test -w @studiometa/vue-mapbox-gl-tests" 24 | }, 25 | "devDependencies": { 26 | "@studiometa/eslint-config": "4.2.0", 27 | "@studiometa/prettier-config": "4.1.0", 28 | "eslint": "9.26.0", 29 | "prettier": "3.5.3" 30 | }, 31 | "dependencies": { 32 | "@vitejs/plugin-vue": "5.2.4", 33 | "@vue/tsconfig": "0.7.0", 34 | "vite": "6.2.7", 35 | "vite-plugin-dts": "4.5.4", 36 | "vue-tsc": "2.2.10" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/demo/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | devtools: { enabled: true }, 4 | compatibilityDate: '2025-01-02', 5 | runtimeConfig: { 6 | public: { 7 | accessToken: 8 | 'pk.eyJ1IjoiYWdlbmNlc3R1ZGlvbWV0YSIsImEiOiJjbTZxZXZidzYxaXR3MmtzaG5qNzc3NGxqIn0.c_YVpXQptiZtOgzj_5jvaw', 9 | }, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studiometa/vue-mapbox-gl-demo", 3 | "version": "2.7.2", 4 | "scripts": { 5 | "dev": "nuxt dev", 6 | "build": "nuxt build" 7 | }, 8 | "dependencies": { 9 | "@mapbox/mapbox-gl-geocoder": "^5.0.3", 10 | "@studiometa/vue-mapbox-gl": "*", 11 | "mapbox-gl": "^3.9.3", 12 | "nuxt": "^3.15.2", 13 | "vue": "^3.5.13" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/demo/pages/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 78 | 79 | 159 | 160 | 165 | -------------------------------------------------------------------------------- /packages/demo/pages/issue-249.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 26 | -------------------------------------------------------------------------------- /packages/demo/pages/issue-77.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 37 | -------------------------------------------------------------------------------- /packages/demo/plugins/errorHandler.js: -------------------------------------------------------------------------------- 1 | import { defineNuxtPlugin } from '#imports'; 2 | 3 | export default defineNuxtPlugin((nuxtApp) => { 4 | nuxtApp.vueApp.config.errorHandler = console.error; 5 | nuxtApp.vueApp.config.warnHandler = console.warn; 6 | }); 7 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxClusterWithCustomImageDemo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 29 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxClusterWithPopupDemo.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 50 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxGeocoderDemo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxGeocoderDemoWithoutMap.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 28 | 29 | 41 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxGeolocateControlDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxImagesDemo.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 67 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxMarkerCustomHtmlDemo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 20 | 21 | 28 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxMarkerPopupDemo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxNavigationControlDemo.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/MapboxPopupDemo.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/StoreLocatorArchitecture.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 87 | 88 | 108 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/StoreLocatorDemo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 25 | 26 | 71 | 72 | 280 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as MapboxClusterWithCustomImageDemo } from './MapboxClusterWithCustomImageDemo.vue'; 2 | export { default as MapboxClusterWithPopupDemo } from './MapboxClusterWithPopupDemo.vue'; 3 | export { default as MapboxGeocoderDemo } from './MapboxGeocoderDemo.vue'; 4 | export { default as MapboxGeocoderDemoWithoutMap } from './MapboxGeocoderDemoWithoutMap.vue'; 5 | export { default as MapboxGeolocateControlDemo } from './MapboxGeolocateControlDemo.vue'; 6 | export { default as MapboxImagesDemo } from './MapboxImagesDemo.vue'; 7 | export { default as MapboxMarkerCustomHtmlDemo } from './MapboxMarkerCustomHtmlDemo.vue'; 8 | export { default as MapboxMarkerPopupDemo } from './MapboxMarkerPopupDemo.vue'; 9 | export { default as MapboxNavigationControlDemo } from './MapboxNavigationControlDemo.vue'; 10 | export { default as MapboxPopupDemo } from './MapboxPopupDemo.vue'; 11 | export { default as StoreLocatorArchitecture } from './StoreLocatorArchitecture.vue'; 12 | export { default as StoreLocatorDemo } from './StoreLocatorDemo.vue'; 13 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress'; 2 | 3 | export default defineConfig({ 4 | lang: 'en-US', 5 | title: 'Vue 3 Mapbox GL', 6 | description: 'A small library of Vue components for mapbox-gl', 7 | lastUpdated: true, 8 | markdown: { 9 | toc: { level: [2] }, 10 | }, 11 | themeConfig: { 12 | logo: '/logo.png', 13 | footer: { 14 | message: 'Released under the GPL 3.0 License.', 15 | copyright: 'Copyright © 2019-present Studio Meta', 16 | }, 17 | search: { 18 | provider: 'local', 19 | }, 20 | editLink: { 21 | pattern: 'https://github.com/studiometa/vue-mapbox-gl/edit/master/packages/docs/:path', 22 | text: 'Edit this page on GitHub', 23 | }, 24 | socialLinks: [{ icon: 'github', link: 'https://github.com/studiometa/vue-mapbox-gl' }], 25 | nav: [ 26 | { text: 'Home', link: '/' }, 27 | { text: 'Guide', link: '/guide/introduction/' }, 28 | { 29 | text: 'Components', 30 | items: [ 31 | { text: 'MapboxMap', link: '/components/MapboxMap/' }, 32 | { text: 'MapboxMarker', link: '/components/MapboxMarker/' }, 33 | { text: 'MapboxCluster', link: '/components/MapboxCluster/' }, 34 | { text: 'MapboxFullscreenControl', link: '/components/MapboxFullscreenControl/' }, 35 | { text: 'MapboxGeocoder', link: '/components/MapboxGeocoder/' }, 36 | { text: 'MapboxGeolocateControl', link: '/components/MapboxGeolocateControl/' }, 37 | { text: 'MapboxImage', link: '/components/MapboxImage/' }, 38 | { text: 'MapboxImages', link: '/components/MapboxImages/' }, 39 | { text: 'MapboxLayer', link: '/components/MapboxLayer/' }, 40 | { text: 'MapboxNavigationControl', link: '/components/MapboxNavigationControl/' }, 41 | { text: 'MapboxPopup', link: '/components/MapboxPopup/' }, 42 | { text: 'MapboxSource', link: '/components/MapboxSource/' }, 43 | { text: 'StoreLocator', link: '/components/StoreLocator/' }, 44 | ], 45 | }, 46 | ], 47 | sidebar: [ 48 | { 49 | text: 'Guide', 50 | collapsible: true, 51 | items: [ 52 | { text: 'Introduction', link: '/guide/introduction/' }, 53 | { text: 'Installation', link: '/guide/installation/' }, 54 | { text: 'Usage', link: '/guide/usage/' }, 55 | ], 56 | }, 57 | { 58 | text: 'Components', 59 | collapsible: true, 60 | items: [ 61 | { text: 'MapboxMap', link: '/components/MapboxMap/' }, 62 | { text: 'MapboxMarker', link: '/components/MapboxMarker/' }, 63 | { text: 'MapboxCluster', link: '/components/MapboxCluster/' }, 64 | { text: 'MapboxGeocoder', link: '/components/MapboxGeocoder/' }, 65 | { text: 'MapboxGeolocateControl', link: '/components/MapboxGeolocateControl/' }, 66 | { text: 'MapboxImage', link: '/components/MapboxImage/' }, 67 | { text: 'MapboxImages', link: '/components/MapboxImages/' }, 68 | { text: 'MapboxLayer', link: '/components/MapboxLayer/' }, 69 | { text: 'MapboxNavigationControl', link: '/components/MapboxNavigationControl/' }, 70 | { text: 'MapboxPopup', link: '/components/MapboxPopup/' }, 71 | { text: 'MapboxSource', link: '/components/MapboxSource/' }, 72 | { text: 'StoreLocator', link: '/components/StoreLocator/' }, 73 | ], 74 | }, 75 | ], 76 | }, 77 | }); 78 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme'; 2 | import 'mapbox-gl/dist/mapbox-gl.css'; 3 | 4 | export default { 5 | ...DefaultTheme, 6 | enhanceApp({ app }) { 7 | app.config.globalProperties.MAPBOX_API_KEY = 8 | 'pk.eyJ1IjoiYWdlbmNlc3R1ZGlvbWV0YSIsImEiOiJjbTZxZXZidzYxaXR3MmtzaG5qNzc3NGxqIn0.c_YVpXQptiZtOgzj_5jvaw'; 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxCluster/index.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # MapboxCluster 7 | 8 | Display a cluster on the map with data coming from a GeoJSON source. 9 | 10 | - [Mapbox cluster example](https://docs.mapbox.com/mapbox-gl-js/example/cluster/) 11 | - [Layer Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers) 12 | 13 | 14 |

Table of contents

15 | 16 | [[toc]] 17 | 18 | ## Examples 19 | 20 | ### Basic usage 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | ```vue {10} 32 | 35 | 36 | 44 | ``` 45 | 46 | ### Open popup on feature click 47 | 48 | 49 | 50 | 51 | 52 | <<< @/.vitepress/components/MapboxClusterWithPopupDemo.vue{6-8,10-28,38-47} 53 | 54 | :::warning 55 | The `:center` prop of the `MapboxMap` component must be set via a data property (see `mapCenter` in the example above) instead of directly in the template, as it can create unexpected behaviours when clicking on a cluster feature. 56 | ::: 57 | 58 | ### Custom marker for unclustured points 59 | 60 | 61 | 62 | 63 | 64 | <<< @/.vitepress/components/MapboxClusterWithCustomImageDemo.vue{8,12-15,17} 65 | 66 | ## Props 67 | 68 | 69 | ### `data` 70 | 71 | - Type `[ String, Object ]` 72 | - Required `true` 73 | 74 | The source of the data for the clustered points, must be a String or an Object of GeoJSON format. 75 | 76 | 77 | ### `clusterMaxZoom` 78 | 79 | - Type `Number` 80 | - Default `14` 81 | 82 | The max zoom to cluster points on. 83 | 84 | ### `clusterRadius` 85 | 86 | - Type `Number` 87 | - Default `50` 88 | 89 | Radius of each cluster when clustering point. 90 | 91 | ### `clusterMinPoints` 92 | 93 | - Type `Number` 94 | - Default `2` 95 | 96 | Minimum number of points necessary to form a cluster. 97 | 98 | ### `clusterProperties` 99 | 100 | - Type `Object` 101 | - Default `{}}` 102 | 103 | An object defining custom properties on the generated clusters. 104 | 105 | ### `clustersLayout` 106 | 107 | - Type `Object` 108 | - Default `{}` 109 | 110 | The layout configuration for the clusters circles layer. 111 | 112 | ### `clustersPaint` 113 | 114 | - Type `Object` 115 | - Default `{ 'circle-color': '#000', 'circle-radius': 40 }` 116 | 117 | The paint configuration for the clusters circles layer. 118 | 119 | ### `clusterCountLayout` 120 | 121 | - Type `Object` 122 | - Default `{ 'text-field': [ 'get', 'point_count_abbreviated' ] }` 123 | 124 | The layout configuration for the clusters count layer. 125 | 126 | ### `clusterCountPaint` 127 | 128 | - Type `Object` 129 | - Default `{ 'text-color': 'white' }` 130 | 131 | The paint configuration for the clusters count layer. 132 | 133 | ### `unclusteredPointLayerType` 134 | 135 | - Type `String` 136 | - Default `'circle'` 137 | 138 | The type of the unclustered points layer. 139 | 140 | ### `unclusteredPointLayout` 141 | 142 | - Type `Object` 143 | - Default `{}` 144 | 145 | The layout configuration for the unclustered points layer. 146 | 147 | ### `unclusteredPointPaint` 148 | 149 | - Type `Object` 150 | - Default `{ 'circle-color': '#000', 'circle-radius': 4 }` 151 | 152 | The paint configuration for the unclustered points layer. 153 | 154 | ## Events 155 | 156 | ### `mb-cluster-click` 157 | 158 | Emitted when the user clicks on a cluster. 159 | 160 | **Params** 161 | - `clusterId`: the ID of the cluster being clicked 162 | - `event`: the Mapbox event object sent by the layer 163 | 164 | ### `mb-feature-click` 165 | 166 | Emitted when the user clicks on a unclustered point (a feature). 167 | 168 | **Params** 169 | - `feature`: the feature being clicked on 170 | - `event`: the Mapbox event object sent by the layer 171 | 172 | ### `mb-feature-mouseenter` 173 | 174 | Emitted when the user's mouse enters an unclustered point. 175 | 176 | **Params** 177 | - `feature`: the feature being clicked on 178 | - `event`: the Mapbox event object sent by the layer 179 | 180 | ### `mb-feature-mouseleave` 181 | 182 | Emitted when the user's mouse leaves an unclustered point. 183 | 184 | **Params** 185 | - `event`: the Mapbox event object sent by the layer 186 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxFullscreenControl/index.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # MapboxFullscreenControl 6 | 7 | Display a fullscreen control button on the map. 8 | 9 | - [Mapbox fullscreen control documentation](https://docs.mapbox.com/mapbox-gl-js/api/markers/#fullscreencontrol) 10 | - [Mapbox fullscreen control exemple](https://docs.mapbox.com/mapbox-gl-js/example/fullscreen/) 11 | 12 |

Table of contents

13 | 14 | [[toc]] 15 | 16 | ## Examples 17 | 18 | ### Basic usage 19 | 20 | 21 | 25 | 26 | 27 | 28 | 29 | ```vue {9} 30 | 33 | 34 | 38 | 39 | 40 | ``` 41 | 42 | 43 | ## Props 44 | 45 | ### `container` 46 | - Type `HTMLElement` 47 | - Required: `false` 48 | - Default `null` 49 | 50 | The compatible DOM element which should be made full screen. By default, the map container element will be made full screen. 51 | 52 | ### `position` 53 | - Type `string` 54 | - Required: `false` 55 | - Default `'top-right'` 56 | 57 | The position for the fullscreen control. 58 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxGeocoder/index.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # MapboxGeocoder 6 | 7 | Display a search form to search for places using Mapbox Geocoding API. 8 | This component does not support outside of the map. 9 | 10 | - [Mapbox geocoder API reference](https://github.com/mapbox/mapbox-gl-geocoder) 11 | 12 |

Table of contents

13 | 14 | [[toc]] 15 | 16 | ## Examples 17 | 18 | ### Basic usage 19 | 20 | 21 | 22 | 23 | 24 | ```vue 25 | 33 | 34 | 38 | ``` 39 | 40 | ### Without a map 41 | 42 | This component can be used outside of the `` component. You will need to pass the `accessToken` props. 43 | 44 | 45 | 46 | 47 | 48 | ```vue 49 | 57 | 58 | 63 | ``` 64 | 65 | :::warning 66 | This feature requires a minimal version of `4.5.0` for the `@mapbox/mapbox-gl-geocoder` package, as per its [changelog entry](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/CHANGELOG.md#v450). 67 | ::: 68 | 69 | ## Props 70 | 71 | ### `accessToken` 72 | - Type `String` 73 | - Required: only when used without a map 74 | - Default: `no-token` 75 | 76 | Your Mapbox access token or `no-token` if you are not using a map style from Mapbox. 77 | 78 | ### `zoom` 79 | - Type `Number` 80 | - Required: `false` 81 | - Default: `16` 82 | Zoom level to use to animate the map when no result is found. 83 | 84 | ### `flyTo` 85 | - Type `[ Boolen, Object ]` 86 | - Required: `false` 87 | - Default: `true` 88 | If `false`, animating the map to a selected result is disabled. If `true`, animating the map will use the default animation parameters. If an object, it will be passed as options to the map flyTo or fitBounds method providing control over the animation of the transition. 89 | 90 | ### `placeholder` 91 | - Type `String` 92 | - Required: `false` 93 | - Default: `Search` 94 | Override the default placeholder attribute value. 95 | 96 | ### `proximity` 97 | - Type `Object` 98 | - Required: `false` 99 | - Default: `{}` 100 | A proximity argument: this is a geographical point given as an object with latitude and longitude properties. Search results closer to this point will be given higher priority. 101 | 102 | ### `trackProximity` 103 | - Type `Boolean` 104 | - Required: `false` 105 | - Default: `true` 106 | If `true`, the geocoder proximity will automatically update based on the map view. 107 | 108 | ### `collapsed` 109 | - Type `Boolean` 110 | - Required: `false` 111 | - Default: `false` 112 | If `true`, the geocoder control will collapse until hovered or in focus. 113 | 114 | ### `clearAndBlurOnEsc` 115 | - Type `Boolean` 116 | - Required: `false` 117 | - Default: `false` 118 | If `true`, the geocoder control will clear it's contents and blur when user presses the escape key. 119 | 120 | ### `clearOnBlur` 121 | - Type `Boolean` 122 | - Required: `false` 123 | - Default: `false` 124 | If `true`, the geocoder control will clear it's value when the input blurs. 125 | 126 | ### `bbox` 127 | - Type `Array` 128 | - Required: `false` 129 | - Default: `[]` 130 | A bounding box argument: this is a bounding box given as an array in the format [minX, minY, maxX, maxY]. Search results will be limited to the bounding box. 131 | 132 | ### `countries` 133 | - Type `String` 134 | - Required: `false` 135 | - Default: `''` 136 | A comma separated list of country codes to limit results to specified country or countries. 137 | 138 | ### `types` 139 | - Type `String` 140 | - Required: `false` 141 | - Default: `''` 142 | A comma seperated list of types that filter results to match those specified. [See documentation for available types](https://docs.mapbox.com/api/search/#data-types ). If reverseGeocode is enabled, you should specify one type. If you configure more than one type, the first type will be used. 143 | 144 | ### `minLength` 145 | - Type `Number` 146 | - Required: `false` 147 | - Default: `2` 148 | Minimum number of characters to enter before results are shown. 149 | 150 | ### `limit` 151 | - Type `Number` 152 | - Required: `false` 153 | - Default: `5` 154 | Maximum number of results to show. 155 | 156 | ### `language` 157 | - Type `String` 158 | - Required: `false` 159 | - Default: `` 160 | Specify the language to use for response text and query result weighting. Options are IETF language tags comprised of a mandatory ISO 639-1 language code and optionally one or more IETF subtags for country or script. More than one value can also be specified, separated by commas. Defaults to the browser's language settings. 161 | 162 | ### `filter` 163 | - Type `Function` 164 | - Required: `false` 165 | - Default: `` 166 | A function which accepts a Feature in the [Carmen GeoJSON format](https://github.com/mapbox/carmen/blob/master/carmen-geojson.md) to filter out results from the Geocoding API response before they are included in the suggestions list. Return true to keep the item, false otherwise. 167 | 168 | ### `localGeocoder` 169 | - Type `Function` 170 | - Required: `false` 171 | - Default: `` 172 | A function accepting the query string which performs local geocoding to supplement results from the Mapbox Geocoding API. Expected to return an Array of GeoJSON Features in the [Carmen GeoJSON format](https://github.com/mapbox/carmen/blob/master/carmen-geojson.md). 173 | 174 | ### `reverseMode` 175 | - Type `String` 176 | - Required: `false` 177 | - Default: `distance` 178 | - Available values: `distance | score` 179 | Set the factors that are used to sort nearby results. 180 | 181 | ### `reverseGeocode` 182 | - Type `Boolean` 183 | - Required: `false` 184 | - Default: `false` 185 | If true, enable reverse geocoding mode. In reverse geocoding, search input is expected to be coordinates in the form lat, lon, with suggestions being the reverse geocodes. 186 | 187 | ### `enableEventLogging` 188 | - Type `Boolean` 189 | - Required: `false` 190 | - Default: `false` 191 | Allow Mapbox to collect anonymous usage statistics from the plugin. 192 | 193 | ### `marker` 194 | - Type `[ Boolean, Object ]` 195 | - Required: `false` 196 | - Default: `true` 197 | If `true`, a Marker will be added to the map at the location of the user-selected result using a default set of Marker options. If the value is an object, the marker will be constructed using these options. If `false`, no marker will be added to the map. Requires that options.mapboxgl also be set. 198 | 199 | ### `render` 200 | - Type `Function,` 201 | - Required: `false` 202 | - Default: `` 203 | A function that specifies how the results should be rendered in the dropdown menu. This function should accepts a single [Carmen GeoJSON](https://github.com/mapbox/carmen/blob/master/carmen-geojson.md) object as input and return a string. Any HTML in the returned string will be rendered. 204 | 205 | ### `getItemValue` 206 | - Type `Function,` 207 | - Required: `false` 208 | - Default: `(item) => item.place_name` 209 | A function that specifies how the selected result should be rendered in the search bar. This function should accept a single [Carmen GeoJSON](https://github.com/mapbox/carmen/blob/master/carmen-geojson.md) object as input and return a string. HTML tags in the output string will not be rendered. 210 | 211 | ### `mode` 212 | - Type `String,` 213 | - Required: `false` 214 | - Default: `mapbox.places` 215 | A string specifying the geocoding endpoint to query. Options are `mapbox.places` and `mapbox.places-permanent`. The `mapbox.places-permanent` mode requires an enterprise license for permanent geocodes. 216 | 217 | ### `localGeocoderOnly` 218 | - Type `Boolean,` 219 | - Required: `false` 220 | - Default: `false` 221 | If `true`, indicates that the localGeocoder results should be the only ones returned to the user. If `false`, indicates that the localGeocoder results should be combined with those from the Mapbox API with the localGeocoder results ranked higher. 222 | 223 | 224 | [Documentation of all paramaters available in options](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters) 225 | 226 | 227 | ## Events 228 | All events available on the `MapboxGeocoder` class are also available on the `MapboxGeocoder` component, prefixed by `mb-`. 229 | 230 | ### `mb-created` 231 | 232 | Emitted when the `MapboxGeocoder` instance is created with the instance as parameter. 233 | 234 | ### `mb-loading` 235 | 236 | Emitted when the geocoder is looking up a query. Receive a `{ query }` parameter. 237 | 238 | ### `mb-results` 239 | 240 | Emitted when the geocoder returns a response. Receive a `{ results }` parameter. 241 | 242 | ### `mb-result` 243 | 244 | Emitted when input is set. Receive a `{ result }` parameter. 245 | 246 | ### `mb-error` 247 | 248 | Emitted when input is set. Receive a `error` parameter. 249 | 250 | ### `mb-clear` 251 | 252 | Emitted when the input is cleared. 253 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxGeolocateControl/index.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # MapboxGeolocateControl 7 | 8 | Display a geolocatation control button on the map. When activated the map will travel to the user location. 9 | 10 | This button **will not display** for user who are blocking the acces to the gps postion. 11 | 12 | - [Mapbox geolocation control documentation](https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol.event:geolocate) 13 | - [Mapbox geolocation control exemple](https://docs.mapbox.com/mapbox-gl-js/example/locate-user/) 14 | 15 | 16 |

Table of contents

17 | 18 | [[toc]] 19 | 20 | ## Examples 21 | 22 | ### Basic usage 23 | 24 | 25 | 29 | 30 | 31 | 32 | 33 | ```vue {9} 34 | 37 | 38 | 42 | 43 | 44 | ``` 45 | 46 | 47 | ## Props 48 | 49 | ### `positionOptions` 50 | - Type `[ Object ]` 51 | - Required: `false` 52 | - Default `{ enableHighAccuracy:false, timeout:6000 }` 53 | 54 | A Geolocation API PositionOptions object. 55 | 56 | ### `fitBoundsOptions` 57 | - Type `[ Object ]` 58 | - Required: `false` 59 | - Default `{ maxZoom: 15 }` 60 | 61 | A fitBounds options object to use when the map is panned and zoomed to the user's location. The default is to use a maxZoom of 15 to limit how far the map will zoom in for very accurate locations. 62 | 63 | ### `trackUserLocation` 64 | - Type `[ Boolean ]` 65 | - Required: `false` 66 | - Default `false` 67 | 68 | If true the Geolocate Control becomes a toggle button and when active the map will receive updates to the user's location as it changes. 69 | 70 | ### `showAccuracyCircle` 71 | - Type `[ Boolean ]` 72 | - Required: `false` 73 | - Default `true` 74 | 75 | By default, if showUserLocation is true , a transparent circle will be drawn around the user location indicating the accuracy (95% confidence level) of the user's location. Set to false to disable. Always disabled when showUserLocation is false . 76 | 77 | ### `showUserHeading` 78 | - Type `[ Boolean ]` 79 | - Required: `false` 80 | - Default `false` 81 | 82 | If `true` an arrow will be drawn next to the user location dot indicating the device's heading. This only has affect when `trackUserLocation` is `true`. 83 | 84 | ### `showUserLocation` 85 | - Type `[ Boolean ]` 86 | - Required: `false` 87 | - Default `true` 88 | 89 | By default a dot will be shown on the map at the user's location. Set to false to disable. 90 | 91 | ### `position` 92 | - Type `[ String ]` 93 | - Required: `false` 94 | - Default `top-right` 95 | 96 | The position for the geolocation control. 97 | 98 | 99 | ## Events 100 | 101 | ### `mb-trackuserlocationstart` 102 | Emitted when the geolocation is started. 103 | 104 | ### `mb-trackuserlocationend` 105 | Emitted when the geolocation is ended. 106 | 107 | ### `mb-trackuserlocationgeolocate` 108 | Emitted on each Geolocation API position update which returned as success. 109 | 110 | ### `mb-error` 111 | Emitted on each Geolocation API position update which returned as an error. 112 | 113 | ### `mb-outofmaxbounds` 114 | Emitted on each Geolocation API position update which returned as success but user position is out of map maxBounds. 115 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxImage/index.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # MapboxImage 9 | 10 | Add an image to be used used in `icon-image`, `background-pattern`, `fill-pattern`, and `line-pattern`. 11 | 12 | - [`addImage` documentation](https://docs.mapbox.com/mapbox-gl-js/api/#map#addimage) 13 | - [Add an icon to the map example](https://docs.mapbox.com/mapbox-gl-js/example/add-image/) 14 | - [Add a generated icon to the map](https://docs.mapbox.com/mapbox-gl-js/example/add-image-generated/) 15 | 16 | 17 |

Table of contents

18 | 19 | [[toc]] 20 | 21 | ## Examples 22 | 23 | ### Add an icon to the map 24 | 25 | 26 | 32 | 35 | 59 | 60 | 61 | 62 | 63 | ```vue {12-14} 64 | 70 | 71 | 83 | ``` 84 | 85 | ## Props 86 | 87 | ### `id` 88 | 89 | - Type `String` 90 | - Required `true` 91 | 92 | The ID of the image. This will be used to refer to this image. 93 | 94 | ### `src` 95 | 96 | - Type `[ String, HTMLImageElement, ImageData, Object ]` 97 | - Required `true` 98 | 99 | The image as String, an HTMLImageElement, ImageData, or object with width, height, and data properties with the same format as ImageData. 100 | 101 | ### `options` 102 | 103 | - Type `Object` 104 | - Default `{ pixelRatio: 1, sdf: false }` 105 | 106 | This options object will be passed directly to the `addImage` method. 107 | 108 | ## Events 109 | 110 | ### `add` 111 | 112 | Emitted when the image has been added to the map with the [`addImage`](https://docs.mapbox.com/mapbox-gl-js/api/#map#addimage) method. 113 | 114 | **Properties** 115 | 116 | - `image` _(`Object`)_ The image's informations 117 | - `image.id` _(`String`)_ The ID given to the image 118 | - `image.src` _(`HTMLImageElement | ImageData | Object`)_ The generated source of the image when the given source is a string; the given source otherwise 119 | - `image.options` _(`Object`)_ The options object used with the `addImage` method 120 | 121 | 122 | ## Slots 123 | 124 | ### `default` 125 | 126 | The default slot will be rendered _after_ the image has been added to the map — when the `add` event is emitted. 127 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxImages/index.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # MapboxImages 6 | 7 | Add multiple images at once to be used used in `icon-image`, `background-pattern`, `fill-pattern`, and `line-pattern`. This component is a wrapper around the [`MapboxImage`](/components/MapboxImage/) component. 8 | 9 |

Table of contents

10 | 11 | [[toc]] 12 | 13 | ## Examples 14 | 15 | ### Add multiple icons to the map 16 | 17 | 18 | 19 | 20 | 21 | <<< @/.vitepress/components/MapboxImagesDemo.vue{4-13,15-49,59-61} 22 | 23 | ## Props 24 | 25 | ### `sources` 26 | 27 | - Type `Array` 28 | - Required `true` 29 | 30 | A list of images to add to the map. 31 | 32 | ### `source.id` 33 | 34 | - Type `String` 35 | - Required `true` 36 | 37 | The ID of the image. This will be used to refer to this image. 38 | 39 | ### `source.src` 40 | 41 | - Type `[ String, HTMLImageElement, ImageData, Object ]` 42 | - Required `true` 43 | 44 | The image as String, an HTMLImageElement, ImageData, or object with width, height, and data properties with the same format as ImageData. 45 | 46 | ### `source.options` 47 | 48 | - Type `Object` 49 | - Default `{ pixelRatio: 1, sdf: false }` 50 | 51 | This options object will be passed directly to the `addImage` method. 52 | 53 | ## Events 54 | 55 | 56 | ### `add` 57 | 58 | Emitted for each image being added to the map with the [`addImage`](https://docs.mapbox.com/mapbox-gl-js/api/#map#addimage) method. 59 | 60 | **Properties** 61 | 62 | - `image` _(`Object`)_ The image's informations, directly passed from the `add` event of the `MapboxImage component 63 | - `image.id` _(`String`)_ The ID given to the image 64 | - `image.src` _(`HTMLImageElement | ImageData | Object`)_ The generated source of the image when the given source is a string; the given source otherwise 65 | - `image.options` _(`Object`)_ The options object used with the `addImage` method 66 | - `index` _(`Number`)_ The index of the image which has been added 67 | - `total` _(`Number`)_ The total number of images to add 68 | 69 | ### `ready` 70 | 71 | Emitted when all images have been added to the map. 72 | 73 | **Properties** 74 | 75 | - `images` _(`Array`)_ An array containing all the added images' object emitted by the `add` event 76 | 77 | ## Slots 78 | 79 | ### `default` 80 | 81 | The default slot will be rendered _after_ the images have been added to the map — when the `ready` event is emitted. 82 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxLayer/index.md: -------------------------------------------------------------------------------- 1 | # MapboxLayer 2 | 3 | ... 4 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxMap/index.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # MapboxMap 9 | 10 | Root component, it is required to have a working map. This component is based on the `Map` class of Mapbox GL, all props are mapped to the `options` passed to the class constructor. 11 | 12 | It is recommended to have a look at their [API reference](https://docs.mapbox.com/mapbox-gl-js/api/#map) on the subject. 13 | 14 |

Table of contents

15 | 16 | [[toc]] 17 | 18 | ## Examples 19 | 20 | ### Basic usage 21 | 22 | 23 | 29 | 30 | 31 | ```vue 32 | 38 | 39 | 47 | ``` 48 | 49 | ### Accessing the Mapbox instance 50 | 51 | You will probably need to use the Mapbox instance to use some of its methods such as `flyTo`, `panTo`, etc. The `MapboxMap` component emits an `mb-ready` event right after the Mapbox instantiation, with the Mapbox instance of [`Map`](https://docs.mapbox.com/mapbox-gl-js/api/#map) as a parameter. See the example below: 52 | 53 | ```vue{5,18} 54 | 60 | 61 | 76 | ``` 77 | 78 | ## Props 79 | 80 | ### `accessToken` 81 | 82 | - Type `String` 83 | - Required `true` 84 | 85 | Your Mapbox access token. 86 | 87 | ### `mapStyle` 88 | 89 | - Type `[ String, Object ]` 90 | - Required `true` 91 | 92 | A map style definition, can be a JSON object following the [Mapbox Style specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/) of an URL to such a JSON. This prop is mapped to the `options.style` configuration of the map creation. 93 | 94 | ### `container` 95 | 96 | - Type `[ HTMLElement, String ]` 97 | - Default `undefined` 98 | 99 | ### `minZoom` 100 | 101 | - Type `Number` 102 | - Default `0` 103 | 104 | ### `maxZoom` 105 | 106 | - Type `Number` 107 | - Default `22` 108 | 109 | ### `minPitch` 110 | 111 | - Type: `Number` 112 | - Default: `0` 113 | 114 | ### `maxPitch` 115 | 116 | - Type: `Number` 117 | - Default: `60` 118 | 119 | ### `hash` 120 | 121 | - Type `Boolean` 122 | - Default `false` 123 | 124 | ### `interactive` 125 | 126 | - Type `Boolean` 127 | - Default `true` 128 | 129 | ### `bearingSnap` 130 | 131 | - Type `Number` 132 | - Default `7` 133 | 134 | ### `pitchWithRotate` 135 | 136 | - Type `Boolean` 137 | - Default `true` 138 | 139 | ### `clickTolerance` 140 | 141 | - Type `Number` 142 | - Default `3` 143 | 144 | ### `attributionControl` 145 | 146 | - Type `Boolean` 147 | - Default `true` 148 | 149 | ### `customAttribution` 150 | 151 | - Type `[ String, Array ]` 152 | - Default `null` 153 | 154 | ### `logoPosition` 155 | 156 | - Type `String` 157 | - Default `'bottom-left'` 158 | 159 | ### `failIfMajorPerformanceCaveat` 160 | 161 | - Type `Boolean` 162 | - Default `false` 163 | 164 | ### `preserveDrawingBuffer` 165 | 166 | - Type `Boolean` 167 | - Default `false` 168 | 169 | ### `antialias` 170 | 171 | - Type `Boolean` 172 | - Default `false` 173 | 174 | ### `refreshExpiredTiles` 175 | 176 | - Type `Boolean` 177 | - Default `true` 178 | 179 | ### `maxBounds` 180 | 181 | - Type `[ LngLatBounds, Array ]` 182 | - Default `undefined` 183 | 184 | ### `scrollZoom` 185 | 186 | - Type `[ Boolean, Object ]` 187 | - Default `true` 188 | 189 | ### `boxZoom` 190 | 191 | - Type `Boolean` 192 | - Default `true` 193 | 194 | ### `dragRotate` 195 | 196 | - Type `Boolean` 197 | - Default `true` 198 | 199 | ### `dragPan` 200 | 201 | - Type `[ Boolean, Object ]` 202 | - Default `true` 203 | 204 | ### `keyboard` 205 | 206 | - Type `Boolean` 207 | - Default `true` 208 | 209 | ### `doubleClickZoom` 210 | 211 | - Type `Boolean` 212 | - Default `true` 213 | 214 | ### `touchZoomRotate` 215 | 216 | - Type `[ Boolean, Object ]` 217 | - Default `true` 218 | 219 | ### `trackResize` 220 | 221 | - Type `Boolean` 222 | - Default `true` 223 | 224 | ### `center` 225 | 226 | - Type `[ LngLat, Array, Object ]` 227 | - Default `() => [ 0, 0 ]` 228 | 229 | ### `zoom` 230 | 231 | - Type `Number` 232 | - Default `0` 233 | 234 | ### `bearing` 235 | 236 | - Type `Number` 237 | - Default `0` 238 | 239 | ### `pitch` 240 | 241 | - Type `Number` 242 | - Default `0` 243 | 244 | ### `bounds` 245 | 246 | - Type `[ LngLatBounds, Array ]` 247 | - Default `undefined` 248 | 249 | ### `fitBoundsOptions` 250 | 251 | - Type `Object` 252 | - Default `null` 253 | 254 | ### `renderWorldCopies` 255 | 256 | - Type `Boolean` 257 | - Default `true` 258 | 259 | ### `maxTileCacheSize` 260 | 261 | - Type `Number` 262 | - Default `null` 263 | 264 | ### `localIdeographFontFamily` 265 | 266 | - Type `String` 267 | - Default `'sans-serif'` 268 | 269 | ### `transformRequest` 270 | 271 | - Type `Function` 272 | - Default `null` 273 | 274 | ### `collectResourceTiming` 275 | 276 | - Type `Boolean` 277 | - Default `false` 278 | 279 | ### `fadeDuration` 280 | 281 | - Type `Number` 282 | - Default `300` 283 | 284 | ### `crossSourceCollisions` 285 | 286 | - Type `Boolean` 287 | - Default `true` 288 | 289 | ### `cooperativeGestures` 290 | 291 | - Type: `Boolean` 292 | - Default: `false` 293 | 294 | ### `language` 295 | 296 | - Type: `["auto", String, Array]` 297 | - Default: `null` 298 | 299 | ### `locale` 300 | 301 | - Type: `Object` 302 | - Default: `null` 303 | 304 | ### `localFontFamily` 305 | 306 | - Type: `String` 307 | - Default: `false` 308 | 309 | ### `minTileCacheSize` 310 | 311 | - Type: `Number` 312 | - Default: `null` 313 | 314 | ### `optimizeForTerrain` 315 | 316 | - Type: `Boolean` 317 | - Default: `true` 318 | 319 | ::: warning 320 | The `optimizeForTerrain` prop will only work with `mapbox-gl@2`, as it has been removed in v3.0.0 of the package (see [release notes](https://github.com/mapbox/mapbox-gl-js/releases/tag/v3.0.0)). 321 | ::: 322 | 323 | ### `performanceMetricsCollection` 324 | 325 | - Type: `Boolean` 326 | - Default: `true` 327 | 328 | ### `projection` 329 | 330 | - Type: `ProjectionSpecification` 331 | - Default: `'mercator'` 332 | 333 | ### `style` 334 | 335 | - Type: `[Object, String]` 336 | 337 | ### `testMode` 338 | 339 | - Type: `Boolean` 340 | - Default: `false` 341 | 342 | ### `touchPitch` 343 | 344 | - Type: `[Boolean, Object]` 345 | - Default: `true` 346 | 347 | ### `useWebGL2` 348 | 349 | - Type: `Boolean` 350 | - Default: `false` 351 | 352 | ### `worldview` 353 | 354 | - Type: `String` 355 | - Default: `null` 356 | 357 | ## Events 358 | 359 | ### `mb-created` 360 | 361 | Emitted when the Mapbox instance has been created. 362 | 363 | **Params** 364 | 365 | - `map` (`Map`): the Mapbox map instance 366 | 367 | ### Other events 368 | 369 | In addition to the `mb-created` event, all events available on the Mapbox `Map` class are also available on the `MapboxMap` component, prefixed by `mb-`. 370 | 371 | - `resize` → `mb-resize` 372 | - `click` → `mb-click` 373 | - ... 374 | 375 | See the [API Reference](https://docs.mapbox.com/mapbox-gl-js/api/#map.event:resize) on the subject for more detailed information about each event. 376 | 377 | ## Slots 378 | 379 | ### `default` 380 | 381 | The `default` slot must contain all other components as the `mapbox-gl` instance is provided by this component to be injected in all its children. 382 | 383 | See the documentation on [provide / inject](https://vuejs.org/v2/api/#provide-inject) for more informations. 384 | 385 | ### `loader` 386 | 387 | This slot is displayed while the map is loading. 388 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxMarker/index.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # MapboxMarker 7 | 8 | Display a marker on the map. 9 | 10 | - [`Marker` API reference](https://docs.mapbox.com/mapbox-gl-js/api/#marker) 11 | 12 |

Table of contents

13 | 14 | [[toc]] 15 | 16 | ## Examples 17 | 18 | ### Basic usage 19 | 20 | 21 | 25 | 26 | 27 | 28 | 29 | ```vue {10} 30 | 33 | 34 | 42 | ``` 43 | 44 | ### Custom HTML 45 | 46 | 47 | 48 | 49 | 50 | <<< @/.vitepress/components/MapboxMarkerCustomHtmlDemo.vue{12-14,19-23} 51 | 52 | ### Linked popup 53 | 54 | 55 | 56 | 57 | 58 | <<< @/.vitepress/components/MapboxMarkerPopupDemo.vue{12-16} 59 | 60 | ## Props 61 | 62 | ### `lngLat` 63 | 64 | - Type `Array` 65 | - Required: `true` 66 | 67 | ### `popup` 68 | 69 | - Type `[ Object, Boolean ]` 70 | - Default: `false` 71 | 72 | ### `element` 73 | 74 | - Type `HTMLElement` 75 | - Default: `null` 76 | 77 | ### `offset` 78 | 79 | - Type `[ Point, Array ]` 80 | - Default: `null` 81 | 82 | ### `anchor` 83 | 84 | - Type `String` 85 | - Default: `'center'` 86 | 87 | ### `color` 88 | 89 | - Type `String` 90 | - Default: `null` 91 | 92 | ### `scale` 93 | 94 | - Type `Number` 95 | - Default: `1` 96 | 97 | ### `draggable` 98 | 99 | - Type `Boolean` 100 | - Default: `false` 101 | 102 | ### `rotation` 103 | 104 | - Type: `Number` 105 | - Default: `0` 106 | 107 | ### `pitchAlignment` 108 | 109 | - Type: `String` 110 | - Default: `'auto'` 111 | 112 | ### `rotationAlignment` 113 | 114 | - Type: `String` 115 | - Default: `'auto'` 116 | 117 | 118 | ## Events 119 | 120 | All events available on the `Marker` class are also available on the `MapboxMarker` component, prefixed by `mb-`. 121 | 122 | ### `mb-dragstart` 123 | 124 | Mapped to the [`dragstart` event](https://docs.mapbox.com/mapbox-gl-js/api/#marker.event:dragstart) of the `Marker` class. 125 | 126 | ### `mb-drag` 127 | 128 | Mapped to the [`drag` event](https://docs.mapbox.com/mapbox-gl-js/api/#marker.event:drag) of the `Marker` class. 129 | 130 | ### `mb-dragend` 131 | 132 | Mapped to the [`dragend` event](https://docs.mapbox.com/mapbox-gl-js/api/#marker.event:dragend) of the `Marker` class. 133 | 134 | ## Slots 135 | 136 | ### `default` 137 | 138 | The `default` slot is used for marker with custom HTML. 139 | 140 | ### `popup` 141 | 142 | The `popup` slot will be rendered inside the attached popup. 143 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxNavigationControl/index.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # MapboxNavigationControl 6 | 7 | Display navigation controls on the map, including two zoom buttons + - and a compass button to rotate the map. 8 | 9 | - [Mapbox navigation controls documentation](https://docs.mapbox.com/mapbox-gl-js/api/#navigationcontrol) 10 | - [Mapbox navigation controls example](https://docs.mapbox.com/mapbox-gl-js/example/navigation/) 11 | 12 | 13 |

Table of contents

14 | 15 | [[toc]] 16 | 17 | ## Examples 18 | 19 | ### Basic usage 20 | 21 | 22 | 23 | 24 | 25 | <<< @/.vitepress/components/MapboxNavigationControlDemo.vue{10} 26 | 27 | ## Props 28 | 29 | ### `position` 30 | 31 | - Type: `String` 32 | - Default: `top-right` 33 | 34 | The position for the navigation control. 35 | 36 | ### `showCompass` 37 | 38 | - Type: `Boolean` 39 | - Default: `true` 40 | 41 | Show the compass button with the navigation control. 42 | 43 | ### `showZoom` 44 | 45 | - Type: `Boolean` 46 | - Default: `true` 47 | 48 | Show the zoom button with the navigation control. 49 | 50 | ### `visualizePitch` 51 | 52 | - Type: `Boolean` 53 | - Default: `false` 54 | 55 | If `true` the pitch is visualized by rotating Y-axis of compass. 56 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxPopup/index.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # MapboxPopup 6 | 7 | Display a popup on the map. 8 | 9 | - [Mapbox popup documentation](https://docs.mapbox.com/mapbox-gl-js/api/#popup) 10 | - [Mapbox popup example](https://docs.mapbox.com/mapbox-gl-js/example/popup/) 11 | 12 | 13 |

Table of contents

14 | 15 | [[toc]] 16 | 17 | ## Examples 18 | 19 | ### Basic usage 20 | 21 | 22 | 23 | 24 | 25 | <<< @/.vitepress/components/MapboxPopupDemo.vue{10-12} 26 | 27 | 28 | ## Props 29 | 30 | ### `lngLat` 31 | 32 | - Type `[ LngLat, Array, Object ]` 33 | - Required `true` 34 | 35 | Center position for the popup. 36 | 37 | ### `closeButton` 38 | 39 | - Type `[ Boolean ]` 40 | - Required `false` 41 | - default `true` 42 | 43 | Display a close button on the popup. 44 | 45 | ### `closeOnClick` 46 | 47 | - Type `[ Boolean ]` 48 | - Required `false` 49 | - default `true` 50 | 51 | Close the popup on close button click. 52 | 53 | ### `closeOnMove` 54 | 55 | - Type `[ Boolean ]` 56 | - Required `false` 57 | - default `false` 58 | 59 | Close the popup when the map moves. 60 | 61 | ### `anchor` 62 | 63 | - Type `[ String ]` 64 | - Required `false` 65 | 66 | A string indicating the part of the Popup that should be positioned closest to its coordinate. [See the mapbox-gl documentation for more details.](https://docs.mapbox.com/mapbox-gl-js/api/#popup). 67 | 68 | ### `offset` 69 | 70 | - Type `[ Number, Point, Array, Object ]` 71 | - Required `false` 72 | - default `null` 73 | 74 | Offset the popup from it's original lngLat position. 75 | 76 | ### `className` 77 | 78 | - Type `[ String ]` 79 | - Required `false` 80 | - default `null` 81 | 82 | Add a className to the popup. 83 | 84 | ### `maxWidth` 85 | 86 | - Type `[ String ]` 87 | - Required `false` 88 | - default `240px` 89 | 90 | Set a max-width to the popup. 91 | 92 | ### `renderless` 93 | 94 | - Type `[ Boolean ]` 95 | - Required `false` 96 | - default `false` 97 | 98 | Do not add the popup to the map on creation. 99 | 100 | ## Events 101 | 102 | ### `mb-open` 103 | 104 | Emitted when the popup is opened manually or programatically. 105 | 106 | **Params** 107 | - `popup`: the object that was opened 108 | - `event`: the Mapbox event object sent by the layer 109 | 110 | ### `mb-close` 111 | 112 | Emitted when the popup is closed manually or programatically. 113 | 114 | **Params** 115 | - `popup`: the object that was closed 116 | - `event`: the Mapbox event object sent by the layer 117 | 118 | ## Slots 119 | 120 | ### `default` 121 | 122 | The default slot will be rendered inside the popup. 123 | 124 | -------------------------------------------------------------------------------- /packages/docs/components/MapboxSource/index.md: -------------------------------------------------------------------------------- 1 | # MapboxSource 2 | 3 | ... 4 | -------------------------------------------------------------------------------- /packages/docs/components/StoreLocator/index.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # StoreLocator 6 | 7 | The `StoreLocator` component will help you display a clustered list of points of interest (POIs) on a map and in a adjacent filtered list. 8 | 9 |

Table of contents

10 | 11 | [[toc]] 12 | 13 | ## Usage 14 | 15 | You will need to import the `StoreLocator` component along with the required CSS files: 16 | 17 | ```vue 18 | 27 | 28 | 33 | ``` 34 | 35 | ## Example 36 | 37 | Displaying the [`earthquake.json`](/earthquakes.json) data on a map with a synchronized list. 38 | 39 |
40 | 41 | 42 | 43 |
44 | 45 | ```vue 46 | 55 | 56 | 92 | ``` 93 | 94 | ## Props 95 | 96 | ### `items` 97 | 98 | - Type `Array<{ lat: number, lng: number, id: string, [prop: string]: unknown }>` 99 | - Required `true` 100 | 101 | A list of items to display. Each item **must** have at least the following properties: `lat` and `lng` and a uniq `id`. 102 | 103 | ### `itemZoomLevel` 104 | 105 | - Type `Number` 106 | - Default `14` 107 | 108 | The zoom level to use when zooming in on an item. 109 | 110 | ### `accessToken` 111 | 112 | - Type `String` 113 | - Default `no-token` 114 | 115 | Your Mapbox access token. 116 | 117 | ### `mapboxMap` 118 | 119 | - Type `MapboxMapProps` 120 | - Default `{}` 121 | 122 | Props for the [MapboxMap component](/components/MapboxMap/#props). 123 | 124 | ### `mapboxCluster` 125 | 126 | - Type `MapboxClusterProps` 127 | - Default `{}` 128 | 129 | Props for the [MapboxCluster component](/components/MapboxCluster/#props). 130 | 131 | ### `mappboxGeocoder` 132 | 133 | - Type `MapboxGeocoder` 134 | - Default `{}` 135 | 136 | Props for the [MapboxGeocoder component](/components/MapboxGeocoder/#props). 137 | 138 | ### `transitions` 139 | 140 | - Type 141 | ```ts 142 | interface StoreLocatorTransitionsProp { 143 | loader?: { 144 | default?: TransitionProps, 145 | map?: TransitionProps, 146 | search?: TransitionProps, 147 | list?: TransitionProps 148 | }, 149 | panel?: TransitionProps 150 | } 151 | ``` 152 | - Default `{}` for each `TransitionProps` 153 | 154 | Props for each transition component: 155 | 156 | - `loader.default`: used for the default loader transition 157 | - `loader.map`: used for the custom map loader transition 158 | - `loader.search`: used for the custom search loader transition 159 | - `loader.list`: used for the custom list loader transition 160 | - `panel`: used for the panel transition 161 | 162 | See the [Transition component documentation](https://vuejs.org/v2/api/#transition) for more details. 163 | 164 | ### `classes` 165 | 166 | - Type 167 | ```ts 168 | type VueClassAttribute = string | Array | { [key:string]: string } | Array<{ [key:string]: string }>; 169 | 170 | interface StoreLocatorClassesProp { 171 | root?: VueClassAttribute, 172 | region?: { 173 | map?: VueClassAttribute, 174 | search?: VueClassAttribute, 175 | list?: VueClassAttribute, 176 | panel?: VueClassAttribute, 177 | }, 178 | map?: VueClassAttribute, 179 | search?: VueClassAttribute, 180 | list?: VueClassAttribute, 181 | listItem?: VueClassAttribute, 182 | panel?: VueClassAttribute, 183 | } 184 | ``` 185 | - Default to a BEM structure: 186 | ```js 187 | { 188 | root : 'store-locator', 189 | region: { 190 | map: [ 191 | 'store-locator__region', 192 | 'store-locator__region--map' 193 | ], 194 | search: [ 195 | 'store-locator__region', 196 | 'store-locator__region--search' 197 | ], 198 | list: [ 199 | 'store-locator__region', 200 | 'store-locator__region--list' 201 | ], 202 | panel: [ 203 | 'store-locator__region', 204 | 'store-locator__region--panel', 205 | ], 206 | }, 207 | map : 'store-locator__map', 208 | search : 'store-locator__search', 209 | list : 'store-locator__list', 210 | listItem : 'store-locator__list-item', 211 | panel : 'store-locator__panel', 212 | } 213 | ``` 214 | 215 | ### `filterItemsCallback` 216 | 217 | - Type `Function|Boolean` 218 | - Default `false` 219 | 220 | Props to add a custom filtering on the `items` props. That is triggered on `onMapCreated` `onMapMoveend` event. 221 | 222 | ### `disableFeatureClickZoom` 223 | 224 | - Type `Boolean` 225 | - Default `false` 226 | 227 | Disable the zoom on a feature click. 228 | 229 | ## Events 230 | 231 | ### `map-created` 232 | 233 | Emitted when the MapboxMap component is created. 234 | 235 | **Params** 236 | - `map` (`Map`): the Mapbox map instance 237 | 238 | ### `map-load` 239 | 240 | Emitted when the MapboxMap component is loaded. 241 | 242 | **Params** 243 | - `map` (`Map`): the Mapbox map instance 244 | 245 | ### `geocoder-created` 246 | 247 | Emitted when the Geocoder component is ready. 248 | 249 | **Params** 250 | - `geocoder` (`Geocoder`): the Geocoder instance 251 | 252 | ### `cluster-cluster-click` 253 | 254 | Emitted when the user clicks on a cluster. See the [MapboxCluster component API](/components/MapboxCluster/#mb-cluster-click) for more information. 255 | 256 | ### `cluster-feature-click` 257 | 258 | Emitted when the user clicks on a unclustered point (a feature). See the [MapboxCluster component API](/components/MapboxCluster/#mb-feature-click) for more information. 259 | 260 | ### `cluster-feature-mouseenter` 261 | 262 | Emitted when the user's mouse enters an unclustered point. See the [MapboxCluster component API](/components/MapboxCluster/#mb-feature-mouseenter) for more information. 263 | 264 | ### `cluster-feature-mouseleave` 265 | 266 | Emitted when the user's mouse leaves an unclustered point. See the [MapboxCluster component API](/components/MapboxCluster/#mb-feature-mouseleave) for more information. 267 | 268 | ### `select-item` 269 | 270 | Emitted when an item is selected from the map or from the list. 271 | 272 | **Params** 273 | - `item` (`Object`): the selected item 274 | 275 | ## Slots 276 | 277 | ### `loader` 278 | 279 | Use this slot to define a generic custom loader used for every region. Loaders are hidden when the `load` event is emitted. 280 | 281 | ### Map region 282 | 283 | #### `map-loader` 284 | 285 | Use this slot to override the loader of the map region. 286 | 287 | #### `before-map` 288 | 289 | Use this slot to display information before the map. 290 | 291 | #### `map` 292 | 293 | Use this slot to inject additionnal Mapbox components in the map. 294 | 295 | **Props** 296 | - `map` (`Object`): the map instance. 297 | - `geojson` (`GeoJSON`): the GeoJSON used for the cluster. 298 | - `filteredGeoJson` (`GeoJSON`): the filtered GeoJSON. 299 | - `items` (`Array`): the list of items. 300 | - `filteredItems` (`Array`): the filtered list of items. 301 | - `selectedItem` (`Object`): the selected item. 302 | 303 | #### `after-map` 304 | 305 | Use this slot to display information after the map. 306 | 307 | ### Search region 308 | 309 | #### `search-loader` 310 | 311 | Use this slot to override the loader of the search region. 312 | 313 | #### `before-search` 314 | 315 | Use this slot to display information before the search. 316 | 317 | **Props** 318 | - `items` (`Array`): the full list of items. 319 | - `filteredItems` (`Array`): the filtered list of items, based on the map bounding box. 320 | - `selectedItem` (`null | Object`): the selected item if defined, `null` otherwise. 321 | 322 | #### `after-search` 323 | 324 | Use this slot to display information after the search. 325 | 326 | **Props** 327 | - `items` (`Array`): the full list of items. 328 | - `filteredItems` (`Array`): the filtered list of items, based on the map bounding box. 329 | - `selectedItem` (`null | Object`): the selected item if defined, `null` otherwise. 330 | 331 | ### List region 332 | 333 | #### `list-loader` 334 | 335 | Use this slot to override the loader of the list region. 336 | 337 | #### `before-list` 338 | 339 | Use this slot to display information before the list. 340 | 341 | **Props** 342 | - `items` (`Array`): the full list of items. 343 | - `filteredItems` (`Array`): the filtered list of items, based on the map bounding box. 344 | - `selectedItem` (`null | Object`): the selected item if defined, `null` otherwise. 345 | 346 | #### `list-item` 347 | 348 | Use this slot to customize the display of the list items. 349 | 350 | **Props** 351 | - `item` (`Object`): the current item in the loop. 352 | - `index` (`Number`): the index of the current item in the filtered list. 353 | - `selectedItem` (`null | Object`): the selected item if defined, `null` otherwise. 354 | 355 | #### `after-list` 356 | 357 | Use this slot to display information after the list. 358 | 359 | **Props** 360 | - `items` (`Array`): the full list of items. 361 | - `filteredItems` (`Array`): the filtered list of items, based on the map bounding box. 362 | - `selectedItem` (`null | Object`): the selected item if defined, `null` otherwise. 363 | 364 | ### Panel region 365 | 366 | #### `panel` 367 | 368 | Use this slot to display content inside the panel. 369 | 370 | **Props** 371 | - `item` (`Object`): the selected item. 372 | - `close` (`Function`): a function to trigger to clear the selected item and close the panel. 373 | 374 | ## Architecture 375 | 376 | The following schema describing the `StoreLocator` component architecture should help you understand how the slots, the `classes` and `transitions` props can be used to customize the components appearance. 377 | 378 | 379 | -------------------------------------------------------------------------------- /packages/docs/guide/installation/index.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Install it with NPM: 4 | 5 | ```bash 6 | npm install @studiometa/vue-mapbox-gl 7 | ``` 8 | 9 | You will have to install the peer dependencies in order for the components to work correctly: 10 | 11 | ```bash 12 | # Install mapbox-gl 13 | npm install mapbox-gl 14 | # The geocoder package is only required if you use the `MapboxGeocoder` component 15 | npm install @mapbox/mapbox-gl-geocoder 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /packages/docs/guide/introduction/index.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The package `@studiometa/vue-mapbox-gl` is a library of Vue 3 components to facilitate usage of `mapbox-gl` in Vue applications. 4 | 5 | It exports a set of components mapped to Mapbox GL main features as well as some premade advanced components (cluster, store locator). 6 | 7 | ## Components 8 | 9 | Check the detailed documentation on each components for a more advanced usage: 10 | 11 | | Component | Description | 12 | |--------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| 13 | | [MapboxMap](/components/MapboxMap/) | Display a map with the given style. | 14 | | [MapboxMarker](/components/MapboxMarker/) | Display a simple or custom marker. | 15 | | [MapboxCluster](/components/MapboxCluster/) | Display a GeoJSON as clusters. | 16 | | [MapboxGeocoder](/components/MapboxGeocoder/) | Display a geocoder search input with the [@mapbox/mapbox-gl-geocoder](https://github.com/mapbox/mapbox-gl-geocoder) plugin. | 17 | | [MapboxImage](/components/MapboxImage/) | Load an image to be used on the map. | 18 | | [MapboxImages](/components/MapboxImages/) | Load multiple images to be used on the map. | 19 | | [MapboxLayer](/components/MapboxLayer/) | Display a layer on the map. | 20 | | [MapboxNavigationControl](/components/MapboxNavigationControl/) | Display the map's navigation controls | 21 | | [MapboxGeolocateControl](/components/MapboxGeolocateControl/) | Display the map's geolocation control | 22 | | [MapboxPopup](/components/MapboxPopup/) | Display a popup on the map | 23 | | [MapboxSource](/components/MapboxSource/) | Load a source of data to be used on the map | 24 | | [StoreLocator](/components/StoreLocator/) | Easily create a Store Locator | 25 | 26 | 27 | ## Note 28 | 29 | This project is a rewrite of a fork of [openearth/vue2mapbox-gl](https://github.com/openearth/vue2mapbox-gl) and is published under the [GNU GPL 3](https://www.gnu.org/licenses/gpl-3.0.en.html) license. 30 | -------------------------------------------------------------------------------- /packages/docs/guide/usage/index.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | Import directly the pieces you need as well as the stylesheet for Mapbox GL: 4 | 5 | ```vue 6 | 10 | 11 | 16 | ``` 17 | 18 | If you need to access to the Mapbox `map` instance, you can get it via the `mb-created` event on the `MapboxMap` component which is emitted when the map has been instantiated. 19 | 20 | ```vue {5,11} 21 | 27 | 28 | 33 | ``` 34 | 35 | Or you can add a ref to the `MapboxMap` component and access it with the `map` property: 36 | 37 | ```vue 38 | 45 | 46 | 51 | ``` 52 | -------------------------------------------------------------------------------- /packages/docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | sidebar: false 4 | hero: 5 | name: 🗺 6 | text: Vue 3 Mapbox GL 7 | tagline: A small library of Vue 3 components for mapbox-gl 8 | actions: 9 | - theme: brand 10 | text: Get Started 11 | link: /guide/introduction/ 12 | - theme: alt 13 | text: View on GitHub 14 | link: https://github.com/studiometa/vue-mapbox-gl 15 | --- 16 | -------------------------------------------------------------------------------- /packages/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studiometa/vue-mapbox-gl-docs", 3 | "private": true, 4 | "type": "module", 5 | "version": "2.7.2", 6 | "scripts": { 7 | "dev": "vitepress", 8 | "build": "vitepress build" 9 | }, 10 | "devDependencies": { 11 | "sass": "1.88.0", 12 | "tailwindcss": "3.4.17", 13 | "vitepress": "1.6.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/docs/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require('tailwindcss')], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/vue-mapbox-gl/c80c7190d1fb927470968832f581fbef9d34d3c5/packages/docs/public/logo.png -------------------------------------------------------------------------------- /packages/docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | content: [ 3 | './.vitepress/**/*.js', 4 | './.vitepress/**/*.vue', 5 | './.vitepress/**/*.ts', 6 | './**/*.md', 7 | './**/*.html', 8 | ], 9 | }; 10 | -------------------------------------------------------------------------------- /packages/tests/components/MapboxMap.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import { render } from 'vitest-browser-vue'; 3 | import { MapboxMap } from '@studiometa/vue-mapbox-gl'; 4 | import 'mapbox-gl/dist/mapbox-gl.css'; 5 | 6 | describe('The MapboxMap component', () => { 7 | it('should display a map', async () => { 8 | const { emitted, getByTestId } = render(MapboxMap, { 9 | props: { 10 | accessToken: 11 | 'pk.eyJ1IjoiYWdlbmNlc3R1ZGlvbWV0YSIsImEiOiJjbTZxZXZidzYxaXR3MmtzaG5qNzc3NGxqIn0.c_YVpXQptiZtOgzj_5jvaw', 12 | mapStyle: 'mapbox://styles/mapbox/streets-v11', 13 | }, 14 | attrs: { 15 | 'data-testid': 'map', 16 | style: { 17 | height: '100vh', 18 | }, 19 | }, 20 | }); 21 | 22 | await expect.element(getByTestId('map')).toBeVisible(); 23 | expect(emitted('mb-created')).toBeDefined(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/tests/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import * as pkg from '@studiometa/vue-mapbox-gl'; 3 | 4 | describe('The package', () => { 5 | it('should export all components', () => { 6 | expect(Object.keys(pkg).sort()).toMatchInlineSnapshot(` 7 | [ 8 | "MapboxCluster", 9 | "MapboxFullscreenControl", 10 | "MapboxGeocoder", 11 | "MapboxGeolocateControl", 12 | "MapboxImage", 13 | "MapboxImages", 14 | "MapboxLayer", 15 | "MapboxMap", 16 | "MapboxMarker", 17 | "MapboxNavigationControl", 18 | "MapboxPopup", 19 | "MapboxSource", 20 | "StoreLocator", 21 | "VueScroller", 22 | "useControl", 23 | "useEventsBinding", 24 | "useMap", 25 | "usePropsBinding", 26 | ] 27 | `); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studiometa/vue-mapbox-gl-tests", 3 | "version": "2.7.2", 4 | "type": "module", 5 | "scripts": { 6 | "test": "vitest" 7 | }, 8 | "dependencies": { 9 | "@mapbox/mapbox-gl-geocoder": "^5.0.3", 10 | "@studiometa/vue-mapbox-gl": "*", 11 | "@vitejs/plugin-vue": "5.2.1", 12 | "@vitest/browser": "3.0.4", 13 | "@vitest/coverage-v8": "3.0.4", 14 | "mapbox-gl": "^3.9.3", 15 | "playwright": "1.50.0", 16 | "vitest": "3.0.4", 17 | "vitest-browser-vue": "0.1.0", 18 | "vue": "^3.5.13" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/tests/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | import vue from '@vitejs/plugin-vue'; 3 | 4 | export default defineConfig({ 5 | plugins: [vue()], 6 | test: { 7 | root: '..', 8 | alias: { 9 | '^#private/(.*)': '../vue-mapbox-gl/$1', 10 | }, 11 | coverage: { 12 | provider: 'v8', 13 | include: ['vue-mapbox-gl/**'], 14 | }, 15 | browser: { 16 | provider: 'playwright', 17 | enabled: true, 18 | instances: [{ browser: 'chromium' }], 19 | }, 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxCluster.vue: -------------------------------------------------------------------------------- 1 | 125 | 126 | 269 | 270 | 288 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxFullscreenControl.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 35 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxGeocoder.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 133 | 134 | 190 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxGeolocateControl.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 65 | 66 | 76 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxImage.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 44 | 45 | 98 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxImages.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 50 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxLayer.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 58 | 59 | 112 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxMap.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 301 | 302 | 354 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxMarker.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 88 | 89 | 149 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxNavigationControl.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 33 | 34 | 45 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxPopup.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 70 | 71 | 110 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/MapboxSource.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 41 | 42 | 45 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/StoreLocator/StoreLocator.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 306 | 307 | 469 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/StoreLocator/VueScroller.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 67 | 68 | 120 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/StoreLocator/index.ts: -------------------------------------------------------------------------------- 1 | export { default as StoreLocator } from './StoreLocator.vue'; 2 | export { default as VueScroller } from './VueScroller.vue'; 3 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './StoreLocator/index.js'; 2 | export { default as MapboxCluster } from './MapboxCluster.vue'; 3 | export { default as MapboxGeocoder } from './MapboxGeocoder.vue'; 4 | export { default as MapboxGeolocateControl } from './MapboxGeolocateControl.vue'; 5 | export { default as MapboxImage } from './MapboxImage.vue'; 6 | export { default as MapboxImages } from './MapboxImages.vue'; 7 | export { default as MapboxLayer } from './MapboxLayer.vue'; 8 | export { default as MapboxMap } from './MapboxMap.vue'; 9 | export { default as MapboxMarker } from './MapboxMarker.vue'; 10 | export { default as MapboxNavigationControl } from './MapboxNavigationControl.vue'; 11 | export { default as MapboxPopup } from './MapboxPopup.vue'; 12 | export { default as MapboxSource } from './MapboxSource.vue'; 13 | export { default as MapboxFullscreenControl } from './MapboxFullscreenControl.vue'; 14 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/composables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useControl.js'; 2 | export * from './useEventsBinding.js'; 3 | export * from './useMap.js'; 4 | export * from './usePropsBinding.js'; 5 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/composables/useControl.ts: -------------------------------------------------------------------------------- 1 | import mapboxgl from 'mapbox-gl'; 2 | import { onMounted, onUnmounted, ref, shallowReactive, unref, watch, nextTick } from 'vue'; 3 | import { useMap } from './useMap.js'; 4 | import { useEventsBinding } from './useEventsBinding.js'; 5 | import { usePropsBinding } from './usePropsBinding.js'; 6 | 7 | /** 8 | * Use a Mapbox control. 9 | * @template {any} T 10 | * @param {T} ControlConstructor A Mapbox control constructor function. 11 | * @param {object} options 12 | * @param {any} options.propsConfig Props configuration for the component. 13 | * @param {an} options.props Resolved props of the component. 14 | * @param {Function} options.emit Emit function of the component. 15 | * @param {string[]} options.events List of events for the Mapbox control. 16 | * @returns {{ control: Ref>, map: Ref }} 17 | */ 18 | export function useControl(ControlConstructor, { propsConfig, props, emit, events = [] }) { 19 | const { map } = useMap(); 20 | const control = ref(); 21 | 22 | if (Array.isArray(events) && events.length) { 23 | useEventsBinding(emit, control, events); 24 | } 25 | 26 | if (typeof propsConfig !== 'undefined') { 27 | usePropsBinding(props, control, propsConfig); 28 | } 29 | 30 | watch( 31 | () => props.position, 32 | (newValue) => { 33 | if (unref(map)) { 34 | unref(map).removeControl(unref(control)).addControl(unref(control), newValue); 35 | } 36 | }, 37 | ); 38 | 39 | onMounted(async () => { 40 | const ctrl = new ControlConstructor(props); 41 | 42 | if (unref(map)) { 43 | unref(map).addControl(ctrl, props.position); 44 | } 45 | 46 | await nextTick(); 47 | 48 | // The GeolocateControl setup includes some async tasks, so we need to wait 49 | // for its _setup property to become true to set it as the control ref value. 50 | 51 | if (ControlConstructor === mapboxgl.GeolocateControl && !ctrl._setup) { 52 | const tmpControl = shallowReactive(ctrl); 53 | const unwatch = watch(tmpControl, (reactiveCtrl) => { 54 | if (reactiveCtrl._setup) { 55 | control.value = ctrl; 56 | unwatch(); 57 | } 58 | }); 59 | } else { 60 | control.value = ctrl; 61 | } 62 | }); 63 | 64 | onUnmounted(() => { 65 | if (unref(control) && unref(map) && unref(map).hasControl(unref(control))) { 66 | unref(map).removeControl(unref(control)); 67 | } 68 | }); 69 | 70 | return { 71 | control, 72 | map, 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/composables/useEventsBinding.ts: -------------------------------------------------------------------------------- 1 | import { watch, computed, useAttrs, unref } from 'vue'; 2 | 3 | /** 4 | * @typedef (import('vue').Ref) Ref 5 | */ 6 | 7 | const cache = new Map(); 8 | const regex = /onMb([A-Z])(.+)/; 9 | 10 | /** 11 | * Get a Mapbox event name from a Vue event name. 12 | * @param {string} vueEventName 13 | * @returns {string} 14 | */ 15 | function getOriginalEvent(vueEventName) { 16 | if (!cache.has(vueEventName)) { 17 | cache.set( 18 | vueEventName, 19 | vueEventName.replace(regex, (match, $1, $2) => $1.toLowerCase() + $2), 20 | ); 21 | } 22 | 23 | return cache.get(vueEventName); 24 | } 25 | 26 | /** 27 | * Map a mapbox element's events to a Vue component. 28 | * @param {Function} emitFn The emit function for the current component 29 | * @param {Ref} mapboxElement The Mapbox element bound to the component 30 | * @param {string[]} [events] The events to map 31 | * @param {string} [layerId] The layer on which the events are delegated 32 | * @returns {void} 33 | */ 34 | export function useEventsBinding(emitFn, mapboxElement, events = [], layerId = null) { 35 | const attrs = useAttrs(); 36 | const vueEventNames = computed(() => 37 | Object.entries(attrs) 38 | .filter(([name, value]) => name.startsWith('on') && typeof value === 'function') 39 | .map(([name]) => name), 40 | ); 41 | 42 | const unbindFunctions = new Map(); 43 | 44 | /** 45 | * Unbind events from the given Mapbox element. 46 | * @param {string[]} eventNames 47 | * @returns {void} 48 | */ 49 | function unbindEvents(eventNames) { 50 | if (!Array.isArray(eventNames)) { 51 | return; 52 | } 53 | 54 | eventNames.forEach((eventName) => { 55 | const unbindFn = unbindFunctions.get(eventName); 56 | if (typeof unbindFn === 'function') { 57 | unbindFn(); 58 | } 59 | }); 60 | } 61 | 62 | /** 63 | * Bind Vue events to the given Mapbox element. 64 | * @param {string[]} eventNames 65 | * @returns {void} 66 | */ 67 | function bindEvents(eventNames) { 68 | if (!Array.isArray(eventNames)) { 69 | return; 70 | } 71 | 72 | eventNames.forEach((eventName) => { 73 | const originalEvent = getOriginalEvent(eventName); 74 | 75 | if (!events.includes(originalEvent)) { 76 | return; 77 | } 78 | 79 | const handler = (...payload) => { 80 | emitFn(`mb-${originalEvent}`, ...payload); 81 | }; 82 | 83 | // If layerId is not null, all events must be 84 | // delegated from the map to the given layerId 85 | if (layerId) { 86 | unref(mapboxElement).on(originalEvent, layerId, handler); 87 | 88 | unbindFunctions.set(eventName, () => { 89 | unref(mapboxElement).off(originalEvent, layerId, handler); 90 | }); 91 | } else { 92 | unref(mapboxElement).on(originalEvent, handler); 93 | 94 | unbindFunctions.set(eventName, () => { 95 | unref(mapboxElement).off(originalEvent, handler); 96 | }); 97 | } 98 | }); 99 | } 100 | 101 | watch( 102 | vueEventNames, 103 | (newVueEventNames, oldVueEventNames) => { 104 | // Get old event names not in the new event names 105 | const eventNamesToDelete = Array.isArray(newVueEventNames) 106 | ? (oldVueEventNames ?? []).filter( 107 | (oldVueEventName) => !newVueEventNames.includes(oldVueEventName), 108 | ) 109 | : (oldVueEventNames ?? []); 110 | 111 | // Get new event names not in the old event names 112 | const eventNamesToAdd = Array.isArray(oldVueEventNames) 113 | ? (newVueEventNames ?? []).filter( 114 | (newVueEventName) => !oldVueEventNames.includes(newVueEventName), 115 | ) 116 | : (newVueEventNames ?? []); 117 | 118 | if (unref(mapboxElement)) { 119 | unbindEvents(eventNamesToDelete); 120 | bindEvents(eventNamesToAdd); 121 | } else { 122 | // We need to watch the mapbox element once as it can 123 | // be null when reaching this part of the code. 124 | const unwatch = watch(mapboxElement, (newValue) => { 125 | if (newValue) { 126 | unbindEvents(eventNamesToDelete); 127 | bindEvents(eventNamesToAdd); 128 | unwatch(); 129 | } 130 | }); 131 | } 132 | }, 133 | { immediate: true }, 134 | ); 135 | } 136 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/composables/useMap.ts: -------------------------------------------------------------------------------- 1 | import { inject } from 'vue'; 2 | import type { ShallowRef } from 'vue'; 3 | import type { Map } from 'mapbox-gl'; 4 | 5 | /** 6 | * Inject the provided map instance. 7 | */ 8 | export function useMap(): { map: ShallowRef } { 9 | const map = inject>('mapbox-map', null); 10 | 11 | return { 12 | map, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/composables/usePropsBinding.ts: -------------------------------------------------------------------------------- 1 | import { watch, unref } from 'vue'; 2 | 3 | /** 4 | * @typedef {import('vue').Ref} Ref 5 | */ 6 | 7 | /** 8 | * Capitalize the first letter of a string 9 | * @param {string} string The string to capitalize 10 | * @returns {string} The capitalized string 11 | */ 12 | function capitalizeFirstLetter(string) { 13 | return string.charAt(0).toUpperCase() + string.slice(1); 14 | } 15 | 16 | /** 17 | * Map a mapbox element's events to the given vue element 18 | * @template {any} T 19 | * @param {any} props The component props. 20 | * @param {Ref} mapboxElement The Mapbox element bound to the component. 21 | * @param {any} propsConfig The props original configuration. 22 | */ 23 | export function usePropsBinding(props, mapboxElement, propsConfig) { 24 | /** 25 | * Bind props to the given mapboxElement in order to update them when they change. 26 | * @param {T} element 27 | * @returns {void} 28 | */ 29 | function bindProps(element) { 30 | Object.keys(props) 31 | .filter((prop) => props[prop] !== undefined && props[prop] !== null) 32 | .forEach((prop) => { 33 | const setMethodName = 34 | prop === 'mapStyle' ? 'setStyle' : `set${capitalizeFirstLetter(prop)}`; 35 | 36 | const methodExists = typeof element[setMethodName] === 'function'; 37 | const propNeedsBinding = 38 | typeof propsConfig[prop] === 'undefined' || 'bind' in propsConfig[prop] 39 | ? (propsConfig[prop]?.bind ?? false) 40 | : true; 41 | 42 | // Do nothing if `setMethodName` is not a function of `mapBoxElement` 43 | // or if the props is not to be bounded 44 | if (!methodExists || !propNeedsBinding) { 45 | return; 46 | } 47 | 48 | // Set deep option to true if prop type is or can be Object 49 | const { type } = propsConfig[prop]; 50 | const options = { 51 | deep: type === Object || (Array.isArray(type) && type.includes(Object)), 52 | }; 53 | 54 | watch( 55 | () => props[prop], 56 | (newValue) => { 57 | element[setMethodName](newValue); 58 | }, 59 | options, 60 | ); 61 | }); 62 | } 63 | 64 | if (unref(mapboxElement)) { 65 | bindProps(unref(mapboxElement)); 66 | } else { 67 | const unwatch = watch(mapboxElement, (newValue) => { 68 | if (newValue) { 69 | bindProps(newValue); 70 | unwatch(); 71 | } 72 | }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components/index.js'; 2 | export * from './composables/index.js'; 3 | -------------------------------------------------------------------------------- /packages/vue-mapbox-gl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studiometa/vue-mapbox-gl", 3 | "version": "2.7.2", 4 | "description": "A small components library to use Mapbox GL in Vue 3.", 5 | "homepage": "https://github.com/studiometa/vue-mapbox-gl#readme", 6 | "bugs": { 7 | "url": "https://github.com/studiometa/vue-mapbox-gl/issues" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/studiometa/vue-mapbox-gl.git" 12 | }, 13 | "license": "GPL-3.0-or-later", 14 | "author": { 15 | "name": "Studio Meta", 16 | "email": "agence@studiometa.fr", 17 | "url": "https://www.studiometa.fr" 18 | }, 19 | "contributors": [ 20 | { 21 | "name": "Titouan Mathis", 22 | "email": "titouan@studiometa.fr" 23 | }, 24 | { 25 | "name": "Ludovic Janot", 26 | "email": "ludovic@studiometa.fr" 27 | } 28 | ], 29 | "type": "module", 30 | "sideEffects": false, 31 | "main": "index.ts", 32 | "exports": { 33 | ".": { 34 | "types": "./index.d.ts", 35 | "import": "./index.ts", 36 | "require": "./index.cjs" 37 | }, 38 | "./*": "./*" 39 | }, 40 | "publishConfig": { 41 | "access": "public" 42 | }, 43 | "devDependencies": { 44 | "@mapbox/mapbox-gl-geocoder": "5.0.3", 45 | "@studiometa/js-toolkit": "3.0.2", 46 | "mapbox-gl": "3.11.1", 47 | "vue": "3.5.13" 48 | }, 49 | "peerDependencies": { 50 | "@mapbox/mapbox-gl-geocoder": "^5.0.1", 51 | "mapbox-gl": "^2.8.2 || ^3.0.0", 52 | "vue": "^3.2.37" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | export { default } from '@studiometa/prettier-config'; 2 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "declaration": true, 6 | "outDir": "dist/", 7 | "emitDeclarationOnly": true, 8 | "types": [] 9 | }, 10 | "include": [ 11 | "packages/global.d.ts", 12 | "packages/vue-mapbox-gl/**/*.ts", 13 | "packages/vue-mapbox-gl/**/*.vue" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@vue/tsconfig/tsconfig.dom.json", "@vue/tsconfig/tsconfig.lib.json"], 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "module": "esnext", 6 | "lib": ["esnext", "dom"], 7 | "strict": false, 8 | "noEmit": true, 9 | "noImplicitThis": true, 10 | "esModuleInterop": true, 11 | "moduleResolution": "node", 12 | "baseUrl": "./packages/vue-mapbox-gl/", 13 | "paths": { 14 | "#private/*": ["./*"] 15 | } 16 | }, 17 | "include": [ 18 | "packages/vue-mapbox-gl/**/*.ts", 19 | "packages/vue-mapbox-gl/**/*.vue", 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tsconfig.lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "types": [] 6 | }, 7 | "include": [ 8 | "packages/vue-mapbox-gl/**/*.ts", 9 | "packages/vue-mapbox-gl/**/*.vue", 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path'; 2 | import { defineConfig } from 'vite'; 3 | import vue from '@vitejs/plugin-vue'; 4 | import dts from 'vite-plugin-dts'; 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | vue(), 9 | dts({ 10 | tsconfigPath: 'tsconfig.build.json', 11 | cleanVueFileName: true, 12 | exclude: ['src/test/**', 'src/**/story/**', 'src/**/*.story.vue'], 13 | }), 14 | ], 15 | resolve: { 16 | dedupe: ['@mapbox/mapbox-gl-geocoder', 'mapbox-gl', 'vue'], 17 | }, 18 | build: { 19 | minify: false, 20 | cssMinify: false, 21 | sourcemap: true, 22 | lib: { 23 | name: '@studiometa/vue-mapbox-gl', 24 | formats: ['es', 'cjs'], 25 | cssFileName: 'index', 26 | fileName: (format) => `index.${format === 'es' ? 'js' : 'cjs'}`, 27 | entry: { 28 | index: resolve(__dirname, 'packages/vue-mapbox-gl/index.ts'), 29 | }, 30 | }, 31 | rollupOptions: { 32 | external: ['@mapbox/mapbox-gl-geocoder', 'mapbox-gl', 'vue'], 33 | }, 34 | }, 35 | }); 36 | --------------------------------------------------------------------------------