diff --git a/packages/docs/components/MapboxMap/examples.md b/packages/docs/components/MapboxMap/examples.md index 10660f8d..ebb6232f 100644 --- a/packages/docs/components/MapboxMap/examples.md +++ b/packages/docs/components/MapboxMap/examples.md @@ -4,7 +4,7 @@ title: MapboxMap examples # Examples -Every example below registers a single `MapboxMap` component — the child components (markers, popups, controls, sources, layers, images, clusters) are resolved automatically once the map is loaded. Each example loads the [Mapbox GL stylesheet](./#installation) from a CDN and picks a Mapbox style through the `map-options` option, which forwards any [`Map` option](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters) to mapbox-gl. Replace the access token with your own [access token](https://docs.mapbox.com/help/getting-started/access-tokens/); the token used here is a public, restricted demo token. +Every component in the family is self-registering, so each example registers exactly the components it uses — `MapboxMap` on its own for a bare map, plus the child components it declares (markers, popups, controls, sources, layers, images, clusters). Each child resolves its parent `MapboxMap` on its own once mounted. Each example loads the [Mapbox GL stylesheet](./#installation) from a CDN and picks a Mapbox style through the `map-options` option, which forwards any [`Map` option](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters) to mapbox-gl. Replace the access token with your own [access token](https://docs.mapbox.com/help/getting-started/access-tokens/); the token used here is a public, restricted demo token. Child components that should not take part in the normal document flow (markers, popups, controls, sources, layers, images, clusters) are wrapped in a `hidden` element: their markup is only used as a declarative definition, the actual rendering happens on the map canvas. @@ -102,7 +102,7 @@ Register images against the map sprite so they can be referenced from a symbol l ## Cluster -The `MapboxCluster` component displays a clustered GeoJSON source, wiring the cluster circles, the cluster count labels and the unclustered points, together with the click-to-zoom interaction. Its `data` option takes the URL of a `.geojson` file, or you can pass inline GeoJSON through a [`geojson` script ref](#inline-geojson-cluster). The example below passes the points inline; click a cluster to zoom in and split it. +The `MapboxCluster` component is a clustered GeoJSON **source driver**: it derives its source from the `MapboxClusterItem`s in its subtree, wiring the cluster circles, the cluster count labels and the unclustered points, together with the click-to-zoom interaction. Each item is at once a list entry and a map feature — the same markup drives both. The example below declares a hidden list of items; click a cluster to zoom in and split it. -### Inline GeoJSON cluster {#inline-geojson-cluster} +### Items drive the source {#cluster-items} -Instead of a `data` URL, pass the GeoJSON inline through a ` + ``` +The cluster reports a click on an unclustered point through its `item-click` event but never selects or flies on its own. To turn this into a full "find a store near you" experience — selection, popups, viewport filtering and address search — wrap the cluster in a [`StoreLocator`](/components/StoreLocator/) orchestrator. + ## Listening to map events The `MapboxMap` component re-emits the Mapbox map events. Listen to them from a parent component by defining `on` methods — for example `onMapboxMapClick` or `onMapboxMapMapLoad` for the custom `map-load` event. diff --git a/packages/docs/components/MapboxMap/index.md b/packages/docs/components/MapboxMap/index.md index 96ac9328..4bf25245 100644 --- a/packages/docs/components/MapboxMap/index.md +++ b/packages/docs/components/MapboxMap/index.md @@ -4,7 +4,7 @@ badges: [JS] # MapboxMap -The `MapboxMap` component and its family let you build [Mapbox GL](https://docs.mapbox.com/mapbox-gl-js/) maps declaratively, straight from your HTML, with [js-toolkit](https://js-toolkit.studiometa.dev/) — no Vue, no framework runtime. A `MapboxMap` element owns the underlying Mapbox `Map` instance, and every other component (markers, popups, controls, sources, layers, images, clusters) is authored as a child element that registers itself against that map once it is loaded. +The `MapboxMap` component and its family let you build [Mapbox GL](https://docs.mapbox.com/mapbox-gl-js/) maps declaratively, straight from your HTML, with [js-toolkit](https://js-toolkit.studiometa.dev/). A `MapboxMap` element owns the underlying Mapbox `Map` instance, and every other component (markers, popups, controls, sources, layers, images, clusters) is authored as a child element that registers itself against that map once it is loaded. These components are published in the standalone [`@studiometa/ui-mapbox`](https://www.npmjs.com/package/@studiometa/ui-mapbox) package and replace the [`@studiometa/vue-mapbox-gl`](https://www.npmjs.com/package/@studiometa/vue-mapbox-gl) library. If you are coming from the Vue library, read the [migration guide](/migration-guides/vue-mapbox-gl/). @@ -39,7 +39,7 @@ You will also need a [Mapbox access token](https://docs.mapbox.com/help/getting- ## Usage -Register the `MapboxMap` component with [`registerComponent`](https://js-toolkit.studiometa.dev/api/helpers/registerComponent.html). All child components are declared internally, so you only ever register `MapboxMap` itself — they are resolved automatically once the map is loaded. +[Register](/guide/usage/#registering-components) each component your page uses: a bare map with just a `container` needs only `MapboxMap`, and each marker, popup, control, source, layer, image or cluster you declare must be registered too. Registration order does not matter, because a child registered before its `MapboxMap` still wires up once the map connects. Author the map with a root `MapboxMap` element holding a `container` ref, and give it a size through CSS. @@ -69,22 +69,22 @@ registerComponent(MapboxMap); ::: -::: tip Options are read once at mount -Component options are read a single time when the map mounts and are **not** reactive, unlike the Vue library. To move the map or update its data afterwards, call the underlying Mapbox objects directly (e.g. `instance.map.setCenter(...)`). See the [reactivity note](./js-api#reactivity-and-updates) for details. -::: +`mapbox-gl` is a heavy dependency (~230 kB gzipped, more with the geocoder), so the recommended default is to register each component lazily — see [Lazy loading](#lazy-loading) below. ## Lazy loading -`mapbox-gl` is a heavy dependency (~230 kB gzipped, more with the geocoder). Registering `MapboxMap` eagerly pulls it into your main bundle even on pages that never render a map. Prefer **lazy registration** so the map is code-split into its own chunk and only loaded when it is actually needed. +Keep `mapbox-gl` out of your main bundle by lazy-registering each component with js-toolkit's [`importWhen*` helpers](https://js-toolkit.studiometa.dev/api/helpers/importWhenVisible.html) and the per-component subpaths. `importWhenVisible` defers the dynamic import until a `MapboxMap` element scrolls into view, then hands the resolved component to `registerComponent`, code-splitting `mapbox-gl` into its own chunk loaded only when a map is actually needed. -js-toolkit ships [`importWhen*` helpers](https://js-toolkit.studiometa.dev/api/helpers/importWhenVisible.html) for this. `importWhenVisible` defers the dynamic import until a `MapboxMap` element scrolls into view, then hands the resolved component to `registerComponent`: +Every component is available at its own subpath (`@studiometa/ui-mapbox/`), whose default export is the component class — so the dynamic import needs no destructuring. Because each component is registered independently, lazy-register each one you use: deferring `MapboxMap` pulls in `mapbox-gl`, but a marker or a cluster is its own module and must get its own lazy registration. ```js -import { registerComponent, importWhenVisible } from '@studiometa/js-toolkit'; +import { registerComponents, importWhenVisible } from '@studiometa/js-toolkit'; -registerComponent(importWhenVisible(() => import('@studiometa/ui-mapbox/MapboxMap'), 'MapboxMap')); +registerComponents( + importWhenVisible(() => import('@studiometa/ui-mapbox/MapboxMap'), 'MapboxMap'), + importWhenVisible(() => import('@studiometa/ui-mapbox/MapboxMarker'), 'MapboxMarker'), + importWhenVisible(() => import('@studiometa/ui-mapbox/MapboxPopup'), 'MapboxPopup'), +); ``` -Every component is also available at its own subpath (`@studiometa/ui-mapbox/`), whose default export is the component class — so the dynamic import needs no destructuring. - -Because every marker, popup, control, source, layer, image and cluster is a child of `MapboxMap`, deferring the map defers the whole family — `mapbox-gl` included. Reach for a different trigger when it fits better: `importWhenIdle` (load during browser idle time), `importOnInteraction` (wait for a first click/focus/touch on the element) or `importOnMediaQuery` (load only above a breakpoint, e.g. to skip the map on small screens). +Reach for a different trigger when it fits better: `importWhenIdle` (load during browser idle time), `importOnInteraction` (wait for a first click/focus/touch on the element) or `importOnMediaQuery` (load only above a breakpoint, e.g. to skip the map on small screens). diff --git a/packages/docs/components/MapboxMap/js-api.md b/packages/docs/components/MapboxMap/js-api.md index f1c66eaf..b9137450 100644 --- a/packages/docs/components/MapboxMap/js-api.md +++ b/packages/docs/components/MapboxMap/js-api.md @@ -5,21 +5,19 @@ outline: deep # JS API -The `@studiometa/ui-mapbox` package exposes twelve components plus the `AbstractMapboxMapChild` base class. They are organized around a single root component, `MapboxMap`, which owns the Mapbox `Map` instance. Every other component is a child that resolves the closest parent `MapboxMap` and registers itself against its map once it is loaded. +This page documents thirteen components — a single root component, `MapboxMap`, which owns the Mapbox `Map` instance, plus the twelve children below — built on the `AbstractMapboxMapChild` (and, for controls, `AbstractMapboxControl`) base classes. The [`StoreLocator`](/components/StoreLocator/) orchestrator completes the family on its own page. Every child resolves the closest parent `MapboxMap` on its own and registers itself against its map once it is loaded. -You only ever register `MapboxMap` with [`registerComponent`](https://js-toolkit.studiometa.dev/api/helpers/registerComponent.html): all child components are declared internally and resolved automatically. +[Register](/guide/usage/#registering-components) each component you use — ideally behind a lazy [`importWhen*` helper](https://js-toolkit.studiometa.dev/api/helpers/importWhenVisible.html) so the heavy `mapbox-gl` dependency stays out of your main bundle (see [Lazy loading](/components/MapboxMap/#lazy-loading)). - **[Map](#map)** — `MapboxMap` - **[Markers & Popups](#markers-popups)** — `MapboxMarker`, `MapboxPopup` - **[Controls](#controls)** — `MapboxNavigationControl`, `MapboxGeolocateControl`, `MapboxFullscreenControl`, `MapboxGeocoder` - **[Data](#data)** — `MapboxSource`, `MapboxLayer`, `MapboxImage`, `MapboxImages` -- **[Cluster](#cluster)** — `MapboxCluster` +- **[Cluster](#cluster)** — `MapboxCluster`, `MapboxClusterItem` (see also the [`StoreLocator`](/components/StoreLocator/) orchestrator) - **[AbstractMapboxMapChild](#abstractmapboxmapchild)** — the shared base class ## Reactivity and updates -Component options are read **once, at mount time**, and are **not reactive**. This is a deliberate behavioral difference from the `@studiometa/vue-mapbox-gl` library, where changing a prop updated the map. - To move the map, change its data or update a marker after mount, reach for the underlying Mapbox objects directly through the component instances: ```js @@ -36,6 +34,10 @@ marker.marker.setLngLat([2.29, 48.86]); Every component documents the Mapbox object it exposes (`map`, `marker`, `popup`, `control`, …) in its **Getters** section below. +::: tip Switching base style keeps your layers +Calling `map.setStyle(…)` wipes the entire style — every source, layer and sprite — while the map instance and the still-mounted child components survive. Each map child subscribes to the map's `style.load` and **re-injects** its contribution automatically, so your declarative sources, layers, images and clusters re-appear on the new base style instead of silently vanishing. You can switch the base style at runtime without re-declaring your data. +::: + ## Map ### MapboxMap @@ -44,12 +46,31 @@ Display an interactive Mapbox GL map. This is the root component of the system a #### Options -| Option | Type | Default | Description | -| -------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `access-token` | `String` | — | Mapbox GL [access token](https://docs.mapbox.com/help/getting-started/access-tokens/) (required). | -| `zoom` | `Number` | — | Initial zoom level. | -| `center` | `Array` | `[0, 0]` | Initial center as `[longitude, latitude]`. | -| `map-options` | `Object` | `{}` | Any other [Mapbox `Map` option](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters), spread into the constructor. This is where `style`, `pitch`, `bearing`, `bounds`, … go. | +##### `access-token` + +- Type: `String` + +Mapbox GL [access token](https://docs.mapbox.com/help/getting-started/access-tokens/) (required). + +##### `zoom` + +- Type: `Number` + +Initial zoom level. + +##### `center` + +- Type: `Array` +- Default: `[0, 0]` + +Initial center as `[longitude, latitude]`. + +##### `map-options` + +- Type: `Object` +- Default: `{}` + +Any other [Mapbox `Map` option](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters), spread into the constructor. This is where `style`, `pitch`, `bearing`, `bounds`, … go. The `access-token`, `zoom` and `center` options act as overridable defaults, then `map-options` is spread into the [Mapbox `Map` constructor](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters). The `container` is always resolved from the component (the `container` ref, falling back to the root element) and can not be overridden. Use `map-options` for anything the convenience options above do not cover — most notably the map [`style`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map-parameters): @@ -64,50 +85,137 @@ The `access-token`, `zoom` and `center` options act as overridable defaults, the #### Refs -| Ref | Type | Description | -| ----------- | ------------- | ----------------------------------------------------------------------------------- | -| `container` | `HTMLElement` | The element used as the map container. Falls back to the root element when omitted. | +##### `container` + +- Type: `HTMLElement` + +The element used as the map container. Falls back to the root element when omitted. #### Getters -| Getter | Type | Description | -| ---------- | -------------- | -------------------------------------- | -| `map` | `mapboxgl.Map` | The underlying Mapbox GL map instance. | -| `isLoaded` | `boolean` | Whether the map has finished loading. | +##### `map` + +- Type: `mapboxgl.Map` + +The underlying Mapbox GL map instance. + +##### `isLoaded` + +- Type: `boolean` + +Whether the map has finished loading. #### Events The component emits a custom `map-load` event, plus all the common Mapbox GL map events, re-emitted under the same name. Each handler receives the corresponding Mapbox event object (the `map-load` handler receives the `map` instance). -| Event | Description | -| ------------- | ---------------------------------------- | -| `map-load` | The map finished loading (custom event). | -| `load` | Map resources are loaded. | -| `idle` | The map is idle after rendering. | -| `render` | A frame is rendered. | -| `resize` | The map container is resized. | -| `remove` | The map is removed. | -| `error` | An error occurred. | -| `click` | A click on the map. | -| `dblclick` | A double-click on the map. | -| `mouseenter` | The pointer enters the map canvas. | -| `mouseleave` | The pointer leaves the map canvas. | -| `mousemove` | The pointer moves over the map. | -| `movestart` | Map movement starts (pan, zoom, rotate). | -| `move` | The map is moving. | -| `moveend` | Map movement ends. | -| `zoomstart` | A zoom transition starts. | -| `zoom` | The zoom level changes. | -| `zoomend` | A zoom transition ends. | -| `rotatestart` | Rotation starts. | -| `rotate` | The map is rotating. | -| `rotateend` | Rotation ends. | -| `pitchstart` | A pitch transition starts. | -| `pitch` | The pitch changes. | -| `pitchend` | A pitch transition ends. | -| `dragstart` | A drag starts. | -| `drag` | The map is being dragged. | -| `dragend` | A drag ends. | +##### `map-load` + +The map finished loading (custom event). + +##### `load` + +Map resources are loaded. + +##### `idle` + +The map is idle after rendering. + +##### `render` + +A frame is rendered. + +##### `resize` + +The map container is resized. + +##### `remove` + +The map is removed. + +##### `error` + +An error occurred. + +##### `click` + +A click on the map. + +##### `dblclick` + +A double-click on the map. + +##### `mouseenter` + +The pointer enters the map canvas. + +##### `mouseleave` + +The pointer leaves the map canvas. + +##### `mousemove` + +The pointer moves over the map. + +##### `movestart` + +Map movement starts (pan, zoom, rotate). + +##### `move` + +The map is moving. + +##### `moveend` + +Map movement ends. + +##### `zoomstart` + +A zoom transition starts. + +##### `zoom` + +The zoom level changes. + +##### `zoomend` + +A zoom transition ends. + +##### `rotatestart` + +Rotation starts. + +##### `rotate` + +The map is rotating. + +##### `rotateend` + +Rotation ends. + +##### `pitchstart` + +A pitch transition starts. + +##### `pitch` + +The pitch changes. + +##### `pitchend` + +A pitch transition ends. + +##### `dragstart` + +A drag starts. + +##### `drag` + +The map is being dragged. + +##### `dragend` + +A drag ends. Listen to these events from a parent component with `on` methods: @@ -145,18 +253,33 @@ Add a [marker](https://docs.mapbox.com/mapbox-gl-js/api/markers/#marker) to the #### Options -| Option | Type | Default | Description | -| ---------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------- | -| `lng-lat` | `Array` | `[0, 0]` | Marker position as `[longitude, latitude]`. | -| `marker-options` | `Object` | `{}` | [Mapbox Marker options](https://docs.mapbox.com/mapbox-gl-js/api/markers/#marker) (color, anchor, draggable, …). | +##### `lng-lat` + +- Type: `Array` +- Default: `[0, 0]` + +Marker position as `[longitude, latitude]`. + +##### `marker-options` + +- Type: `Object` +- Default: `{}` + +[Mapbox Marker options](https://docs.mapbox.com/mapbox-gl-js/api/markers/#marker) (color, anchor, draggable, …). #### Getters -| Getter | Type | Description | -| --------------- | ----------------- | --------------------------------------------- | -| `marker` | `mapboxgl.Marker` | The underlying Marker instance. | -| `popup` | `MapboxPopup` | The first nested `MapboxPopup` child, if any. | -| `markerOptions` | `Object` | The resolved marker options. | +##### `marker` + +- Type: `mapboxgl.Marker` + +The underlying Marker instance. + +##### `popup` + +- Type: `MapboxPopup` + +The first nested `MapboxPopup` child, if any. ### MapboxPopup @@ -164,17 +287,27 @@ Display a [popup](https://docs.mapbox.com/mapbox-gl-js/api/markers/#popup) on th #### Options -| Option | Type | Default | Description | -| --------------- | -------- | -------- | -------------------------------------------------------------------------------- | -| `lng-lat` | `Array` | `[0, 0]` | Popup position as `[longitude, latitude]` (standalone popups only). | -| `popup-options` | `Object` | `{}` | [Mapbox Popup options](https://docs.mapbox.com/mapbox-gl-js/api/markers/#popup). | +##### `lng-lat` + +- Type: `Array` +- Default: `[0, 0]` + +Popup position as `[longitude, latitude]` (standalone popups only). + +##### `popup-options` + +- Type: `Object` +- Default: `{}` + +[Mapbox Popup options](https://docs.mapbox.com/mapbox-gl-js/api/markers/#popup). #### Getters -| Getter | Type | Description | -| -------------- | ---------------- | ------------------------------ | -| `popup` | `mapboxgl.Popup` | The underlying Popup instance. | -| `popupOptions` | `Object` | The resolved popup options. | +##### `popup` + +- Type: `mapboxgl.Popup` + +The underlying Popup instance. ## Controls @@ -186,12 +319,33 @@ Add zoom in/out and compass controls to the map. #### Options -| Option | Type | Default | Description | -| ----------------- | --------- | ------------- | --------------------------------------------------------------------------- | -| `position` | `String` | `'top-right'` | Control position: `top-left`, `top-right`, `bottom-left` or `bottom-right`. | -| `show-compass` | `Boolean` | `false` | Show the compass button. | -| `show-zoom` | `Boolean` | `false` | Show the zoom in/out buttons. | -| `visualize-pitch` | `Boolean` | `false` | Visualize the pitch on the compass button. | +##### `position` + +- Type: `String` +- Default: `'top-right'` + +Control position: `top-left`, `top-right`, `bottom-left` or `bottom-right`. + +##### `show-compass` + +- Type: `Boolean` +- Default: `false` + +Show the compass button. + +##### `show-zoom` + +- Type: `Boolean` +- Default: `false` + +Show the zoom in/out buttons. + +##### `visualize-pitch` + +- Type: `Boolean` +- Default: `false` + +Visualize the pitch on the compass button. ### MapboxGeolocateControl @@ -199,15 +353,52 @@ Add a button that uses the browser's geolocation API to locate the user on the m #### Options -| Option | Type | Default | Description | -| ---------------------- | --------- | ------------- | ----------------------------------------------------------------------------------------------------- | -| `position` | `String` | `'top-right'` | Control position. | -| `position-options` | `Object` | — | Browser [`PositionOptions`](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions). | -| `fit-bounds-options` | `Object` | — | [`FitBoundsOptions`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#fitbounds) used when tracking. | -| `track-user-location` | `Boolean` | `false` | Continuously track the user location. | -| `show-accuracy-circle` | `Boolean` | `false` | Show the accuracy circle around the user location. | -| `show-user-location` | `Boolean` | `false` | Show the user location dot. | -| `show-user-heading` | `Boolean` | `false` | Show the user heading indicator. | +##### `position` + +- Type: `String` +- Default: `'top-right'` + +Control position. + +##### `position-options` + +- Type: `Object` + +Browser [`PositionOptions`](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions). + +##### `fit-bounds-options` + +- Type: `Object` + +[`FitBoundsOptions`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#fitbounds) used when tracking. + +##### `track-user-location` + +- Type: `Boolean` +- Default: `false` + +Continuously track the user location. + +##### `show-accuracy-circle` + +- Type: `Boolean` +- Default: `false` + +Show the accuracy circle around the user location. + +##### `show-user-location` + +- Type: `Boolean` +- Default: `false` + +Show the user location dot. + +##### `show-user-heading` + +- Type: `Boolean` +- Default: `false` + +Show the user heading indicator. ### MapboxFullscreenControl @@ -215,9 +406,12 @@ Add a button that toggles the map fullscreen. #### Options -| Option | Type | Default | Description | -| ---------- | -------- | ------------- | ----------------- | -| `position` | `String` | `'top-right'` | Control position. | +##### `position` + +- Type: `String` +- Default: `'top-right'` + +Control position. ### MapboxGeocoder @@ -229,19 +423,43 @@ Add an address search control powered by [`@mapbox/mapbox-gl-geocoder`](https:// #### Options -| Option | Type | Default | Description | -| ------------ | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `add-to-map` | `Boolean` | `false` | When `true`, the geocoder is added to the map as a control. Otherwise it is rendered inside the component's element. | -| `options` | `Object` | `{}` | [Geocoder options](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters). Non-serializable options (`filter`, `externalGeocoder`, `render`, `getItemValue`, `localGeocoder`) are not supported. | +##### `add-to-map` + +- Type: `Boolean` +- Default: `false` + +Add the geocoder to the map as a control. Otherwise it is rendered inside the component's element. + +##### `options` + +- Type: `Object` +- Default: `{}` + +[Geocoder options](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters). Non-serializable options (`filter`, `externalGeocoder`, `render`, `getItemValue`, `localGeocoder`) are not supported. The `accessToken` is inherited from the parent `MapboxMap` when it is not set in `options`. #### Getters -| Getter | Type | Description | -| --------- | -------------------- | -------------------------------------------------------- | -| `control` | `MapboxGeocoder` | The underlying `mapbox-gl-geocoder` control instance. | -| `target` | `Map \| HTMLElement` | Where the control is mounted, depending on `add-to-map`. | +##### `control` + +- Type: `MapboxGeocoder` + +The underlying `mapbox-gl-geocoder` control instance. + +##### `target` + +- Type: `Map | HTMLElement` + +Where the control is mounted, depending on `add-to-map`. + +#### Events + +##### `result` + +- Payload: `result` + +Emitted when the geocoder resolves an address, carrying the geocoder's `result` (its selected feature). ## Data @@ -251,16 +469,33 @@ Add a [source](https://docs.mapbox.com/style-spec/reference/sources/) to the map #### Options -| Option | Type | Default | Description | -| -------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------- | -| `id` | `String` | — | Unique source id, referenced by layers. | -| `source` | `Object` | — | A [source specification](https://docs.mapbox.com/style-spec/reference/sources/), e.g. `{ "type": "geojson", "data": … }`. | +##### `id` + +- Type: `String` + +Unique source id, referenced by layers. + +##### `source` + +- Type: `Object` + +A [source specification](https://docs.mapbox.com/style-spec/reference/sources/), e.g. `{ "type": "geojson", "data": … }`. #### Refs -| Ref | Type | Description | -| --------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `geojson` | `HTMLScriptElement` | Optional ` +
    + {% for point in points %} +
  • + {% endfor %} +
