├── phpstan-baseline.neon ├── resources └── views │ ├── .gitkeep │ ├── components │ ├── mapbox.blade.php │ └── mapbox-search.blade.php │ └── includes │ ├── search.blade.php │ └── script.blade.php ├── src ├── LaravelMapbox.php ├── Facades │ └── LaravelMapbox.php ├── Components │ ├── Mapbox.php │ └── MapboxSearch.php └── LaravelMapboxServiceProvider.php ├── config └── mapbox.php ├── phpstan.neon.dist ├── LICENSE.md ├── .php_cs.dist.php ├── CHANGELOG.md ├── composer.json └── README.md /phpstan-baseline.neon: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/LaravelMapbox.php: -------------------------------------------------------------------------------- 1 | (env('MAPBOX_TOKEN', null)) 5 | ]; 6 | -------------------------------------------------------------------------------- /phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | includes: 2 | - phpstan-baseline.neon 3 | 4 | parameters: 5 | level: 4 6 | paths: 7 | - src 8 | - config 9 | tmpDir: build/phpstan 10 | checkOctaneCompatibility: true 11 | checkModelProperties: true 12 | checkMissingIterableValueType: false 13 | 14 | -------------------------------------------------------------------------------- /src/Facades/LaravelMapbox.php: -------------------------------------------------------------------------------- 1 | 2 | #{{ $id }} { 3 | position: {{ $position }}; 4 | top: 0; 5 | bottom: 0; 6 | {{ $attributes['style'] && Str::contains($attributes['style'], 'width') ? $attributes['style'] : $attributes['style'] . 'width: 100%;' }} 7 | } 8 | 9 | .marker { 10 | display: block; 11 | border: none; 12 | cursor: pointer; 13 | padding: 0; 14 | } 15 | 16 | 17 |
18 | 19 | @include('mapbox::includes.script') 20 | -------------------------------------------------------------------------------- /resources/views/components/mapbox-search.blade.php: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 | 19 | @include('mapbox::includes.search') 20 | -------------------------------------------------------------------------------- /src/Components/Mapbox.php: -------------------------------------------------------------------------------- 1 | name('laravel-mapbox') 22 | ->hasConfigFile() 23 | ->hasViews(); 24 | } 25 | 26 | public function packageBooted() 27 | { 28 | Blade::component('mapbox', Mapbox::class); 29 | Blade::component('mapbox-search', MapboxSearch::class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /resources/views/includes/search.blade.php: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) koossaayy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /.php_cs.dist.php: -------------------------------------------------------------------------------- 1 | in([ 5 | __DIR__ . '/src', 6 | __DIR__ . '/tests', 7 | ]) 8 | ->name('*.php') 9 | ->notName('*.blade.php') 10 | ->ignoreDotFiles(true) 11 | ->ignoreVCS(true); 12 | 13 | return (new PhpCsFixer\Config()) 14 | ->setRules([ 15 | '@PSR12' => true, 16 | 'array_syntax' => ['syntax' => 'short'], 17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 18 | 'no_unused_imports' => true, 19 | 'not_operator_with_successor_space' => true, 20 | 'trailing_comma_in_multiline' => true, 21 | 'phpdoc_scalar' => true, 22 | 'unary_operator_spaces' => true, 23 | 'binary_operator_spaces' => true, 24 | 'blank_line_before_statement' => [ 25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], 26 | ], 27 | 'phpdoc_single_line_var_spacing' => true, 28 | 'phpdoc_var_without_name' => true, 29 | 'class_attributes_separation' => [ 30 | 'elements' => [ 31 | 'method' => 'one', 32 | ], 33 | ], 34 | 'method_argument_space' => [ 35 | 'on_multiline' => 'ensure_fully_multiline', 36 | 'keep_multiple_spaces_after_comma' => true, 37 | ], 38 | 'single_trait_insert_per_statement' => true, 39 | ]) 40 | ->setFinder($finder); 41 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `laravel-mapbox` will be documented in this file. 4 | 5 | ## Laravel 12 Support - 2025-04-02 6 | 7 | Added Laravel 12 Support 8 | 9 | ## HTML in description - 2024-09-10 10 | 11 | In this release, I've added the ability to set description as HTML code. 12 | 13 | ## Multiple Maps - 2024-06-20 14 | 15 | This release added the ability to add multiple maps on the same page. 16 | 17 | ## 0.4.3 - 2023-08-05 18 | 19 | ### What's Changed 20 | 21 | - Add tests by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/12 22 | - Fix the geocoderPosition documentation by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/14 23 | - Add map position as param by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/16 24 | - Updating docs by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/17 25 | 26 | **Full Changelog**: https://github.com/koossaayy/laravel-mapbox/compare/v0.4.2...v0.4.3 27 | 28 | ## v0.4.1 - 2022-10-13 29 | 30 | ### What's Changed 31 | 32 | - fixing marker customization issue by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/9 33 | 34 | **Full Changelog**: https://github.com/koossaayy/laravel-mapbox/compare/v0.4.0...v0.4.1 35 | 36 | ## Marker Customization support - 2022-10-13 37 | 38 | ### What's Changed 39 | 40 | - Adding marker customization by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/8 41 | 42 | **Full Changelog**: https://github.com/koossaayy/laravel-mapbox/compare/v0.3.0...v0.4.0 43 | 44 | ## v0.3.0 - 2022-07-23 45 | 46 | ### What's Changed 47 | 48 | - added search component and updating documentations & dependencies by @koossaayy in https://github.com/koossaayy/laravel-mapbox/pull/6 49 | 50 | **Full Changelog**: https://github.com/koossaayy/laravel-mapbox/compare/v0.2.1...v0.3.0 51 | 52 | ## Laravel 9 Support - 2022-02-08 53 | 54 | Laravel 9 Support 55 | 56 | ## 0.0.1 - 2021-29-11 57 | 58 | - initial release 59 | 60 | ## 0.0.2 - 2021-13-12 61 | 62 | - Added RTL Support for the names of places 63 | - Added support to cooperative gestures 64 | - Added free marker support, so the end user can interact with the map 65 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koossaayy/laravel-mapbox", 3 | "description": "Easily Integration of Mapbox inside your Laravel application", 4 | "keywords": [ 5 | "koossaayy", 6 | "laravel", 7 | "laravel-mapbox" 8 | ], 9 | "homepage": "https://github.com/koossaayy/laravel-mapbox", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "koossaayy", 14 | "email": "tounessna.2010@gmail.com", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.1|^8.2|^8.3|^8.4", 20 | "illuminate/contracts": "^9.0|^10.0|^11.0|^12.0", 21 | "spatie/laravel-package-tools": "^1.14" 22 | }, 23 | "require-dev": { 24 | "nunomaduro/collision": "^7.0|^8.0", 25 | "orchestra/testbench": "^8.0|^9.0|^10.0", 26 | "pestphp/pest": "^2.0|^3.0", 27 | "pestphp/pest-plugin-laravel": "^2.0|^3.0", 28 | "phpstan/extension-installer": "^1.1", 29 | "phpstan/phpstan-deprecation-rules": "^1.0", 30 | "phpstan/phpstan-phpunit": "^1.0", 31 | "phpunit/phpunit": "^10.0|^11.0", 32 | "spatie/laravel-ray": "^1.26", 33 | "mockery/mockery": "^1.4" 34 | }, 35 | "autoload": { 36 | "psr-4": { 37 | "Koossaayy\\LaravelMapbox\\": "src", 38 | "Koossaayy\\LaravelMapbox\\Database\\Factories\\": "database/factories" 39 | } 40 | }, 41 | "autoload-dev": { 42 | "psr-4": { 43 | "Koossaayy\\LaravelMapbox\\Tests\\": "tests" 44 | } 45 | }, 46 | "scripts": { 47 | "phpstan": "vendor/bin/phpstan analyse", 48 | "test": "vendor/bin/pest", 49 | "test-coverage": "vendor/bin/pest coverage" 50 | }, 51 | "config": { 52 | "sort-packages": true, 53 | "allow-plugins": { 54 | "phpstan/extension-installer": true, 55 | "pestphp/pest-plugin": true 56 | } 57 | }, 58 | "extra": { 59 | "laravel": { 60 | "providers": [ 61 | "Koossaayy\\LaravelMapbox\\LaravelMapboxServiceProvider" 62 | ], 63 | "aliases": { 64 | "LaravelMapbox": "Koossaayy\\LaravelMapbox\\Facades\\LaravelMapbox" 65 | } 66 | } 67 | }, 68 | "minimum-stability": "dev", 69 | "prefer-stable": true 70 | } 71 | -------------------------------------------------------------------------------- /resources/views/includes/script.blade.php: -------------------------------------------------------------------------------- 1 | 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Mapbox 2 | 3 | Easily Integration of Mapbox inside your Laravel application 4 | 5 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/koossaayy/laravel-mapbox.svg?style=flat-square)](https://packagist.org/packages/koossaayy/laravel-mapbox) 6 | [![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/koossaayy/laravel-mapbox/run-tests.yml?branch=main)](https://github.com/koossaayy/laravel-mapbox/actions?query=workflow%3Arun-tests+branch%3Amain) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/koossaayy/laravel-mapbox.svg?style=flat-square)](https://packagist.org/packages/koossaayy/laravel-mapbox) 8 | 9 | --- 10 | 11 | ![Laravel Mapbox](https://banners.beyondco.de/Laravel%20Mapbox.png?theme=dark&packageManager=composer+require&packageName=koossaayy%2Flaravel-mapbox&pattern=architect&style=style_1&description=Easily+Integrate+Mapbox+into+your+Laravel+application&md=1&showWatermark=1&fontSize=100px&images=https%3A%2F%2Flaravel.com%2Fimg%2Flogomark.min.svg) 12 | 13 | Easily inetgrate mapbox maps to your Laravel app using only blade components. 14 | 15 | ## Installation 16 | 17 | You can install the package via composer: 18 | 19 | ```bash 20 | composer require koossaayy/laravel-mapbox 21 | ``` 22 | 23 | After installing the package, [create an account](https://mapbox.com) on MapBox and get your token. 24 | 25 | Expose that token in your `.env` file as below: 26 | 27 | ``` 28 | MAPBOX_TOKEN={your mapbox token here} 29 | ``` 30 | 31 | For example 32 | 33 | ``` 34 | MAPBOX_TOKEN=pk.eyJ1IjoiiJjddd20yaDIzdmgwzWpqMm9vMDVrb3I1c2QzIn0.jepDEulAySscpF3o3w 35 | ``` 36 | 37 | Don't forget to publish your config file using: 38 | 39 | ```bash 40 | php artisan vendor:publish --tag="mapbox-config" 41 | ``` 42 | 43 | This is the contents of the published config file: 44 | 45 | ```php 46 | return [ 47 | 'mapbox_token' => (env('MAPBOX_TOKEN', null)) 48 | ]; 49 | ``` 50 | 51 | ## Usage 52 | 53 | The goal of this package is to use Blade components to render Mapbox GL maps. 54 | 55 | Before starting using this component, you must include the CSS and JS files in the file where you want to display your map: 56 | 57 | ```html 58 | 62 | 63 | ``` 64 | 65 | To show a basic map, you can use the component as follows : 66 | 67 | ```html 68 | 69 | ``` 70 | 71 | Note: The `id` parameter is mandatory since it's used by Mapbox JS. 72 | 73 | Next, here's how you can use the component with other options: 74 | 75 | In some scenarios, you may want to control the `position` CSS attribute of the map, you can do that with the `position` parameter. 76 | The default value will be `absolute` as the documentation in Mapbox. 77 | 78 | ```html 79 | 80 | ``` 81 | 82 | To show/hide navigation controls (Zoom in/Zoom out/Rotation), you can the use `:navigationControls` attribute as follows: 83 | 84 | ```html 85 | 86 | ``` 87 | 88 | To customize the map style (not to be confused with default style like width and height...), using either [Mapbpox predefined styles or your own styles](), you can use the `mapStyle` attribute as follows : 89 | 90 | ```html 91 | 92 | ``` 93 | 94 | Note: Providing a wrong style identifier will result in some glitches while showing the map. 95 | 96 | To center the camera of the map, on a certain point, you can use the `:center` attribute as follows: 97 | 98 | ```html 99 | 100 | ``` 101 | 102 | To control the map interactivity (Enable/Disable mouse events like dragging or zooming), you can use 103 | the `:interactive` attribute, as follows : 104 | 105 | ```html 106 | 107 | ``` 108 | 109 | To add markers to your map, you can use the `:markers` attribute, as follows : 110 | 111 | ```html 112 | 116 | ``` 117 | 118 | The `:markers` attribute accepts an array of arrays, each array must have at least the `long` and `lat` keys. 119 | If you want to add a popup description, you may use the `description` key. If you want to enable HTML description, you may add `html` key and set it to true to enable it. However there is a catch, you can't directly pass the HTML string, you should encapsulate it in a PHP variable and pass the variable to the array. 120 | For example: 121 | 122 | ```php 123 | //Somewhere in your code 124 | $htmlString = '

