diff --git a/src/components/attribution-control.ts b/src/components/attribution-control.ts index be095742..592d66ed 100644 --- a/src/components/attribution-control.ts +++ b/src/components/attribution-control.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import mapboxgl from '../utils/mapboxgl'; import useControl from './use-control'; -import type {ControlPosition} from '../utils/types'; +import type {ControlPosition} from '../types'; export type AttributionControlProps = { /** diff --git a/src/components/fullscreen-control.ts b/src/components/fullscreen-control.ts index 43bb521d..c594194c 100644 --- a/src/components/fullscreen-control.ts +++ b/src/components/fullscreen-control.ts @@ -3,7 +3,7 @@ import * as React from 'react'; import mapboxgl from '../utils/mapboxgl'; import useControl from './use-control'; -import type {ControlPosition} from '../utils/types'; +import type {ControlPosition} from '../types'; export type FullscreenControlProps = { /** Id of the DOM element which should be made full screen. By default, the map container diff --git a/src/components/geolocate-control.ts b/src/components/geolocate-control.ts index fba37930..567e15f1 100644 --- a/src/components/geolocate-control.ts +++ b/src/components/geolocate-control.ts @@ -10,7 +10,7 @@ import type { MapboxEvent, GeolocateEvent, GeolocateErrorEvent -} from '../utils/types'; +} from '../types'; export type GeolocateControlRef = { /** Triggers a geolocate event */ @@ -18,25 +18,34 @@ export type GeolocateControlRef = { }; export type GeolocateControlProps = { - /** A Geolocation API PositionOptions object. */ + /** + * A Geolocation API PositionOptions object. + * @default {enableHighAccuracy:false,timeout:6000} + */ positionOptions?: PositionOptions; /** A Map#fitBounds options object to use when the map is panned and zoomed to the user's location. - * The default is to use a maxZoom of 15 to limit how far the map will zoom in for very accurate locations. + * @default {maxZoom:15} */ fitBoundsOptions?: FitBoundsOptions; /** If true the GeolocateControl becomes a toggle button and when active the map will receive * updates to the user's location as it changes. Default false. + * @default false */ trackUserLocation?: boolean; /** Draw a transparent circle will be drawn around the user location indicating the accuracy * (95% confidence level) of the user's location. Set to false to disable. - * This only has effect if `showUserLocation` is true. Default true. + * This only has effect if `showUserLocation` is true. + * @default true */ showAccuracyCircle?: boolean; - /** Show a dot on the map at the user's location. Set to false to disable. Default true. */ + /** + * Show a dot on the map at the user's location. Set to false to disable. + * @default true + */ showUserLocation?: boolean; /** If true an arrow will be drawn next to the user location dot indicating the device's heading. * This only has affect when `trackUserLocation` is true. Default false. + * @default false */ showUserHeading?: boolean; /** Placement of the control relative to the map. */ @@ -96,4 +105,6 @@ const GeolocateControl = forwardRef( return null; }); +GeolocateControl.displayName = 'GeolocateControl'; + export default React.memo(GeolocateControl); diff --git a/src/components/layer.ts b/src/components/layer.ts index 80c498d9..4b651295 100644 --- a/src/components/layer.ts +++ b/src/components/layer.ts @@ -3,10 +3,11 @@ import {MapContext} from './map'; import assert from '../utils/assert'; import {deepEqual} from '../utils/deep-equal'; -import type {MapboxMap, AnyLayer} from '../utils/types'; +import type {MapboxMap, AnyLayer} from '../types'; export type LayerProps = AnyLayer & { id?: string; + /** If set, the layer will be inserted before the specified layer */ beforeId?: string; }; diff --git a/src/components/map.tsx b/src/components/map.tsx index 30955c1f..4bd60c95 100644 --- a/src/components/map.tsx +++ b/src/components/map.tsx @@ -2,11 +2,12 @@ import * as React from 'react'; import {useState, useRef, useEffect, useContext, forwardRef, useImperativeHandle} from 'react'; import {MountedMapsContext} from './use-map'; +import mapboxgl from '../utils/mapboxgl'; import Mapbox, {MapboxProps} from '../mapbox/mapbox'; import createRef, {MapRef} from '../mapbox/create-ref'; import type {CSSProperties} from 'react'; -import type {MapboxMap} from '../utils/types'; +import type {MapboxMap} from '../types'; import useIsomorphicLayoutEffect from '../utils/use-isomorphic-layout-effect'; export const MapContext = React.createContext(null); @@ -17,8 +18,6 @@ export type MapProps = MapboxProps & { /** Map container CSS style */ style?: CSSProperties; children?: any; - - ref?: React.Ref; }; const defaultProps: MapProps = { @@ -51,7 +50,7 @@ const Map = forwardRef((props, ref) => { const containerRef = useRef(); useEffect(() => { - const map = new Mapbox(props); + const map = new Mapbox(mapboxgl.Map, props); map.initialize(containerRef.current); setMapInstance(map); mountedMapsContext?.onMapMount(createRef(map), props.id); @@ -86,6 +85,7 @@ const Map = forwardRef((props, ref) => { ); }); +Map.displayName = 'Map'; Map.defaultProps = defaultProps; export default Map; diff --git a/src/components/marker.ts b/src/components/marker.ts index bdb8baf7..5608e43e 100644 --- a/src/components/marker.ts +++ b/src/components/marker.ts @@ -4,14 +4,58 @@ import {createPortal} from 'react-dom'; import {useEffect, useState, useRef, useContext} from 'react'; import mapboxgl from '../utils/mapboxgl'; -import type {MarkerDragEvent, MarkerOptions, MapboxPopup} from '../utils/types'; +import type {MarkerDragEvent, MapboxPopup, PointLike, Anchor, Alignment} from '../types'; import {MapContext} from './map'; import {arePointsEqual} from '../utils/deep-equal'; -export type MarkerProps = Omit & { +export type MarkerProps = { + /** Longitude of the anchor location */ longitude: number; + /** Latitude of the anchor location */ latitude: number; + /** A string indicating the part of the Marker that should be positioned closest to the coordinate set via Marker.setLngLat. + * Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. + * @default "center" + */ + anchor?: Anchor; + /** + * The max number of pixels a user can shift the mouse pointer during a click on the marker for it to be considered a valid click + * (as opposed to a marker drag). The default (0) is to inherit map's clickTolerance. + */ + clickTolerance?: number; + /** The color to use for the default marker if options.element is not provided. + * @default "#3FB1CE" + */ + color?: string; + /** A boolean indicating whether or not a marker is able to be dragged to a new position on the map. + * @default false + */ + draggable?: boolean; + /** The offset in pixels as a PointLike object to apply relative to the element's center. Negatives indicate left and up. */ + offset?: PointLike; + /** `map` aligns the `Marker` to the plane of the map. + * `viewport` aligns the `Marker` to the plane of the viewport. + * `auto` automatically matches the value of `rotationAlignment`. + * @default "auto" + */ + pitchAlignment?: Alignment; + /** The rotation angle of the marker in degrees, relative to its `rotationAlignment` setting. A positive value will rotate the marker clockwise. + * @default 0 + */ + rotation?: number; + /** `map` aligns the `Marker`'s rotation relative to the map, maintaining a bearing as the map rotates. + * `viewport` aligns the `Marker`'s rotation relative to the viewport, agnostic to map rotations. + * `auto` is equivalent to `viewport`. + * @default "auto" + */ + rotationAlignment?: Alignment; + /** The scale to use for the default marker if options.element is not provided. + * The default scale (1) corresponds to a height of `41px` and a width of `27px`. + * @default 1 + */ + scale?: number; + /** A Popup instance that is bound to the marker */ popup?: MapboxPopup; onDragStart?: (e: MarkerDragEvent) => void; onDrag?: (e: MarkerDragEvent) => void; diff --git a/src/components/navigation-control.ts b/src/components/navigation-control.ts index a5fd54e7..2e2ce9e7 100644 --- a/src/components/navigation-control.ts +++ b/src/components/navigation-control.ts @@ -2,14 +2,20 @@ import * as React from 'react'; import mapboxgl from '../utils/mapboxgl'; import useControl from './use-control'; -import type {ControlPosition} from '../utils/types'; +import type {ControlPosition} from '../types'; export type NavigationControlProps = { - /** If true the compass button is included. */ + /** If true the compass button is included. + * @default true + */ showCompass?: boolean; - /** If true the zoom-in and zoom-out buttons are included. */ + /** If true the zoom-in and zoom-out buttons are included. + * @default true + */ showZoom?: boolean; - /** If true the pitch is visualized by rotating X-axis of compass. */ + /** If true the pitch is visualized by rotating X-axis of compass. + * @default false + */ visualizePitch?: boolean; /** Placement of the control relative to the map. */ position?: ControlPosition; diff --git a/src/components/popup.ts b/src/components/popup.ts index cdf5ce3c..1ab815e8 100644 --- a/src/components/popup.ts +++ b/src/components/popup.ts @@ -4,14 +4,59 @@ import {createPortal} from 'react-dom'; import {useEffect, useState, useRef, useContext} from 'react'; import mapboxgl from '../utils/mapboxgl'; -import type {PopupOptions, MapboxEvent} from '../utils/types'; +import type {MapboxEvent, Anchor, PointLike} from '../types'; import {MapContext} from './map'; import {deepEqual} from '../utils/deep-equal'; -export type PopupProps = PopupOptions & { +export type PopupProps = { + /** Longitude of the anchor location */ longitude: number; + /** Latitude of the anchor location */ latitude: number; + /** + * A string indicating the part of the popup that should be positioned closest to the coordinate. + * Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, `'top-right'`, `'bottom-left'`, + * and `'bottom-right'`. If unset, the anchor will be dynamically set to ensure the popup falls within the map + * container with a preference for `'bottom'`. + */ + anchor?: Anchor; + /** + * If `true`, a close button will appear in the top right corner of the popup. + * @default true + */ + closeButton?: boolean; + /** + * If `true`, the popup will close when the map is clicked. + * @default true + */ + closeOnClick?: boolean; + /** + * If `true`, the popup will closed when the map moves. + * @default false + */ + closeOnMove?: boolean; + /** + * If `true`, the popup will try to focus the first focusable element inside the popup. + * @default true + */ + focusAfterOpen?: boolean; + /** + * A pixel offset applied to the popup's location specified as: + * - a single number specifying a distance from the popup's location + * - a PointLike specifying a constant offset + * - an object of Points specifing an offset for each anchor position. + */ + offset?: number | PointLike | Partial<{[anchor in Anchor]: PointLike}>; + /** Space-separated CSS class names to add to popup container. */ + className?: string; + /** + * A string that sets the CSS property of the popup's maximum width (for example, `'300px'`). + * To ensure the popup resizes to fit its content, set this property to `'none'` + * @default "240px" + */ + maxWidth?: string; + onOpen?: (e: MapboxEvent) => void; onClose?: (e: MapboxEvent) => void; children?: React.ReactNode; diff --git a/src/components/scale-control.ts b/src/components/scale-control.ts index 1b54d28a..ebcc5be7 100644 --- a/src/components/scale-control.ts +++ b/src/components/scale-control.ts @@ -2,12 +2,16 @@ import * as React from 'react'; import mapboxgl from '../utils/mapboxgl'; import useControl from './use-control'; -import type {ControlPosition} from '../utils/types'; +import type {ControlPosition} from '../types'; export type ScaleControlProps = { - /** Unit of the distance. Default 'metric'. */ + /** Unit of the distance. + * @default "metric" + */ unit?: 'imperial' | 'metric' | 'nautical'; - /** The maximum length of the scale control in pixels. Default 100. */ + /** The maximum length of the scale control in pixels. + * @default 100 + */ maxWidth?: number; /** Placement of the control relative to the map. */ position?: ControlPosition; diff --git a/src/components/source.ts b/src/components/source.ts index 81e9345e..c4aa1deb 100644 --- a/src/components/source.ts +++ b/src/components/source.ts @@ -12,7 +12,7 @@ import type { ImageSource, VideoSource, AnySourceImpl -} from '../utils/types'; +} from '../types'; export type SourceProps = AnySourceData & { id?: string; diff --git a/src/components/use-control.ts b/src/components/use-control.ts index 90293e92..3844258b 100644 --- a/src/components/use-control.ts +++ b/src/components/use-control.ts @@ -1,5 +1,5 @@ import {useContext, useState, useEffect} from 'react'; -import type {IControl, ControlPosition, MapboxMap} from '../utils/types'; +import type {IControl, ControlPosition, MapboxMap} from '../types'; import {MapContext} from './map'; export default function useControl( diff --git a/src/index.ts b/src/index.ts index 3cb8bd6b..6cd02367 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,4 +27,4 @@ export {default as useControl} from './components/use-control'; export {MapProvider, useMap} from './components/use-map'; // Types -export * from './utils/types'; +export * from './types/external'; diff --git a/src/mapbox/create-ref.ts b/src/mapbox/create-ref.ts index ffd5d54e..4ab2a8bb 100644 --- a/src/mapbox/create-ref.ts +++ b/src/mapbox/create-ref.ts @@ -1,4 +1,4 @@ -import type {MapboxMap, ViewState} from '../utils/types'; +import type {MapboxMap, ViewState} from '../types'; import type Mapbox from './mapbox'; /** mapboxgl.Map methods to forward to the ref object diff --git a/src/mapbox/mapbox.ts b/src/mapbox/mapbox.ts index 8fc1426b..c823811f 100644 --- a/src/mapbox/mapbox.ts +++ b/src/mapbox/mapbox.ts @@ -1,4 +1,3 @@ -import mapboxgl from '../utils/mapboxgl'; import {Transform, transformToViewState, applyViewStateToTransform} from '../utils/transform'; import {normalizeStyle} from '../utils/style-utils'; import {deepEqual} from '../utils/deep-equal'; @@ -7,7 +6,9 @@ import type { ProjectionSpecification, ViewState, ViewStateChangeEvent, - MapboxOptions, + DragPanOptions, + InteractiveOptions, + TransformRequestFunction, MapboxStyle, ImmutableLike, LngLatBoundsLike, @@ -21,85 +22,292 @@ import type { ErrorEvent, MapboxGeoJSONFeature, MapboxMap -} from '../utils/types'; +} from '../types'; -export type MapboxProps = Omit< - MapboxOptions, - 'center' | 'accessToken' | 'container' | 'style' | 'bounds' | 'fitBoundsOptions' -> & - ViewState & { - mapboxAccessToken?: string; +export type MapboxProps = ViewState & { + // Init options + mapboxAccessToken?: string; - /** Camera options used when constructing the Map instance */ - initialViewState?: ViewState & { - bounds?: LngLatBoundsLike; - fitBoundsOptions?: FitBoundsOptions; - }; - - /** If provided, render into an external WebGL context */ - gl?: WebGLRenderingContext; - - /** Aternative way to specify camera state */ - viewState?: ViewState; - - /** Mapbox style */ - mapStyle?: string | MapboxStyle | ImmutableLike; - /** Enable diffing when the map style changes */ - styleDiffing?: boolean; - /** Default layers to query on pointer events */ - interactiveLayerIds?: string[]; - /** The projection the map should be rendered in */ - projection?: ProjectionSpecification | string; - /** CSS cursor */ - cursor?: string; - - // Callbacks - onMouseDown?: (e: MapLayerMouseEvent) => void; - onMouseUp?: (e: MapLayerMouseEvent) => void; - onMouseOver?: (e: MapLayerMouseEvent) => void; - onMouseMove?: (e: MapLayerMouseEvent) => void; - onClick?: (e: MapLayerMouseEvent) => void; - onDblClick?: (e: MapLayerMouseEvent) => void; - onMouseEnter?: (e: MapLayerMouseEvent) => void; - onMouseLeave?: (e: MapLayerMouseEvent) => void; - onMouseOut?: (e: MapLayerMouseEvent) => void; - onContextMenu?: (e: MapLayerMouseEvent) => void; - onWheel?: (e: MapWheelEvent) => void; - onTouchStart?: (e: MapLayerTouchEvent) => void; - onTouchEnd?: (e: MapLayerTouchEvent) => void; - onTouchMove?: (e: MapLayerTouchEvent) => void; - onTouchCancel?: (e: MapLayerTouchEvent) => void; - - onMoveStart?: (e: ViewStateChangeEvent) => void; - onMove?: (e: ViewStateChangeEvent) => void; - onMoveEnd?: (e: ViewStateChangeEvent) => void; - onDragStart?: (e: ViewStateChangeEvent) => void; - onDrag?: (e: ViewStateChangeEvent) => void; - onDragEnd?: (e: ViewStateChangeEvent) => void; - onZoomStart?: (e: ViewStateChangeEvent) => void; - onZoom?: (e: ViewStateChangeEvent) => void; - onZoomEnd?: (e: ViewStateChangeEvent) => void; - onRotateStart?: (e: ViewStateChangeEvent) => void; - onRotate?: (e: ViewStateChangeEvent) => void; - onRotateEnd?: (e: ViewStateChangeEvent) => void; - onPitchStart?: (e: ViewStateChangeEvent) => void; - onPitch?: (e: ViewStateChangeEvent) => void; - onPitchEnd?: (e: ViewStateChangeEvent) => void; - onBoxZoomStart?: (e: ViewStateChangeEvent) => void; - onBoxZoomEnd?: (e: ViewStateChangeEvent) => void; - onBoxZoomCancel?: (e: ViewStateChangeEvent) => void; - - onResize?: (e: MapboxEvent) => void; - onLoad?: (e: MapboxEvent) => void; - onRender?: (e: MapboxEvent) => void; - onIdle?: (e: MapboxEvent) => void; - onError?: (e: ErrorEvent) => void; - onRemove?: (e: MapboxEvent) => void; - onData?: (e: MapDataEvent) => void; - onStyleData?: (e: MapDataEvent) => void; - onSourceData?: (e: MapDataEvent) => void; + /** Camera options used when constructing the Map instance */ + initialViewState?: ViewState & { + /** The initial bounds of the map. If bounds is specified, it overrides longitude, latitude and zoom options. */ + bounds?: LngLatBoundsLike; + /** A fitBounds options object to use only when setting the bounds option. */ + fitBoundsOptions?: FitBoundsOptions; }; + /** If provided, render into an external WebGL context */ + gl?: WebGLRenderingContext; + + /** + * If true, the gl context will be created with MSA antialiasing, which can be useful for antialiasing custom layers. + * This is false by default as a performance optimization. + * @default false + */ + antialias?: boolean; + /** + * If true, an attribution control will be added to the map. + * @default true + */ + attributionControl?: boolean; + /** + * Snap to north threshold in degrees. + * @default 7 + */ + bearingSnap?: number; + /** + * The max number of pixels a user can shift the mouse pointer during a click for it to be + * considered a valid click (as opposed to a mouse drag). + * @default 3 + */ + clickTolerance?: number; + /** + * If `true`, Resource Timing API information will be collected for requests made by GeoJSON + * and Vector Tile web workers (this information is normally inaccessible from the main + * Javascript thread). Information will be returned in a `resourceTiming` property of + * relevant `data` events. + * @default false + */ + collectResourceTiming?: boolean; + /** + * If `true` , scroll zoom will require pressing the ctrl or ⌘ key while scrolling to zoom map, + * and touch pan will require using two fingers while panning to move the map. + * Touch pitch will require three fingers to activate if enabled. + */ + cooperativeGestures?: boolean; + /** + * If `true`, symbols from multiple sources can collide with each other during collision + * detection. If `false`, collision detection is run separately for the symbols in each source. + * @default true + */ + crossSourceCollisions?: boolean; + /** String or strings to show in an AttributionControl. + * Only applicable if options.attributionControl is `true`. */ + customAttribution?: string | string[]; + /** + * Controls the duration of the fade-in/fade-out animation for label collisions, in milliseconds. + * This setting affects all symbol layers. This setting does not affect the duration of runtime + * styling transitions or raster tile cross-fading. + * @default 300 + */ + fadeDuration?: number; + /** If true, map creation will fail if the implementation determines that the performance of the created WebGL context would be dramatically lower than expected. + * @default false + */ + failIfMajorPerformanceCaveat?: boolean; + /** If `true`, the map's position (zoom, center latitude, center longitude, bearing, and pitch) will be synced with the hash fragment of the page's URL. + * For example, `http://path/to/my/page.html#2.59/39.26/53.07/-24.1/60`. + * An additional string may optionally be provided to indicate a parameter-styled hash, + * e.g. http://path/to/my/page.html#map=2.59/39.26/53.07/-24.1/60&foo=bar, where foo + * is a custom parameter and bar is an arbitrary hash distinct from the map hash. + */ + hash?: boolean | string; + /** If false, no mouse, touch, or keyboard listeners are attached to the map, so it will not respond to input + * @default true + */ + interactive?: boolean; + /** A patch to apply to the default localization table for UI strings, e.g. control tooltips. + * The `locale` object maps namespaced UI string IDs to translated strings in the target language; + * see `src/ui/default_locale.js` for an example with all supported string IDs. + * The object may specify all UI strings (thereby adding support for a new translation) or + * only a subset of strings (thereby patching the default translation table). + */ + locale?: {[key: string]: string}; + /** + * Overrides the generation of all glyphs and font settings except font-weight keywords + * Also overrides localIdeographFontFamily + * @default null + */ + localFontFamily?: string; + /** + * If specified, defines a CSS font-family for locally overriding generation of glyphs in the + * 'CJK Unified Ideographs' and 'Hangul Syllables' ranges. In these ranges, font settings from + * the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold). + * The purpose of this option is to avoid bandwidth-intensive glyph server requests. + * @default "sans-serif" + */ + localIdeographFontFamily?: string; + /** + * A string representing the position of the Mapbox wordmark on the map. + * @default "bottom-left" + */ + logoPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'; + /** + * The maximum number of tiles stored in the tile cache for a given source. If omitted, the + * cache will be dynamically sized based on the current viewport. + * @default null + */ + maxTileCacheSize?: number; + /** + * If true, map will prioritize rendering for performance by reordering layers + * If false, layers will always be drawn in the specified order + * @default true + */ + optimizeForTerrain?: boolean; + /** + * If `false`, the map's pitch (tilt) control with "drag to rotate" interaction will be disabled. + * @default true + */ + pitchWithRotate?: boolean; + /** If true, The maps canvas can be exported to a PNG using map.getCanvas().toDataURL();. This is false by default as a performance optimization. + * @default false + */ + preserveDrawingBuffer?: boolean; + /** + * If `false`, the map won't attempt to re-request tiles once they expire per their HTTP + * `cacheControl`/`expires` headers. + * @default true + */ + refreshExpiredTiles?: boolean; + /** + * Allows for the usage of the map in automated tests without an accessToken with custom self-hosted test fixtures. + * @default null + */ + testMode?: boolean; + /** + * If true, the map will automatically resize when the browser window resizes + * @default true + */ + trackResize?: boolean; + /** + * A callback run before the Map makes a request for an external URL. The callback can be + * used to modify the url, set headers, or set the credentials property for cross-origin requests. + * @default null + */ + transformRequest?: TransformRequestFunction; + + // Handlers + + /** + * If true, enable the "box zoom" interaction (see BoxZoomHandler) + * @default true + */ + boxZoom?: boolean; + /** + * If true, enable the "double click to zoom" interaction (see DoubleClickZoomHandler). + * @default true + */ + doubleClickZoom?: boolean; + /** + * If `true`, the "drag to pan" interaction is enabled. + * An `Object` value is passed as options to {@link DragPanHandler#enable}. + * @default true + */ + dragPan?: boolean | DragPanOptions; + /** + * If true, enable the "drag to rotate" interaction (see DragRotateHandler). + * @default true + */ + dragRotate?: boolean; + /** + * If true, enable keyboard shortcuts (see KeyboardHandler). + * @default true + */ + keyboard?: boolean; + /** + * If `true`, the "scroll to zoom" interaction is enabled. + * An `Object` value is passed as options to {@link ScrollZoomHandler#enable}. + * @default true + */ + scrollZoom?: boolean | InteractiveOptions; + /** + * If `true`, the "drag to pitch" interaction is enabled. + * An `Object` value is passed as options to {@link TouchPitchHandler#enable}. + * @default true + */ + touchPitch?: boolean | InteractiveOptions; + /** + * If `true`, the "pinch to rotate and zoom" interaction is enabled. + * An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}. + * @default true + */ + touchZoomRotate?: boolean | InteractiveOptions; + + // Constraints + + /** If set, the map is constrained to the given bounds. */ + maxBounds?: LngLatBoundsLike; + /** Maximum pitch of the map. */ + maxPitch?: number; + /** Maximum zoom of the map. */ + maxZoom?: number; + /** Minimum pitch of the map. */ + minPitch?: number; + /** Minimum zoom of the map. */ + minZoom?: number; + + /** Aternative way to specify camera state */ + viewState?: ViewState; + + // Styling + + /** Mapbox style */ + mapStyle?: string | MapboxStyle | ImmutableLike; + /** Enable diffing when the map style changes + * @default true + */ + styleDiffing?: boolean; + /** Default layers to query on pointer events */ + interactiveLayerIds?: string[]; + /** The projection the map should be rendered in + * @default "mercator" + */ + projection?: ProjectionSpecification | string; + /** + * If `true`, multiple copies of the world will be rendered, when zoomed out. + * @default true + */ + renderWorldCopies?: boolean; + /** CSS cursor */ + cursor?: string; + + // Callbacks + onMouseDown?: (e: MapLayerMouseEvent) => void; + onMouseUp?: (e: MapLayerMouseEvent) => void; + onMouseOver?: (e: MapLayerMouseEvent) => void; + onMouseMove?: (e: MapLayerMouseEvent) => void; + onClick?: (e: MapLayerMouseEvent) => void; + onDblClick?: (e: MapLayerMouseEvent) => void; + onMouseEnter?: (e: MapLayerMouseEvent) => void; + onMouseLeave?: (e: MapLayerMouseEvent) => void; + onMouseOut?: (e: MapLayerMouseEvent) => void; + onContextMenu?: (e: MapLayerMouseEvent) => void; + onWheel?: (e: MapWheelEvent) => void; + onTouchStart?: (e: MapLayerTouchEvent) => void; + onTouchEnd?: (e: MapLayerTouchEvent) => void; + onTouchMove?: (e: MapLayerTouchEvent) => void; + onTouchCancel?: (e: MapLayerTouchEvent) => void; + + onMoveStart?: (e: ViewStateChangeEvent) => void; + onMove?: (e: ViewStateChangeEvent) => void; + onMoveEnd?: (e: ViewStateChangeEvent) => void; + onDragStart?: (e: ViewStateChangeEvent) => void; + onDrag?: (e: ViewStateChangeEvent) => void; + onDragEnd?: (e: ViewStateChangeEvent) => void; + onZoomStart?: (e: ViewStateChangeEvent) => void; + onZoom?: (e: ViewStateChangeEvent) => void; + onZoomEnd?: (e: ViewStateChangeEvent) => void; + onRotateStart?: (e: ViewStateChangeEvent) => void; + onRotate?: (e: ViewStateChangeEvent) => void; + onRotateEnd?: (e: ViewStateChangeEvent) => void; + onPitchStart?: (e: ViewStateChangeEvent) => void; + onPitch?: (e: ViewStateChangeEvent) => void; + onPitchEnd?: (e: ViewStateChangeEvent) => void; + onBoxZoomStart?: (e: ViewStateChangeEvent) => void; + onBoxZoomEnd?: (e: ViewStateChangeEvent) => void; + onBoxZoomCancel?: (e: ViewStateChangeEvent) => void; + + onResize?: (e: MapboxEvent) => void; + onLoad?: (e: MapboxEvent) => void; + onRender?: (e: MapboxEvent) => void; + onIdle?: (e: MapboxEvent) => void; + onError?: (e: ErrorEvent) => void; + onRemove?: (e: MapboxEvent) => void; + onData?: (e: MapDataEvent) => void; + onStyleData?: (e: MapDataEvent) => void; + onSourceData?: (e: MapDataEvent) => void; +}; + const pointerEvents = { mousedown: 'onMouseDown', mouseup: 'onMouseUp', @@ -171,6 +379,7 @@ const handlerNames: (keyof MapboxProps)[] = [ * A wrapper for mapbox-gl's Map class */ export default class Mapbox { + private _MapClass: typeof MapboxMap; // mapboxgl.Map instance. Not using type here because we are accessing // private members and methods private _map: any = null; @@ -195,7 +404,8 @@ export default class Mapbox { private _rotated: boolean = false; private _nextProps: MapboxProps | null; - constructor(props: MapboxProps) { + constructor(MapClass: typeof MapboxMap, props: MapboxProps) { + this._MapClass = MapClass; this.props = props; } @@ -263,7 +473,7 @@ export default class Mapbox { }; } - const map: any = new mapboxgl.Map(mapOptions); + const map: any = new this._MapClass(mapOptions); if (viewState.padding) { map.setPadding(viewState.padding); } @@ -429,6 +639,7 @@ export default class Mapbox { if (this.props.onError) { this.props.onError(e); } else { + // eslint-disable-next-line console.error(e.error); } }; @@ -520,6 +731,8 @@ export default class Mapbox { // @ts-ignore this._updateHover(event); break; + + default: } if (eventType in cameraEvents) { if (typeof event === 'object') { diff --git a/src/utils/types.ts b/src/types/external.ts similarity index 91% rename from src/utils/types.ts rename to src/types/external.ts index eeeba700..1d9c8542 100644 --- a/src/utils/types.ts +++ b/src/types/external.ts @@ -30,6 +30,14 @@ export type ViewState = { padding?: PaddingOptions; }; +export type ControlPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; + +export interface ImmutableLike { + toJS: () => any; +} + +/* Events */ + export type ViewStateChangeEvent = MapboxEvent & { viewState: ViewState; }; @@ -42,13 +50,8 @@ export type GeolocateEvent = MapboxEvent & GeolocationPosition; export type GeolocateErrorEvent = MapboxEvent & GeolocationPositionError; -export type ControlPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; +/* re-export mapbox types */ -export interface ImmutableLike { - toJS: () => any; -} - -// re-export mapbox types export type { Point, PointLike, @@ -56,14 +59,15 @@ export type { LngLatLike, LngLatBounds, LngLatBoundsLike, - MapboxOptions, - MarkerOptions, - PopupOptions, + Anchor, + Alignment, PaddingOptions, PositionOptions, FitBoundsOptions, + DragPanOptions, + InteractiveOptions, + TransformRequestFunction, Style as MapboxStyle, - AnyLayer, BackgroundLayer, CircleLayer, FillExtrusionLayer, @@ -75,12 +79,10 @@ export type { SymbolLayer, CustomLayerInterface, SkyLayer, - AnySourceData, GeoJSONSourceRaw, VideoSourceRaw, ImageSourceRaw, CanvasSourceRaw, - AnySourceImpl, GeoJSONSource, VideoSource, ImageSource, @@ -98,7 +100,5 @@ export type { ErrorEvent, MapboxGeoJSONFeature, IControl, - Map as MapboxMap, - Marker as MapboxMarker, - Popup as MapboxPopup + Map as MapboxMap } from 'mapbox-gl'; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 00000000..8b8c8f6d --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './external'; + +// re-export mapbox types +export type {AnyLayer, AnySourceData, AnySourceImpl, Popup as MapboxPopup} from 'mapbox-gl'; diff --git a/src/utils/deep-equal.ts b/src/utils/deep-equal.ts index f18c2612..663e7a2d 100644 --- a/src/utils/deep-equal.ts +++ b/src/utils/deep-equal.ts @@ -1,4 +1,4 @@ -import type {PointLike} from './types'; +import type {PointLike} from '../types'; /** * Compare two points diff --git a/src/utils/style-utils.ts b/src/utils/style-utils.ts index c2748937..b668aa5a 100644 --- a/src/utils/style-utils.ts +++ b/src/utils/style-utils.ts @@ -1,4 +1,4 @@ -import {ImmutableLike, MapboxStyle} from './types'; +import {ImmutableLike, MapboxStyle} from '../types'; const refProps = ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout']; diff --git a/src/utils/transform.ts b/src/utils/transform.ts index 83704517..c172b303 100644 --- a/src/utils/transform.ts +++ b/src/utils/transform.ts @@ -1,6 +1,6 @@ import mapboxgl from './mapboxgl'; -import type {PaddingOptions, ViewState} from './types'; +import type {PaddingOptions, ViewState} from '../types'; /** * Stub for mapbox's Transform class