map
A mapboxgl wrapper.
const pickStyle = preview.querySelector('select')
const mapbox = preview.querySelector('tosi-map')
const here = preview.querySelector('button')
pickStyle.addEventListener('change', () => {
mapbox.mapStyle = pickStyle.value
})
function getUserGPSCoordinates() {
return new Promise((resolve) => {
// Check if geolocation is supported
if (!navigator.geolocation) {
console.log("Geolocation is not supported by this browser.");
resolve(null);
return;
}
// Request position with options
navigator.geolocation.getCurrentPosition(
// Success callback
(position) => {
resolve({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
},
// Error callback
(error) => {
console.log(`Error getting location: ${error.message}`);
resolve(null);
},
// Options
{
enableHighAccuracy: true, // Request high accuracy if available
timeout: 10000, // Time to wait for position (10 seconds)
maximumAge: 0 // Don't use cached position
}
);
});
}
here.addEventListener('click', async () => {
const location = await getUserGPSCoordinates()
if (location) {
mapbox.coords = `${location.latitude},${location.longitude},12`
}
})
// The demo token, base64'd — NOT a security measure, and it would be a bad one.
//
// Mapbox `pk.` tokens are PUBLIC BY DESIGN. Mapbox's own docs tell you to put them in your
// client-side JavaScript; that is what they are for, and this one has been in a public repo
// for years without incident. There is nothing here to protect.
//
// What this avoids is a FALSE POSITIVE. The literal `pk.` + base64 shape matches GitHub's
// published secret pattern, so the string in a doc example compiled into `dist/`, inlined
// into `iife.js`, and reached every adopter's sourcemap — and then GitHub push protection
// blocked THEM the first time they committed their built site (tosijs-ui#145). A wall with
// someone else's name on it, over a token that was never secret.
//
// Not a pattern to copy for anything that IS secret: `atob()` protects nothing from anyone,
// which is exactly why it suits a value that needs no protection and only needs to stop
// matching a regex.
//
// LINE comments, deliberately. A block comment inside a doc comment ends the DOC comment at
// its first close token, silently truncating the page and dropping the rest of the file into
// code. Note that this warning cannot spell the token out either, for the same reason —
// which is how it got written three times (tosijs-ui#142 reports the identical experience).
const DEMO_TOKEN = atob(
'cGsuZXlKMUlqb2ljRzlrY0dWeWMyOXVJaXdpWVNJNkltTnFjMkpsYldVMGJqQTFabVkwWVc1eWNIWm9kM1ZoYldjaWZRLmFydnFmcE9xTWdGWWtLZ1EzNVVTY0E='
)
mapbox.token = DEMO_TOKEN
<tosi-map
style="width: 100%; height: 100%"
coords="14.0093606,120.995083,17"
map-style="mapbox://styles/mapbox/streets-v12"
></tosi-map>
<select>
<option selected value="mapbox://styles/mapbox/streets-v12">Streets</option>
<option value="mapbox://styles/mapbox/satellite-v9">Satellite</option>
<option value="mapbox://styles/mapbox/light-v11">Light</option>
<option value="mapbox://styles/mapbox/dark-v11">Dark</option>
<option value="mapbox://styles/mapbox/outdoors-v12">Outdoors</option>
</select>
<button>
<tosi-icon icon="mapPin"></tosi-icon>
<span>Your Location</span>
</button>
.preview button {
position: absolute;
right: 10px;
top: 10px;
display: flex;
align-items: center;
gap: 5px;
}
.preview select {
position: absolute;
bottom: 10px;
right: 10px;
}
There's no need to learn new APIs or write wrappers, just access the element's map property
and use the standard mapbox APIs directly.
Form Integration
You need your own token. Get a public (pk.) one from
account.mapbox.com and set it as the token
attribute or the .token property. Restrict it to your domains while you are there — not
because it is secret (it is not; Mapbox tokens are public by design and belong in your
client-side code) but because it bills to whoever owns it.
The demos on this page assign a token programmatically, base64'd. That is not security and
would be a poor imitation of it — it stops the literal pk.eyJ… string matching GitHub's
published secret pattern, which is a false positive on a value that was never secret. It had
to stop matching because a doc example compiles into dist/, inlines into iife.js, and
lands in every adopter's sourcemap — so GitHub push protection blocked adopters the first
time they committed their built site (tosijs-ui#145). A wall with someone else's name on it.
<tosi-map> is form-associated, making it useful as a location picker in forms:
<form class="map-form">
<label>
<b>Select your location:</b>
<tosi-map
name="location"
style="width: 100%; height: 200px"
coords="40.7128,-74.0060,10"
></tosi-map>
</label>
<button type="submit">Submit Location</button>
<button type="reset">Reset</button>
<span class="output"></span>
</form>
.preview .map-form {
display: flex;
flex-direction: column;
gap: 10px;
}
.preview .map-form label {
display: flex;
flex-direction: column;
gap: 5px;
}
// Same public demo token as the example above — see the note about why it is base64'd.
preview.querySelector('tosi-map').token = atob(
'cGsuZXlKMUlqb2ljRzlrY0dWeWMyOXVJaXdpWVNJNkltTnFjMkpsYldVMGJqQTFabVkwWVc1eWNIWm9kM1ZoYldjaWZRLmFydnFmcE9xTWdGWWtLZ1EzNVVTY0E='
)
const form = preview.querySelector('.map-form')
form.addEventListener('submit', (e) => {
e.preventDefault()
const data = new FormData(form)
form.querySelector('.output').textContent = 'Location: ' + data.get('location')
})