Hello world

'; 125 | ``` 126 | 127 | ```html 128 | 132 | ``` 133 | 134 | If the array is missing the `html` key, it won't render the passed variable, so make sure to pass it if you want to render an HTML description. 135 | 136 | > **Note** 137 | > Please notice that `description` key accepts HTML, and it will render it, so if you are getting your data from your users, please make sure to sanitize it before using it. 138 | 139 | Also you can customize the marker icons, instead of using the default ones provided by Mapbox. 140 | To do so you can add `icon` key to the array of markers as follows: 141 | 142 | ```php 143 | $icon = ''; 144 | ``` 145 | 146 | ```html 147 | 151 | ``` 152 | 153 | > **Note** 154 | > Please notice that `icon` key accepts HTML, and it will render it, so if you are getting your data from your users, please make sure to sanitize it before using it. 155 | 156 | > **Note** 157 | > It's recommended to keep the number of markers to a max of 20, for performance reasons. 158 | 159 | To control the style of the map (width, height, etc... Not to be confused with the `mapStyle` attribute), you can use the `style` and `class` attributes as follows : 160 | 161 | ```html 162 | 163 | ``` 164 | 165 | To add RTL support to show Arabic/Hebrew, etc... names correctly, you can use the `:rtl` attribute, as follows 166 | 167 | ```html 168 | 169 | ``` 170 | 171 | To add cooperative gestures (This allows the user to scroll the page without unintentionally zooming or panning the map.), you may use `:cooperativeGestures` attribute as follows: 172 | 173 | ```html 174 | 179 | ``` 180 | 181 | In some cases, you want a draggable marker, for example, when you want the end user to select a point on the map and then return its coordinates, in that case, you can use the `:draggable` attribute as follows: 182 | 183 | ```html 184 | 185 | ``` 186 | 187 | This will render a draggable marker. In order to get the coordinates of the marker, you must add the following JavaScript code after the `` component as follows: 188 | 189 | ```js 190 | markerid.on("dragend", function (e) { 191 | /*here you can get the coordinates as follows 192 | * e.target.getLngLat().lng : to get the longitude 193 | * e.target.getLngLat().lat : to get the latitude 194 | */ 195 | }); 196 | ``` 197 | 198 | For example, if you have a map with id `map1`, the resulting code will be as follows : 199 | 200 | ```js 201 | markermap1.on("dragend", function (e) { 202 | /*here you can get the coordinates as follows 203 | * e.target.getLngLat().lng : to get the longitude 204 | * e.target.getLngLat().lat : to get the latitude 205 | */ 206 | }); 207 | ``` 208 | 209 | Here's a full example, with all options being used: 210 | 211 | ```html 212 | 222 | ``` 223 | 224 | In addition to regular map component, we added the map search component. This will add a search bar into the map container, and will allow the end user to search for places.
225 | Before start using the search component, you must add the Mapbox geocoding plugin. 226 | 227 | ```html 228 | 229 | 230 | 235 | ``` 236 | 237 | > **Note** 238 | > The plugin must be imported after the Mapbox JS and CSS files. 239 | 240 | After importing the geocoding plugin, now you can use the search component as follows:
241 | 242 | ```html 243 | 244 | ``` 245 | 246 | The example below, is the search component with full options:
247 | 248 | ```html 249 | 259 | ``` 260 | 261 | As the example illustrates, the only difference here is the geocoder position, which is the position of the search input. It can be one of those `['top-left', 'top-right', 'bottom-left','bottom-right']` 262 | 263 | In order to listen to the change event, you need to add the `result` event listener, so you can get the result object. 264 | 265 | ```js 266 | geocoderid.on("result", function (event) { 267 | /** 268 | * Here you can lisen to the result event and get the result 269 | * for example you can get the longitude, atitude, and the place name as follows: 270 | * const long = event.result.geometry.coordinates[0]; 271 | * const lat = event.result.geometry.coordinates[1]; 272 | * const name = name = event.result.place_name; 273 | */ 274 | }); 275 | ``` 276 | 277 | For example, if you have a map with id `searchmap`, the code will be as follows : 278 | 279 | ```js 280 | geocodersearchmap.on("result", function (event) { 281 | /** 282 | * Here you can lisen to the result event and get the result 283 | * for example you can get the longitude, atitude, and the place name as follows: 284 | * const long = event.result.geometry.coordinates[0]; 285 | * const lat = event.result.geometry.coordinates[1]; 286 | * const name = name = event.result.place_name; 287 | */ 288 | }); 289 | ``` 290 | 291 | ## Testing 292 | 293 | This package is tested using PestPHP 294 | 295 | ```bash 296 | composer test 297 | ``` 298 | 299 | ## Changelog 300 | 301 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 302 | 303 | ## Contributing 304 | 305 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 306 | 307 | ## License 308 | 309 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 310 | --------------------------------------------------------------------------------