diff --git a/packages/docs/components/MapboxMap/stories/controls/app.js b/packages/docs/components/MapboxMap/stories/controls/app.js index e40fade7..51bd9354 100644 --- a/packages/docs/components/MapboxMap/stories/controls/app.js +++ b/packages/docs/components/MapboxMap/stories/controls/app.js @@ -1,4 +1,15 @@ -import { registerComponent } from '@studiometa/js-toolkit'; -import { MapboxMap } from '@studiometa/ui-mapbox'; +import { registerComponents } from '@studiometa/js-toolkit'; +import { + MapboxMap, + MapboxNavigationControl, + MapboxGeolocateControl, + MapboxFullscreenControl, +} from '@studiometa/ui-mapbox'; -registerComponent(MapboxMap); +// Register every component the markup uses. +registerComponents( + MapboxMap, + MapboxNavigationControl, + MapboxGeolocateControl, + MapboxFullscreenControl, +); diff --git a/packages/docs/components/MapboxMap/stories/images/app.js b/packages/docs/components/MapboxMap/stories/images/app.js index e40fade7..e1947f06 100644 --- a/packages/docs/components/MapboxMap/stories/images/app.js +++ b/packages/docs/components/MapboxMap/stories/images/app.js @@ -1,4 +1,5 @@ -import { registerComponent } from '@studiometa/js-toolkit'; -import { MapboxMap } from '@studiometa/ui-mapbox'; +import { registerComponents } from '@studiometa/js-toolkit'; +import { MapboxMap, MapboxImages, MapboxSource, MapboxLayer } from '@studiometa/ui-mapbox'; -registerComponent(MapboxMap); +// Register every component the markup uses. +registerComponents(MapboxMap, MapboxImages, MapboxSource, MapboxLayer); diff --git a/packages/docs/components/MapboxMap/stories/markers/app.js b/packages/docs/components/MapboxMap/stories/markers/app.js index e40fade7..58d2e4a4 100644 --- a/packages/docs/components/MapboxMap/stories/markers/app.js +++ b/packages/docs/components/MapboxMap/stories/markers/app.js @@ -1,4 +1,5 @@ -import { registerComponent } from '@studiometa/js-toolkit'; -import { MapboxMap } from '@studiometa/ui-mapbox'; +import { registerComponents } from '@studiometa/js-toolkit'; +import { MapboxMap, MapboxMarker, MapboxPopup } from '@studiometa/ui-mapbox'; -registerComponent(MapboxMap); +// Register every component the markup uses. +registerComponents(MapboxMap, MapboxMarker, MapboxPopup); diff --git a/packages/docs/components/MapboxMap/stories/source-layer/app.js b/packages/docs/components/MapboxMap/stories/source-layer/app.js index e40fade7..4c0e2ae8 100644 --- a/packages/docs/components/MapboxMap/stories/source-layer/app.js +++ b/packages/docs/components/MapboxMap/stories/source-layer/app.js @@ -1,4 +1,5 @@ -import { registerComponent } from '@studiometa/js-toolkit'; -import { MapboxMap } from '@studiometa/ui-mapbox'; +import { registerComponents } from '@studiometa/js-toolkit'; +import { MapboxMap, MapboxSource, MapboxLayer } from '@studiometa/ui-mapbox'; -registerComponent(MapboxMap); +// Register every component the markup uses. +registerComponents(MapboxMap, MapboxSource, MapboxLayer); diff --git a/packages/docs/components/StoreLocator/examples.md b/packages/docs/components/StoreLocator/examples.md index 342bedb0..87b5546c 100644 --- a/packages/docs/components/StoreLocator/examples.md +++ b/packages/docs/components/StoreLocator/examples.md @@ -4,19 +4,19 @@ title: StoreLocator examples # Examples -Both examples register a single root component that declares the `StoreLocator` — its `MapboxMap` and `StoreLocatorItem` children are resolved automatically, and the `MapboxCluster` inside the map is fed by the coordinator once the map has loaded. Each example loads the [Mapbox GL stylesheet](/components/MapboxMap/#installation) from a CDN and picks a Mapbox style through the `map-options` option. Replace the access token with your own [access token](https://docs.mapbox.com/help/getting-started/access-tokens/); the token used here is a public, restricted demo token. +Both examples register the Mapbox components they use (`StoreLocator`, `MapboxMap`, `MapboxCluster`, `MapboxClusterItem`) independently — see [Usage](./#usage) for the recommended lazy registration — and add a small root component for the detail panel. The `StoreLocator` orchestrates a `MapboxMap` containing a `MapboxCluster` whose `MapboxClusterItem`s are the sidebar entries. Each example loads the [Mapbox GL stylesheet](/components/MapboxMap/#installation) from a CDN and picks a Mapbox style through the `map-options` option. Replace the access token with your own [access token](https://docs.mapbox.com/help/getting-started/access-tokens/); the token used here is a public, restricted demo token. ## Basic store locator -A `StoreLocator` wrapping a sidebar list of Paris stores and a clustered map. Note that the `MapboxCluster` has **no** authored data: the coordinator derives a GeoJSON `FeatureCollection` from the list items and pushes it to the cluster after the map loads. +A `StoreLocator` wrapping a clustered map whose `MapboxCluster` holds a sidebar list of Paris `MapboxClusterItem`s. The cluster has **no** authored data: it derives a GeoJSON `FeatureCollection` from its registered items, and the orchestrator adds selection, viewport filtering and the detail drawer on top. Try it out: - **Pan or zoom the map** — the sidebar filters to the in-view stores and reorders them nearest-first. -- **Click a store in the list** — the map flies there, the item is marked active and the detail drawer opens. +- **Click a store in the list** — the map flies there, the item is marked active, a popup opens and the detail drawer opens. - **Click a cluster** — the map zooms in and splits it; click an individual pin to select its store. -The detail panel is the integrator's choice. Here it is a [`Dialog`](/components/Dialog/) drawer, opened from the [`select`](./js-api#select) event through a small root component's `onStoreLocatorSelect` handler, which copies the selected item's `