import React, { useState, useId } from 'react'; import { Popover, RadioGroup } from '@headlessui/react'; import { usePopper } from 'react-popper'; import { MapIcon } from '@heroicons/react/outline'; import { Slider } from '@reach/slider'; import '@reach/slider/styles.css'; import { LayersMap, NBS } from './styles'; const STYLES = { ortho: 'Satellite', vector: 'Vectoriel', ign: 'Carte IGN' }; export function StyleControl({ styleId, layers, setStyle, setLayerEnabled, setLayerOpacity }: { styleId: string; setStyle: (style: string) => void; layers: LayersMap; setLayerEnabled: (layer: string, enabled: boolean) => void; setLayerOpacity: (layer: string, opacity: number) => void; }) { const [buttonElement, setButtonElement] = useState<HTMLButtonElement | null>(); const [panelElement, setPanelElement] = useState<HTMLDivElement | null>(); const { styles, attributes } = usePopper(buttonElement, panelElement, { placement: 'bottom-end' }); const configurableLayers = Object.entries(layers).filter( ([, { configurable }]) => configurable ); const mapId = useId(); return ( <div className="form map-style-control mapboxgl-ctrl-group" style={{ zIndex: 10 }} > <Popover> <Popover.Button ref={setButtonElement} className="map-style-button" title="Sélectionner les couches cartographiques" > <MapIcon className="icon-size" /> </Popover.Button> <Popover.Panel className="flex map-style-panel mapboxgl-ctrl-group" ref={setPanelElement} style={styles.popper} {...attributes.popper} > <RadioGroup value={styleId} onChange={setStyle} className="styles-list" as="ul" > {Object.entries(STYLES).map(([style, title]) => ( <RadioGroup.Option key={style} value={style} as="li" className="flex" > {({ checked }) => ( <> <input type="radio" key={`${style}-${checked}`} defaultChecked={checked} name="map-style" className="m-0 p-0 mr-1" /> <RadioGroup.Label> {title.replace(/\s/g, ' ')} </RadioGroup.Label> </> )} </RadioGroup.Option> ))} </RadioGroup> {configurableLayers.length ? ( <ul className="layers-list"> {configurableLayers.map(([layer, { enabled, opacity, name }]) => ( <li key={layer}> <div className="flex mb-1"> <input id={`${mapId}-${layer}`} className="m-0 p-0 mr-1" type="checkbox" checked={enabled} onChange={(event) => { setLayerEnabled(layer, event.target.checked); }} /> <label className="m-0" htmlFor={`${mapId}-${layer}`}> {name} </label> </div> <Slider min={10} max={100} step={5} value={opacity} onChange={(value) => { setLayerOpacity(layer, value); }} className="mb-1" title={`Réglage de l’opacité de la couche «${NBS}${name}${NBS}»`} getAriaLabel={() => `Réglage de l’opacité de la couche «${NBS}${name}${NBS}»` } getAriaValueText={(value) => `L’opacité de la couche «${NBS}${name}${NBS}» est à ${value}${NBS}%` } /> </li> ))} </ul> ) : null} </Popover.Panel> </Popover> </div> ); }