react-mapfilter
Version:
These components are designed for viewing data in Mapeo. They share a common interface:
124 lines (119 loc) • 3.14 kB
JavaScript
import "core-js/modules/es.array.iterator";
import "core-js/modules/web.dom-collections.iterator";
// @flow
import React, { useContext, useCallback, useLayoutEffect, useState, useRef } from 'react';
import { MapContext } from 'react-mapbox-gl';
import Typography from '@material-ui/core/Typography';
import clsx from 'clsx';
import Image from '../internal/Image';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles({
wrapper: {
width: 200,
padding: 0,
backgroundColor: 'black',
cursor: 'pointer',
position: 'absolute',
willChange: 'transform',
top: 0,
left: 0,
pointerEvents: 'none'
},
wrapperImage: {
height: 200
},
image: {
width: 200,
height: 200,
objectFit: 'cover',
display: 'block',
background: '#000000'
},
titleBox: {
position: 'absolute',
bottom: 0,
width: '100%',
backgroundColor: 'rgba(0,0,0,0.5)',
color: 'white',
padding: '0.25em 0.5em',
boxSizing: 'border-box'
},
title: {
color: 'white'
},
subheading: {
color: 'white'
}
});
/*:: type Props = {
coordinates: [number, number],
imageUrl?: string,
title: string,
subtitle: string
}*/
const Popup = ({
imageUrl,
title,
subtitle,
coordinates
}
/*: Props*/
) => {
const map = useContext(MapContext);
const ref = useRef(null);
const classes = useStyles();
const getPopupTransform = useCallback(() => {
if (!ref.current) return;
const width = ref.current.offsetWidth;
const height = ref.current.offsetHeight;
const pos = map.project(coordinates).round();
let anchor;
if (pos.y < height) {
anchor = 'top';
} else {
anchor = 'bottom';
}
if (pos.x > map.transform.width - width) {
anchor += '-right';
} else {
anchor += '-left';
}
const anchorTranslate = {
'top-left': 'translate(0,0)',
'top-right': 'translate(-100%,0)',
'bottom-left': 'translate(0,-100%)',
'bottom-right': 'translate(-100%,-100%)'
};
return `${anchorTranslate[anchor]} translate(${pos.x}px,${pos.y}px)`;
}, [coordinates, map]);
const [transform, setTransform] = useState(getPopupTransform());
const update = useCallback(() => setTransform(getPopupTransform()), [getPopupTransform]);
useLayoutEffect(() => {
map.on('move', update);
update();
return () => map.off('move', update);
}, [map, update]);
return /*#__PURE__*/React.createElement("div", {
className: clsx(classes.wrapper, {
[classes.wrapperImage]: imageUrl
}),
style: {
transform
},
ref: ref
}, imageUrl && /*#__PURE__*/React.createElement(Image, {
src: imageUrl,
className: classes.image
}), /*#__PURE__*/React.createElement("div", {
className: classes.titleBox
}, title && /*#__PURE__*/React.createElement(Typography, {
variant: "h6",
className: classes.title
}, title), subtitle && /*#__PURE__*/React.createElement(Typography, {
variant: "caption",
className: classes.subheading
}, subtitle)));
};
Popup.imageSize = 200;
export default Popup;
//# sourceMappingURL=Popup.js.map