2024-09-20 18:22:49 +02:00
|
|
|
|
import { useId, useRef, useEffect } from 'react';
|
|
|
|
|
import { Button, Dialog, DialogTrigger, Popover } from 'react-aria-components';
|
2021-06-30 10:28:02 +02:00
|
|
|
|
import { MapIcon } from '@heroicons/react/outline';
|
2021-07-01 18:50:35 +02:00
|
|
|
|
import { Slider } from '@reach/slider';
|
|
|
|
|
import '@reach/slider/styles.css';
|
2021-05-06 18:51:19 +02:00
|
|
|
|
|
2022-02-08 12:49:51 +01:00
|
|
|
|
import { LayersMap, NBS } from './styles';
|
2021-05-06 18:51:19 +02:00
|
|
|
|
|
|
|
|
|
const STYLES = {
|
2021-06-30 10:28:02 +02:00
|
|
|
|
ortho: 'Satellite',
|
|
|
|
|
vector: 'Vectoriel',
|
|
|
|
|
ign: 'Carte IGN'
|
2021-05-06 18:51:19 +02:00
|
|
|
|
};
|
|
|
|
|
|
2024-09-20 18:22:49 +02:00
|
|
|
|
export function StyleSwitch({
|
2022-02-08 12:49:51 +01:00
|
|
|
|
styleId,
|
2021-07-01 18:50:35 +02:00
|
|
|
|
layers,
|
|
|
|
|
setStyle,
|
|
|
|
|
setLayerEnabled,
|
|
|
|
|
setLayerOpacity
|
2022-02-08 12:49:51 +01:00
|
|
|
|
}: {
|
|
|
|
|
styleId: string;
|
|
|
|
|
setStyle: (style: string) => void;
|
|
|
|
|
layers: LayersMap;
|
|
|
|
|
setLayerEnabled: (layer: string, enabled: boolean) => void;
|
|
|
|
|
setLayerOpacity: (layer: string, opacity: number) => void;
|
2021-07-01 18:50:35 +02:00
|
|
|
|
}) {
|
2021-07-07 14:02:55 +02:00
|
|
|
|
const configurableLayers = Object.entries(layers).filter(
|
|
|
|
|
([, { configurable }]) => configurable
|
|
|
|
|
);
|
2021-07-07 14:12:50 +02:00
|
|
|
|
const mapId = useId();
|
2024-09-20 18:22:49 +02:00
|
|
|
|
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (buttonRef.current) {
|
|
|
|
|
buttonRef.current.title = 'Sélectionner les couches cartographiques';
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
2021-05-06 18:51:19 +02:00
|
|
|
|
|
|
|
|
|
return (
|
2024-09-20 18:22:49 +02:00
|
|
|
|
<DialogTrigger>
|
|
|
|
|
<Button ref={buttonRef}>
|
|
|
|
|
<MapIcon className="icon-size" />
|
|
|
|
|
</Button>
|
|
|
|
|
<Popover className="react-aria-popover">
|
|
|
|
|
<Dialog className="fr-modal__body">
|
|
|
|
|
<form
|
|
|
|
|
className="fr-modal__content flex m-2"
|
|
|
|
|
onSubmit={(event) => event.preventDefault()}
|
2021-06-30 10:28:02 +02:00
|
|
|
|
>
|
2024-09-20 18:22:49 +02:00
|
|
|
|
<div className="fr-fieldset">
|
|
|
|
|
{Object.entries(STYLES).map(([style, title]) => (
|
|
|
|
|
<div className="fr-fieldset__element" key={style}>
|
|
|
|
|
<div className="fr-radio-group">
|
2021-06-30 10:28:02 +02:00
|
|
|
|
<input
|
2024-09-20 18:22:49 +02:00
|
|
|
|
id={`${mapId}-${style}`}
|
|
|
|
|
value={style}
|
2021-06-30 10:28:02 +02:00
|
|
|
|
type="radio"
|
|
|
|
|
name="map-style"
|
2024-09-20 18:22:49 +02:00
|
|
|
|
defaultValue={style}
|
|
|
|
|
checked={styleId == style}
|
2021-07-07 14:02:55 +02:00
|
|
|
|
onChange={(event) => {
|
2024-09-20 18:22:49 +02:00
|
|
|
|
setStyle(event.target.value);
|
2021-07-01 18:50:35 +02:00
|
|
|
|
}}
|
|
|
|
|
/>
|
2024-09-20 18:22:49 +02:00
|
|
|
|
<label htmlFor={`${mapId}-${style}`} className="fr-label">
|
|
|
|
|
{title.replace(/\s/g, ' ')}
|
2021-07-07 14:12:50 +02:00
|
|
|
|
</label>
|
2021-07-07 14:02:55 +02:00
|
|
|
|
</div>
|
2024-09-20 18:22:49 +02:00
|
|
|
|
</div>
|
2021-07-07 14:02:55 +02:00
|
|
|
|
))}
|
2024-09-20 18:22:49 +02:00
|
|
|
|
</div>
|
|
|
|
|
{configurableLayers.length ? (
|
|
|
|
|
<div className="fr-fieldset__element">
|
|
|
|
|
{configurableLayers.map(
|
|
|
|
|
([layer, { enabled, opacity, name }]) => (
|
|
|
|
|
<div key={layer} className="fr-fieldset__element">
|
|
|
|
|
<div className="fr-checkbox-group">
|
|
|
|
|
<input
|
|
|
|
|
id={`${mapId}-${layer}`}
|
|
|
|
|
type="checkbox"
|
|
|
|
|
checked={enabled}
|
|
|
|
|
onChange={(event) => {
|
|
|
|
|
setLayerEnabled(layer, event.target.checked);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<label
|
|
|
|
|
className="fr-label"
|
|
|
|
|
htmlFor={`${mapId}-${layer}`}
|
|
|
|
|
>
|
|
|
|
|
{name}
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<Slider
|
|
|
|
|
min={10}
|
|
|
|
|
max={100}
|
|
|
|
|
step={5}
|
|
|
|
|
value={opacity}
|
|
|
|
|
onChange={(value) => {
|
|
|
|
|
setLayerOpacity(layer, value);
|
|
|
|
|
}}
|
|
|
|
|
className="fr-range fr-range--sm mt-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}%`
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
|
|
|
|
</form>
|
|
|
|
|
</Dialog>
|
2021-06-30 10:28:02 +02:00
|
|
|
|
</Popover>
|
2024-09-20 18:22:49 +02:00
|
|
|
|
</DialogTrigger>
|
2021-05-06 18:51:19 +02:00
|
|
|
|
);
|
|
|
|
|
}
|