diff --git a/types/expo/expo-tests.tsx b/types/expo/expo-tests.tsx index 8778ae655b..f79b044de2 100644 --- a/types/expo/expo-tests.tsx +++ b/types/expo/expo-tests.tsx @@ -33,6 +33,7 @@ import { Linking, Location, MailComposer, + MapView, MediaLibrary, Permissions, PublisherBanner, @@ -835,6 +836,20 @@ async () => { result.status === 'saved'; }; +// #region MapView +() => ( + +); +// #endegion + async () => { const updateEventListener: Updates.UpdateEventListener = ({ type, manifest, message }) => { switch (type) { @@ -914,6 +929,7 @@ async () => { return true; } }; + // #region MediaLibrary async () => { const mlAsset: MediaLibrary.Asset = await MediaLibrary.createAssetAsync('localUri'); diff --git a/types/expo/index.d.ts b/types/expo/index.d.ts index 9e48e391d8..818af22880 100644 --- a/types/expo/index.d.ts +++ b/types/expo/index.d.ts @@ -16,6 +16,8 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 +export { MapView } from './mapview'; + import { EventSubscription } from 'fbemitter'; import { Component, ComponentClass, Ref, ComponentType } from 'react'; import { diff --git a/types/expo/mapview.d.ts b/types/expo/mapview.d.ts new file mode 100644 index 0000000000..1885badf3a --- /dev/null +++ b/types/expo/mapview.d.ts @@ -0,0 +1,421 @@ +// Based on https://github.com/react-community/react-native-maps/blob/master/index.d.ts. + +import * as React from 'react'; +import { + Animated, + ImageRequireSource, + ImageURISource, + NativeSyntheticEvent, + ViewProperties +} from 'react-native'; + +export interface Region { + latitude: number; + longitude: number; + latitudeDelta: number; + longitudeDelta: number; +} + +export interface LatLng { + latitude: number; + longitude: number; +} + +export interface Point { + x: number; + y: number; +} + +// helper interface +export interface MapEvent extends NativeSyntheticEvent { } + +export type LineCapType = 'butt' | 'round' | 'square'; +export type LineJoinType = 'miter' | 'round' | 'bevel'; + +// ======================================================================= +// AnimatedRegion +// ======================================================================= + +export interface AnimatedRegionTimingConfig extends Animated.AnimationConfig, Partial { + easing?: (value: number) => number; + duration?: number; + delay?: number; +} + +export interface AnimatedRegionSpringConfig extends Animated.AnimationConfig, Partial { + overshootClamping?: boolean; + restDisplacementThreshold?: number; + restSpeedThreshold?: number; + velocity?: number | Point; + bounciness?: number; + speed?: number; + tension?: number; + friction?: number; + stiffness?: number; + mass?: number; + damping?: number; +} + +export class AnimatedRegion extends Animated.AnimatedWithChildren { + latitude: Animated.Value; + longitude: Animated.Value; + latitudeDelta: Animated.Value; + longitudeDelta: Animated.Value; + + constructor(region?: Region); + + setValue(value: Region): void; + setOffset(offset: Region): void; + flattenOffset(): void; + stopAnimation(callback?: (region: Region) => void): void; + addListener(callback: (region: Region) => void): string; + removeListener(id: string): void; + spring(config: AnimatedRegionSpringConfig): Animated.CompositeAnimation; + timing(config: AnimatedRegionTimingConfig): Animated.CompositeAnimation; +} + +// ======================================================================= +// MapView (default export) +// ======================================================================= + +/** + * takeSnapshot options + */ +export interface SnapshotOptions { + /** optional, when omitted the view-width is used */ + width?: number; + /** optional, when omitted the view-height is used */ + height?: number; + /** __iOS only__, optional region to render */ + region?: Region; + /** image formats, defaults to 'png' */ + format?: 'png' | 'jpg'; + /** image quality: 0..1 (only relevant for jpg, default: 1) */ + quality?: number; + /** result types, defaults to 'file' */ + result?: 'file' | 'base64'; +} + +/** + * onUserLocationChange parameters + */ +export interface EventUserLocation extends NativeSyntheticEvent<{}> { + nativeEvent: { + coordinate: { + latitude: number, + longitude: number, + altitude: number, + timestamp: number, + accuracy: number, + speed: number, + isFromMockProvider: boolean, + }, + }; +} + +/** + * Map style elements. + * @see https://developers.google.com/maps/documentation/ios-sdk/styling#use_a_string_resource + * @see https://developers.google.com/maps/documentation/android-api/styling + */ +export interface MapStyleElement { + featureType?: string; + elementType?: string; + stylers: object[]; +} + +export interface EdgePadding { + top: number; + right: number; + bottom: number; + left: number; +} + +export interface EdgeInsets { + top: number; + right: number; + bottom: number; + left: number; +} + +export interface KmlMarker { + id: string; + title: string; + description: string; + coordinate: LatLng; + position: Point; +} + +/** + * onKmlReady parameter + */ +export interface KmlMapEvent extends NativeSyntheticEvent<{ markers: KmlMarker[] }> { +} + +export type MapTypes = 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none' | 'mutedStandard'; + +export interface MapViewProps extends ViewProperties { + provider?: 'google' | null; + customMapStyle?: MapStyleElement[]; + customMapStyleString?: string; + showsUserLocation?: boolean; + userLocationAnnotationTitle?: string; + showsMyLocationButton?: boolean; + followsUserLocation?: boolean; + showsPointsOfInterest?: boolean; + showsCompass?: boolean; + zoomEnabled?: boolean; + zoomControlEnabled?: boolean; + rotateEnabled?: boolean; + cacheEnabled?: boolean; + loadingEnabled?: boolean; + loadingBackgroundColor?: string; + loadingIndicatorColor?: string; + scrollEnabled?: boolean; + pitchEnabled?: boolean; + toolbarEnabled?: boolean; + moveOnMarkerPress?: boolean; + showsScale?: boolean; + showsBuildings?: boolean; + showsTraffic?: boolean; + showsIndoors?: boolean; + showsIndoorLevelPicker?: boolean; + mapType?: MapTypes; + region?: Region; + initialRegion?: Region; + liteMode?: boolean; + mapPadding?: EdgePadding; + maxDelta?: number; + minDelta?: number; + legalLabelInsets?: EdgeInsets; + + onMapReady?: () => void; + onKmlReady?: (values: KmlMapEvent) => void; + onRegionChange?: (region: Region) => void; + onRegionChangeComplete?: (region: Region) => void; + onPress?: (event: MapEvent) => void; + onLongPress?: (event: MapEvent) => void; + onUserLocationChange?: (event: EventUserLocation) => void; + onPanDrag?: (event: MapEvent) => void; + onPoiClick?: (event: MapEvent<{ placeId: string, name: string }>) => void; + onMarkerPress?: (event: MapEvent<{ action: 'marker-press', id: string }>) => void; + onMarkerSelect?: (event: MapEvent<{ action: 'marker-select', id: string }>) => void; + onMarkerDeselect?: (event: MapEvent<{ action: 'marker-deselect', id: string }>) => void; + onCalloutPress?: (event: MapEvent<{ action: 'callout-press' }>) => void; + onMarkerDragStart?: (event: MapEvent) => void; + onMarkerDrag?: (event: MapEvent) => void; + onMarkerDragEnd?: (event: MapEvent) => void; + + minZoomLevel?: number; + maxZoomLevel?: number; + kmlSrc?: string; +} + +export class MapView extends React.Component { + animateToNavigation(location: LatLng, bearing: number, angle: number, duration?: number): void; + animateToRegion(region: Region, duration?: number): void; + animateToCoordinate(latLng: LatLng, duration?: number): void; + animateToBearing(bearing: number, duration?: number): void; + animateToViewingAngle(angle: number, duration?: number): void; + fitToElements(animated: boolean): void; + fitToSuppliedMarkers(markers: string[], options?: { edgePadding?: EdgePadding, animated?: boolean }): void; + fitToCoordinates(coordinates?: LatLng[], options?: { edgePadding?: EdgePadding, animated?: boolean }): void; + setMapBoundaries(northEast: LatLng, southWest: LatLng): void; + takeSnapshot(options?: SnapshotOptions): Promise; +} + +export class MapViewAnimated extends MapView { +} + +// ======================================================================= +// Marker +// ======================================================================= + +export interface MarkerProps extends ViewProperties { + identifier?: string; + reuseIdentifier?: string; + title?: string; + description?: string; + image?: ImageURISource | ImageRequireSource; + opacity?: number; + pinColor?: string; + coordinate: LatLng | AnimatedRegion; + centerOffset?: Point; + calloutOffset?: Point; + anchor?: Point; + calloutAnchor?: Point; + flat?: boolean; + draggable?: boolean; + tracksViewChanges?: boolean; + tracksInfoWindowChanges?: boolean; + stopPropagation?: boolean; + onPress?: (event: MapEvent<{ action: 'marker-press', id: string }>) => void; + onSelect?: (event: MapEvent<{ action: 'marker-select', id: string }>) => void; + onDeselect?: (event: MapEvent<{ action: 'marker-deselect', id: string }>) => void; + onCalloutPress?: (event: MapEvent<{ action: 'callout-press' }>) => void; + onDragStart?: (event: MapEvent) => void; + onDrag?: (event: MapEvent) => void; + onDragEnd?: (event: MapEvent) => void; + + rotation?: number; + zIndex?: number; +} + +export class Marker extends React.Component { + /** + * Shows the callout for this marker + */ + showCallout(): void; + /** + * Hides the callout for this marker + */ + hideCallout(): void; + /** + * Animates marker movement. + * __Android only__ + */ + animateMarkerToCoordinate(coordinate: LatLng, duration?: number): void; +} + +export class MarkerAnimated extends Marker { +} + +// ======================================================================= +// Callout +// ======================================================================= + +export interface MapCalloutProps extends ViewProperties { + tooltip?: boolean; + onPress?: (event: MapEvent<{ action: 'callout-press' }>) => void; +} + +export class Callout extends React.Component { +} + +// ======================================================================= +// Polyline +// ======================================================================= + +export interface MapPolylineProps extends ViewProperties { + coordinates: LatLng[]; + onPress?: (event: MapEvent) => void; + tappable?: boolean; + fillColor?: string; + strokeWidth?: number; + strokeColor?: string; + strokeColors?: string[]; + zIndex?: number; + lineCap?: LineCapType; + lineJoin?: LineJoinType; + miterLimit?: number; + geodesic?: boolean; + lineDashPhase?: number; + lineDashPattern?: number[]; +} + +export class Polyline extends React.Component { +} + +// ======================================================================= +// Polygon +// ======================================================================= + +export interface MapPolygonProps extends ViewProperties { + coordinates: LatLng[]; + holes?: LatLng[][]; + onPress?: (event: MapEvent) => void; + tappable?: boolean; + strokeWidth?: number; + strokeColor?: string; + fillColor?: string; + zIndex?: number; + lineCap?: LineCapType; + lineJoin?: LineJoinType; + miterLimit?: number; + geodesic?: boolean; + lineDashPhase?: number; + lineDashPattern?: number[]; +} + +export class Polygon extends React.Component { +} + +// ======================================================================= +// Circle +// ======================================================================= + +export interface MapCircleProps extends ViewProperties { + center: LatLng; + radius: number; + onPress?: (event: MapEvent) => void; + strokeWidth?: number; + strokeColor?: string; + fillColor?: string; + zIndex?: number; + lineCap?: LineCapType; + lineJoin?: LineJoinType; + miterLimit?: number; + lineDashPhase?: number; + lineDashPattern?: number[]; +} + +export class Circle extends React.Component { +} + +// ======================================================================= +// UrlTile & LocalTile +// ======================================================================= + +export interface MapUrlTileProps extends ViewProperties { + urlTemplate: string; + maximumZ?: number; + zIndex?: number; +} + +export class UrlTile extends React.Component { +} + +export interface MapLocalTileProps extends ViewProperties { + pathTemplate: string; + tileSize?: number; + zIndex?: number; +} + +export class LocalTile extends React.Component { +} + +// ======================================================================= +// Overlay +// ======================================================================= + +export type Coordinate = [number, number]; + +export interface MapOverlayProps extends ViewProperties { + image?: ImageURISource | ImageRequireSource; + bounds: [Coordinate, Coordinate]; +} + +export class Overlay extends React.Component { +} + +export class OverlayAnimated extends Overlay { +} + +// ======================================================================= +// Constants +// ======================================================================= + +export const MAP_TYPES: { + STANDARD: MapTypes, + SATELLITE: MapTypes, + HYBRID: MapTypes, + TERRAIN: MapTypes, + NONE: MapTypes, + MUTEDSTANDARD: MapTypes, +}; + +export const PROVIDER_DEFAULT: null; +export const PROVIDER_GOOGLE: 'google'; diff --git a/types/expo/tsconfig.json b/types/expo/tsconfig.json index e00f046e0e..f05d1c29ef 100644 --- a/types/expo/tsconfig.json +++ b/types/expo/tsconfig.json @@ -17,6 +17,7 @@ }, "files": [ "index.d.ts", + "mapview.d.ts", "expo-tests.tsx" ] }