Skip to content

Commit

Permalink
[feat] Using tippy for map popover (#1539)
Browse files Browse the repository at this point in the history
- Using Tippy to avoid complex positioning calculations. Hopefully, this will also prevent React RangeError: Maximum call stack size exceeded from happening. (BTW, I was wrong, Tippy does expose Popper's virtual element functionality, but under a different name: [getReferenceClientRect](https://atomiks.github.io/tippyjs/v6/all-props/#getreferenceclientrect), so I could use it here). Tried to keep the current tooltip behavior mostly unchanged
- A bit of a clean up of the display logic in `MapContainer`
- Tooltip positioning and overflow prevention now takes the boundaries of the container into account (`DeckGL` element)
- Improve CSS styling:
     - using Flexbox instead of absolute positioning for the header row
     - setting margins _between_ the children of the containers instead of before the individual child elements (using `& > *+* { margin-top: ...}`)
     - using CSS grid for the tables - we can specify `row-gap` and `column-gap` and avoid outer padding for the content of the cells. This way the content can be correctly aligned with the text outside of the table

Co-authored-by: Ilya Boyandin <ilyabo@gmail.com>
  • Loading branch information
heshan0131 and ilyabo committed Jul 18, 2021
1 parent 2e6f8b7 commit 9bcb341
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 212 deletions.
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -95,6 +95,7 @@
"@mapbox/geo-viewport": "^0.4.1",
"@mapbox/geojson-normalize": "0.0.1",
"@mapbox/vector-tile": "^1.3.1",
"@tippyjs/react": "^4.2.0",
"@turf/bbox": "^6.0.1",
"@turf/boolean-within": "^6.0.1",
"@turf/helpers": "^6.1.4",
Expand Down Expand Up @@ -281,6 +282,6 @@
"Giuseppe Macri <gmacri@uber.com>"
],
"volta": {
"node": "10.23.0"
"node": "12.19.0"
}
}
}
36 changes: 18 additions & 18 deletions src/components/map-container.js
Expand Up @@ -49,6 +49,8 @@ import {
} from 'constants/default-settings';
import {OVERLAY_TYPE} from 'layers/base-layer';

import ErrorBoundary from 'components/common/error-boundary';

/** @type {{[key: string]: React.CSSProperties}} */
const MAP_STYLE = {
container: {
Expand Down Expand Up @@ -293,16 +295,11 @@ export default function MapContainerFactory(MapPopover, MapControl, Editor) {
mousePos: {mousePosition, coordinate, pinned}
} = this.props;

if (!mousePosition) {
if (!mousePosition || !interactionConfig.tooltip) {
return null;
}
// if clicked something, ignore hover behavior
let layerHoverProp = null;
let layerPinnedProp = null;
const position = {x: mousePosition[0], y: mousePosition[1]};
let pinnedPosition = {};

layerHoverProp = getLayerHoverProp({
const layerHoverProp = getLayerHoverProp({
interactionConfig,
hoverInfo,
layers,
Expand All @@ -314,10 +311,9 @@ export default function MapContainerFactory(MapPopover, MapControl, Editor) {
? interactionConfig.tooltip.config.compareMode
: false;

const hasTooltip = pinned || clicked;
const hasComparisonTooltip = compareMode || (!clicked && !pinned);

if (hasTooltip) {
let pinnedPosition = {};
let layerPinnedProp = null;
if (pinned || clicked) {
// project lnglat to screen so that tooltip follows the object on zoom
const viewport = new WebMercatorViewport(mapState);
const lngLat = clicked ? clicked.lngLat : pinned.coordinate;
Expand All @@ -334,34 +330,38 @@ export default function MapContainerFactory(MapPopover, MapControl, Editor) {
layerHoverProp.compareType = interactionConfig.tooltip.config.compareType;
}
}

const commonProp = {
onClose: this._onCloseMapPopover,
mapW: mapState.width,
mapH: mapState.height,
zoom: mapState.zoom
zoom: mapState.zoom,
container: this._deck ? this._deck.canvas : undefined
};

return (
<div>
{hasTooltip && (
<ErrorBoundary>
{layerPinnedProp && (
<MapPopover
{...pinnedPosition}
{...commonProp}
layerHoverProp={layerPinnedProp}
coordinate={interactionConfig.coordinate.enabled && (pinned || {}).coordinate}
frozen={Boolean(hasTooltip)}
frozen={true}
isBase={compareMode}
/>
)}
{hasComparisonTooltip && (
{layerHoverProp && (!layerPinnedProp || compareMode) && (
<MapPopover
{...position}
x={mousePosition[0]}
y={mousePosition[1]}
{...commonProp}
layerHoverProp={layerHoverProp}
frozen={false}
coordinate={interactionConfig.coordinate.enabled && coordinate}
/>
)}
</div>
</ErrorBoundary>
);
}

Expand Down
2 changes: 0 additions & 2 deletions src/components/map/layer-hover-info.js
Expand Up @@ -31,8 +31,6 @@ export const StyledLayerName = styled(CenterFlexbox)`
font-size: 12px;
letter-spacing: 0.43px;
text-transform: capitalize;
padding: 0 14px;
margin-top: 12px;
svg {
margin-right: 4px;
Expand Down
2 changes: 2 additions & 0 deletions src/components/map/map-popover.d.ts
@@ -1,3 +1,4 @@
import React from 'react';
import {FunctionComponent} from 'react';
import {IntlShape} from 'react-intl';
import {LayerHoverProp} from '../../utils/layer-utils';
Expand All @@ -12,6 +13,7 @@ export type MapPopoverProps = {
layerHoverProp: LayerHoverProp | null;
isBase?: boolean;
zoom: number;
container?: HTMLElement | null;
onClose: () => void;
};

Expand Down

0 comments on commit 9bcb341

Please sign in to comment.