Mapbox-gl-js: Attach controls to arbitrary DOM nodes

Created on 22 Nov 2016  路  4Comments  路  Source: mapbox/mapbox-gl-js

Currently, the API for adding a control defines that you return an element and the map adds that element. This breaks previous functionality (_see compatibility changes_) in Mapbox GL Geocoder where you could add this control outside of the map container. This has come up again in an issue and I'd love to retain that functionality for the flexibility it gives.

feature

Most helpful comment

My 2c here is:

The IControl interface is a set of expectations: of what controls do, how they interact with the map, how they can interface with Mapbox GL JS. Right now a control is:

  • A plugin for Mapbox GL JS that implements onAdd and onRemove
  • It is a UI control that can interface with the map object's API
  • Controls have a standard style based on the mapboxgl-ctrl class and standard positioning based on corners.

This leaves out many other kinds of add-ons: if we want to implement custom source types, they aren't controls. If we want custom handlers, also not controls. Wrappers for the map object aren't controls. Lots of things don't fit in this restrictive box, and that's by design: it's restrictive so that we can keep the guarantees of the box strong, for the foreseeable future.

Controls that _aren't_ on the map don't seem like controls to me. For instance:

  • Should they implement mapboxgl-ctrl class or not? If we nest that class in mapbox gl js's stylesheet, like .mapbox-map .mapboxgl-ctrl, that'd break their styles. Does this mean that all Mapbox GL JS styles for all things in the map should be un-scoped so that they also work anywhere else on the page?
  • Right now the _map_ owns controls, not the other way around: you don't addTo, you addControl always. .onAdd and .onRemove are internal methods. What does an .addControl interface look like that doesn't actually guarantee anything about the control?

So where I land with this issue (currently) is that _controls outside of the map shouldn't follow the IControl API_. They are arbitrary classes that subscribe to map events. They require no special API or designation to exist, and we should not extend IControl to deal with them, because doing so would dilute the usecase for which it's strongest and strictest, in the positive meaning of strict.

All 4 comments

My 2c here is:

The IControl interface is a set of expectations: of what controls do, how they interact with the map, how they can interface with Mapbox GL JS. Right now a control is:

  • A plugin for Mapbox GL JS that implements onAdd and onRemove
  • It is a UI control that can interface with the map object's API
  • Controls have a standard style based on the mapboxgl-ctrl class and standard positioning based on corners.

This leaves out many other kinds of add-ons: if we want to implement custom source types, they aren't controls. If we want custom handlers, also not controls. Wrappers for the map object aren't controls. Lots of things don't fit in this restrictive box, and that's by design: it's restrictive so that we can keep the guarantees of the box strong, for the foreseeable future.

Controls that _aren't_ on the map don't seem like controls to me. For instance:

  • Should they implement mapboxgl-ctrl class or not? If we nest that class in mapbox gl js's stylesheet, like .mapbox-map .mapboxgl-ctrl, that'd break their styles. Does this mean that all Mapbox GL JS styles for all things in the map should be un-scoped so that they also work anywhere else on the page?
  • Right now the _map_ owns controls, not the other way around: you don't addTo, you addControl always. .onAdd and .onRemove are internal methods. What does an .addControl interface look like that doesn't actually guarantee anything about the control?

So where I land with this issue (currently) is that _controls outside of the map shouldn't follow the IControl API_. They are arbitrary classes that subscribe to map events. They require no special API or designation to exist, and we should not extend IControl to deal with them, because doing so would dilute the usecase for which it's strongest and strictest, in the positive meaning of strict.

Curious where others land on this but that makes a lot of sense to me. I guess it's a question for Mapbox GL Geocoder to figure out whether it's a control or not.

You can use the IControl interface add the control to an arbitrary DOM node like this:

arbitraryDOMNode.appendChild(control.onAdd(map))

While it wasn't an intended use case of the IControl interface, it is valid and shouldn't break in the future.

(Styling caveats regarding mapboxgl-ctrl still apply)

馃憤 @lucaswoj that's a solid solution.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aendrew picture aendrew  路  3Comments

PBrockmann picture PBrockmann  路  3Comments

bgentry picture bgentry  路  3Comments

aderaaij picture aderaaij  路  3Comments

yoursweater picture yoursweater  路  3Comments