Merge pull request #6987 from tchak/fix-map-spec

fix(carto): show map UI before loading map styles
This commit is contained in:
Paul Chavard 2022-03-01 11:13:32 +00:00 committed by GitHub
commit 9bd1d128d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 40 deletions

View file

@ -57,7 +57,8 @@ module.exports = {
'prettier/prettier': 'error',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
'@typescript-eslint/no-explicit-any': 'error'
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': 'error'
}
}
]

View file

@ -1,12 +1,9 @@
import React from 'react';
import type { Point } from 'geojson';
import { fire } from '@utils';
import ComboAdresseSearch from '../../ComboAdresseSearch';
import { useFlyTo } from '../../shared/maplibre/hooks';
export function AddressInput() {
const flyTo = useFlyTo();
return (
<div
style={{
@ -17,9 +14,8 @@ export function AddressInput() {
className="no-margin"
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
allowInputValues={false}
onChange={(_, result) => {
const geometry = result?.geometry as Point;
flyTo(17, geometry.coordinates as [number, number]);
onChange={(_, feature) => {
fire(document, 'map:zoom', { feature });
}}
/>
</div>

View file

@ -7,7 +7,8 @@ import { useMapLibre } from '../../shared/maplibre/MapLibre';
import {
useFitBounds,
useEvent,
useMapEvent
useMapEvent,
useFlyTo
} from '../../shared/maplibre/hooks';
import {
filterFeatureCollection,
@ -116,6 +117,7 @@ function useExternalEvents(
}
) {
const fitBounds = useFitBounds();
const flyTo = useFlyTo();
const onFeatureFocus = useCallback(
({ detail }) => {
@ -132,6 +134,16 @@ function useExternalEvents(
[featureCollection, fitBounds]
);
const onZoomFocus = useCallback(
({ detail }) => {
const { feature } = detail;
if (feature) {
flyTo(17, feature.geometry.coordinates);
}
},
[flyTo]
);
const onFeatureCreate = useCallback(
({ detail }) => {
const { geometry, properties } = detail;
@ -181,6 +193,7 @@ function useExternalEvents(
useEvent('map:feature:create', onFeatureCreate);
useEvent('map:feature:update', onFeatureUpdate);
useEvent('map:feature:delete', onFeatureDelete);
useEvent('map:zoom', onZoomFocus);
}
const translations = [

View file

@ -5,11 +5,7 @@ import { PlusIcon, LocationMarkerIcon } from '@heroicons/react/outline';
import { useId } from '@reach/auto-id';
import CoordinateInput from 'react-coordinate-input';
import { useFlyTo } from '../../shared/maplibre/hooks';
export function PointInput() {
const flyTo = useFlyTo();
const inputId = useId();
const [value, setValue] = useState('');
const [feature, setFeature] = useState<Feature | null>(null);
@ -60,15 +56,13 @@ export function PointInput() {
setValue(value);
if (dd.length) {
const coordinates: [number, number] = [dd[1], dd[0]];
setFeature({
type: 'Feature',
geometry: {
type: 'Point',
coordinates
},
const feature = {
type: 'Feature' as const,
geometry: { type: 'Point' as const, coordinates },
properties: {}
});
flyTo(17, coordinates);
};
setFeature(feature);
fire(document, 'map:zoom', { feature });
} else {
setFeature(null);
}

View file

@ -46,19 +46,11 @@ export default function MapEditor({
</p>
</div>
{error && <FlashMessage message={error} level="alert" fixed={true} />}
<MapLibre
layers={options.layers}
header={
<>
<ImportFileInput
featureCollection={featureCollection}
{...actions}
/>
<AddressInput />
</>
}
footer={<PointInput />}
>
<ImportFileInput featureCollection={featureCollection} {...actions} />
<AddressInput />
<MapLibre layers={options.layers}>
<DrawLayer
featureCollection={featureCollection}
{...actions}
@ -86,6 +78,7 @@ export default function MapEditor({
</>
) : null}
</MapLibre>
<PointInput />
</>
);
}

View file

@ -7,7 +7,8 @@ import {
useFitBounds,
useEvent,
EventHandler,
useMapEvent
useMapEvent,
useFlyTo
} from '../../shared/maplibre/hooks';
import {
filterFeatureCollection,
@ -99,6 +100,7 @@ export function GeoJSONLayer({
function useExternalEvents(featureCollection: FeatureCollection) {
const fitBounds = useFitBounds();
const flyTo = useFlyTo();
const onFeatureFocus = useCallback(
({ detail }) => {
const { id } = detail;
@ -109,6 +111,15 @@ function useExternalEvents(featureCollection: FeatureCollection) {
},
[featureCollection, fitBounds]
);
const onZoomFocus = useCallback(
({ detail }) => {
const { feature } = detail;
if (feature) {
flyTo(17, feature.geometry.coordinates);
}
},
[flyTo]
);
useEffect(() => {
fitBounds(featureCollection.bbox as LngLatBoundsLike);
@ -117,6 +128,7 @@ function useExternalEvents(featureCollection: FeatureCollection) {
}, [fitBounds]);
useEvent('map:feature:focus', onFeatureFocus);
useEvent('map:zoom', onZoomFocus);
}
function LineStringLayer({

View file

@ -19,8 +19,6 @@ const Context = createContext<{ map?: Map | null }>({});
type MapLibreProps = {
layers: string[];
header?: ReactNode;
footer?: ReactNode;
children: ReactNode;
};
@ -30,7 +28,7 @@ export function useMapLibre() {
return context.map;
}
export function MapLibre({ children, header, footer, layers }: MapLibreProps) {
export function MapLibre({ children, layers }: MapLibreProps) {
const isSupported = useMemo(
() => maplibre.supported({ failIfMajorPerformanceCaveat: true }) && !isIE(),
[]
@ -90,12 +88,10 @@ export function MapLibre({ children, header, footer, layers }: MapLibreProps) {
return (
<Context.Provider value={{ map }}>
{map ? header : null}
<div ref={containerRef} style={{ height: '500px' }}>
<StyleControl styleId={style.id} {...mapStyleProps} />
{map ? children : null}
</div>
{map ? footer : null}
</Context.Provider>
);
}