Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved web Mapview and MarkerView #3499

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions src/components/MapView.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { debounce } from 'debounce';
import React, { Component } from 'react';
import {
View,
StyleSheet,
NativeModules,
ViewProps,
NativeSyntheticEvent,
NativeMethods,
HostComponent,
LayoutChangeEvent,
NativeMethods,
NativeModules,
NativeSyntheticEvent,
StyleSheet,
View,
ViewProps,
} from 'react-native';
import { debounce } from 'debounce';

import { type Location } from '../modules/location/locationManager';
import NativeMapViewModule from '../specs/NativeMapViewModule';
import NativeMapView, {
type NativeMapViewActual,
} from '../specs/RNMBXMapViewNativeComponent';
import NativeMapViewModule from '../specs/NativeMapViewModule';
import { type Position } from '../types/Position';
import {
isFunction,
isAndroid,
isFunction,
type NativeArg,
type OrnamentPositonProp,
} from '../utils';
import { getFilter } from '../utils/filterUtils';
import Logger from '../utils/Logger';
import { FilterExpression } from '../utils/MapboxStyles';
import { type Position } from '../types/Position';
import { type Location } from '../modules/location/locationManager';

import NativeBridgeComponent from './NativeBridgeComponent';

Expand Down Expand Up @@ -158,7 +158,7 @@ type LocalizeLabels =
}
| true;

