backpack-ui
Version:
Lonely Planet's Components
1,380 lines (1,350 loc) • 166 kB
JSX
import React from "react";
import PropTypes from "prop-types";
import { StyleRoot } from "radium";
import "leaflet/dist/leaflet.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import "react-photoswipe/lib/photoswipe.css";
import "rc-slider/assets/index.css";
import "react-dates/lib/css/_datepicker.css";
import { storiesOf } from "@storybook/react";
import {
withKnobs,
text,
boolean,
number,
array,
object,
select,
color,
date,
} from "@storybook/addon-knobs";
import { action } from "@storybook/addon-actions";
import moment from "moment";
import data from "./data.json";
import Center from "./center";
import Colors from "./Colors";
import DesignTokens from "./designTokens";
import Fonts from "./fonts";
import Typography from "./typography";
import {
Accordion,
AccordionItem,
} from "../src/components/accordion";
import Ad from "../src/components/ad";
import AlbumThumbnailImage from "../src/components/albumThumbnailImage";
import Amenities from "../src/components/amenities";
import ArticleAuthor from "../src/components/articleAuthor";
import ArticlePaginationItem from "../src/components/articlePaginationItem";
import ArticlePaginationNav from "../src/components/articlePaginationNav";
import ArticlePreview from "../src/components/articlePreview";
import Author from "../src/components/author";
import AuthorName from "../src/components/authorName";
import Avatar from "../src/components/avatar";
import AvatarMarker from "../src/components/avatarMarker";
import AvatarUpload from "../src/components/avatarUpload";
import BookmarkButton from "../src/components/bookmarkButton";
import BookmarkButtonAlt from "../src/components/bookmarkButtonAlt";
import BookmarkListAuthor from "../src/components/bookmarkListAuthor";
import BookmarkListHeader from "../src/components/bookmarkListHeader";
import BookmarkListMenu from "../src/components/bookmarkListMenu";
import BookmarkListMenuOption from "../src/components/bookmarkListMenu/option.jsx";
import Breadcrumbs from "../src/components/breadcrumbs";
import BulletDescription from "../src/components/bulletDescription";
import Button from "../src/components/button";
import Calendar from "../src/components/calendar";
import Callout from "../src/components/callout";
import CalloutLink from "../src/components/calloutLink";
import CardBasic from "../src/components/cardBasic";
import CardPrice from "../src/components/cardPrice";
import CardShelfVideo from "../src/components/cardShelfVideo";
import CardShelfVideoSlider from "../src/components/cardShelfVideoSlider";
import CardShelfVideoSwiper from "../src/components/cardShelfVideoSwiper";
import CardVideo from "../src/components/cardVideo";
import CardBook from "../src/components/cardBook";
import CategoryLabel from "../src/components/categoryLabel";
import CategoryLabelLink from "../src/components/categoryLabelLink";
import Checkbox from "../src/components/checkbox";
import Container from "../src/components/container";
import ContentHeader from "../src/components/contentHeader";
import DateRange, { DeveloperNote as DateRangeDeveloperNote} from "../src/components/form/daterange";
import Dialog from "../src/components/dialog";
import DisclaimerText from "../src/components/disclaimerText";
import DotLoader from "../src/components/dotLoader";
import Dropdown from "../src/components/dropdown";
import EditLink from "../src/components/editLink";
import ErrorMessages from "../src/components/form/errorMessages";
import ExpandButton from "../src/components/expandButton";
import FeaturedArticle from "../src/components/featuredArticle";
import Flag from "../src/components/flag";
import Flyout from "../src/components/flyout";
import GridColumn from "../src/components/gridColumn";
import GridRow from "../src/components/gridRow";
import Heading from "../src/components/heading";
import Icons from "./icons";
import Icon from "../src/components/icon";
import IconButton from "../src/components/iconButton";
import IconCallout from "../src/components/iconCallout";
import IconCalloutGroup from "../src/components/iconCalloutGroup";
import ImageCarousel from "../src/components/imageCarousel";
import ImageHero from "../src/components/imageHero";
import Input from "../src/components/input";
import FormInput from "../src/components/form/input";
import IconRevealButton from "../src/components/iconRevealButton";
import InteractiveMap from "../src/components/interactiveMap";
import ItalicText from "../src/components/italicText";
import Lede from "../src/components/lede";
import ListButton from "../src/components/listButton";
import ListItemBookmark from "../src/components/listItemBookmark";
import ListItemBookmarkEntry from "../src/components/listItemBookmarkEntry";
import ListItemNews from "../src/components/listItemNews";
import Loading from "../src/components/loading";
import LocationLabel from "../src/components/locationLabel";
import Logo from "../src/components/logo";
import MapMarker from "../src/components/mapMarker";
import Masthead from "../src/components/masthead";
import MastheadSlider from "../src/components/mastheadSlider";
import Modal from "../src/components/modal";
import ModalLogIn from "../src/components/modalLogIn";
import MoreLink from "../src/components/moreLink";
import {
MultiStep,
MultiStepWrapper,
} from "../src/components/multiStep";
import MultiStepLogin from "../src/components/multiStep/multiStepLogin";
import Narrative from "../src/components/narrative";
import {
Navigation,
NavigationTab,
} from "../src/components/navigation";
import NewsArticleAuthor from "../src/components/newsArticleAuthor";
import NewsList from "../src/components/newsList";
import Newsletter from "../src/components/newsletter";
import NoResults from "../src/components/noResults";
import NumberList from "../src/components/numberList";
import NumberMarker from "../src/components/numberMarker";
import PageHeader from "../src/components/pageHeader";
import PaginatorButton from "../src/components/paginatorButton";
import PhotoGallery from "../src/components/photoGallery";
import Placeholder from "../src/components/placeholder";
import PoiPaginator from "../src/components/poiPaginator";
import PriceRangeLabel from "../src/components/priceRangeLabel";
import ProfileHeader from "../src/components/profileHeader";
import PromotedGuidebook from "../src/components/promotedGuidebook";
import ProviderLogo from "../src/components/providerLogo";
import Rating from "../src/components/rating";
import Range from "../src/components/form/range";
import RecommendedArticles from "../src/components/recommendedArticles";
import RelatedTour from "../src/components/relatedTour";
import ReviewedBadge from "../src/components/reviewedBadge";
import ScrollIndicator from "../src/components/scrollIndicator";
import SectionalNav from "../src/components/sectionalNav";
import SectionHeader from "../src/components/sectionHeader";
import Select from "../src/components/form/select";
import {
SettingBlockSection,
SettingBlockListItemWrapper,
} from "../src/components/settingBlock";
import SettingBlockCheckbox from "../src/components/settingBlockCheckbox";
import SettingBlockAction from "../src/components/settingBlockAction";
import SettingBlockAccordion from "../src/components/settingBlockAccordion";
import SettingBlockTextArea from "../src/components/settingBlockTextArea";
import SettingBlockInput from "../src/components/settingBlockInput";
import FormTextArea from "../src/components/form/textarea";
import ToggleController from "../src/utils/toggleController";
import ShareMenu from "../src/components/shareMenu";
import ShareSettings from "../src/components/shareMenu/shareSettings";
import Slide from "../src/components/slide";
import SocialIconButton from "../src/components/socialIconButton";
import SocialLoginButton from "../src/components/socialLoginButton";
import SocialShare from "../src/components/socialShare";
import SocialShareContainer from "../src/components/socialShareContainer";
import SightsListItem from "../src/components/sightsListItem";
import SponsorLabel from "../src/components/sponsorLabel";
import SpotlightZone from "../src/components/spotlightZone";
import StaticMap from "../src/components/staticMap";
import Strapline from "../src/components/strapline";
import Switch from "../src/components/switch";
import TabbedNav from "../src/components/tabbedNav";
import {
Tabs,
Tab,
} from "../src/components/tabs";
import Tag from "../src/components/tag";
import TagList from "../src/components/tagList";
import TallCarousel from "../src/components/tallCarousel";
import {
TextAccent,
TextBodyArticle,
TextBodySmall,
TextHeading,
TextSuper,
TextUppercase,
} from "../src/components/text";
import TextBubble from "../src/components/textBubble";
import Textarea from "../src/components/textarea";
import ThumbnailList from "../src/components/thumbnailList";
import ThumbnailListItem from "../src/components/thumbnailListItem";
import TileGrid from "../src/components/tileGrid";
import TileVideo from "../src/components/tileVideo";
import TileVideoPoster from "../src/components/tileVideoPoster";
import Timestamp from "../src/components/timestamp";
import Toast from "../src/components/toast";
import Tooltip from "../src/components/tooltip";
import TourItinerary from "../src/components/tourItinerary";
import TravelAlert from "../src/components/travelAlert";
import {
Typeahead,
TypeaheadTokenizer,
} from "../src/components/typeahead";
import TypeSelector from "../src/components/typeSelector";
import {
VideoEmbed,
VideoFeatured,
VideoInfo,
VideoPlaylist,
VideoPlaylistWithSlider,
VideoPopout,
VideoSlider,
VideoUpNext,
} from "../src/components/video";
import WatchLaterModal from "../src/components/watchLater/watchLaterModal";
import colorTokens from "../src/styles/colors";
class ModalWrapper extends React.Component {
static propTypes = {
children: PropTypes.function,
}
state = {
open: true,
}
toggleOpen() {
this.setState({ open: !this.state.open });
}
render() {
return this.props.children(this.state.open, this.toggleOpen.bind(this));
}
}
storiesOf("Styles", module)
.addDecorator(withKnobs)
.add("Design tokens", () => (
<DesignTokens />
))
.add("Colors", () => (
<Colors />
))
.add("Fonts", () => (
<Fonts />
))
.add("Typography", () => (
<Typography />
))
.add("Icons", () => (
<Icons />
));
storiesOf("Ads", module)
.addDecorator(withKnobs)
.add("Ad", () => (
<StyleRoot>
<Center>
<Ad
id={text("ID", "backpackAdIdentifier")}
framed={boolean("Framed", false)}
className={text("Class Name", "")}
qaHook={boolean("QA Hook", false)}
/>
</Center>
</StyleRoot>
))
.add("Ad Wrapper", () => (
<StyleRoot>
<Center>
<Ad
id={text("ID", "backpackAdIdentifier")}
framed={boolean("Framed", true)}
className={text("Class Name", "")}
qaHook={boolean("QA Hook", false)}
>
<div>Add Children to the Ad to use the Ad Component as a Wrapper.</div>
</Ad>
</Center>
</StyleRoot>
));
storiesOf("Authors", module)
.addDecorator(withKnobs)
.add("Article author", () => (
<ArticleAuthor
name={text("Name", "Alex Butler")}
title={text("Title", "Global news reporter")}
avatarSrc={text("Avatar image URL", data.avatar.default)}
orientation={select("Orientation", {
vertical: "Vertical",
horizontal: "Horizontal",
}, "vertical")}
/>
))
.add("Author", () => (
<Author
name={text("Name", "Alex Butler")}
title={text("Title", "Global news reporter")}
alignment={select("Alignment", ["left", "center", "right"], "left")}
/>
))
.add("Bookmark list author", () => (
<BookmarkListAuthor
href={text("URL", "/")}
imageSrc={text("Image source", data.avatar.default)}
qaHook={boolean("QA Hook", false)}
>
{text("Name", "Alex Butler")}
</BookmarkListAuthor>
))
.add("News article author", () => (
<NewsArticleAuthor
name={text("Name", "Alex Butler")}
title={text("Title", "Global news reporter")}
absoluteTime={text("Absolute time", "2017-01-17")}
relativeTime={text("Relative time", "3 days ago")}
theme={select("Theme", ["light", "dark"], "light")}
/>
));
storiesOf("Avatars", module)
.addDecorator(withKnobs)
.add("Avatar", () => (
<Avatar
src={text("Image source", data.avatar.rizzo)}
alt={text("Alternate text", "Rizzo")}
size={select("Size", [24, 40, 48, 80, 104], 80)}
href={text("URL", "")}
qaHook={boolean("QA Hook (if link)", false)}
/>
))
.add("Avatar marker (similar to bookmark list author)", () => (
<AvatarMarker
href={text("URL", "/profile")}
src={text("Avatar URL", "http://img2.wikia.nocookie.net/__cb20111018235020/muppet/images/thumb/1/14/Rizzo11.png/300px-Rizzo11.png")}
username={text("Username", "Rizzo the Rat")}
/>
));
storiesOf("Buttons", module)
.addDecorator(withKnobs)
// Button
.add("Button - primary", () => (
<Center backgroundColor="white">
<Button
color={select("Color", ["blue", "white", "gray", "red", "transparent"], "blue")}
size={select("Size", ["tiny", "small", "medium", "large", "huge"], "medium")}
border={boolean("Border", true)}
disabled={boolean("Disabled", false)}
full={boolean("Full width", false)}
rounded={boolean("Rounded", false)}
onClick={action("clicked")}
qaHook={boolean("QA Hook", false)}
>
{text("Text", "Hello Button")}
</Button>
</Center>
))
.add("Button - secondary", () => (
<Center backgroundColor="white">
<Button
color="white"
size={select("Size", ["tiny", "small", "medium", "large", "huge"], "medium")}
border={boolean("Border", true)}
disabled={boolean("Disabled", false)}
full={boolean("Full width", false)}
rounded={boolean("Rounded", false)}
onClick={action("clicked")}
qaHook={boolean("QA Hook", false)}
>
{text("Text", "Hello Button")}
</Button>
</Center>
))
// Bookmark button
.add("Bookmark button - default", () => (
<Center backgroundColor="white">
<BookmarkButton
id={text("ID", null)}
className={text("Classname", null)}
onClick={action("Bookmark clicked")}
marked={boolean("Marked", false)}
qaHook={boolean("QA Hook", false)}
/>
</Center>
))
.add("Bookmark button - alternate", () => (
<Center backgroundColor="white">
<BookmarkButtonAlt
id={text("ID", null)}
className={text("Classname", null)}
onClick={action("Bookmark clicked")}
marked={boolean("Marked", false)}
qaHook={boolean("QA Hook", false)}
/>
</Center>
))
.add("Bookmark button - custom button", () => (
<Center backgroundColor="white">
<BookmarkButton
id={text("ID", null)}
className={text("Classname", null)}
onClick={action("Bookmark clicked")}
marked={boolean("Marked", false)}
button={
<Button
color="gray"
size="small"
border
rounded
customStyles={{
alignItems: "center",
display: "inline-flex",
paddingBottom: "0.5em",
paddingLeft: "1.3em",
paddingRight: "1.3em",
paddingTop: "0.7em",
textTransform: "capitalize",
}}
qaHook={boolean("QA Hook", false)}
>
{true ?
<Icon.BookmarkActive
style={{
height: "16px",
marginBottom: "3px",
marginRight: "4px",
width: "auto",
}}
/> :
<Icon.Bookmark
style={{
height: "16px",
width: "auto",
marginRight: "4px",
marginBottom: "3px",
}}
/>
}
Save
</Button>
}
/>
</Center>
))
// Expand button
.add("Expand button", () => (
<ExpandButton qaHook={boolean("QA Hook", false)} label={text("Label", "Open")} />
))
// Icon button
.add("Icon button", () => (
<Center backgroundColor="white">
<IconButton
iconName={select("Icon name", [
"Bookmark",
"BookmarkActive",
"BookmarkAlt",
"BookmarkAltActive",
"ChevronLeft",
"ChevronRight",
"ClockOutline",
"Ellipsis",
"Play",
"Share",
], "Share")}
label={text("Label", "Share this")}
id={text("ID", null)}
className={text("Classname", null)}
href={text("href", null)}
onClick={action("onClick action")}
size={select("Size", [32, 40, 56], 32)}
owns={text("Aria owns", null)}
backgroundColor={text("Background color", null)}
hoverBackgroundColor={text("Hover background color", null)}
hoverBackgroundScale={number("Hover background scale", null)}
color={text("Color", null)}
hoverColor={text("Hover color", null)}
border={boolean("Border", false)}
borderWidth={text("Border width", "1px")}
borderColor={text("Border color", "currentColor")}
shadow={boolean("Shadow", false)}
transitionDuration={text("Transition duration", "400ms")}
qaHook={boolean("QA Hook", false)}
/>
</Center>
))
// Icon reveal button
.add("Icon reveal button", () => (
<StyleRoot>
<Center>
<IconRevealButton
id={text("ID", null)}
icon={<Icon.Share />}
label={text("Label", "Label")}
className={text("Classname", null)}
onClick={action("Bookmark clicked")}
qaHook={boolean("QA Hook", false)}
/>
</Center>
</StyleRoot>
))
// List button
.add("List button", () => (
<Center>
<ListButton
id={text("ID", null)}
className={text("Classname", null)}
onClick={action("List Button clicked")}
icon={select("Icon", [
"Bookmark",
"BookmarkActive",
"BookmarkAlt",
"BookmarkAltActive",
"Ellipsis",
"Map",
], "Ellipsis")}
qaHook={boolean("QA Hook", false)}
/>
</Center>
))
// Paginator button
.add("Paginator button", () => (
<PaginatorButton
direction={select("Arrow direction", ["up", "down", "left", "right"], "up")}
arrow={select("Arrow style", ["chevron", "triangle"], "chevron")}
size={select("Size", ["medium", "small"], "medium")}
shadow={select("Shadow", ["loose", "tight"], "loose")}
color={select("Color", ["", "blue"], "")}
onClick={action("PaginatorButton clicked")}
qaHook={boolean("QA Hook", false)}
/>
))
// Social icon button
.add("Social icon button - Email", () => (
<SocialIconButton
href="mailto:?subject=&body="
onClick={action("Email clicked")}
network="email"
qaHook={boolean("QA Hook", false)}
/>
))
.add("Social icon button - Facebook", () => (
<SocialIconButton
href="https://www.facebook.com/sharer/sharer.php?u="
onClick={action("Facebook clicked")}
network="facebook"
qaHook={boolean("QA Hook", false)}
/>
))
.add("Social icon button - Facebook Messenger", () => (
<SocialIconButton
href="fb-messenger://share/?link="
onClick={action("Facebook Messenger clicked")}
network="facebookMessenger"
qaHook={boolean("QA Hook", false)}
/>
))
.add("Social icon button - Reddit", () => (
<SocialIconButton
href="http://www.reddit.com/submit/?url="
onClick={action("Reddit clicked")}
network="reddit"
qaHook={boolean("QA Hook", false)}
/>
))
.add("Social icon button - Twitter", () => (
<SocialIconButton
href="https://twitter.com/intent/tweet?text=&url=&via="
onClick={action("Twitter clicked")}
network="twitter"
qaHook={boolean("QA Hook", false)}
/>
))
.add("Social icon button - WeChat", () => (
<SocialIconButton
onClick={action("WeChat clicked")}
network="weChat"
qaHook={boolean("QA Hook", false)}
/>
))
// Social login button
.add("Social login button", () => (
<SocialLoginButton
iconName={select("Icon Name", [
"FacebookBlockColor",
"GoogleColor",
"TwitterColor",
], "FacebookBlockColor")}
onClick={action("Handle Log In")}
qaHook={boolean("QA Hook", false)}
>
{text("Text", "Continue with Facebook")}
</SocialLoginButton>
))
// Tag
.add("Tag - anchor", () => (
<Tag
href={text("URL", "#")}
selected={boolean("Selected", false)}
qaHook={boolean("QA Hook", false)}
>
{text("Text", "The Americas")}
</Tag>
))
.add("Tag - button", () => (
<Tag
onClick={action("Tag clicked")}
selected={boolean("Selected", false)}
qaHook={boolean("QA Hook", false)}
>
{text("Text", "The Americas")}
</Tag>
))
.add("Tag - no click", () => (
<Tag qaHook={boolean("QA Hook", false)} selected={boolean("Selected", false)}>
{text("Text", "The Americas")}
</Tag>
));
storiesOf("Callouts", module)
.addDecorator(withKnobs)
.add("Callout - book", () => (
<StyleRoot>
<Callout
qaHook={boolean("QA Hook", false)}
type="book"
align="center"
heading="Lonely Planet’s Best in Travel 2016"
slug="/"
price={{
currency: "USD",
amount: 21.99,
}}
description={`Be an in-the-know traveler this year with Lonely
Planet’s collection of the hottest trends, destinations,
journeys.`}
image="http://dummyimage.com/132x168/4d494d/686a82.gif"
/>
</StyleRoot>
))
.add("Callout - activity", () => (
<StyleRoot>
<Callout
qaHook={boolean("QA Hook", false)}
type="activity"
heading="Cycle Linz to Vienna"
slug="/"
price={{
currency: "USD",
amount: 50,
}}
image="http://dummyimage.com/300x158/4d494d/686a82.gif"
category="Food and drink"
/>
</StyleRoot>
))
.add("Icon callout", () => (
<IconCallout
iconName={select("Icon name", {
SurvivalAirplane: "Airplane",
SurvivalBear: "Bear",
SurvivalBed: "Bed",
SurvivalBookPencil: "Book / pencil",
SurvivalCar: "Car",
SurvivalHealth: "Health",
SurvivalLamp: "Lamp",
SurvivalLgbt: "LGBT",
SurvivalMoney: "Money",
SurvivalPassport: "Passport",
SurvivalSafety: "Safety",
SurvivalSpeechBubbles: "Speech bubbles",
SurvivalSuitcase: "Suitcase",
SurvivalUmbrella: "Umbrella",
SurvivalVespa: "Vespa",
SurvivalVisa: "Visa",
SurvivalWheelchair: "Wheelchair",
}, "SurvivalMoney")}
title={text("Title", "Money and costs")}
copy={text("Copy", "Budgets, currency rates and on-the-ground costs")}
url={text("URL", "https://www.lonelyplanet.com")}
qaHook={boolean("QA Hook", false)}
/>
));
storiesOf("Cards", module)
.addDecorator(withKnobs)
.add("Card - basic", () => (
<StyleRoot>
<div style={{ padding: "32px" }}>
<CardBasic
heading={text("Heading", "High Sierra routes with Ken Walker Smith")}
bullets={array("Bullets", ["Card things", "More Card Things"])}
imageSrc={text("Image source", "//media.gadventures.com/media-server/cache/a6/2c/a62ca9f86982dd950319138334e7248b.jpg")}
href={text("URL", "#")}
/>
</div>
</StyleRoot>
))
.add("Card - video", () => (
<StyleRoot>
<div style={{ width: "400px", padding: "32px" }}>
<CardVideo
heading={text("Heading", "High Sierra routes with Ken Walker Smith")}
bullets={array("Bullets", ["On The Road", "E.01"])}
runtime={number("Video runtime", 129365)}
mobile={boolean("Mobile", false)}
imageSrc={text("Image source", "//media.gadventures.com/media-server/cache/a6/2c/a62ca9f86982dd950319138334e7248b.jpg")}
href={text("URL", "#")}
layout={select("Layout", ["card", "tile"], "card")}
theme={select("Theme", ["light", "dark"], "light")}
spacing={select("Spacing", ["normal", "compact"], "normal")}
aspectRatio={select("Aspect ratio", ["video", "poster"], "video")}
/>
</div>
</StyleRoot>
))
.add("Card - book", () => (
<StyleRoot>
<div style={{ width: "500px", padding: "32px" }}>
<CardBook
title={text("Title", "Book or activity title")}
subtitle={text("Subtitle", "Ages 0-0")}
shopLinkText={text("Link text", "Associated bookshop link")}
shopLinkUrl={text("Link url", "https://www.lonelyplanet.com")}
imageSrc={text("Image source", "//media.gadventures.com/media-server/cache/a6/2c/a62ca9f86982dd950319138334e7248b.jpg")}
aspectRatio={select("Aspect ratio", ["portrait", "landscape"], "portrait")}
previewLink="https://www.lonelyplanet.com"
downloadLink="https://www.lonelyplanet.com"
shareText="test"
shareUrl="https://www.lonelyplanet.com"
hideShareButton={boolean("Hide share button", false)}
hideBorder={boolean("Hide border", false)}
hideMenu={boolean("Hide menu", false)}
/>
</div>
</StyleRoot>
))
.add("Card - price", () => (
<StyleRoot>
<div style={{ padding: "32px" }}>
<CardPrice
heading={text("Heading", "End of the Earth")}
bullets={array("Bullets", ["15 Days", "Buenos Aires to Buenos Aires"])}
imageSrc={text("Image source", "//media.gadventures.com/media-server/cache/a6/2c/a62ca9f86982dd950319138334e7248b.jpg")}
href={text("URL", "#")}
price={{
regular: 3999,
sale: 3399,
}}
/>
</div>
</StyleRoot>
));
storiesOf("Carousels", module)
.addDecorator(withKnobs)
.add("Image carousel", () => (
<ImageCarousel
images={[
"https://s3.amazonaws.com/static-asset/backpack-ui/scotland-1.770x430.jpg",
"https://s3.amazonaws.com/static-asset/backpack-ui/scotland-2.770x430.jpg",
"https://s3.amazonaws.com/static-asset/backpack-ui/scotland-3.770x430.jpg",
]}
imageSize={[770, 430]}
index={null}
/>
))
.add("Masthead slider", () => {
const items = [{
adPosition: "",
image: "https://lonelyplanetstatic.imgix.net/copilot%2Fimages%2FR2V0dHlJbWFnZXMtNjA3Njk2MTAzX2Z1bGwuanBnV2VkIEZlYiAwMSAyMDE3IDA5OjAxOjU1IEdNVCswMDAwIChVVEMp.jpg?q=40&sharp=10&w=2500",
type: "Featured article",
headline: "Honeymoon hacks: a guide for newly-weds abroad",
description: ["Item 1", "Item 2"],
callToAction: {
text: "Happily Ever After",
icon: "Play",
link: "https://www.lonelyplanet.com/travel-tips-and-articles/honeymoon-survival-the-ultimate-guide-for-newlyweds-abroad",
},
id: 3,
}, {
adPosition: "",
tabTitle: "Sicily’s best coastal hikes",
image: "https://lonelyplanetstatic.imgix.net/copilot/images/R2V0dHlJbWFnZXMtNDY3NTY3MjI4X3N1cGVyLTc1YzEyMjJjOGNhOC5qcGdUdWUgSmFuIDMxIDIwMTcgMTA6NDA6MzUgR01UKzAwMDAgKFVUQyk%3D.jpg?q=40&sharp=10&w=2500",
type: "FEATURED ARTICLE",
headline: "Sicily’s best coastal hikes",
description: "",
callToAction: {
text: "Isles for Miles",
icon: "Play",
link: "https://www.lonelyplanet.com/italy/sicily/aeolian-islands/travel-tips-and-articles/sicilys-best-coastal-hikes",
},
id: 1,
}, {
adPosition: "",
tabTitle: "Architecture for travellers: a novice's guide",
image: "https://lonelyplanetstatic.imgix.net/copilot%2Fimages%2FR2V0dHlJbWFnZXMtNTM0NzUzNjQ1X3N1cGVyLmpwZ01vbiBKYW4gMzAgMjAxNyAwOTo0MToyOSBHTVQrMDAwMCAoVVRDKQ%3D%3D.jpg?q=40&sharp=10&w=2500",
type: "FEATURED ARTICLE",
headline: "Architecture for travellers: a novice's guide",
graphic: "https://s3.amazonaws.com/static-asset/op-video-sync/assets/gopro_graphic_test.png",
description: "",
callToAction: {
text: "Play",
icon: "Play",
link: "https://www.lonelyplanet.com/travel-tips-and-articles/architecture-for-travellers-a-novices-guide",
},
id: 4,
}];
const slides = items.map((item, index) => <Slide key={index} {...item} />);
return (
<StyleRoot>
<MastheadSlider
height={text("Masthead Height", "100vh")}
slides={slides}
/>
</StyleRoot>
);
})
.add("Tall Carousel", () => (
<TallCarousel
slides={[
{
"type": "Busan, South Korea",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/Busan.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/south-korea/gyeongsangnam-do/busan/travel-tips-and-articles/bites-of-busan-unique-eats-in-koreas-seaside-city/40625c8c-8a11-5710-a052-1479d2755de9",
},
{
"type": "Uzbekistan",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/Uzbekistan.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop&crop=left",
"link": "https://www.lonelyplanet.com/uzbekistan/travel-tips-and-articles/why-now-is-the-time-to-visit-uzbekistan/40625c8c-8a11-5710-a052-1479d2755c81"
},
{
"type": "Ho Chi Minh City, Vietnam",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/HoChiMinhCity.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop&crop=left",
"link": "https://www.lonelyplanet.com/vietnam/ho-chi-minh-city/travel-tips-and-articles/a-beginners-guide-to-ho-chi-minh-citys-street-food/40625c8c-8a11-5710-a052-1479d2755bd6"
},
{
"type": "Western Ghats, India",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/WesternGhats.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/india/south-india/travel-tips-and-articles/tea-trains-relics-from-the-raj-exploring-indias-western-ghats/40625c8c-8a11-5710-a052-1479d2755a47"
},
{
"type": "Nagasaki, Japan",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/Nagasaki.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/japan/kyushu/nagasaki/travel-tips-and-articles/48-hours-in-nagasaki-a-diverse-citys-powerful-character/40625c8c-8a11-5710-a052-1479d2755aec"
},
{
"type": "Chiang Mai, Thailand",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/ChiangMai.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/thailand/chiang-mai-province/chiang-mai/travel-tips-and-articles/creative-city-celebrating-chiang-mais-past-and-present/40625c8c-8a11-5710-a052-1479d2755a0e"
},
{
"type": "Lumbini, Nepal",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/Lumbini.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/nepal/the-terai-and-mahabharat-range/central-terai/travel-tips-and-articles/walking-in-buddhas-footsteps-at-lumbini/40625c8c-8a11-5710-a052-1479d2755e14"
},
{
"type": "Arugam Bay, Sri Lanka",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/ArugamBay.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/sri-lanka/the-east/travel-tips-and-articles/the-arugam-effect-taking-it-easy-on-sri-lankas-east-coast/40625c8c-8a11-5710-a052-1479d2755b2d"
},
{
"type": "Sìchuān, China",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/Sichuan.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/china/sichuan/travel-tips-and-articles/sizzling-sichuan-exploring-chinas-quintessential-province/40625c8c-8a11-5710-a052-1479d2755e8b"
},
{
"type": "Komodo National Park, Indonesia",
"image": "https://lonelyplanetstatic.imgix.net/marketing/2018/BIA/places/Komodo.jpg?q=40&sharp=10&vib=20&w=540&h=540&fit=crop",
"link": "https://www.lonelyplanet.com/indonesia/komodo-rinca-islands/travel-tips-and-articles/enter-the-dragon-exploring-komodo-national-parks-wild-attractions/40625c8c-8a11-5710-a052-1479d2755890"
},
]}
/>
));
storiesOf("Controls", module)
.addDecorator(withKnobs)
.add("Avatar upload", () => (
<AvatarUpload
src={text("Image source", data.avatar.rizzo)}
/>
))
.add("Calendar", () => (
<Calendar />
))
.add("Checkbox", () => (
<Checkbox
value={text("Value", "Some value")}
id={text("ID", "check")}
name={text("Name", "check")}
label={text("Label", "Checkbox")}
checked={boolean("Checked", true)}
rounded={boolean("Rounded", false)}
removeBorder={boolean("Remove border", false)}
size={select("Size", [16, 24, 32], 16)}
onClick={action(event)}
/>
))
.add("Date range - without selection", () => (
<React.Fragment>
<DateRange
id="testDateRange"
numberOfMonths={number("Number of Months", 1)}
startDatePlaceholderText={text("Start Date Placeholder", "Check-in")}
endDatePlaceholderText={text("End Date Placeholder", "Check-out")}
startDate={object("Start Date", null)}
endDate={object("End Date", null)}
lastSelectableDate={object("Last selectable date", moment().add(365, "days"))}
noBorder={boolean("noBorder", false)}
withFullScreenPortal={boolean("withFullScreenPortal", false)}
soldOut={boolean("soldOut", false)}
onDatesChange={action(event)}
onFocusChange={action(event)}
qaHook={boolean("QA Hook", false)}
/>
<DateRangeDeveloperNote />
</React.Fragment>
))
.add("Date range - with just startDate selected", () => (
<React.Fragment>
<DateRange
id="testDateRange"
numberOfMonths={number("Number of Months", 1)}
startDatePlaceholderText={text("Start Date Placeholder", "Check-in")}
endDatePlaceholderText={text("End Date Placeholder", "Check-out")}
startDate={object("Start Date", moment().add(1, "days"))}
endDate={object("End Date", null)}
noBorder={boolean("noBorder", false)}
withFullScreenPortal={boolean("withFullScreenPortal", false)}
soldOut={boolean("soldOut", false)}
onDatesChange={action(event)}
onFocusChange={action(event)}
qaHook={boolean("QA Hook", false)}
/>
<DateRangeDeveloperNote />
</React.Fragment>
))
.add("Date range - with selection", () => (
<React.Fragment>
<DateRange
id="testDateRange"
numberOfMonths={number("Number of Months", 1)}
startDatePlaceholderText={text("Start Date Placeholder", "Check-in")}
endDatePlaceholderText={text("End Date Placeholder", "Check-out")}
startDate={object("Start Date", moment().add(35, "days"))}
endDate={object("End Date", moment().add(36, "days"))}
noBorder={boolean("noBorder", false)}
withFullScreenPortal={boolean("withFullScreenPortal", false)}
soldOut={boolean("soldOut", false)}
onDatesChange={action(event)}
onFocusChange={action(event)}
qaHook={boolean("QA Hook", false)}
/>
<DateRangeDeveloperNote />
</React.Fragment>
))
.add("Dropdown", () => (
<Dropdown
options={array("Options", ["AUD", "EUR", "GBP", "USD"])}
defaultValue={text("Default value", "USD")}
onChange={action(event)}
qaHook={boolean("QA Hook", false)}
/>
))
.add("Input", () => (
<Center backgroundColor="white">
<Input qaHook={boolean("QA Hook", false)} />
</Center>
))
.add("Range", () => (
<Center backgroundColor="white" grow>
<Range
onAfterChange={action(event)}
min={0}
max={10}
defaultValue={[0, 10]}
label="Range control"
/>
</Center>
))
.add("Range - price", () => (
<Center backgroundColor="white" grow>
<Range
onAfterChange={action(event)}
min={0}
max={10}
defaultValue={[0, 10]}
label="Range control"
price
/>
</Center>
))
.add("Range - time", () => (
<Center backgroundColor="white" grow>
<Range
onAfterChange={action(event)}
min={0}
max={10}
defaultValue={[0, 10]}
label="Range control"
time
/>
</Center>
))
.add("Select - array of string", () => (
<Center backgroundColor="white">
<Select
id={text("ID", "select-control")}
options={array("Options", ["USA", "France", "Spain"])}
label={text("Label", "Select label")}
name={text("Name", "select-control")}
defaultValue={text("Value", "")}
required={boolean("Required", false)}
size={select("Size", ["tiny", "small", "medium", "large", "huge"], "medium")}
theme={select("Theme", ["base", "light", "dark", "inputGroup"], "base")}
noBorder={boolean("No border?", false)}
style={{}}
qaHook={boolean("QA Hook", false)}
onChange={action(event)}
/>
</Center>
))
.add("Select - array of object", () => (
<Center backgroundColor="white">
<Select
id={text("ID", "select-control")}
options={array("Options", [
{ label: "USA", value: "usa" },
{ label: "France", value: "france" },
{ label: "Spain", value: "spain" },
])}
label={text("Label", "Select label")}
name={text("Name", "select-control")}
defaultValue={text("Value", "")}
required={boolean("Required", false)}
size={select("Size", ["tiny", "small", "medium", "large", "huge"], "medium")}
theme={select("Theme", ["base", "light", "dark", "inputGroup"], "base")}
noBorder={boolean("No border?", false)}
style={{}}
onChange={action(event)}
qaHook={boolean("QA Hook", false)}
/>
</Center>
))
.add("Switch", () => (
<Center backgroundColor="white">
<Switch
id={text("ID", "privacy-control")}
name={text("Name", "privacy_control")}
className={text("Classname", null)}
value={text("Value", "private")}
checked={boolean("Checked", false)}
onClick={action("Switch toggled")}
/>
</Center>
))
.add("Textarea - default", () => (
<Center backgroundColor="white">
<Textarea />
</Center>
))
.add("Textarea - autogrow", () => (
<Center backgroundColor="white">
<Textarea
maxLines={number("Maximum lines", 3)}
disableEnter={boolean("Disable enter", false)}
autogrow
/>
</Center>
))
.add("Typeahead - default", () => (
<Typeahead
options={data.typeaheadPlaces}
placeholder="Select a place to go"
/>
))
.add("Typeahead - tokenizer", () => (
<TypeaheadTokenizer
options={data.travelInterests}
placeholder="Select your travel interests"
/>
));
storiesOf("Images", module)
.addDecorator(withKnobs)
.add("Album thumbnail image - default", () => (
<Center>
<AlbumThumbnailImage />
</Center>
))
.add("Album thumbnail image - plus icon", () => (
<Center>
<AlbumThumbnailImage icon="Plus" />
</Center>
))
.add("Album thumbnail image - image", () => (
<Center>
<AlbumThumbnailImage
src={text("Source", "https://lonelyplanetwp.imgix.net/2017/07/GettyImages-647005142_high_1-360ee8e327d5.jpg?crop=entropy&fit=crop&h=96&sharp=10&vib=20&w=104")}
alt={text("Alternate text", "")}
/>
</Center>
))
.add("Image hero", () => (
<ImageHero
image={text("Image URL", "https://s3.amazonaws.com/static-asset/backpack-ui/ImageHero.770x430.jpg")}
imageSize={array("Size", [770, 430])}
/>
))
.add("Placeholder", () => (
<Placeholder title={text("Title", "The best place in the world")} />
));
storiesOf("Links", module)
.addDecorator(withKnobs)
.add("Callout link - default", () => (
<CalloutLink href="/" qaHook={boolean("QA Hook", false)}>
{text("Text", "More recommendations")}
</CalloutLink>
))
.add("Callout link - overlay", () => (
<div style={{ backgroundColor: "#000", padding: "20px" }}>
<CalloutLink href="/" overlay qaHook={boolean("QA Hook", false)}>
{text("Text", "More recommendations")}
</CalloutLink>
</div>
))
.add("Edit link", () => (
<EditLink url={text("URL", "/")} qaHook={boolean("QA Hook", false)} />
))
.add("More link - anchor", () => (
<MoreLink
href={text("URL", "/")}
size={select("Size", ["", "small"], "")}
caps={boolean("Capitalized", false)}
hideIcon={boolean("Hide icon", false)}
arrowDirection={select("Arrow diretion", ["up", "down", "left", "right"], "right")}
qaHook={text("QA Hook", "hook")}
>
{text("Text", "View all tours")}
</MoreLink>
))
.add("More link - button", () => (
<MoreLink
onClick={action("MoreLink clicked")}
size={select("Size", ["", "small"], "")}
caps={boolean("Capitalized", false)}
hideIcon={boolean("Hide icon", false)}
arrowDirection={select("Arrow diretion", ["up", "down", "left", "right"], "right")}
qaHook={text("QA Hook", "hook")}
>
{text("Text", "View all tours")}
</MoreLink>
))
.add("More link - span", () => (
<MoreLink
isNested
size={select("Size", ["", "small"], "")}
caps={boolean("Capitalized", false)}
hideIcon={boolean("Hide icon", false)}
arrowDirection={select("Arrow diretion", ["up", "down", "left", "right"], "right")}
qaHook={text("QA Hook", "hook")}
>
{text("Text", "View all tours")}
</MoreLink>
));
storiesOf("List items", module)
.addDecorator(withKnobs)
.add("List item - bookmark - default", () => (
<StyleRoot>
<ListItemBookmark
name={text("Name", "Favorites")}
thumbnail={text("Thumbnail", "")}
entriesCount={5}
visibility={select("Visibility", ["Private", "Public"], "Private")}
large={boolean("Large", false)}
hideDetail={boolean("Hide details", false)}
qaHook={boolean("QA Hook", false)}
/>
</StyleRoot>
))
.add("List item - bookmark - with onClick event", () => (
<StyleRoot>
<ListItemBookmark
name={text("Name", "Places to see in Nashville")}
onClick={action("List item clicked")}
checked={boolean("Checked", false)}
thumbnail={text("Thumbnail", "")}
entriesCount={5}
visibility={select("Visibility", ["Private", "Public"], "Private")}
large={boolean("Large", false)}
hideDetail={boolean("Hide details", false)}
qaHook={boolean("QA Hook", false)}
/>
</StyleRoot>
))
.add("List item - bookmark - as “add item” button", () => (
<StyleRoot>
<ListItemBookmark
name={text("Name", "New item")}
onClick={action("Add item clicked")}
large={boolean("Large", false)}
hideDetail={boolean("Hide details", true)}
addItem={boolean("Add item UI", true)}
qaHook={boolean("QA Hook", false)}
/>
</StyleRoot>
))
.add("List item - bookmark entry", () => (
<StyleRoot>
<ListItemBookmarkEntry
name={text("Name", "POI Name")}
category={text("Category", "Category")}
city={text("City", "City")}
priceRange={select("Range", ["$", "$$", "$$$"], "$")}
topChoice={boolean("Top choice", false)}
note={text("Note", "This is where a nice little note goes.")}
large={boolean("Large", false)}
qaHook={boolean("QA Hook", false)}
/>
</StyleRoot>
))
.add("List item - news", () => (
<StyleRoot>
<ListItemNews
title={text("Title", "Ireland is set to have the world’s largest redwood forest outside of California")}
category={text("Category", "Europe")}
categoryLink={text("Category URL", "/")}
link={text("URL", "/")}
thumbnail={text("Image URL", "http://placehold.it/110x110")}
size={select("Size", ["small", "medium"], "medium")}
isSponsored={boolean("Sponsored", false)}
qaHook={boolean("QA Hook", false)}
/>
</StyleRoot>
))
.add("Sights list item - default", () => (
<SightsListItem
slug="/path/to/item"
title="Zimbabwe"
subtitle="Southern Africa"
markerNumber={1}
qaHook={boolean("QA Hook", false)}
/>
))
.add("Sights list item - with Image", () => (
<SightsListItem
slug="/path/to/item"
title="Zimbabwe"
subtitle="Southern Africa"
imgPath="https://s3.amazonaws.com/static-asset/backpack-ui/south-pole.80x60.jpg"
markerNumber={1}
qaHook={boolean("QA Hook", false)}
/>
));
storiesOf("Lists", module)
.addDecorator(withKnobs)
.add("News list - default", () => (
<StyleRoot>
<NewsList
newsItems={[{
title: "Whales migration patterns passed down from mother to child",
category: "The World",
categoryLink: "/path/to/category",
description: `Life has a languid quality in the stunning landscapes of
the Upper Peninsula (called the UP by visitors, and its residents are
known as Yoopers). Americans`,
link: "/path/to/full/article",
thumbnail: "https://lonelyplanetwp.imgix.net/2016/08/Hubud-657aa84af2b1.jpg?w=110&h=110&fit=crop&q=50&auto=enhance&crop=entropy",
}, {
title: `Watch this adorable Kangaroo invade a family's campervan and
then return with her friends`,
category: "Asia & the pacific",
categoryLink: "/path/to/category",
description: `Life has a languid quality in the stunning landscapes of
the Upper Peninsula (called the UP by visitors, and its residents are
known as Yoopers). Americans`,
link: "/path/to/full/article",
thumbnail: "https://lonelyplanetwp.imgix.net/2016/08/Hubud-657aa84af2b1.jpg?w=110&h=110&fit=crop&q=50&auto=enhance&crop=entropy",
}]}
/>
</StyleRoot>
))
.add("News list - small list items", () => (
<StyleRoot>
<NewsList
newsItems={[{
title: "Whales migration patterns passed down from mother to child",
category: "The World",
categoryLink: "/path/to/category",
description: `Life has a languid quality in the stunning landscapes of
the Upper Peninsula (called the UP by visitors, and its residents are
known as Yoopers). Americans`,
link: "/path/to/full/article",
thumbnail: "https://lonelyplanetwp.imgix.net/2016/08/Hubud-657aa84af2b1.jpg?w=110&h=110&fit=crop&q=50&auto=enhance&crop=entropy",
size: "small",
}, {
title: `Watch this adorable Kangaroo invade a family's campervan and
then return with her friends`,
category: "Asia & the pacific",
categoryLink: "/path/to/category",
description: `Life has a languid quality in the stunning landscapes of
the Upper Peninsula (called the UP by visitors, and its residents are
known as Yoopers). Americans`,
link: "/path/to/full/article",
thumbnail: "https://lonelyplanetwp.imgix.net/2016/08/Hubud-657aa84af2b1.jpg?w=110&h=110&fit=crop&q=50&auto=enhance&crop=entropy",
size: "small",
}]}
/>
</StyleRoot>
))
.add("Number list", () => (
<NumberList qaHook={boolean("QA Hook", false)} list={data.numberList} />
));
storiesOf("Labels", module)
.addDecorator(withKnobs)
.add("Category label - default", () => (
<CategoryLabel
light={boolean("Light", false)}
qaHook={boolean("QA Hook", false)}
>
{text("Text", "Art and culture")}
</CategoryLabel>
))
.add("Category label - link", () => (
<CategoryLabelLink href={text("URL", "/")} qaHook={boolean("QA Hook", false)}>
{text("Text", "Art and culture")}
</CategoryLabelLink>
))
.add("Flag", () => (
<Flag>{text("Text", "Private")}</Flag>
))
.add("Location label", () => (
<LocationLabel>Ottawa, ON</LocationLabel>
))
.add("Number marker", () => (
<NumberMarker number={number("Number", 4)} />
))
.add("Reviewed badge", () => (
<ReviewedBadge />
))
.add("Sponsor label", () => (
<SponsorLabel>
{text("Text", "Sponsored")}
</SponsorLabel>
))
.add("Text bubble", () => (
<TextBubble>{text("Text", "44 mins")}</TextBubble>
));
storiesOf("Loaders", module)
.addDecorator(withKnobs)
.add("Loading", () => (
<StyleRoot>
<Center backgroundColor="white">
<Loading />
</Center>
</StyleRoot>
))
.add("Dot loader", () => (
<StyleRoot>
<Center backgroundColor="white">
<DotLoader inline={boolean("Inline", false)} />
</Center>
</StyleRoot>
));
storiesOf("Lockups", module)
.addDecorator(withKnobs)
.add("Accordio