mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.2k stars 2.22k forks source link

Attach controls to arbitrary DOM nodes #3685

Closed tristen closed 7 years ago

tristen commented 7 years ago

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.

tmcw commented 7 years ago

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:

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:


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.

tristen commented 7 years ago

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.

lucaswoj commented 7 years ago

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)

tristen commented 7 years ago

👍 @lucaswoj that's a solid solution.