type Props = ViewProps & {
export type MapViewProps = ViewProps & {
/**
* The distance from the edges of the map view’s frame to the edges of the map view’s logical viewport.
* @deprecated use Camera `padding` instead
Expand Down Expand Up @@ -474,10 +474,10 @@ type Debounced<F> = F & { clear(): void; flush(): void };
* MapView backed by Mapbox Native GL
*/
class MapView extends NativeBridgeComponent(
React.PureComponent<Props>,
React.PureComponent<MapViewProps>,
NativeMapViewModule,
) {
static defaultProps: Props = {
static defaultProps: MapViewProps = {
scrollEnabled: true,
pitchEnabled: true,
rotateEnabled: true,
Expand Down Expand Up @@ -527,7 +527,7 @@ class MapView extends NativeBridgeComponent(
isUserInteraction: boolean;
};

constructor(props: Props) {
constructor(props: MapViewProps) {
super(props);

this.logger = Logger.sharedInstance();
Expand Down Expand Up @@ -570,11 +570,11 @@ class MapView extends NativeBridgeComponent(
this.logger.stop();
}

UNSAFE_componentWillReceiveProps(nextProps: Props) {
UNSAFE_componentWillReceiveProps(nextProps: MapViewProps) {
this._setHandledMapChangedEvents(nextProps);
}

_setHandledMapChangedEvents(props: Props) {
_setHandledMapChangedEvents(props: MapViewProps) {
if (isAndroid() || RNMBXModule.MapboxV10) {
const events: string[] = [];

Expand Down Expand Up @@ -1110,7 +1110,7 @@ class MapView extends NativeBridgeComponent(
}
}

_setStyleURL(props: Props) {
_setStyleURL(props: MapViewProps) {
// user set a styleURL, no need to alter props
if (props.styleURL) {
return;
Expand All @@ -1128,7 +1128,7 @@ class MapView extends NativeBridgeComponent(
}
}

_setLocalizeLabels(props: Props) {
_setLocalizeLabels(props: MapViewProps) {
if (!RNMBXModule.MapboxV10) {
return;
}
Expand Down Expand Up @@ -1184,7 +1184,7 @@ class MapView extends NativeBridgeComponent(
}

type NativeProps = Omit<
Props,
MapViewProps,
'onPress' | 'onLongPress' | 'onCameraChanged'
> & {
onPress?: (
Expand Down
6 changes: 3 additions & 3 deletions src/components/MarkerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import PointAnnotation from './PointAnnotation';

const Mapbox = NativeModules.RNMBXModule;

type Props = ViewProps & {
export type MarkerViewProps = ViewProps & {
/**
* The center point (specified as a map coordinate) of the marker.
*/
Expand Down Expand Up @@ -61,8 +61,8 @@ type Props = ViewProps & {
* This component has no dedicated `onPress` method. Instead, you should handle gestures
* with the React views passed in as `children`.
*/
class MarkerView extends React.PureComponent<Props> {
static defaultProps: Partial<Props> = {
class MarkerView extends React.PureComponent<MarkerViewProps> {
static defaultProps: Partial<MarkerViewProps> = {
anchor: { x: 0.5, y: 0.5 },
allowOverlap: false,
allowOverlapWithPuck: false,
Expand Down
93 changes: 54 additions & 39 deletions src/web/components/MapView.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,66 @@
import React from 'react';
import mapboxgl from 'mapbox-gl';
import React, { useEffect, useRef, useState } from 'react';

Check failure on line 2 in src/web/components/MapView.tsx

View workflow job for this annotation

GitHub Actions / lint_test_generate

There should be no empty line within import group

import { point } from '@turf/helpers';

Check failure on line 4 in src/web/components/MapView.tsx

View workflow job for this annotation

GitHub Actions / lint_test_generate

There should be at least one empty line between import groups
import { MapViewProps } from '../../components/MapView';
import MapContext from '../MapContext';

/**
* MapView backed by Mapbox GL KS
*/
class MapView extends React.Component<
{ styleURL: string; children: JSX.Element },
{ map?: object | null }
> {
state = { map: null };
mapContainer: HTMLElement | null = null;
map: object | null = null;

componentDidMount() {
const { styleURL } = this.props;
if (!this.mapContainer) {
console.error('MapView - mapContainer should is null');
export default function MapView(
props: Pick<MapViewProps, 'styleURL' | 'children' | 'onPress'>,
) {
const mapContainerRef = useRef<HTMLDivElement>(null);

const [map, setMap] = useState<mapboxgl.Map | undefined>(undefined);

const _propsRef = useRef(props);
useEffect(() => {
_propsRef.current = props;
}, [props]);

useEffect(() => {
if (mapContainerRef.current === null) {
console.error('MapView - mapContainerRef should not be null');
return;
}
const map = new mapboxgl.Map({
container: this.mapContainer,

// Initialize map
const { styleURL } = props;
const _map = new mapboxgl.Map({
container: mapContainerRef.current,
style: styleURL || 'mapbox://styles/mapbox/streets-v11',
});
this.map = map;
this.setState({ map });
}

render() {
const { children } = this.props;
const { map } = this.state;
return (
<div
style={{ width: '100%', height: '100%' }}
ref={(el) => (this.mapContainer = el)}
>
{map && (
<div style={{ position: 'absolute' }}>
<MapContext.Provider value={{ map }}>
{children}
</MapContext.Provider>
</div>
)}
</div>
);
}
}

export default MapView;
// Set map event listeners
_map.on('click', (e) => {
if (_propsRef.current.onPress === undefined) {
return;
}

_propsRef.current.onPress(point(e.lngLat.toArray()));
});

setMap(_map);

return () => {
_map.remove();
if (_map === map) {
setMap(undefined);
}
};
}, []);

Check failure on line 53 in src/web/components/MapView.tsx

View workflow job for this annotation

GitHub Actions / lint_test_generate

React Hook useEffect has missing dependencies: 'map' and 'props'. Either include them or remove the dependency array

return (
<div style={{ width: '100%', height: '100%' }} ref={mapContainerRef}>
{map && (
<div style={{ position: 'absolute' }}>
<MapContext.Provider value={{ map }}>
{props.children}
</MapContext.Provider>
</div>
)}
</div>
);
}
20 changes: 11 additions & 9 deletions src/web/components/MarkerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
forwardRef,
isValidElement,
memo,
ReactElement,
Ref,
useContext,
useEffect,
Expand All @@ -12,14 +11,13 @@ import {
} from 'react';
import { createPortal } from 'react-dom';

import { MarkerViewProps } from '../../components/MarkerView';
import MapContext from '../MapContext';

type MarkerViewProps = {
coordinate: [number, number];
children?: ReactElement;
};

function MarkerView(props: MarkerViewProps, ref: Ref<Marker>) {
function MarkerView(
props: Pick<MarkerViewProps, 'coordinate' | 'children'>,
ref: Ref<Marker>,
) {
const { map } = useContext(MapContext);

// Create marker instance
Expand All @@ -30,8 +28,12 @@ function MarkerView(props: MarkerViewProps, ref: Ref<Marker>) {
: undefined,
});

// Set marker coordinates
_marker.setLngLat(props.coordinate);
if (props.coordinate.length !== 2) {
console.error('MarkerView - coordinate should be an array of length 2');
} else {
// Set marker coordinates
_marker.setLngLat(props.coordinate as [number, number]);
}

// Fix marker position
const { style } = _marker.getElement();
Expand Down
Loading