From 91550c7c185590d919b2ee6e1e2d260744c19fb9 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Sat, 13 Oct 2018 21:27:47 -0700 Subject: [PATCH] Remove usage of deprecated `interactive` properties in map styles (#621) --- docs/components/interactive-map.md | 23 +++++++++++-------- src/components/interactive-map.js | 28 ++++++++++------------- src/utils/style-utils.js | 21 ----------------- test/src/utils/index.js | 1 - test/src/utils/style-utils.spec.js | 36 ------------------------------ 5 files changed, 26 insertions(+), 83 deletions(-) delete mode 100644 test/src/utils/style-utils.spec.js diff --git a/docs/components/interactive-map.md b/docs/components/interactive-map.md index 0e810950..953ffc64 100644 --- a/docs/components/interactive-map.md +++ b/docs/components/interactive-map.md @@ -136,12 +136,15 @@ This object must implement the following interface: - `events` - An array of subscribed events - `handleEvent(event, context)` - A method that handles interactive events -Parameters -- `event` - The pointer event. - + `event.lngLat` - The geo coordinates that is being hovered. - + `event.features` - The array of features under the pointer, queried using Mapbox's - [queryRenderedFeatures](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures) API. - To make a layer interactive, set the `interactive` property in the layer style to `true`. +##### `interactiveLayerIds` {Array} [default: null] + +A list of layer ids that are interactive. If specified: +- Pointer event callbacks will only query the features under the pointer of these layers. +- The `getCursor` callback will receive `isHovering: true` when hover over features of these layers. + +If not specified: +- Pointer event callbacks will query the features under the pointer of all layers. +- The `getCursor` callback will always receive `isHovering: false`. ##### `onHover` {Function} @@ -152,7 +155,7 @@ Parameters + `event.lngLat` - The geo coordinates that is being clicked. + `event.features` - The array of features under the pointer, queried using Mapbox's [queryRenderedFeatures](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures) API. - To make a layer interactive, set the `interactive` property in the layer style to `true`. + To make only selected layers interactive, set the `interactiveLayerIds` prop. ##### `onClick` {Function} @@ -163,7 +166,7 @@ Parameters + `event.lngLat` - The geo coordinates that is being clicked. + `event.features` - The array of features under the pointer, queried using Mapbox's [queryRenderedFeatures](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures) API. - To make a layer interactive, set the `interactive` property in the layer style to `true`. + To make only selected layers interactive, set the `interactiveLayerIds` prop. ##### `onContextMenu` {Function} @@ -178,7 +181,9 @@ Accessor that returns a cursor style to show interactive state. Called when the Parameters - `state` - The current state of the component. + `state.isDragging` - If the map is being dragged. - + `state.isHovering` - If the pointer is over a clickable feature. + + `state.isHovering` - If the pointer is over an interactive feature. See `interactiveLayerIds` prop. + +The default implementation of `getCursor` returns `'pointer'` if `isHovering`, `'grabbing'` if `isDragging` and `'grab'` otherwise. ##### `transitionDuration` {Number} diff --git a/src/components/interactive-map.js b/src/components/interactive-map.js index f0749e98..fbc5ddc0 100644 --- a/src/components/interactive-map.js +++ b/src/components/interactive-map.js @@ -6,7 +6,6 @@ import {MAPBOX_LIMITS} from '../utils/map-state'; import WebMercatorViewport from 'viewport-mercator-project'; import TransitionManager from '../utils/transition-manager'; -import {getInteractiveLayerIds} from '../utils/style-utils'; import {EventManager} from 'mjolnir.js'; import MapControls from '../utils/map-controls'; @@ -104,6 +103,9 @@ const propTypes = Object.assign({}, StaticMap.propTypes, { /** Radius to detect features around a clicked point. Defaults to 0. */ clickRadius: PropTypes.number, + /** List of layers that are interactive */ + interactiveLayerIds: PropTypes.array, + /** Accessor that returns a cursor style to show interactive state */ getCursor: PropTypes.func, @@ -168,8 +170,6 @@ export default class InteractiveMap extends PureComponent { }); this._width = 0; this._height = 0; - - this._updateQueryParams(props.mapStyle); } componentDidMount() { @@ -186,10 +186,6 @@ export default class InteractiveMap extends PureComponent { } componentWillUpdate(nextProps) { - if (this.props.mapStyle !== nextProps.mapStyle) { - this._updateQueryParams(nextProps.mapStyle); - } - this._setControllerProps(nextProps); } @@ -217,23 +213,23 @@ export default class InteractiveMap extends PureComponent { _getFeatures({pos, radius}) { let features; + const queryParams = {}; + + if (this.props.interactiveLayerIds) { + queryParams.layers = this.props.interactiveLayerIds; + } + if (radius) { // Radius enables point features, like marker symbols, to be clicked. const size = radius; const bbox = [[pos[0] - size, pos[1] + size], [pos[0] + size, pos[1] - size]]; - features = this._map.queryRenderedFeatures(bbox, this._queryParams); + features = this._map.queryRenderedFeatures(bbox, queryParams); } else { - features = this._map.queryRenderedFeatures(pos, this._queryParams); + features = this._map.queryRenderedFeatures(pos, queryParams); } return features; } - // Hover and click only query layers whose interactive property is true - _updateQueryParams(mapStyle) { - const interactiveLayerIds = getInteractiveLayerIds(mapStyle); - this._queryParams = {layers: interactiveLayerIds}; - } - _onInteractionStateChange = (interactionState) => { const {isDragging = false} = interactionState; if (isDragging !== this.state.isDragging) { @@ -276,7 +272,7 @@ export default class InteractiveMap extends PureComponent { const pos = this._getPos(event); const features = this._getFeatures({pos, radius: this.props.clickRadius}); - const isHovering = features && features.length > 0; + const isHovering = this.props.interactiveLayerIds && features && features.length > 0; if (isHovering !== this.state.isHovering) { this.setState({isHovering}); } diff --git a/src/utils/style-utils.js b/src/utils/style-utils.js index 44fc60cb..bb8cacd3 100644 --- a/src/utils/style-utils.js +++ b/src/utils/style-utils.js @@ -1,24 +1,3 @@ - -// TODO - remove in the next major release -// Mapbox dropped the `interactive` property: https://github.com/mapbox/mapbox-gl-js/issues/1479 -export function getInteractiveLayerIds(style) { - if (!style) { - return null; - } - if (typeof style === 'string') { - return null; - } - if (style.toJS) { - style = style.toJS(); - } - - if (Array.isArray(style.layers)) { - return style.layers.filter(l => l.interactive).map(l => l.id); - } - - return null; -} - // Prepare a map style object for diffing // If immutable - convert to plain object // Work around some issues in the styles that would fail Mapbox's diffing diff --git a/test/src/utils/index.js b/test/src/utils/index.js index b577fefa..c8684cd7 100644 --- a/test/src/utils/index.js +++ b/test/src/utils/index.js @@ -1,5 +1,4 @@ import './transition'; -import './style-utils.spec'; import './map-state.spec'; import './map-constraints.spec'; import './dynamic-position.spec'; diff --git a/test/src/utils/style-utils.spec.js b/test/src/utils/style-utils.spec.js deleted file mode 100644 index ac65365e..00000000 --- a/test/src/utils/style-utils.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import test from 'tape-catch'; -import Immutable from 'immutable'; -import deepEqual from 'deep-equal'; -import {getInteractiveLayerIds} from 'react-map-gl/utils/style-utils'; - -const TEST_STYLE_STRING = 'mapbox://styles/mapbox/streets-v9'; -const TEST_STYLE_JS = { - layers: [ - { - id: 'interactive', - interactive: true - }, { - id: 'non-interactive', - interactive: false - } - ] -}; -const TEST_STYLE_IMMUTABLE = Immutable.fromJS(TEST_STYLE_JS); - -test('getInteractiveLayerIds#String style', t => { - const layers = getInteractiveLayerIds(TEST_STYLE_STRING); - t.notOk(layers, 'should not return layer ids'); - t.end(); -}); - -test('getInteractiveLayerIds#JS style', t => { - const layers = getInteractiveLayerIds(TEST_STYLE_JS); - t.equal(deepEqual(layers, ['interactive']), true, 'got expected layer ids'); - t.end(); -}); - -test('getInteractiveLayerIds#Immutable style', t => { - const layers = getInteractiveLayerIds(TEST_STYLE_IMMUTABLE); - t.equal(deepEqual(layers, ['interactive']), true, 'got expected layer ids'); - t.end(); -});