backpack-ui
Version:
Lonely Planet's Components
201 lines (180 loc) • 4.86 kB
JSX
import React from "react";
import radium from "radium";
import { color } from "../../../settings.json";
import { rgb } from "../../utils/color";
import Icon from "../icon";
function mapMarker({ poiType, size, hideShadow, inverse }) {
const types = {
sleeping: {
icon: "Sleep",
color: color.poiSleep,
},
drinking_nightlife: {
icon: "Drink",
color: color.poiDrink,
},
transport: {
icon: "Transport",
color: color.poiTransport,
},
activities: {
icon: "See",
color: color.poiSee,
},
tours: {
icon: "See",
color: color.poiSee,
},
entertainment: {
icon: "Play",
color: color.poiPlay,
},
shopping: {
icon: "Shop",
color: color.poiShop,
},
eating: {
icon: "Eat",
color: color.poiEat,
},
restaurants: {
icon: "Eat",
color: color.poiEat,
},
sights: {
icon: "See",
color: color.poiSee,
},
info: {
icon: "Default",
color: color.poiDefault,
},
festivals_events: {
icon: "Play",
color: color.poiPlay,
},
};
/**
* Get a size (in pixels) to use in the CSS. A ratio is created by dividing a
* given number by the default icon size (20). That ratio is then multiplied
* by the size recieved in the component’s props to create a value that is
* proportional to the size of the marker.
* @param {Number} number Pixel value of desired size
* @return {Number} Calculated pixel value
*/
const getSize = (number) => Math.ceil(size * (number / 20));
/**
* Calculate the font size from the size (height, width). The ratio is
* calculated by dividing 11 (which is the font size for a 20x20 icon) by 20
* (which has been defined as the default size).
*/
const fontSize = getSize(11);
/**
* Calculate the border width from the size (height, width). The ratio is
* calculated by dividing 1 (which is the lowest posible width) by 20 (which
* has been defined as the default size and is the smallest size that a 1px
* border should be applied to).
*/
const borderWidth = getSize(1);
const styles = {
container: {
base: {
borderRadius: "100%",
backgroundColor: poiType === "center" ?
color.blue :
types[poiType].color,
color: color.white,
borderColor: `rgba(${rgb(color.black)}, .12)`,
borderStyle: "solid",
borderWidth: `${borderWidth / fontSize}em`,
display: "inline-block",
fontSize: `${fontSize}px`,
height: `${size / fontSize}em`,
lineHeight: 1,
textAlign: "center",
width: `${size / fontSize}em`,
},
shadow: {
boxShadow: `0 ${getSize(1) / fontSize}em
${getSize(5) / fontSize}em
rgba(${rgb(color.black)}, .25)`,
},
inverse: {
backgroundColor: color.white,
borderColor: "transparent",
borderWidth: 0,
boxShadow: `0 0 ${getSize(5) / fontSize}em
rgba(${rgb(color.black)}, .25)`,
color: poiType === "center" ?
color.blue :
types[poiType].color,
},
},
icon: {
base: {
position: "relative",
top: "50%",
transform: "translateY(-50%)",
verticalAlign: "top",
},
},
};
const MarkerIcon = React.createElement(Icon[`Map${types[poiType].icon}`], {
style: styles.icon.base,
fill: inverse ? types[poiType].color : color.white,
});
return (
<div
className="MapMarker"
style={[
styles.container.base,
!hideShadow && styles.container.shadow,
inverse && styles.container.inverse,
]}
>
{poiType === "center" ? <Icon.MapDefault /> : MarkerIcon}
</div>
);
}
mapMarker.propTypes = {
/**
* A pre-defined POI type that maps to an icon; "center" is a custom value
* that can be used to create an LP Blue marker that uses the default icon
*/
poiType: React.PropTypes.oneOf([
"center",
"activities",
"drinking_nightlife",
"eating",
"entertainment",
"festivals_events",
"info",
"restaurants",
"shopping",
"sights",
"sleeping",
"tours",
"transport",
]),
/**
* Number to define width and height
*/
size: React.PropTypes.number,
/**
* Whether or not to hide the shadow on the marker; note that the "inverse"
* marker always has a shadow, regardless of the value of this prop
*/
hideShadow: React.PropTypes.bool,
/**
* Reverse the colors; the background becomes white and the icon a color
*/
inverse: React.PropTypes.bool,
};
mapMarker.defaultProps = {
poiType: "center",
size: 20,
hideShadow: false,
inverse: false,
};
// mapMarker.styles = styles;
export default radium(mapMarker);