style-switcher icon indicating copy to clipboard operation
style-switcher copied to clipboard

Provide a way to update active style (so the correct style is bold in the option menu)

Open mmnoo opened this issue 1 year ago • 3 comments

The app I am working on includes manual updates to the base map style that happen outside of the style switcher. It would be nice if the style switcher took its active state for option bolding from the basemap in the map regardless of how it was set. Im assuming the active state for a style gets set when a user selects a style with the switcher, but maybe there can be a listener that sets the active state on basemap change instead (assuming Mapbox provides such a listener that would work)

Right now I am considering manually updating the css classes myself but that is really hacky and not durable.

mmnoo avatar Feb 27 '24 17:02 mmnoo

Hello,

the active state is just a css class ".active".

You can just set it to whatever you like with css.

el avatar Feb 27 '24 20:02 el

I ended up doing that, and it blew up the style switcher. I cant rule out the complicated code base I am working in though (within the constraints of my time box anyway).

Instead of manually setting the style on the map instance and then setting css classes to make the switcher have the right style in bold, my current approach is to hack into the private properties of the style switcher instance to grab the target style button and click it with JavaScript. Very not ideal, and definitely not durable against any internal changes you guys may make, but it seems to be working without bugs currently!

mmnoo avatar Feb 27 '24 21:02 mmnoo

Not exactly code I take pride in, but sometimes you need to do gross things quickly :)

const clickOnStyleSwitcherTargetStyleHack = ({ mapInstance, styleToSelect }: {
	styleToSelect: string;
	mapInstance: IMapInstance;
}) => {
	// Instead of manually changing the map instance style to match another map instance, we click on the other instance's style switcher target style
	// This ensures the style is bolded in both map instances, and also that subsequent styles render property (when we have a style switcher on both map sides)
	// this hack may break if the internals of the style switcher or mapbox change. Use with caution.
	// @ts-expect-error - this is definitely a dirty hack, so we are using private properties
	const styleSwitcherControl = mapInstance._controls.find((control) => control instanceof MapboxStyleSwitcherControl);
	const styleButtons = styleSwitcherControl.mapStyleContainer.children;

	for (let index = 0; index < styleButtons.length; index++) {
		const button = styleButtons[index];
		const isButtonForTheTargetStyle = button.getAttribute('data-uri') === `"${styleToSelect}"`; // getAttribute returns a string including quotes
		if (isButtonForTheTargetStyle) {
			button.click();
		}
	}
};

mmnoo avatar Feb 27 '24 21:02 mmnoo