diff --git a/.flowconfig b/.flowconfig index cecae58751e..48b53a95fc1 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,6 +3,9 @@ .*/node_modules/stylelint/.* .*/node_modules/unflowify/.* .*/node_modules/flow-coverage-report/.* +.*/node_modules/babel-plugin-transform-react-remove-prop-types/.* +.*/node_modules/conventional-changelog-core/.* +.*/node_modules/htmltojsx/.* .*/test/unit/style-spec/fixture/invalidjson.input.json [options] diff --git a/.gitignore b/.gitignore index 29dcf10064d..e9f3c8383ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -/docs/api -/docs/style-spec/index.html -/_site +/docs/components/api.json /dist/mapbox-gl-dev.js /dist/mapbox-gl.js *.js.map @@ -17,3 +15,5 @@ test/integration/**/index*.html test/integration/**/actual.png test/integration/**/diff.png .eslintcache +_batfish_site +_batfish_tmp diff --git a/_config.mb-pages.yml b/_config.mb-pages.yml deleted file mode 100755 index 5e3a70043cd..00000000000 --- a/_config.mb-pages.yml +++ /dev/null @@ -1,10 +0,0 @@ -env: production -url: https://www.mapbox.com -api: https://www.mapbox.com/core -tileApi: https://api.mapbox.com -source: docs -permalink: /:categories/:title/ -baseurl: https://www.mapbox.com/mapbox-gl-js -excerpt_separator: "" -exclude: [dist] -future: true diff --git a/_config.yml b/_config.yml index d8c0fb1c30f..9765a6579fa 100755 --- a/_config.yml +++ b/_config.yml @@ -1,9 +1,3 @@ -url: https://122e4e-mapbox.global.ssl.fastly.net -api: https://122e4e-mapbox.global.ssl.fastly.net/core -tileApi: https://api-maps-staging.tilestream.net -source: docs -permalink: /:categories/:title/ -baseurl: /mapbox-gl-js -excerpt_separator: "" -mapboxglbase: /mapbox-gl-js/dist -future: true +# When Publisher runs Jekyll (which it always does), it will simply copy this +# source directory to _site. Then Publisher will copy _site to S3. +source: _batfish_site diff --git a/batfish.config.js b/batfish.config.js new file mode 100644 index 00000000000..2c12a095581 --- /dev/null +++ b/batfish.config.js @@ -0,0 +1,51 @@ +const webpack = require('webpack'); + +module.exports = () => { + const config = { + siteBasePath: '/mapbox-gl-js', + siteOrigin: 'https://www.mapbox.com', + pagesDirectory: `${__dirname}/docs/pages`, + stylesheets: [ + `${__dirname}/docs/components/site.css`, + `${__dirname}/docs/components/prism_highlight.css`, + `${__dirname}/vendor/dotcom-page-shell/page-shell-styles.css` + ], + applicationWrapperPath: `${__dirname}/docs/components/application-wrapper.js`, + webpackLoaders: [ + // Use raw loader to get the HTML string contents of examples + { + test: /\.html$/, + use: 'raw-loader' + } + ], + ignoreWithinPagesDirectory: ['example/*.html'], + webpackPlugins: [ + // Make environment variables available within JS that Webpack compiles. + new webpack.DefinePlugin({ + // DEPLOY_ENV is used in config to pick between local/production. + 'process.env.DEPLOY_ENV': `"${process.env.DEPLOY_ENV}"` + }) + ], + inlineJs: [ + { + filename: `${__dirname}/vendor/dotcom-page-shell/page-shell-script.js` + } + ], + dataSelectors: { + examples: ({pages}) => { + return pages + .filter(({path, frontMatter}) => /\/example\//.test(path) && frontMatter.tags) + .map(({frontMatter}) => frontMatter); + } + } + }; + + // Local builds treat the `dist` directory as static assets, allowing you to test examples against the + // local branch build. Non-local builds ignore the `dist` directory, and examples load assets from the CDN. + config.unprocessedPageFiles = ['dist/**/*.*']; + if (process.env.DEPLOY_ENV !== 'local') { + config.ignoreWithinPagesDirectory.push('dist/**/*.*'); + } + + return config; +}; diff --git a/convert-examples.js b/convert-examples.js new file mode 100644 index 00000000000..9fb89f59bdc --- /dev/null +++ b/convert-examples.js @@ -0,0 +1,41 @@ +const fs = require('fs'); +const matter = require('gray-matter'); + +fs.readdirSync(`examples`).forEach((file) => { + if (file[0] === '.') { + return; + } + + const name = /\d\d\d\d-\d\d-\d\d-(.*)\.html$/.exec(file)[1]; + const example = matter(fs.readFileSync(`examples/${file}`, 'utf8')); + + fs.writeFileSync(`docs/pages/example/${name}.html`, example.content); + + delete example.data.layout; + delete example.data.category; + delete example.data.permalink; + + example.data.pathname = `/mapbox-gl-js/example/${name}/`; + + fs.writeFileSync(`docs/pages/example/${name}.js`, +`/*${matter.stringify('', example.data).slice(0, -2)}*/ +import Example from '../../components/example'; +import html from './${name}.html'; +export default Example(html); +`) +}); + +fs.readdirSync(`redirects`).forEach((file) => { + if (file[0] === '.') { + return; + } + + const name = /\d\d\d\d-\d\d-\d\d-(.*)\.html$/.exec(file)[1]; + const example = matter(fs.readFileSync(`redirects/${file}`, 'utf8')); + + fs.writeFileSync(`docs/pages/example/${name}.js`, + `import Redirect from '../../components/redirect'; +import {prefixUrl} from '@mapbox/batfish/modules/prefix-url'; +export default Redirect(prefixUrl('${example.data.redirect}')); +`) +}); diff --git a/docs/README.md b/docs/README.md index 0d9aa18cf62..4f5080905ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,14 +18,15 @@ API documentation is written as [JSDoc comments](http://usejsdoc.org/) and proce ## Writing Examples -Examples are written as Jekyll posts in `docs/_posts/examples`. The Jekyll front matter should include the following items: +Examples are written as [Batfish](https://github.com/mapbox/batfish) pages in `docs/pages/example`. Each example requires two files: an `.html` file containing the source +code for the example, and a `.js` file containing example boilerplate and front matter. The front matter should include the following items: -* `layout`: `example` -* `category`: `example` * `title`: A short title for the example in **sentence case** as a **verb phrase** * `description`: A one sentence description of the example +* `tags`: An array of tags for the example, which determine the sections it is listed in in the sidebar navigation +* `pathname`: The relative path of the example, including leading `/mapbox-gl-js/example/` path -In the post body, write the HTML and JavaScript constituting the example. +In the `.html` file, write the HTML and JavaScript constituting the example. * Use **4 space indentation**. Exception: do not add an initial level of indentation to code within ` - -{% endhighlight html %}{% endcopyable %} - -
Include the following code in the <body>
of your HTML file.
As a mitigation for Cross-Site Scripting and other types of web security vulnerabilities, you may use a - Content Security Policy (CSP) - to specify security policies for your website. If you do, Mapbox GL JS requires the following CSP - directives:
-
-child-src blob: ;
-img-src data: blob: ;
-script-src 'unsafe-eval' ;
-
-
-Requesting styles from Mapbox or other services will require additional
- directives. For Mapbox, you can use this connect-src
directive:
-connect-src https://*.tiles.mapbox.com https://api.mapbox.com
-
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
deleted file mode 100644
index f40fde28449..00000000000
--- a/docs/_layouts/default.html
+++ /dev/null
@@ -1,139 +0,0 @@
-
-
-
-
-{% if page.prehead %}{{page.prehead}}{% endif %}
-{% if page.description %}{% endif %}
-Mapbox GL JS is a JavaScript library that uses WebGL to render interactive maps - from vector tiles and Mapbox styles. - It is part of the Mapbox GL ecosystem, which includes Mapbox Mobile, a compatible renderer written in C++ with bindings - for desktop and mobile platforms. To see what new features our team is working on, take a look at our roadmap.
-Extends <%= section.augments.map(function(tag) { return autolink(tag.name); }).join(', ') %>.
- <% } %> - - <% if (section.kind === 'class' && !section.interface) { %> -(<%= formatType(param.type) %><% if (param.default) { %>
- (default <%- param.default %>
)
- <% } %>)
<%= md(param.description, true) %>
- Name | -Description | -
<%- property.name %> <%= formatType(property.type) %>
- <% if (property.default) { %>
- (default <%- property.default %> )
- <% } %> |
- <%= md(property.description, true) %> | -
(<%= formatType(property.type) %>)
- <% if (property.default) { %>
- (default <%- property.default %>
)
- <% } %><% if (property.description) {
- %>: <%= md(property.description, true) %><%
- } %>
- <% if (property.properties) { %>
- <%- name%>
<%= formatType(property.type) %>
- <% if (property.default) { %>
- (default <%- property.default %>
)
- <% } %>
- <%= md(property.description) %><%= formatType(ret.type) %>
<% if (ret.description) { %>:
- <%= md(ret.description, true) %>
- <% }%>
- <% }) %>
- <% } %>
-
- <% if (section.throws) { %>
- <%= md(example.caption) %>
<% } %> -<%= highlight(example.description) %>- <% }) %> - <% } %> - - <% if (section.members.static && section.members.static.length) { %> -
+}
+
+export function highlightMarkup(code) {
+ return prismHighlight(code, 'markup');
+}
+
+export function highlightJavascript(code) {
+ return prismHighlight(code, 'javascript');
+}
+
+export function highlightJSON(code) {
+ return prismHighlight(code, 'json');
+}
+
+export function highlightShell(code) {
+ return {code}
+}
diff --git a/docs/components/quickstart.js b/docs/components/quickstart.js
new file mode 100644
index 00000000000..423f12eb33d
--- /dev/null
+++ b/docs/components/quickstart.js
@@ -0,0 +1,149 @@
+import React from 'react';
+import {prefixUrl} from '@mapbox/batfish/modules/prefix-url';
+import urls from './urls';
+import {version} from '../../package.json';
+import {highlightJavascript, highlightMarkup, highlightShell} from './prism_highlight';
+import Copyable from './copyable';
+
+class QuickstartCDN extends React.Component {
+ render() {
+ return (
+ Include the JavaScript and CSS files in the <head>
of your HTML file.
Include the following code in the <body>
of your HTML file.
Install the npm package.
+ {highlightShell(`npm install --save mapbox-gl`)} + +Include the CSS file in the <head>
of your HTML file.
Include the following code in the <body>
of your HTML file.
Mapbox GL JS is a JavaScript library that uses WebGL to render interactive maps + from vector tiles and Mapbox styles. + It is part of the Mapbox GL ecosystem, which includes Mapbox Mobile, a compatible renderer written in C++ with bindings + for desktop and mobile platforms. To see what new features our team is working on, take a look at our roadmap.
+ +As a mitigation for Cross-Site Scripting and other types of web security vulnerabilities, you may use + a Content Security Policy (CSP) to + specify security policies for your website. If you do, Mapbox GL JS requires the following CSP + directives:
+{`child-src blob: ;\nimg-src data: blob: ;\nscript-src 'unsafe-eval' ;`}
+
+ Requesting styles from Mapbox or other services will require additional
+ directives. For Mapbox, you can use this connect-src
directive:
{`connect-src https://*.tiles.mapbox.com https://api.mapbox.com`}
+ Extends {section.augments.map((tag, i) => + )}.
} + + {section.kind === 'class' && !section.interface && + } + + {section.version &&({formatType(param.type)})
+ {param.default && {'('}default {param.default}
{')'}}
+ {md(param.description, true)}
+ Name | +Description | +
+ {property.name}
+ {formatType(property.type)}
+ {property.default && {'('}default {property.default} {')'}}
+ |
+ {md(property.description, true)} | +
({formatType(property.type)})
+ {property.default && {'('}default {property.default}
{')'}}
+ {property.description && : {md(property.description, true)}}
+ {property.properties &&
+ {property.name}
{formatType(property.type)}
+ {property.default && {'('}default {property.default}
{')'}}
+ {md(property.description)}
+ {formatType(ret.type)}
+ {ret.description && : {md(ret.description, true)}}
+ {md(example.caption)}
} + {highlightJavascript(example.description)} +The GL JS team is focused on making our priorities transparent and + reliable. Below is a list of which major projects and features are currently in + active development, upcoming, or we are thinking about long-term. Each item includes + links to the relevant issues and pull requests on GitHub.
+This roadmap is updated weekly on Tuesdays. The roadmap does not + include bug fixes, and features that take less than a day to develop. Due to the + pace at which GL JS is being developed, we are unable to confidently estimate which + release version a feature will ship with.
+#{issue}
)}
+ {item.project &&
+ project#{item.project}
}
+ SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
{md(key)} | +{this.support(entry, 'js')} | +{this.support(entry, 'android')} | +{this.support(entry, 'ios')} | +{this.support(entry, 'macos')} | +
A Mapbox style is a document that defines the visual appearance of a map: what data to + draw, the order to draw it in, and how to style the data when drawing it. A style + document is a JSON object with specific root level + and nested properties. This specification defines and describes these properties.
+The intended audience of this specification includes:
+Developers using the Mapbox iOS SDK or Mapbox + macOS SDK should consult the iOS SDK API reference for platform-appropriate + documentation of style-related features.
+Root level properties of a Mapbox style specify the map's layers, tile sources and other + resources, and default values for the initial camera position when not specified + elsewhere.
+
+ A style's light
property provides global light source for that style.
+
+ Sources supply data to be shown on the map. The type of source is specified by the
+ "type"
property, and must be one of {sourceTypes.map((t, i) => {t}).reduce((prev, curr) => [prev, ', ', curr])}.
+ Adding a source
+ won't immediately make data appear on the map because sources don't contain
+ styling details like color or width. Layers refer
+ to a source and give it a visual representation. This makes it possible
+ to style the same source in different ways, like differentiating between
+ types of roads in a highways layer.
+
+ Tiled sources (vector and raster) must specify + their details in terms of the TileJSON + specification. + This can be done in several ways: +
+"tiles"
, "minzoom"
, and
+ "maxzoom"
directly in the source:
+ "url"
to a TileJSON resource:
+ "{`{bbox-epsg-3857}`}"
+ replacement token to supply the bbox
parameter.
+ {highlightJSON(`
+ "wms-imagery": {
+ "type": "raster",
+ "tiles": [
+ 'http://a.example.com/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=example'
+ ],
+ "tileSize": 256
+ }`)}
+
+ A vector tile source. Tiles must be in Mapbox
+ Vector Tile format. All geometric coordinates in vector tiles must be
+ between -1 * extent
and (extent * 2) - 1
inclusive.
+ All layers that use a vector source must specify a "source-layer"
+ value.
+ For vector tiles hosted by Mapbox, the "url"
value should be of the
+ form mapbox://mapid
.
+
SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 | +>= 2.0.1 | +>= 2.0.0 | +>= 0.1.0 | +
+ A raster tile source. For raster tiles hosted by Mapbox, the "url"
value should be of the
+ form mapbox://mapid
.
+
SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 | +>= 2.0.1 | +>= 2.0.0 | +>= 0.1.0 | +
+ A GeoJSON source. Data must be provided via a "data"
+ property, whose value can be a URL or inline GeoJSON.
+
+ This example of a GeoJSON source refers to an external GeoJSON document via its URL. The + GeoJSON document must be on the same domain or accessible using CORS. +
+SDK Requirements | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 | +>= 2.0.1 | +>= 2.0.0 | +>= 0.1.0 | +
clustering | +>= 0.14.0 | +>= 4.2.0 | +>= 3.4.0 | +>= 0.3.0 | +
+ An image source. The "url"
value contains the image location.
+
+ The "coordinates"
array contains [longitude, latitude]
pairs for the image
+ corners listed in clockwise order: top left, top right, bottom right, bottom left.
+
SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 | +Not yet supported | +Not yet supported | +Not yet supported | +
+ A video source. The "urls"
value is an array. For each URL in the array,
+ a video element source will
+ be created, in order to support same media in multiple formats supported by different browsers.
+
+ The "coordinates"
array contains [longitude, latitude]
pairs for the video
+ corners listed in clockwise order: top left, top right, bottom right, bottom left.
+
SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 | +Not yet supported | +Not yet supported | +Not yet supported | +
+ A canvas source. The "canvas"
value is the ID of the canvas element in the document.
+
+ The "coordinates"
array contains [longitude, latitude]
pairs for the video
+ corners listed in clockwise order: top left, top right, bottom right, bottom left.
+
+ If an HTML document contains a canvas such as this: +
++ the corresponding canvas source would be specified as follows: +
+SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.32.0 | +Not supported | +Not supported | +Not supported | +
+ A style's sprite
property supplies a URL template for loading small images to use in
+ rendering background-pattern
, fill-pattern
, line-pattern
,
+ and icon-image
style properties.
+
+ A valid sprite source must supply two types of files: +
+width
and
+ height
properties) and pixel ratio (pixelRatio
) of the image and its location within
+ the sprite (x
and y
). For example, a sprite containing a single image might have the
+ following index file contents:
+ "icon-image": "poi"
, or with the tokenized value "icon-image": "{`{icon}`}"
and vector
+ tile features with a icon
property with the value poi
.
+
+ Mapbox SDKs will use the value of the sprite
property in the style to generate the URLs for
+ loading both files. First, for both file types, it will append @2x
to the URL on high-DPI devices.
+ Second, it will append a file extension: .json
for the index file, and .png
for the
+ image file. For example, if you specified "sprite": "https://example.com/sprite"
, renderers would
+ load https://example.com/sprite.json
and https://example.com/sprite.png
, or
+ https://example.com/sprite@2x.json
and https://example.com/sprite@2x.png
.
+
+ If you are using Mapbox Studio, you will use prebuilt sprites provided by Mapbox, or you can upload custom SVG + images to build your own sprite. In either case, the sprite will be built automatically and supplied by Mapbox + APIs. If you want to build a sprite by hand and self-host the files, you can use + spritezero-cli, a command line utility that builds Mapbox + GL compatible sprite PNGs and index files from a directory of SVGs. +
+
+ A style's glyphs
property provides a URL template for loading signed-distance-field glyph sets in PBF format.
+
+ This URL template should include two tokens: +
+{`{fontstack}`}
+ When requesting glyphs, this token is replaced with a comma separated list of fonts from a font
+ stack specified in the text-font
property of
+ a symbol layer.
+ {`{range}`}
+ When requesting glyphs, this token is replaced with a range of 256 Unicode code points. For example,
+ to load glyphs for the Unicode Basic Latin and
+ Basic Latin-1 Supplement blocks, the range would be 0-255
. The actual ranges that
+ are loaded are determined at runtime based on what text needs to be displayed.
+
+ A style's transition
property provides global transition defaults for that style.
+
+ A style's layers
property lists all of the layers available in that style. The type of
+ layer is specified by the "type"
property, and must be one of {layerTypes.map((t, i) => {t}).reduce((prev, curr) => [prev, ', ', curr])}.
+
+ Except for layers of the background type, each layer needs + to refer to a source. Layers take the data that they get from a source, + optionally filter features, and then define how those features are + styled. +
+
+ Layers have two sub-properties that determine how data from that layer is rendered: layout
and
+ paint
properties.
+
+ Layout properties appear in the layer's "layout"
object. They are applied early in the
+ rendering process and define how data for that layer is passed to the GPU. Changes to a layout property
+ require an asynchronous "layout" step.
+
+ Paint properties are applied later in the rendering process. Paint properties appear in the layer's
+ "paint"
object. Changes to a paint property are cheap and happen synchronously.
+
Key: + supports all interpolation types + supports "step" interpolation only + transitionable +
+A Mapbox style contains values of various types, most commonly as values for the style properties of a layer.
+ +
+ Colors are written as JSON strings in a variety of permitted formats: HTML-style hex values, rgb, rgba, hsl, and hsla. Predefined HTML colors names, like yellow
and blue
, are also permitted.
+
Especially of note is the support for hsl, which can be easier to reason about than rgb().
+One of a fixed list of string values. Use quotes around values.
+ {highlightJSON(` + { + "text-transform": "uppercase" + }`)} +A string is basically just text. In Mapbox styles, you're going to put it in quotes. Strings can be anything, though pay attention to the case of text-field
- it actually will refer to features, which you refer to by putting them in curly braces, as seen in the example below.
Boolean means yes or no, so it accepts the values true
or false
.
A number value, often an integer or floating point (decimal number). Written without quotes.
+ {highlightJSON(` + { + "text-size": 24 + }`)} +Arrays are comma-separated lists of one or more numbers in a specific + order. For example, they're used in line dash arrays, in which the numbers specify intervals of line, break, and line again.
+ {highlightJSON(` + { + "line-dasharray": [2, 4] + }`)} +The value for any layout property, paint property, or filter may be specified as an expression. + Expressions define how one or more feature + property values and/or the current zoom level are combined using + logical, mathematical, string, or color operations to produce the + appropriate style property value or filter decision.
+ +SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
layout and paint properties |
+ >= 0.41.0 | +Not yet supported | +Not yet supported | +Not yet supported | +
filter |
+ >= 0.41.0 | +Not yet supported | +Not yet supported | +Not yet supported | +
Mapbox GL JS expressions uses a Lisp-like syntax, represented using JSON arrays. Expressions follow this format:
+The expression_name
is the name of a specific expression, e.g. '*'
or 'case'
. Each argument_i
is either
+ a literal value (a string, number, boolean, or null
), or else another
+ expression in the array form above.
A property expression is + any expression defined using an expression that includes a reference to feature property + data. Property expressions allow the appearance of a feature to change with its + properties. They can be used to visually differentate types of features within the same + layer or create data visualizations.
+ +In this example ["get", "temperature"]
uses 'get'
to look up
+ the "temperature"
property of each feature. That value is then used in the 'rgb'
expression to define a color in terms
+ of its red, green, and blue components.
A zoom expression is any
+ expression defined using an expression that includes ["zoom"]
. Such
+ expressions allow the the appearance of a layer to change with the map’s zoom level.
+ Zoom expressions can be used to create the illusion of depth and control data density.
+
This example uses a 'curve'
expression to
+ define a linear relationship between zoom level and circle size using a set of
+ input-output pairs. In this case, the expression indicates that the circle radius should
+ be 1 pixel when the zoom level is 5, and 2 pixels when the zoom is 10. (See the 'curve' documentation
for more
+ details.)
Note that any zoom expression used in a layout or paint property must be of the following form:
+ +Or:
+ +That is, in layout or paint properties, ["zoom"]
may only appear as the
+ input to an outer curve, and may not appear anywhere
+ else in the expression.
Combining zoom and property expressions allows a layer's or appearance to change with + both the zoom level and each feature's properties.
+ +There is an important difference between layout and paint properties in
+ the way that expressions are evaluated. Paint properties are re-evaluated whenever the
+ zoom level changes, even fractionally. The rendered value of a paint property will
+ change, for example, as the map moves between zoom levels 4.1
and
+ 4.6
. Layout properties, on the other hand, are evaluated only once for each
+ integer zoom level. To continue the prior example: the rendering of a layout property
+ will not change between zoom levels 4.1
and 4.6
, no
+ matter what stops are specified; but at zoom level 5
, the expression will
+ be re-evaluated, and the property's rendered value will change. (You can include
+ fractional zoom levels in a layout property zoom expression, and it will affect the
+ generated values; but, still, the rendering will only change at integer zoom levels.)
+
The expressions in this section are provided for the purpose of + testing for and converting between different data types like strings, + numbers, and boolean values.
+Often, such tests and conversions are
+ unnecessary, but they may be necessary in some expressions where the
+ type of a certain sub-expression is ambiguous. They can also be
+ useful in cases where your feature data has inconsistent types; for
+ example, you could use to-number
to make sure that
+ values like "1.5"
(instead of 1.5
) are
+ treated as numeric values.
+
+ The expressions in this section can be used to add conditional
+ logic to your styles. For example, the 'case'
expression
+ provides basic "if/then/else" logic, and 'match'
allows you to
+ map specific values of an input expression to different output
+ expressions.
+
The value for any layout or paint property may be specified as a + function. Functions allow you to make the appearance of a map feature + change with the current zoom level and/or the feature's properties.
+SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 | +>= 2.0.1 | +>= 2.0.0 | +>= 0.1.0 | +
property |
+ >= 0.18.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
type |
+ >= 0.18.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
exponential type |
+ >= 0.18.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
interval type |
+ >= 0.18.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
categorical type |
+ >= 0.18.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
identity type |
+ >= 0.26.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
default |
+ >= 0.33.0 | +>= 5.0.0 | +>= 3.5.0 | +>= 0.4.0 | +
colorSpace |
+ >= 0.26.0 | +Not yet supported | +Not yet supported | +Not yet supported | +
Zoom functions allow the appearance of a map feature to change with map’s zoom level. Zoom functions can be used to create the illusion of depth and control data density. Each stop is an array with two elements: the first is a zoom level and the second is a function output value.
+ +The rendered values of color, number, and array properties are intepolated between stops. Enum, boolean, and string property values cannot be intepolated, so their rendered values only change at the specified stops.
+ +There is an important difference between the way that zoom functions render for layout and paint properties. Paint properties are continuously re-evaluated whenever the zoom level changes, even fractionally. The rendered value of a paint property will change, for example, as the map moves between zoom levels 4.1
and 4.6
. Layout properties, on the other hand, are evaluated only once for each integer zoom level. To continue the prior example: the rendering of a layout property will not change between zoom levels 4.1
and 4.6
, no matter what stops are specified; but at zoom level 5
, the function will be re-evaluated according to the function, and the property's rendered value will change. (You can include fractional zoom levels in a layout property zoom function, and it will affect the generated values; but, still, the rendering will only change at integer zoom levels.)
Property functions allow the appearance of a map feature to change with its properties. Property functions can be used to visually differentate types of features within the same layer or create data visualizations. Each stop is an array with two elements, the first is a property input value and the second is a function output value. Note that support for property functions is not available across all properties and platforms at this time.
+ +Zoom-and-property functions allow the appearance of a map feature to change with both its properties and zoom. Each stop is an array with two elements, the first is an object with a property input value and a zoom, and the second is a function output value. Note that support for property functions is not yet complete.
+ +A filter selects specific features from a layer. A filter is defined using any boolean expression. In previous versions of the style specification, filters were defined using the deprecated syntax documented below:
+ +["has", key]
feature[key] exists
+ ["!has", key]
feature[key] does not exist
+ ["==", key, value]
equality: feature[key] = value
+ ["!=", key, value]
inequality: feature[key] ≠ value
+ [">", key, value]
greater than: feature[key] > value
+ [">=", key, value]
greater than or equal: feature[key] ≥ value
+ ["<", key, value]
less than: feature[key] < value
+ ["<=", key, value]
less than or equal: feature[key] ≤ value
+ ["in", key, v0, ..., vn]
set inclusion: feature[key] ∈ {`{`}v0, ..., vn{`}`}
+ ["!in", key, v0, ..., vn]
set exclusion: feature[key] ∉ {`{`}v0, ..., vn{`}`}
+ ["all", f0, ..., fn]
logical AND
: f0 ∧ ... ∧ fn
+ ["any", f0, ..., fn]
logical OR
: f0 ∨ ... ∨ fn
+ ["none", f0, ..., fn]
logical NOR
: ¬f0 ∧ ... ∧ ¬fn
+ + A key must be a string that identifies a feature property, or one of the following special keys: +
+"$type"
: the feature type. This key may be used with the "=="
,
+ "!="
, "in"
, and "!in"
operators. Possible values are
+ "Point"
, "LineString"
, and "Polygon"
."$id"
: the feature identifier. This key may be used with the "=="
,
+ "!="
, "has"
, "!has"
, "in"
,
+ and "!in"
operators.+ A value (and v0, ..., vn for set operators) must be a + string, number, or boolean to compare + the property value against. +
+ ++ Set membership filters are a compact and efficient way to test whether a + field matches any of multiple values. +
+ +
+ The comparison and set membership filters implement strictly-typed comparisons; for example, all of the
+ following evaluate to false: 0 < "1"
, 2 == "2"
, "true" in [true, false]
.
+
+ The "all"
, "any"
, and "none"
filter operators are
+ used to create compound filters. The values f0, ..., fn must be
+ filter expressions themselves.
+
+ This filter requires that the class
property of
+ each feature is equal to either "street_major", "street_minor",
+ or "street_limited".
+
+ The combining filter "all" takes the three other filters that
+ follow it and requires all of them to be true for a feature
+ to be included: a feature must have a class
equal
+ to "street_limited", its admin_level
must be greater
+ than or equal to 3, and its type cannot be Polygon. You could
+ change the combining filter to "any" to allow features matching
+ any of those criteria to be included - features that are Polygons,
+ but have a different class
value, and so on.
+
SDK Support | +Mapbox GL JS | +Android SDK | +iOS SDK | +macOS SDK | +
---|---|---|---|---|
basic functionality | +>= 0.10.0 deprecated >= 0.41.0 |
+ >= 2.0.1 | +>= 2.0.0 | +>= 0.1.0 | +
has /!has |
+ >= 0.19.0 | +>= 4.1.0 | +>= 3.3.0 | +>= 0.1.0 | +
The GL JS team is focused on making our priorities transparent and reliable. Below is a list of which major projects and features are currently in active development, upcoming, or we are thinking about long-term. Each item includes links to the relevant issues and pull requests on GitHub.
-This roadmap is updated weekly on Tuesdays. The roadmap does not include bug fixes, and features that take less than a day to develop. Due to the pace at which GL JS is being developed, we are unable to confidently estimate which release version a feature will ship with.
-#{{i}}
- {% endfor %}{% endif %}
- {% if item.project %}
- project#{{item.project}}
- {% endif %}
- A Mapbox style is a document that defines the visual appearance of a map: what data to draw, the order to draw it in, and how to style the data when drawing it. A style document is a JSON object with specific root level and nested properties. This specification defines and describes these properties.
-The intended audience of this specification includes: -
Developers using the Mapbox iOS SDK or Mapbox macOS SDK should consult the iOS SDK API reference for platform-appropriate documentation of style-related features.
-Root level properties of a Mapbox style specify the map's layers, tile sources and other resources, and default values for the initial camera position when not specified elsewhere.
-
- A style's light
property provides global light source for that style.
- <% if (ref.$root.light.example) { %>
-
- Sources supply data to be shown on the map. The type of source is specified by the "type"
property,
- and must be one of <%= source_types.join(', ') %>. Adding a source
- won't immediately make data appear on the map because sources don't contain
- styling details like color or width. Layers refer
- to a source and give it a visual representation. This makes it possible
- to style the same source in different ways, like differentiating between
- types of roads in a highways layer.
-
- Tiled sources (vector and raster) must specify - their details in terms of the TileJSON specification. - This can be done in several ways: -
-"tiles"
, "minzoom"
, and
- "maxzoom"
directly in the source:
- "url"
to a TileJSON resource:
- "{bbox-epsg-3857}"
- replacement token to supply the bbox
parameter.
-{% highlight json%}
-"wms-imagery": {
- "type": "raster",
- "tiles": [
- 'http://a.example.com/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=example'
- ],
- "tileSize": 256
-}
-{% endhighlight %}
-
- A vector tile source. Tiles must be in Mapbox
- Vector Tile format. All geometric coordinates in vector tiles must be between -1 * extent
and (extent * 2) - 1
inclusive. All layers that use a vector source must specify a "source-layer"
value.
- For vector tiles hosted by Mapbox, the "url"
value should be of the
- form mapbox://mapid
.
-
SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 | ->= 2.0.1 | ->= 2.0.0 | ->= 0.1.0 | -
- A raster tile source. For raster tiles hosted by Mapbox, the "url"
value should be of the
- form mapbox://mapid
.
-
SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 | ->= 2.0.1 | ->= 2.0.0 | ->= 0.1.0 | -
- A GeoJSON source. Data must be provided via a "data"
- property, whose value can be a URL or inline GeoJSON.
-
- This example of a GeoJSON source refers to an external GeoJSON document via its URL. The - GeoJSON document must be on the same domain or accessible using - CORS. -
-SDK Requirements | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 | ->= 2.0.1 | ->= 2.0.0 | ->= 0.1.0 | -
clustering | ->= 0.14.0 | ->= 4.2.0 | ->= 3.4.0 | ->= 0.3.0 | -
- An image source. The "url"
value contains the image location.
-
- The "coordinates"
array contains [longitude, latitude]
pairs for the image
- corners listed in clockwise order: top left, top right, bottom right, bottom left.
-
SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 | -Not yet supported | -Not yet supported | -Not yet supported | -
- A video source. The "urls"
value is an array. For each URL in the array,
- a video element source will
- be created, in order to support same media in multiple formats supported by different browsers.
-
- The "coordinates"
array contains [longitude, latitude]
pairs for the video
- corners listed in clockwise order: top left, top right, bottom right, bottom left.
-
SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 | -Not yet supported | -Not yet supported | -Not yet supported | -
- A canvas source. The "canvas"
value is the ID of the canvas element in the document.
-
- The "coordinates"
array contains [longitude, latitude]
pairs for the video
- corners listed in clockwise order: top left, top right, bottom right, bottom left.
-
- If an HTML document contains a canvas such as this: -
-- the corresponding canvas source would be specified as follows: -
-SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.32.0 | -Not supported | -Not supported | -Not supported | -
- A style's sprite
property supplies a URL template for loading small images to use in
- rendering background-pattern
, fill-pattern
, line-pattern
,
- and icon-image
style properties.
- <% if (ref.$root.sprite.example) { %>
-
- A valid sprite source must supply two types of files: -
-width
and
- height
properties) and pixel ratio (pixelRatio
) of the image and its location within
- the sprite (x
and y
). For example, a sprite containing a single image might have the
- following index file contents:
- "icon-image": "poi"
, or with the tokenized value "icon-image": "{icon}"
and vector
- tile features with a icon
property with the value poi
.
-
- Mapbox SDKs will use the value of the sprite
property in the style to generate the URLs for
- loading both files. First, for both file types, it will append @2x
to the URL on high-DPI devices.
- Second, it will append a file extension: .json
for the index file, and .png
for the
- image file. For example, if you specified "sprite": "https://example.com/sprite"
, renderers would
- load https://example.com/sprite.json
and https://example.com/sprite.png
, or
- https://example.com/sprite@2x.json
and https://example.com/sprite@2x.png
.
-
- If you are using Mapbox Studio, you will use prebuilt sprites provided by Mapbox, or you can upload custom SVG - images to build your own sprite. In either case, the sprite will be built automatically and supplied by Mapbox - APIs. If you want to build a sprite by hand and self-host the files, you can use - spritezero-cli, a command line utility that builds Mapbox - GL compatible sprite PNGs and index files from a directory of SVGs. -
-
- A style's glyphs
property provides a URL template for loading signed-distance-field glyph sets in PBF format.
- <% if (ref.$root.glyphs.example) { %>
-
{fontstack}
- When requesting glyphs, this token is replaced with a comma separated list of fonts from a font
- stack specified in the text-font
property of
- a symbol layer.
- {range}
- When requesting glyphs, this token is replaced with a range of 256 Unicode code points. For example,
- to load glyphs for the Unicode Basic Latin and
- Basic Latin-1 Supplement blocks, the range would be 0-255
. The actual ranges that
- are loaded are determined at runtime based on what text needs to be displayed.
-
- A style's transition
property provides global transition defaults for that style.
- <% if (ref.$root.transition.example) { %>
-
- A style's layers
property lists all of the layers available in that style. The type of
- layer is specified by the "type"
property, and must be one of <%= layer_types.join(', ') %>.
-
- Except for layers of the background type, each layer needs - to refer to a source. Layers take the data that they get from a source, - optionally filter features, and then define how those features are - styled. -
- <% if (ref.$root.layers.example) { %> -
- Layers have two sub-properties that determine how data from that layer is rendered: layout
and
- paint
properties.
-
- Layout properties appear in the layer's "layout"
object. They are applied early in the
- rendering process and define how data for that layer is passed to the GPU. Changes to a layout property
- require an asynchronous "layout" step.
-
- Paint properties are applied later in the rendering process. Paint properties appear in the layer's
- "paint"
object. Changes to a paint property are cheap and happen synchronously.
-
Key: - supports all interpolation types - supports "step" interpolation only - transitionable -
- -A Mapbox style contains values of various types, most commonly as values for the style properties of a layer.
- -
- Colors are written as JSON strings in a variety of permitted formats: HTML-style hex values, rgb, rgba, hsl, and hsla. Predefined HTML colors names, like yellow
and blue
, are also permitted.
-
Especially of note is the support for hsl, which can be easier to reason about than rgb().
-One of a fixed list of string values. Use quotes around values.
-{% highlight json %} -{ - "text-transform": "uppercase" -} -{% endhighlight %} -A string is basically just text. In Mapbox styles, you're going to put it in quotes. Strings can be anything, though pay attention to the case of text-field
- it actually will refer to features, which you refer to by putting them in curly braces, as seen in the example below.
Boolean means yes or no, so it accepts the values true
or false
.
A number value, often an integer or floating point (decimal number). Written without quotes.
-{% highlight json %} -{ - "text-size": 24 -} -{% endhighlight %} -Arrays are comma-separated lists of one or more numbers in a specific - order. For example, they're used in line dash arrays, in which the numbers specify intervals of line, break, and line again.
-{% highlight json %} -{ - "line-dasharray": [2, 4] -} -{% endhighlight %} -The value for any layout property, paint property, or filter may be specified as an - expression. Expressions define how one or more feature - property values and/or the current zoom level are combined using - logical, mathematical, string, or color operations to produce the - appropriate style property value or filter decision.
- -SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
layout and paint properties |
- >= 0.41.0 | -Not yet supported | -Not yet supported | -Not yet supported | -
filter |
- >= 0.41.0 | -Not yet supported | -Not yet supported | -Not yet supported | -
Mapbox GL JS expressions uses a Lisp-like syntax, represented using JSON arrays. Expressions follow this format:
-The expression_name
is the name of a specific expression, e.g. '*'
or 'case'
. Each argument_i
is either a literal value (a string, number, boolean, or null
), or else another expression in the array form above.
A property expression is any expression defined using an expression that includes a reference to feature property data. Property expressions allow the appearance of a feature to change with its properties. They can be used to visually differentate types of features within the same layer or create data visualizations.
- -In this example ["get", "temperature"]
uses 'get'
to look up the "temperature"
property of each feature. That value is then used in the 'rgb'
expression to define a color in terms of its red, green, and blue components.
-
-
A zoom expression is any expression defined using an expression that includes ["zoom"]
. Such expressions allow the the appearance of a layer to change with the map’s zoom level. Zoom expressions can be used to create the illusion of depth and control data density.
This example uses a 'curve'
expression to define a linear relationship between zoom level and circle size using a set of input-output pairs. In this case, the expression indicates that the circle radius should be 1 pixel when the zoom level is 5, and 2 pixels when the zoom is 10. (See the 'curve' documentation
for more details.)
-
-
Note that any zoom expression used in a layout or paint property must be of the following form:
- -Or:
- -That is, in layout or paint properties, ["zoom"]
may only appear as the input to an outer curve, and may not appear anywhere else in the expression.
Combining zoom and property expressions allows a layer's or appearance to change with both the zoom level and each feature's properties.
- -There is an important difference between layout and paint properties in the way that expressions are evaluated. Paint properties are re-evaluated whenever the zoom level changes, even fractionally. The rendered value of a paint property will change, for example, as the map moves between zoom levels 4.1
and 4.6
. Layout properties, on the other hand, are evaluated only once for each integer zoom level. To continue the prior example: the rendering of a layout property will not change between zoom levels 4.1
and 4.6
, no matter what stops are specified; but at zoom level 5
, the expression will be re-evaluated, and the property's rendered value will change. (You can include fractional zoom levels in a layout property zoom expression, and it will affect the generated values; but, still, the rendering will only change at integer zoom levels.)
- The expressions in this section are provided for the purpose of - testing for and converting between different data types like strings, - numbers, and boolean values.
-Often, such tests and conversions are
- unnecessary, but they may be necessary in some expressions where the
- type of a certain sub-expression is ambiguous. They can also be
- useful in cases where your feature data has inconsistent types; for
- example, you could use to-number
to make sure that
- values like "1.5"
(instead of 1.5
) are
- treated as numeric values.
-
- The expressions in this section can be used to add conditional
- logic to your styles. For example, the 'case'
expression
- provides basic "if/then/else" logic, and 'match'
allows you to
- map specific values of an input expression to different output
- expressions.
-
The value for any layout or paint property may be specified as a function. Functions allow you to make the appearance of a map feature change with the current zoom level and/or the feature's properties.
-SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 | ->= 2.0.1 | ->= 2.0.0 | ->= 0.1.0 | -
property |
- >= 0.18.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
type |
- >= 0.18.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
exponential type |
- >= 0.18.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
interval type |
- >= 0.18.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
categorical type |
- >= 0.18.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
identity type |
- >= 0.26.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
default |
- >= 0.33.0 | ->= 5.0.0 | ->= 3.5.0 | ->= 0.4.0 | -
colorSpace |
- >= 0.26.0 | -Not yet supported | -Not yet supported | -Not yet supported | -
Zoom functions allow the appearance of a map feature to change with map’s zoom level. Zoom functions can be used to create the illusion of depth and control data density. Each stop is an array with two elements: the first is a zoom level and the second is a function output value.
- -The rendered values of color, number, and array properties are intepolated between stops. Enum, boolean, and string property values cannot be intepolated, so their rendered values only change at the specified stops.
- -There is an important difference between the way that zoom functions render for layout and paint properties. Paint properties are continuously re-evaluated whenever the zoom level changes, even fractionally. The rendered value of a paint property will change, for example, as the map moves between zoom levels 4.1
and 4.6
. Layout properties, on the other hand, are evaluated only once for each integer zoom level. To continue the prior example: the rendering of a layout property will not change between zoom levels 4.1
and 4.6
, no matter what stops are specified; but at zoom level 5
, the function will be re-evaluated according to the function, and the property's rendered value will change. (You can include fractional zoom levels in a layout property zoom function, and it will affect the generated values; but, still, the rendering will only change at integer zoom levels.)
Property functions allow the appearance of a map feature to change with its properties. Property functions can be used to visually differentate types of features within the same layer or create data visualizations. Each stop is an array with two elements, the first is a property input value and the second is a function output value. Note that support for property functions is not available across all properties and platforms at this time.
- -Zoom-and-property functions allow the appearance of a map feature to change with both its properties and zoom. Each stop is an array with two elements, the first is an object with a property input value and a zoom, and the second is a function output value. Note that support for property functions is not yet complete.
- -A filter selects specific features from a layer. A filter is defined using any boolean expression. In previous versions of the style specification, filters were defined using the deprecated syntax documented below:
- -["has", key]
feature[key] exists
- ["!has", key]
feature[key] does not exist
- ["==", key, value]
equality: feature[key] = value
- ["!=", key, value]
inequality: feature[key] ≠ value
- [">", key, value]
greater than: feature[key] > value
- [">=", key, value]
greater than or equal: feature[key] ≥ value
- ["<", key, value]
less than: feature[key] < value
- ["<=", key, value]
less than or equal: feature[key] ≤ value
- ["in", key, v0, ..., vn]
set inclusion: feature[key] ∈ {v0, ..., vn}
- ["!in", key, v0, ..., vn]
set exclusion: feature[key] ∉ {v0, ..., vn}
- ["all", f0, ..., fn]
logical AND
: f0 ∧ ... ∧ fn
- ["any", f0, ..., fn]
logical OR
: f0 ∨ ... ∨ fn
- ["none", f0, ..., fn]
logical NOR
: ¬f0 ∧ ... ∧ ¬fn
- - A key must be a string that identifies a feature property, or one of the following special keys: -
-"$type"
: the feature type. This key may be used with the "=="
,
- "!="
, "in"
, and "!in"
operators. Possible values are
- "Point"
, "LineString"
, and "Polygon"
."$id"
: the feature identifier. This key may be used with the "=="
,
- "!="
, "has"
, "!has"
, "in"
,
- and "!in"
operators.- A value (and v0, ..., vn for set operators) must be a - string, number, or boolean to compare - the property value against. -
- -- Set membership filters are a compact and efficient way to test whether a - field matches any of multiple values. -
- -
- The comparison and set membership filters implement strictly-typed comparisons; for example, all of the
- following evaluate to false: 0 < "1"
, 2 == "2"
, "true" in [true, false]
.
-
- The "all"
, "any"
, and "none"
filter operators are
- used to create compound filters. The values f0, ..., fn must be
- filter expressions themselves.
-
- This filter requires that the class
property of
- each feature is equal to either "street_major", "street_minor",
- or "street_limited".
-
- The combining filter "all" takes the three other filters that
- follow it and requires all of them to be true for a feature
- to be included: a feature must have a class
equal
- to "street_limited", its admin_level
must be greater
- than or equal to 3, and its type cannot be Polygon. You could
- change the combining filter to "any" to allow features matching
- any of those criteria to be included - features that are Polygons,
- but have a different class
value, and so on.
-
SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
basic functionality | ->= 0.10.0 deprecated >= 0.41.0 |
- >= 2.0.1 | ->= 2.0.0 | ->= 0.1.0 | -
has /!has |
- >= 0.19.0 | ->= 4.1.0 | ->= 3.3.0 | ->= 0.1.0 | -
SDK Support | -Mapbox GL JS | -Android SDK | -iOS SDK | -macOS SDK | -
---|---|---|---|---|
<%= md(key) %> | -<%- support(key, 'js') %> | -<%- support(key, 'android') %> | -<%- support(key, 'ios') %> | -<%- support(key, 'macos') %> | -