backpack-ui
Version:
Lonely Planet's Components
256 lines (214 loc) • 4.8 kB
JSX
import React from "react";
import radium from "radium";
import { color, media } from "../../../settings.json";
import { rgb } from "../../utils/color";
import Heading from "../heading";
import Price from "../price";
import MoreLink from "../moreLink";
function calculateContentWidth(imageWidth) {
return `${((630 - 60 - imageWidth - 30) / (630 - 60)) * 100}%`;
}
const styles = {
container: {
base: {
backgroundColor: color.white,
boxShadow: `0 0 20px rgba(${rgb(color.black)}, .05)`,
overflow: "hidden",
[`@media (min-width: ${media.min["600"]})`]: {
padding: `${(30 / 630) * 100}%`,
},
},
},
content: {
base: {
[`@media (max-width: ${media.max["600"]})`]: {
padding: "25px",
},
[`@media (min-width: ${media.min["600"]})`]: {
float: "right",
},
},
align: {
center: {
alignSelf: "center",
},
},
type: {
activity: {
[`@media (min-width: ${media.min["600"]})`]: {
width: calculateContentWidth(300),
},
},
book: {
[`@media (min-width: ${media.min["600"]})`]: {
width: calculateContentWidth(80),
},
},
},
},
heading: {
base: {
fontSize: "20px",
lineHeight: (26 / 20),
},
},
description: {
base: {
color: color.text,
fontSize: "14px",
lineHeight: 1.5,
marginTop: "1em",
paddingRight: `${40 / 14}em`,
},
},
image: {
base: {
[`@media (min-width: ${media.min["600"]})`]: {
float: "left",
marginRight: `${(30 / 630) * 100}%`,
},
},
type: {
activity: {
[`@media (min-width: ${media.min["600"]})`]: {
width: `${(300 / (630 - 60)) * 100}%`,
},
},
book: {
[`@media (min-width: ${media.min["600"]})`]: {
width: `${(80 / (630 - 60)) * 100}%`,
},
},
},
anchor: {
display: "block",
},
img: {
display: "block",
},
},
category: {
base: {
color: color.lightText,
fontSize: "11px",
lineHeight: 1,
marginBottom: `${4 / 11}em`,
textTransform: "uppercase",
},
},
price: {
base: {
marginTop: "12px",
},
},
moreLink: {
base: {
marginTop: "16px",
},
},
};
function Callout({ type, heading, slug, image, price, description, category, align }) {
return (
<div
className="Callout"
style={styles.container.base}
data-type={type}
>
<div
className="Callout-image"
style={[
styles.image.base,
type && styles.image.type[type],
]}
>
<a href={slug} style={styles.image.anchor}>
<img
style={styles.image.img}
src={image}
alt=""
/>
</a>
</div>
<div
className="Callout-content"
style={[
styles.content.base,
type && styles.content.type[type],
align && styles.content.align[align],
]}
>
{category &&
<div style={styles.category.base}>
{category} {type}
</div>
}
<Heading
size="medium"
weight="thick"
override={styles.heading.base}
>
<a href={slug} style={{ color: "inherit" }}>
{heading}
</a>
</Heading>
{price && price.amount &&
<div
className="Callout-price"
style={styles.price.base}
>
<Price
amount={price.amount}
currency={price.currency}
thin
/>
</div>
}
{description &&
<p style={styles.description.base}>
{description}
</p>
}
<div
className="Callout-moreLink"
style={styles.moreLink.base}
>
<MoreLink
href={slug}
size="small"
caps
>
Learn more
</MoreLink>
</div>
</div>
</div>
);
}
Callout.propTypes = {
type: React.PropTypes.oneOf([
"activity",
"book",
]).isRequired,
heading: React.PropTypes.string.isRequired,
slug: React.PropTypes.string.isRequired,
image: React.PropTypes.string.isRequired,
price: React.PropTypes.shape(Price.propTypes),
description: React.PropTypes.string,
category: React.PropTypes.string,
align: React.PropTypes.oneOf([
"",
"center",
]),
};
Callout.defaultProps = {
type: "",
heading: "",
slug: "",
image: "",
price: {},
description: "",
category: "",
align: "",
};
Callout.styles = styles;
export default radium(Callout);