├── .editorconfig ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── assets ├── mapbox.jpg └── osm.jpg ├── config.dist.json ├── package.json ├── sanity.json └── src ├── GeoSearchPlugin.js ├── GeopointInput.css ├── GeopointInput.js ├── Leaflet.css └── MapBoxAccessTokenMissing.js /.editorconfig: -------------------------------------------------------------------------------- 1 | ; editorconfig.org 2 | root = true 3 | charset= utf8 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | indent_style = space 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # macOS finder cache file 40 | .DS_Store 41 | 42 | # VS Code settings 43 | .vscode 44 | 45 | # Lockfiles 46 | yarn.lock 47 | package-lock.json 48 | 49 | # Cache 50 | .cache 51 | 52 | # Build output 53 | /lib 54 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /assets 2 | .editorconfig 3 | .gitignore 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Espen Hovlandsdal 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sanity-plugin-leaflet-input 2 | 3 | [Leaflet](https://leafletjs.com/) is an open-source JavaScript library for mobile-friendly interactive maps. This plugin is an input component for [Sanity.io](https://www.sanity.io/) which lets you use the Leaflet library for the [Geopoint](https://www.sanity.io/docs/geopoint-type) schema type. 4 | 5 | By default it will use OpenStreetMaps tiles, but it can be configured to use a different provider, such as Mapbox. 6 | 7 | ## Screenshots 8 | 9 | **Using OpenStreetMaps** 10 | 11 | ![sanity-plugin-leaflet with OpenStreetMaps](assets/osm.jpg) 12 | 13 | **Using MapBox (streets style)** 14 | 15 | ![sanity-plugin-leaflet with MapBox](assets/mapbox.jpg) 16 | 17 | ## Installing 18 | 19 | ``` 20 | sanity install leaflet-input 21 | ``` 22 | 23 | **Note**: If you have another geopoint input installed (such as `@sanity/google-maps-input`), you'll either need to move this plugin below it in your studios `sanity.json` `plugins` array (easiest), or explicitly [importing the input component](#importing-the-component) where you want to use it. 24 | 25 | ## Configuring 26 | 27 | The plugin can be configured both "globally" and "locally". 28 | 29 | The global options can be defined in `/config/leaflet-input.json`: 30 | 31 | ```json 32 | { 33 | "tileLayer": { 34 | "attribution": "© OpenStreetMap contributors", 35 | "url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" 36 | }, 37 | "defaultLocation": { 38 | "lat": 37.779048, 39 | "lng": -122.415214 40 | }, 41 | "defaultZoom": 13 42 | } 43 | ``` 44 | 45 | The same options can be defined on a field level ("local"): 46 | 47 | ```js 48 | // some-schema-type.js 49 | export default { 50 | name: 'restaurant', 51 | type: 'document', 52 | fields: [ 53 | { 54 | name: 'location', 55 | type: 'geopoint', 56 | options: { 57 | leaflet: { 58 | defaultLocation: { 59 | lat: 59.924095, 60 | lng: 10.758458, 61 | }, 62 | }, 63 | }, 64 | }, 65 | ], 66 | } 67 | ``` 68 | 69 | ## Using Mapbox 70 | 71 | In your studios `config/leaflet-input.json` file (if it's missing, run `sanity start` to generate it): 72 | 73 | ```json 74 | { 75 | "tileLayer": { 76 | "accessToken": "SOME_ACCESS_TOKEN", 77 | "id": "mapbox.streets", 78 | "maxZoom": 18, 79 | "url": "https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}", 80 | "attribution": "© Mapbox © OpenStreetMap Improve this map" 81 | } 82 | } 83 | ``` 84 | 85 | Read more about access tokens [here](https://docs.mapbox.com/help/how-mapbox-works/access-tokens/). 86 | 87 | ## Importing the component 88 | 89 | If you have multiple Geopoint inputs installed, you may need to import the leaflet plugin specifically in the cases where you want to use it: 90 | 91 | ```js 92 | // some-schema-type.js 93 | import LeafletGeopointInput from 'sanity-plugin-leaflet-input' 94 | 95 | export default { 96 | name: 'restaurant', 97 | type: 'document', 98 | fields: [ 99 | { 100 | name: 'location', 101 | type: 'geopoint', 102 | inputComponent: LeafletGeopointInput, 103 | }, 104 | ], 105 | } 106 | ``` 107 | 108 | ## License 109 | 110 | MIT © [Espen Hovlandsdal](https://espen.codes/) 111 | -------------------------------------------------------------------------------- /assets/mapbox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rexxars/sanity-plugin-leaflet-input/f49ff6da6562433bfa29b6a4280a21c174891e7e/assets/mapbox.jpg -------------------------------------------------------------------------------- /assets/osm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rexxars/sanity-plugin-leaflet-input/f49ff6da6562433bfa29b6a4280a21c174891e7e/assets/osm.jpg -------------------------------------------------------------------------------- /config.dist.json: -------------------------------------------------------------------------------- 1 | { 2 | "tileLayer": { 3 | "attribution": "© OpenStreetMap contributors", 4 | "url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" 5 | }, 6 | "defaultLocation": { 7 | "lat": 37.779048, 8 | "lng": -122.415214 9 | }, 10 | "defaultZoom": 13 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sanity-plugin-leaflet-input", 3 | "version": "1.0.1", 4 | "description": "Leaflet geopoint input component for Sanity.io", 5 | "main": "lib/GeopointInput.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "sanipack build", 9 | "prepublishOnly": "sanipack build && sanipack verify" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+ssh://git@github.com/rexxars/sanity-plugin-leaflet-input.git" 14 | }, 15 | "keywords": [ 16 | "sanity-io", 17 | "sanity", 18 | "sanity-input-component", 19 | "sanity-plugin", 20 | "geopoint", 21 | "map" 22 | ], 23 | "author": "Espen Hovlandsdal", 24 | "license": "MIT", 25 | "dependencies": { 26 | "esri-leaflet-geocoder": "^2.3.4", 27 | "leaflet": "^1.6.0", 28 | "prop-types": "^15.0.0", 29 | "react-leaflet": "^2.6.3" 30 | }, 31 | "devDependencies": { 32 | "eslint": "^7.18.0", 33 | "eslint-config-prettier": "^7.2.0", 34 | "eslint-config-sanity": "^1.149.0", 35 | "eslint-plugin-react": "^7.19.0", 36 | "prettier": "^2.0.4", 37 | "react": "^17.0.0", 38 | "sanipack": "^1.0.1" 39 | }, 40 | "peerDependencies": { 41 | "react": ">=16.2", 42 | "react-dom": ">=16.2" 43 | }, 44 | "bugs": { 45 | "url": "https://github.com/rexxars/sanity-plugin-leaflet-input/issues" 46 | }, 47 | "homepage": "https://github.com/rexxars/sanity-plugin-leaflet-input#readme", 48 | "prettier": { 49 | "semi": false, 50 | "printWidth": 100, 51 | "bracketSpacing": false, 52 | "singleQuote": true 53 | }, 54 | "eslintConfig": { 55 | "extends": [ 56 | "sanity", 57 | "sanity/react", 58 | "prettier", 59 | "prettier/react" 60 | ], 61 | "env": { 62 | "node": true, 63 | "browser": true 64 | }, 65 | "parserOptions": { 66 | "ecmaVersion": 2020, 67 | "ecmaFeatures": { 68 | "jsx": true 69 | } 70 | }, 71 | "settings": { 72 | "react": { 73 | "version": "detect" 74 | } 75 | }, 76 | "rules": { 77 | "complexity": "off" 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /sanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "paths": { 3 | "source": "./src", 4 | "compiled": "./lib" 5 | }, 6 | 7 | "parts": [ 8 | { 9 | "name": "part:leaflet-input/input/geopoint", 10 | "implements": "part:@sanity/form-builder/input/geopoint", 11 | "path": "GeopointInput.js" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/GeoSearchPlugin.js: -------------------------------------------------------------------------------- 1 | import {withLeaflet, MapControl} from 'react-leaflet' 2 | import {Geosearch} from 'esri-leaflet-geocoder' 3 | 4 | class LeafletGeoSearch extends MapControl { 5 | // eslint-disable-next-line class-methods-use-this 6 | createLeafletElement(props) { 7 | const GeoSearch = new Geosearch() 8 | 9 | GeoSearch.on('results', ({latlng}) => { 10 | props.onSelectLocation(latlng) 11 | }) 12 | 13 | return GeoSearch 14 | } 15 | 16 | componentDidMount() { 17 | const {map} = this.props.leaflet 18 | 19 | this.leafletElement.addTo(map) 20 | } 21 | 22 | componentWillUnmount() { 23 | this.leafletElement.remove() 24 | } 25 | } 26 | 27 | export default withLeaflet(LeafletGeoSearch) 28 | -------------------------------------------------------------------------------- /src/GeopointInput.css: -------------------------------------------------------------------------------- 1 | @import 'part:@sanity/base/theme/variables-style'; 2 | 3 | .map { 4 | height: 400px; 5 | width: 100%; 6 | } 7 | 8 | .errorContainer { 9 | background: var(--state-warning-color); 10 | padding: var(--small-padding); 11 | } 12 | 13 | .errorContainer a { 14 | color: black; 15 | } 16 | 17 | .errorContainer code { 18 | background: rgba(255, 255, 255, 0.35); 19 | padding: 2.5px; 20 | white-space: nowrap; 21 | } 22 | 23 | .errorHeading { 24 | margin: var(--small-padding) 0; 25 | } 26 | 27 | .helpText { 28 | background: #eee; 29 | margin: 0; 30 | padding: var(--small-padding); 31 | text-align: center; 32 | font-size: var(--font-size-small); 33 | } 34 | -------------------------------------------------------------------------------- /src/GeopointInput.js: -------------------------------------------------------------------------------- 1 | import React, {createRef, useState} from 'react' 2 | import PropTypes from 'prop-types' 3 | import Leaflet from 'leaflet' 4 | import {Map, TileLayer, Marker, ZoomControl, Popup} from 'react-leaflet' 5 | import Button from 'part:@sanity/components/buttons/default' 6 | import Fieldset from 'part:@sanity/components/fieldsets/default' 7 | import {PatchEvent, set, setIfMissing, unset} from 'part:@sanity/form-builder/patch-event' 8 | import config from 'config:leaflet-input' 9 | import leafStyles from './Leaflet.css' 10 | import styles from './GeopointInput.css' 11 | import GeoSearchInput from './GeoSearchPlugin' 12 | import MapBoxAccessTokenMissing from './MapBoxAccessTokenMissing' 13 | 14 | Leaflet.Icon.Default.mergeOptions({ 15 | iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'), 16 | iconUrl: require('leaflet/dist/images/marker-icon.png'), 17 | shadowUrl: require('leaflet/dist/images/marker-shadow.png'), 18 | }) 19 | 20 | const EMPTY_MARKERS = [] 21 | const DEFAULT_ZOOM = 13 22 | const DEFAULT_CENTER = [37.779048, -122.415214] 23 | 24 | const clickToMove = 25 | typeof window !== 'undefined' && 26 | typeof window.matchMedia === 'function' && 27 | !matchMedia('(pointer:fine)').matches 28 | 29 | function getKeyPlaceholder(url) { 30 | const [, key] = url.match(/access_token=\{(.*?)\}/) || [] 31 | return key 32 | } 33 | 34 | function isMissingMapboxApiKey(tileConfig) { 35 | const url = tileConfig.url || '' 36 | const hasStaticAccessKey = /accessToken=[^{]/.test(url) 37 | const keyPlaceholder = !hasStaticAccessKey && getKeyPlaceholder(url) 38 | return url.includes('tiles.mapbox.com') && keyPlaceholder && !tileConfig[keyPlaceholder] 39 | } 40 | 41 | function getHelpText(value) { 42 | if (!value || !value.lat) { 43 | return `Click on map to set location` 44 | } 45 | 46 | if (clickToMove) { 47 | return `Click on map to change location. Click marker to remove it.` 48 | } 49 | 50 | return `Drag marker to change location. Click marker to remove it.` 51 | } 52 | 53 | // eslint-disable-next-line prefer-arrow-callback 54 | const GeopointInput = React.forwardRef(function GeopointInput(props, ref) { 55 | const {type, level, value, markers, onChange} = props 56 | const typeOptions = type.options?.leaflet || {} 57 | const tileConfig = {...config.tileLayer, ...typeOptions.tileLayer} 58 | const center = value || typeOptions.defaultLocation || config.defaultLocation || DEFAULT_CENTER 59 | const [zoom, setZoom] = useState(typeOptions.defaultZoom || config.defaultZoom || DEFAULT_ZOOM) 60 | const markerRef = createRef() 61 | 62 | if (isMissingMapboxApiKey(tileConfig)) { 63 | return ( 64 |
65 | 66 |
67 | ) 68 | } 69 | 70 | function setMarkerLocation(latLng) { 71 | onChange( 72 | PatchEvent.from([ 73 | setIfMissing({ 74 | _type: type.name, 75 | }), 76 | set(latLng.lat, ['lat']), 77 | set(latLng.lng, ['lng']), 78 | ]) 79 | ) 80 | } 81 | 82 | function handleMapClick(evt) { 83 | if (!clickToMove && value && value.lat) { 84 | return 85 | } 86 | 87 | setMarkerLocation(evt.latlng) 88 | } 89 | 90 | function handleMarkerDragEnd() { 91 | if (!markerRef.current) { 92 | return 93 | } 94 | 95 | setMarkerLocation(markerRef.current.leafletElement.getLatLng()) 96 | } 97 | 98 | function handleUnsetMarker() { 99 | onChange(PatchEvent.from(unset())) 100 | } 101 | 102 | function onZoom(evt) { 103 | setZoom(evt.target.getZoom()) 104 | } 105 | 106 | return ( 107 |
108 |
109 | 120 | 121 | 122 | {value && value.lat && ( 123 | 129 | {!type.readOnly && ( 130 | 131 | 134 | 135 | )} 136 | 137 | )} 138 | 139 | 140 | 141 | 142 | 143 | 144 |

{getHelpText(value)}

145 |
146 |
147 | ) 148 | }) 149 | 150 | GeopointInput.propTypes = { 151 | value: PropTypes.shape({ 152 | _type: PropTypes.string.isRequired, 153 | lat: PropTypes.number.isRequired, 154 | lng: PropTypes.number.isRequired, 155 | }), 156 | level: PropTypes.number.isRequired, 157 | onChange: PropTypes.func.isRequired, 158 | type: PropTypes.shape({ 159 | name: PropTypes.string.isRequired, 160 | title: PropTypes.string, 161 | description: PropTypes.string, 162 | readOnly: PropTypes.bool, 163 | options: PropTypes.shape({ 164 | leaflet: PropTypes.shape({ 165 | tileLayer: PropTypes.shape({ 166 | url: PropTypes.string.isRequired, 167 | maxZoom: PropTypes.number, 168 | attribution: PropTypes.string, 169 | accessToken: PropTypes.string, 170 | }), 171 | defaultLocation: PropTypes.shape({ 172 | lat: PropTypes.number, 173 | lng: PropTypes.number, 174 | }), 175 | defaultZoom: PropTypes.number, 176 | }), 177 | }), 178 | }).isRequired, 179 | markers: PropTypes.arrayOf( 180 | PropTypes.shape({ 181 | type: PropTypes.string, 182 | }) 183 | ), 184 | } 185 | 186 | GeopointInput.defaultProps = { 187 | value: undefined, 188 | markers: EMPTY_MARKERS, 189 | } 190 | 191 | export default GeopointInput 192 | -------------------------------------------------------------------------------- /src/Leaflet.css: -------------------------------------------------------------------------------- 1 | /* generated with https://github.com/rexxars/prefixify-css */ 2 | /* `prefixify originalLeaflet.css .leaflet` */ 3 | /* required styles */ 4 | .leaflet { 5 | } 6 | .leaflet :global(.leaflet-pane), 7 | .leaflet :global(.leaflet-tile), 8 | .leaflet :global(.leaflet-marker-icon), 9 | .leaflet :global(.leaflet-marker-shadow), 10 | .leaflet :global(.leaflet-tile-container), 11 | .leaflet :global(.leaflet-pane > svg), 12 | .leaflet :global(.leaflet-pane > canvas), 13 | .leaflet :global(.leaflet-zoom-box), 14 | .leaflet :global(.leaflet-image-layer), 15 | .leaflet :global(.leaflet-layer) { 16 | position: absolute; 17 | left: 0; 18 | top: 0; 19 | } 20 | .leaflet :global(.leaflet-container) { 21 | overflow: hidden; 22 | } 23 | .leaflet :global(.leaflet-tile), 24 | .leaflet :global(.leaflet-marker-icon), 25 | .leaflet :global(.leaflet-marker-shadow) { 26 | -webkit-user-select: none; 27 | -moz-user-select: none; 28 | user-select: none; 29 | -webkit-user-drag: none; 30 | } 31 | /* Prevents IE11 from highlighting tiles in blue */ 32 | .leaflet :global(.leaflet-tile::selection) { 33 | background: transparent; 34 | } 35 | /* Safari renders non-retina tile on retina better with this, but Chrome is worse */ 36 | .leaflet :global(.leaflet-safari .leaflet-tile) { 37 | image-rendering: -webkit-optimize-contrast; 38 | } 39 | /* hack that prevents hw layers "stretching" when loading new tiles */ 40 | .leaflet :global(.leaflet-safari .leaflet-tile-container) { 41 | width: 1600px; 42 | height: 1600px; 43 | -webkit-transform-origin: 0 0; 44 | } 45 | .leaflet :global(.leaflet-marker-icon), 46 | .leaflet :global(.leaflet-marker-shadow) { 47 | display: block; 48 | } 49 | /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ 50 | /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ 51 | .leaflet :global(.leaflet-container .leaflet-overlay-pane svg), 52 | .leaflet :global(.leaflet-container .leaflet-marker-pane img), 53 | .leaflet :global(.leaflet-container .leaflet-shadow-pane img), 54 | .leaflet :global(.leaflet-container .leaflet-tile-pane img), 55 | .leaflet :global(.leaflet-container img.leaflet-image-layer), 56 | .leaflet :global(.leaflet-container .leaflet-tile) { 57 | max-width: none !important; 58 | max-height: none !important; 59 | } 60 | 61 | .leaflet :global(.leaflet-container.leaflet-touch-zoom) { 62 | -ms-touch-action: pan-x pan-y; 63 | touch-action: pan-x pan-y; 64 | } 65 | .leaflet :global(.leaflet-container.leaflet-touch-drag) { 66 | -ms-touch-action: pinch-zoom; 67 | /* Fallback for FF which doesn't support pinch-zoom */ 68 | touch-action: none; 69 | touch-action: pinch-zoom; 70 | } 71 | .leaflet :global(.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom) { 72 | -ms-touch-action: none; 73 | touch-action: none; 74 | } 75 | .leaflet :global(.leaflet-container) { 76 | -webkit-tap-highlight-color: transparent; 77 | } 78 | .leaflet :global(.leaflet-container a) { 79 | -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); 80 | } 81 | .leaflet :global(.leaflet-tile) { 82 | filter: inherit; 83 | visibility: hidden; 84 | } 85 | .leaflet :global(.leaflet-tile-loaded) { 86 | visibility: inherit; 87 | } 88 | .leaflet :global(.leaflet-zoom-box) { 89 | width: 0; 90 | height: 0; 91 | -moz-box-sizing: border-box; 92 | box-sizing: border-box; 93 | z-index: 800; 94 | } 95 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ 96 | .leaflet :global(.leaflet-overlay-pane svg) { 97 | -moz-user-select: none; 98 | } 99 | 100 | .leaflet :global(.leaflet-pane) { 101 | z-index: 400; 102 | } 103 | 104 | .leaflet :global(.leaflet-tile-pane) { 105 | z-index: 200; 106 | } 107 | .leaflet :global(.leaflet-overlay-pane) { 108 | z-index: 400; 109 | } 110 | .leaflet :global(.leaflet-shadow-pane) { 111 | z-index: 500; 112 | } 113 | .leaflet :global(.leaflet-marker-pane) { 114 | z-index: 600; 115 | } 116 | .leaflet :global(.leaflet-tooltip-pane) { 117 | z-index: 650; 118 | } 119 | .leaflet :global(.leaflet-popup-pane) { 120 | z-index: 700; 121 | } 122 | 123 | .leaflet :global(.leaflet-map-pane canvas) { 124 | z-index: 100; 125 | } 126 | .leaflet :global(.leaflet-map-pane svg) { 127 | z-index: 200; 128 | } 129 | 130 | .leaflet :global(.leaflet-vml-shape) { 131 | width: 1px; 132 | height: 1px; 133 | } 134 | .leaflet :global(.lvml) { 135 | behavior: url(#default#VML); 136 | display: inline-block; 137 | position: absolute; 138 | } 139 | 140 | /* control positioning */ 141 | 142 | .leaflet :global(.leaflet-control) { 143 | position: relative; 144 | z-index: 800; 145 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 146 | pointer-events: auto; 147 | } 148 | .leaflet :global(.leaflet-top), 149 | .leaflet :global(.leaflet-bottom) { 150 | position: absolute; 151 | z-index: 1000; 152 | pointer-events: none; 153 | } 154 | .leaflet :global(.leaflet-top) { 155 | top: 0; 156 | } 157 | .leaflet :global(.leaflet-right) { 158 | right: 0; 159 | } 160 | .leaflet :global(.leaflet-bottom) { 161 | bottom: 0; 162 | } 163 | .leaflet :global(.leaflet-left) { 164 | left: 0; 165 | } 166 | .leaflet :global(.leaflet-control) { 167 | float: left; 168 | clear: both; 169 | } 170 | .leaflet :global(.leaflet-right .leaflet-control) { 171 | float: right; 172 | } 173 | .leaflet :global(.leaflet-top .leaflet-control) { 174 | margin-top: 10px; 175 | } 176 | .leaflet :global(.leaflet-bottom .leaflet-control) { 177 | margin-bottom: 10px; 178 | } 179 | .leaflet :global(.leaflet-left .leaflet-control) { 180 | margin-left: 10px; 181 | } 182 | .leaflet :global(.leaflet-right .leaflet-control) { 183 | margin-right: 10px; 184 | } 185 | 186 | /* zoom and fade animations */ 187 | 188 | .leaflet :global(.leaflet-fade-anim .leaflet-tile) { 189 | will-change: opacity; 190 | } 191 | .leaflet :global(.leaflet-fade-anim .leaflet-popup) { 192 | opacity: 0; 193 | -webkit-transition: opacity 0.2s linear; 194 | -moz-transition: opacity 0.2s linear; 195 | transition: opacity 0.2s linear; 196 | } 197 | .leaflet :global(.leaflet-fade-anim .leaflet-map-pane .leaflet-popup) { 198 | opacity: 1; 199 | } 200 | .leaflet :global(.leaflet-zoom-animated) { 201 | -webkit-transform-origin: 0 0; 202 | -ms-transform-origin: 0 0; 203 | transform-origin: 0 0; 204 | } 205 | .leaflet :global(.leaflet-zoom-anim .leaflet-zoom-animated) { 206 | will-change: transform; 207 | } 208 | .leaflet :global(.leaflet-zoom-anim .leaflet-zoom-animated) { 209 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0, 0, 0.25, 1); 210 | -moz-transition: -moz-transform 0.25s cubic-bezier(0, 0, 0.25, 1); 211 | transition: transform 0.25s cubic-bezier(0, 0, 0.25, 1); 212 | } 213 | .leaflet :global(.leaflet-zoom-anim .leaflet-tile), 214 | .leaflet :global(.leaflet-pan-anim .leaflet-tile) { 215 | -webkit-transition: none; 216 | -moz-transition: none; 217 | transition: none; 218 | } 219 | 220 | .leaflet :global(.leaflet-zoom-anim .leaflet-zoom-hide) { 221 | visibility: hidden; 222 | } 223 | 224 | /* cursors */ 225 | 226 | .leaflet :global(.leaflet-interactive) { 227 | cursor: pointer; 228 | } 229 | .leaflet :global(.leaflet-grab) { 230 | cursor: -webkit-grab; 231 | cursor: -moz-grab; 232 | cursor: grab; 233 | } 234 | .leaflet :global(.leaflet-crosshair), 235 | .leaflet :global(.leaflet-crosshair .leaflet-interactive) { 236 | cursor: crosshair; 237 | } 238 | .leaflet :global(.leaflet-popup-pane), 239 | .leaflet :global(.leaflet-control) { 240 | cursor: auto; 241 | } 242 | .leaflet :global(.leaflet-dragging .leaflet-grab), 243 | .leaflet :global(.leaflet-dragging .leaflet-grab .leaflet-interactive), 244 | .leaflet :global(.leaflet-dragging .leaflet-marker-draggable) { 245 | cursor: move; 246 | cursor: -webkit-grabbing; 247 | cursor: -moz-grabbing; 248 | cursor: grabbing; 249 | } 250 | 251 | /* marker & overlays interactivity */ 252 | .leaflet :global(.leaflet-marker-icon), 253 | .leaflet :global(.leaflet-marker-shadow), 254 | .leaflet :global(.leaflet-image-layer), 255 | .leaflet :global(.leaflet-pane > svg path), 256 | .leaflet :global(.leaflet-tile-container) { 257 | pointer-events: none; 258 | } 259 | 260 | .leaflet :global(.leaflet-marker-icon.leaflet-interactive), 261 | .leaflet :global(.leaflet-image-layer.leaflet-interactive), 262 | .leaflet :global(.leaflet-pane > svg path.leaflet-interactive), 263 | .leaflet :global(svg.leaflet-image-layer.leaflet-interactive path) { 264 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 265 | pointer-events: auto; 266 | } 267 | 268 | /* visual tweaks */ 269 | 270 | .leaflet :global(.leaflet-container) { 271 | background: #ddd; 272 | outline: 0; 273 | } 274 | .leaflet :global(.leaflet-container a) { 275 | color: #0078a8; 276 | } 277 | .leaflet :global(.leaflet-container a.leaflet-active) { 278 | outline: 2px solid orange; 279 | } 280 | .leaflet :global(.leaflet-zoom-box) { 281 | border: 2px dotted #38f; 282 | background: rgba(255, 255, 255, 0.5); 283 | } 284 | 285 | /* general typography */ 286 | .leaflet :global(.leaflet-container) { 287 | font: 12px/1.5 'Helvetica Neue', Arial, Helvetica, sans-serif; 288 | } 289 | 290 | /* general toolbar styles */ 291 | 292 | .leaflet :global(.leaflet-bar) { 293 | box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65); 294 | border-radius: 4px; 295 | } 296 | .leaflet :global(.leaflet-bar a), 297 | .leaflet :global(.leaflet-bar a:hover) { 298 | background-color: #fff; 299 | border-bottom: 1px solid #ccc; 300 | width: 26px; 301 | height: 26px; 302 | line-height: 26px; 303 | display: block; 304 | text-align: center; 305 | text-decoration: none; 306 | color: black; 307 | } 308 | .leaflet :global(.leaflet-bar a), 309 | .leaflet :global(.leaflet-control-layers-toggle) { 310 | background-position: 50% 50%; 311 | background-repeat: no-repeat; 312 | display: block; 313 | } 314 | .leaflet :global(.leaflet-bar a:hover) { 315 | background-color: #f4f4f4; 316 | } 317 | .leaflet :global(.leaflet-bar a:first-child) { 318 | border-top-left-radius: 4px; 319 | border-top-right-radius: 4px; 320 | } 321 | .leaflet :global(.leaflet-bar a:last-child) { 322 | border-bottom-left-radius: 4px; 323 | border-bottom-right-radius: 4px; 324 | border-bottom: none; 325 | } 326 | .leaflet :global(.leaflet-bar a.leaflet-disabled) { 327 | cursor: default; 328 | background-color: #f4f4f4; 329 | color: #bbb; 330 | } 331 | 332 | .leaflet :global(.leaflet-touch .leaflet-bar a) { 333 | width: 30px; 334 | height: 30px; 335 | line-height: 30px; 336 | } 337 | .leaflet :global(.leaflet-touch .leaflet-bar a:first-child) { 338 | border-top-left-radius: 2px; 339 | border-top-right-radius: 2px; 340 | } 341 | .leaflet :global(.leaflet-touch .leaflet-bar a:last-child) { 342 | border-bottom-left-radius: 2px; 343 | border-bottom-right-radius: 2px; 344 | } 345 | 346 | /* zoom control */ 347 | 348 | .leaflet :global(.leaflet-control-zoom-in), 349 | .leaflet :global(.leaflet-control-zoom-out) { 350 | font: bold 18px 'Lucida Console', Monaco, monospace; 351 | text-indent: 1px; 352 | } 353 | 354 | .leaflet :global(.leaflet-touch .leaflet-control-zoom-in), 355 | .leaflet :global(.leaflet-touch .leaflet-control-zoom-out) { 356 | font-size: 22px; 357 | } 358 | 359 | /* layers control */ 360 | 361 | .leaflet :global(.leaflet-control-layers) { 362 | box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4); 363 | background: #fff; 364 | border-radius: 5px; 365 | } 366 | .leaflet :global(.leaflet-control-layers-toggle) { 367 | background-image: url(leaflet/dist/images/layers.png); 368 | width: 36px; 369 | height: 36px; 370 | } 371 | .leaflet :global(.leaflet-retina .leaflet-control-layers-toggle) { 372 | background-image: url(leaflet/dist/images/layers-2x.png); 373 | background-size: 26px 26px; 374 | } 375 | .leaflet :global(.leaflet-touch .leaflet-control-layers-toggle) { 376 | width: 44px; 377 | height: 44px; 378 | } 379 | .leaflet :global(.leaflet-control-layers .leaflet-control-layers-list), 380 | .leaflet :global(.leaflet-control-layers-expanded .leaflet-control-layers-toggle) { 381 | display: none; 382 | } 383 | .leaflet :global(.leaflet-control-layers-expanded .leaflet-control-layers-list) { 384 | display: block; 385 | position: relative; 386 | } 387 | .leaflet :global(.leaflet-control-layers-expanded) { 388 | padding: 6px 10px 6px 6px; 389 | color: #333; 390 | background: #fff; 391 | } 392 | .leaflet :global(.leaflet-control-layers-scrollbar) { 393 | overflow-y: scroll; 394 | overflow-x: hidden; 395 | padding-right: 5px; 396 | } 397 | .leaflet :global(.leaflet-control-layers-selector) { 398 | margin-top: 2px; 399 | position: relative; 400 | top: 1px; 401 | } 402 | .leaflet :global(.leaflet-control-layers label) { 403 | display: block; 404 | } 405 | .leaflet :global(.leaflet-control-layers-separator) { 406 | height: 0; 407 | border-top: 1px solid #ddd; 408 | margin: 5px -10px 5px -6px; 409 | } 410 | 411 | /* Default icon URLs */ 412 | .leaflet :global(.leaflet-default-icon-path) { 413 | background-image: url(leaflet/dist/images/marker-icon.png); 414 | } 415 | 416 | /* attribution and scale controls */ 417 | 418 | .leaflet :global(.leaflet-container .leaflet-control-attribution) { 419 | background: #fff; 420 | background: rgba(255, 255, 255, 0.7); 421 | margin: 0; 422 | } 423 | .leaflet :global(.leaflet-control-attribution), 424 | .leaflet :global(.leaflet-control-scale-line) { 425 | padding: 0 5px; 426 | color: #333; 427 | } 428 | .leaflet :global(.leaflet-control-attribution a) { 429 | text-decoration: none; 430 | } 431 | .leaflet :global(.leaflet-control-attribution a:hover) { 432 | text-decoration: underline; 433 | } 434 | .leaflet :global(.leaflet-container .leaflet-control-attribution), 435 | .leaflet :global(.leaflet-container .leaflet-control-scale) { 436 | font-size: 11px; 437 | } 438 | .leaflet :global(.leaflet-left .leaflet-control-scale) { 439 | margin-left: 5px; 440 | } 441 | .leaflet :global(.leaflet-bottom .leaflet-control-scale) { 442 | margin-bottom: 5px; 443 | } 444 | .leaflet :global(.leaflet-control-scale-line) { 445 | border: 2px solid #777; 446 | border-top: none; 447 | line-height: 1.1; 448 | padding: 2px 5px 1px; 449 | font-size: 11px; 450 | white-space: nowrap; 451 | overflow: hidden; 452 | -moz-box-sizing: border-box; 453 | box-sizing: border-box; 454 | 455 | background: #fff; 456 | background: rgba(255, 255, 255, 0.5); 457 | } 458 | .leaflet :global(.leaflet-control-scale-line:not(:first-child)) { 459 | border-top: 2px solid #777; 460 | border-bottom: none; 461 | margin-top: -2px; 462 | } 463 | .leaflet :global(.leaflet-control-scale-line:not(:first-child):not(:last-child)) { 464 | border-bottom: 2px solid #777; 465 | } 466 | 467 | .leaflet :global(.leaflet-touch .leaflet-control-attribution), 468 | .leaflet :global(.leaflet-touch .leaflet-control-layers), 469 | .leaflet :global(.leaflet-touch .leaflet-bar) { 470 | box-shadow: none; 471 | } 472 | .leaflet :global(.leaflet-touch .leaflet-control-layers), 473 | .leaflet :global(.leaflet-touch .leaflet-bar) { 474 | border: 2px solid rgba(0, 0, 0, 0.2); 475 | background-clip: padding-box; 476 | } 477 | 478 | /* popup */ 479 | 480 | .leaflet :global(.leaflet-popup) { 481 | position: absolute; 482 | text-align: center; 483 | margin-bottom: 20px; 484 | } 485 | .leaflet :global(.leaflet-popup-content-wrapper) { 486 | padding: 1px; 487 | text-align: left; 488 | border-radius: 12px; 489 | } 490 | .leaflet :global(.leaflet-popup-content) { 491 | margin: 13px 19px; 492 | line-height: 1.4; 493 | } 494 | .leaflet :global(.leaflet-popup-content p) { 495 | margin: 18px 0; 496 | } 497 | .leaflet :global(.leaflet-popup-tip-container) { 498 | width: 40px; 499 | height: 20px; 500 | position: absolute; 501 | left: 50%; 502 | margin-left: -20px; 503 | overflow: hidden; 504 | pointer-events: none; 505 | } 506 | .leaflet :global(.leaflet-popup-tip) { 507 | width: 17px; 508 | height: 17px; 509 | padding: 1px; 510 | 511 | margin: -10px auto 0; 512 | 513 | -webkit-transform: rotate(45deg); 514 | -moz-transform: rotate(45deg); 515 | -ms-transform: rotate(45deg); 516 | transform: rotate(45deg); 517 | } 518 | .leaflet :global(.leaflet-popup-content-wrapper), 519 | .leaflet :global(.leaflet-popup-tip) { 520 | background: white; 521 | color: #333; 522 | box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4); 523 | } 524 | .leaflet :global(.leaflet-container a.leaflet-popup-close-button) { 525 | position: absolute; 526 | top: 0; 527 | right: 0; 528 | padding: 4px 4px 0 0; 529 | border: none; 530 | text-align: center; 531 | width: 18px; 532 | height: 14px; 533 | font: 16px/14px Tahoma, Verdana, sans-serif; 534 | color: #c3c3c3; 535 | text-decoration: none; 536 | font-weight: bold; 537 | background: transparent; 538 | } 539 | .leaflet :global(.leaflet-container a.leaflet-popup-close-button:hover) { 540 | color: #999; 541 | } 542 | .leaflet :global(.leaflet-popup-scrolled) { 543 | overflow: auto; 544 | border-bottom: 1px solid #ddd; 545 | border-top: 1px solid #ddd; 546 | } 547 | 548 | .leaflet :global(.leaflet-oldie .leaflet-popup-content-wrapper) { 549 | zoom: 1; 550 | } 551 | .leaflet :global(.leaflet-oldie .leaflet-popup-tip) { 552 | width: 24px; 553 | margin: 0 auto; 554 | 555 | -ms-filter: 'progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)'; 556 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 557 | } 558 | .leaflet :global(.leaflet-oldie .leaflet-popup-tip-container) { 559 | margin-top: -1px; 560 | } 561 | 562 | .leaflet :global(.leaflet-oldie .leaflet-control-zoom), 563 | .leaflet :global(.leaflet-oldie .leaflet-control-layers), 564 | .leaflet :global(.leaflet-oldie .leaflet-popup-content-wrapper), 565 | .leaflet :global(.leaflet-oldie .leaflet-popup-tip) { 566 | border: 1px solid #999; 567 | } 568 | 569 | /* div icon */ 570 | 571 | .leaflet :global(.leaflet-div-icon) { 572 | background: #fff; 573 | border: 1px solid #666; 574 | } 575 | 576 | /* Tooltip */ 577 | /* Base styles for the element that has a tooltip */ 578 | .leaflet :global(.leaflet-tooltip) { 579 | position: absolute; 580 | padding: 6px; 581 | background-color: #fff; 582 | border: 1px solid #fff; 583 | border-radius: 3px; 584 | color: #222; 585 | white-space: nowrap; 586 | -webkit-user-select: none; 587 | -moz-user-select: none; 588 | -ms-user-select: none; 589 | user-select: none; 590 | pointer-events: none; 591 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); 592 | } 593 | .leaflet :global(.leaflet-tooltip.leaflet-clickable) { 594 | cursor: pointer; 595 | pointer-events: auto; 596 | } 597 | .leaflet :global(.leaflet-tooltip-top:before), 598 | .leaflet :global(.leaflet-tooltip-bottom:before), 599 | .leaflet :global(.leaflet-tooltip-left:before), 600 | .leaflet :global(.leaflet-tooltip-right:before) { 601 | position: absolute; 602 | pointer-events: none; 603 | border: 6px solid transparent; 604 | background: transparent; 605 | content: ''; 606 | } 607 | 608 | /* Directions */ 609 | 610 | .leaflet :global(.leaflet-tooltip-bottom) { 611 | margin-top: 6px; 612 | } 613 | .leaflet :global(.leaflet-tooltip-top) { 614 | margin-top: -6px; 615 | } 616 | .leaflet :global(.leaflet-tooltip-bottom:before), 617 | .leaflet :global(.leaflet-tooltip-top:before) { 618 | left: 50%; 619 | margin-left: -6px; 620 | } 621 | .leaflet :global(.leaflet-tooltip-top:before) { 622 | bottom: 0; 623 | margin-bottom: -12px; 624 | border-top-color: #fff; 625 | } 626 | .leaflet :global(.leaflet-tooltip-bottom:before) { 627 | top: 0; 628 | margin-top: -12px; 629 | margin-left: -6px; 630 | border-bottom-color: #fff; 631 | } 632 | .leaflet :global(.leaflet-tooltip-left) { 633 | margin-left: -6px; 634 | } 635 | .leaflet :global(.leaflet-tooltip-right) { 636 | margin-left: 6px; 637 | } 638 | .leaflet :global(.leaflet-tooltip-left:before), 639 | .leaflet :global(.leaflet-tooltip-right:before) { 640 | top: 50%; 641 | margin-top: -6px; 642 | } 643 | .leaflet :global(.leaflet-tooltip-left:before) { 644 | right: 0; 645 | margin-right: -12px; 646 | border-left-color: #fff; 647 | } 648 | .leaflet :global(.leaflet-tooltip-right:before) { 649 | left: 0; 650 | margin-left: -12px; 651 | border-right-color: #fff; 652 | } 653 | 654 | /* GeoSearchInput */ 655 | 656 | .leaflet :global(.geocoder-control-input) { 657 | position: absolute; 658 | left: 0; 659 | top: 0; 660 | background-color: white; 661 | background-repeat: no-repeat; 662 | background-image: url('esri-leaflet-geocoder/dist/img/search.png'); 663 | background-size: 26px; 664 | border: none; 665 | padding: 0; 666 | text-indent: 6px; 667 | font-size: 13px; 668 | line-height: normal; 669 | height: auto; 670 | padding-top: 5px; 671 | padding-bottom: 5px; 672 | width: 100%; 673 | background-position: right center; 674 | cursor: pointer; 675 | box-sizing: border-box; 676 | } 677 | 678 | .leaflet :global(.geocoder-control-input-disabled) { 679 | background-color: #f4f4f4; 680 | background-image: url('esri-leaflet-geocoder/dist/img/search-disabled.png'); 681 | } 682 | 683 | .leaflet :global(.geocoder-control) { 684 | width: 26px; 685 | height: 26px; 686 | -webkit-transition: width 0.175s ease-in; 687 | -moz-transition: width 0.175s ease-in; 688 | -ms-transition: width 0.175s ease-in; 689 | -o-transition: width 0.175s ease-in; 690 | transition: width 0.175s ease-in; 691 | } 692 | 693 | .leaflet :global(.geocoder-control-expanded), 694 | .leaflet :global(.leaflet-touch .geocoder-control-expanded) { 695 | width: 275px; 696 | } 697 | 698 | .leaflet :global(.geocoder-control-input.geocoder-control-loading) { 699 | background-image: url('esri-leaflet-geocoder/dist/img/loading.gif'); 700 | background-size: 26px; 701 | } 702 | 703 | @media only screen and (min--moz-device-pixel-ratio: 2), 704 | only screen and (-o-min-device-pixel-ratio: 2 / 1), 705 | only screen and (-webkit-min-device-pixel-ratio: 2), 706 | only screen and (min-device-pixel-ratio: 2) { 707 | .leaflet :global(.geocoder-control-input) { 708 | background-image: url('esri-leaflet-geocoder/dist/img/search@2x.png'); 709 | } 710 | .leaflet :global(.geocoder-control-input-disabled) { 711 | background-image: url('esri-leaflet-geocoder/dist/img/search@2x-disabled.png'); 712 | } 713 | .leaflet :global(.geocoder-control-input.geocoder-control-loading) { 714 | background-image: url('esri-leaflet-geocoder/dist/img/loading@2x.gif'); 715 | } 716 | } 717 | 718 | .leaflet :global(.geocoder-control-input:focus) { 719 | outline: none; 720 | cursor: text; 721 | } 722 | 723 | .leaflet :global(.geocoder-control-input::-ms-clear) { 724 | display: none; 725 | } 726 | 727 | .leaflet :global(.geocoder-control-suggestions) { 728 | width: 100%; 729 | position: absolute; 730 | top: 26px; 731 | left: 0; 732 | margin-top: 10px; 733 | overflow: auto; 734 | display: none; 735 | } 736 | 737 | .leaflet :global(.geocoder-control-list + .geocoder-control-header) { 738 | border-top: 1px solid #d5d5d5; 739 | } 740 | 741 | .leaflet :global(.geocoder-control-header) { 742 | font-size: 10px; 743 | font-weight: 700; 744 | text-transform: uppercase; 745 | letter-spacing: 0.05em; 746 | color: #444; 747 | background: #f2f2f2; 748 | border-bottom: 1px solid #d5d5d5; 749 | display: block; 750 | padding: 0.5em; 751 | } 752 | 753 | .leaflet :global(.geocoder-control-list) { 754 | list-style: none; 755 | margin: 0; 756 | padding: 0; 757 | } 758 | 759 | .leaflet :global(.geocoder-control-suggestions .geocoder-control-suggestion) { 760 | font-size: 13px; 761 | padding: 7px; 762 | background: white; 763 | border-top: 1px solid #f1f1f1; 764 | white-space: nowrap; 765 | overflow: hidden; 766 | text-overflow: ellipsis; 767 | cursor: pointer; 768 | } 769 | 770 | .leaflet :global(.geocoder-control-suggestions .geocoder-control-suggestion:first-child) { 771 | border: none; 772 | } 773 | 774 | .leaflet 775 | :global(.geocoder-control-suggestions .geocoder-control-suggestion.geocoder-control-selected), 776 | .leaflet :global(.geocoder-control-suggestions .geocoder-control-suggestion:hover) { 777 | background: #7fdfff; 778 | border-color: #7fdfff; 779 | } 780 | 781 | .leaflet :global(.leaflet-right .geocoder-control-suggestions) { 782 | left: auto; 783 | right: 0; 784 | } 785 | 786 | .leaflet :global(.leaflet-right .geocoder-control-input) { 787 | left: auto; 788 | right: 0; 789 | } 790 | 791 | .leaflet :global(.leaflet-bottom .geocoder-control-suggestions) { 792 | margin-top: 0; 793 | top: 0; 794 | } 795 | 796 | .leaflet :global(.leaflet-touch .geocoder-control) { 797 | width: 34px; 798 | } 799 | 800 | .leaflet :global(.leaflet-touch .geocoder-control.geocoder-control-expanded) { 801 | width: 275px; 802 | } 803 | 804 | .leaflet :global(.leaflet-touch .geocoder-control-input) { 805 | height: 34px; 806 | line-height: 30px; 807 | background-size: 30px; 808 | } 809 | 810 | .leaflet :global(.leaflet-touch .geocoder-control-suggestions) { 811 | top: 30px; 812 | width: 271px; 813 | } 814 | 815 | .leaflet :global(.leaflet-oldie .geocoder-control-input) { 816 | width: 28px; 817 | height: 28px; 818 | } 819 | 820 | .leaflet :global(.leaflet-oldie .geocoder-control-expanded .geocoder-control-input) { 821 | width: auto; 822 | } 823 | 824 | .leaflet :global(.leaflet-oldie .geocoder-control-input), 825 | .leaflet :global(.leaflet-oldie .geocoder-control-suggestions) { 826 | border: 1px solid #999; 827 | } 828 | -------------------------------------------------------------------------------- /src/MapBoxAccessTokenMissing.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styles from './GeopointInput.css' 3 | 4 | const MapBoxAccessTokenMissing = () => ( 5 |
6 |

Error

7 |

Mapbox access token is missing from configuration.

8 |

9 | Please add it to the tileLayer.accessToken property in{' '} 10 | <sanity-studio>/config/leaflet-input.json. 11 |

12 |

13 | 17 | Read more 18 | {' '} 19 | about how to get hold of an access token, or consider specifying the URL of a different tile 20 | provider in the tileLayer.url property. 21 |

22 |
23 | ) 24 | 25 | export default MapBoxAccessTokenMissing 26 | --------------------------------------------------------------------------------