import React, { useState, useEffect } from "react"; import { fromJS, Map } from "immutable"; import MAP_STYLE from "./map-style-basic-v8.json"; const defaultMapStyle: Map = fromJS(MAP_STYLE); const defaultLayers = defaultMapStyle.get("layers"); const categories: string[] = [ "labels", "roads", "buildings", "parks", "water", "background", ]; // Layer id patterns by category const layerSelector: { [key: string]: RegExp } = { background: /background/, water: /water/, parks: /park/, buildings: /building/, roads: /bridge|road|tunnel/, labels: /label|place|poi/, }; // Layer color class by type const colorClass: { [key: string]: string } = { line: "line-color", fill: "fill-color", background: "background-color", symbol: "text-color", }; function getMapStyle({ visibility, color }: MapStyleOptions): Map { const layers = defaultLayers .filter((layer: any) => { const id = layer.get("id"); return categories.every( (name) => visibility[name] || !layerSelector[name].test(id) ); }) .map((layer: any) => { const id = layer.get("id"); const type = layer.get("type"); const category = categories.find((name) => layerSelector[name].test(id)); if (category && colorClass[type]) { return layer.setIn(["paint", colorClass[type]], color[category]); } return layer; }); return defaultMapStyle.set("layers", layers); } interface MapStyleOptions { visibility: { [key: string]: boolean }; color: { [key: string]: string }; } interface StyleControlsProps { onChange: (style: Map) => void; } function StyleControls(props: StyleControlsProps) { const [visibility, setVisibility] = useState({ water: true, parks: true, buildings: true, roads: true, labels: true, background: true, }); const [color, setColor] = useState({ water: "#DBE2E6", parks: "#E6EAE9", buildings: "#c0c0c8", roads: "#ffffff", labels: "#78888a", background: "#EBF0F0", }); useEffect(() => { props.onChange(getMapStyle({ visibility, color })); }, [visibility, color]); const onColorChange = (name: string, value: string) => { setColor({ ...color, [name]: value }); }; const onVisibilityChange = (name: string, value: boolean) => { setVisibility({ ...visibility, [name]: value }); }; return (

Dynamic Styling


{categories.map((name) => (
onVisibilityChange(name, evt.target.checked)} /> onColorChange(name, evt.target.value)} />
))}
); } export default React.memo(StyleControls);