🔖 Upgrade to Gatsby 1.8.12

This commit is contained in:
wpioneer
2017-08-20 14:43:49 +03:00
parent 88481e75f0
commit a2f8738ea6
115 changed files with 4734 additions and 5018 deletions

View File

@@ -0,0 +1,44 @@
import React from 'react';
import PropTypes from 'prop-types';
import Post from '../Post';
class CategoryTemplateDetails extends React.Component {
render() {
const items = [];
const category = this.props.pathContext.category;
const posts = this.props.data.allMarkdownRemark.edges;
posts.forEach((post) => {
items.push(
<Post data={post} key={post.node.fields.slug} />
);
});
return (
<div className="content">
<div className="content__inner">
<div className="page">
<h1 className="page__title">
{category}
</h1>
<div className="page__body">
{items}
</div>
</div>
</div>
</div>
);
}
}
CategoryTemplateDetails.propTypes = {
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
edges: PropTypes.array.isRequired
})
}),
pathContext: PropTypes.shape({
category: PropTypes.string.isRequired
})
};
export default CategoryTemplateDetails;

View File

@@ -0,0 +1,65 @@
import React from 'react';
import PropTypes from 'prop-types';
import './style.scss';
import '../../assets/fonts/fontello-771c82e0/css/fontello.css';
class Links extends React.Component {
render() {
const author = this.props.data;
const links = {
telegram: author.telegram,
twitter: author.twitter,
github: author.github,
vk: author.vk,
rss: author.rss,
email: author.email
};
return (
<div className="links">
<ul className="links__list">
<li className="links__list-item">
<a href={links.twitter}>
<i className="icon-twitter" />
</a>
</li>
<li className="links__list-item">
<a href={links.github}>
<i className="icon-github" />
</a>
</li>
<li className="links__list-item">
<a href={links.vk}>
<i className="icon-vkontakte" />
</a>
</li>
</ul>
<ul className="links__list">
<li className="links__list-item">
<a href={`mailto:${links.email}`}>
<i className="icon-mail" />
</a>
</li>
<li className="links__list-item">
<a href={`telegram:${links.telegram}`}>
<i className="icon-paper-plane" />
</a>
</li>
</ul>
<ul className="links__list">
<li className="links__list-item">
<a href={links.rss}>
<i className="icon-rss" />
</a>
</li>
</ul>
</div>
);
}
}
Links.propTypes = {
data: PropTypes.object.isRequired
};
export default Links;

View File

@@ -0,0 +1,35 @@
@import "../../assets/scss/variables";
@import "../../assets/scss/mixins";
.links {
@include margin-bottom(1);
&__list {
display: flex;
list-style: none;
padding: 0;
margin: 10px -3px;
&-item {
padding: 0;
margin: 0 3px;
height: 24px;
width: 24px;
line-height: 24px;
border-radius: 3px;
text-align: center;
background: $color-gray-bg;
& a {
border: 0;
& i {
font-size: 14px;
color: lighten($color-base, 20%);
}
&:hover,
&:focus {
& i {
color: $color-base;
}
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
import React from 'react';
import PropTypes from 'prop-types';
import Link from 'gatsby-link';
import './style.scss';
class Menu extends React.Component {
render() {
const menu = this.props.data;
const menuBlock = (
<ul className="menu__list">
{menu.map(item =>
<li className="menu__list-item" key={item.path}>
<Link
exact to={item.path}
className="menu__list-item-link"
activeClassName="menu__list-item-link menu__list-item-link--active"
>
{item.label}
</Link>
</li>
)}
</ul>
);
return (
<nav className="menu">
{menuBlock}
</nav>
);
}
}
Menu.propTypes = {
data: PropTypes.array.isRequired
};
export default Menu;

View File

@@ -0,0 +1,30 @@
@import "../../assets/scss/variables";
@import "../../assets/scss/mixins";
.menu {
@include margin-bottom(1);
&__list {
list-style: none;
padding: 0;
margin: 0;
&-item {
padding: 0;
margin: 10px 0;
&-link {
font-size: $typographic-base-font-size;
color: $typographic-base-font-color;
font-weight: 400;
border: 0;
&:hover,
&:focus {
color: $color-primary;
border-bottom: 1px solid $color-primary;
}
&--active {
color: $color-base;
border-bottom: 1px solid $color-base;
}
}
}
}
}

View File

@@ -0,0 +1,32 @@
import React from 'react';
import PropTypes from 'prop-types';
import Sidebar from '../Sidebar';
import './style.scss';
class PageTemplateDetails extends React.Component {
render() {
const page = this.props.data.markdownRemark;
return (
<div>
<Sidebar {...this.props} />
<div className="content">
<div className="content__inner">
<div className="page">
<h1 className="page__title">{page.frontmatter.title}</h1>
<div className="page__body" dangerouslySetInnerHTML={{ __html: page.html }} />
</div>
</div>
</div>
</div>
);
}
}
PageTemplateDetails.propTypes = {
data: PropTypes.shape({
markdownRemark: PropTypes.object.isRequired
})
};
export default PageTemplateDetails;

View File

@@ -0,0 +1,18 @@
@import "../../assets/scss/variables";
@import "../../assets/scss/mixins";
.page {
@include margin-bottom(2);
&__title {
font-size: $typographic-base-font-size * 2.5;
font-weight: 500;
@include line-height(2);
@include margin-top(0);
@include margin-bottom(1.45);
}
&__body {
font-size: $typographic-base-font-size;
@include line-height(1);
@include margin(0, 0, 1);
}
}

View File

@@ -0,0 +1,46 @@
import React from 'react';
import PropTypes from 'prop-types';
import Link from 'gatsby-link';
import moment from 'moment';
import './style.scss';
class Post extends React.Component {
render() {
const data = this.props.data;
const post = {
title: data.node.frontmatter.title,
slug: data.node.fields.slug,
description: data.node.frontmatter.description,
date: data.node.frontmatter.date,
category: data.node.frontmatter.category,
categorySlug: data.node.fields.categorySlug
};
return (
<div className="post">
<div className="post__meta">
<time className="post__meta-time" dateTime={moment(post.date).format('MMMM D, YYYY')}>
{moment(post.date).format('MMMM YYYY')}
</time>
<span className="post__meta-divider" />
<span className="post__meta-category" key={post.categorySlug}>
<Link to={post.categorySlug} className="post__meta-category-link">
{post.category}
</Link>
</span>
</div>
<h2 className="post__title">
<Link className="post__title-link" to={post.slug}>{post.title}</Link>
</h2>
<p className="post__description">{post.description}</p>
<Link className="post__readmore" to={post.slug}>Read</Link>
</div>
);
}
}
Post.propTypes = {
data: PropTypes.object.isRequired
};
export default Post;

View File

@@ -0,0 +1,60 @@
@import "../../assets/scss/variables";
@import "../../assets/scss/mixins";
.post {
@include margin-bottom(1.25);
&:last-child {
@include margin-bottom(.5);
}
&__title {
font-size: $typographic-base-font-size * 1.6875;
@include line-height(1.5);
@include margin-top(0);
@include margin-bottom(.5);
&-link {
color: $color-base;
&:hover,
&:focus {
color: $color-base;
border-bottom: 1px solid $color-base;
}
}
}
&__description {
font-size: $typographic-base-font-size;
@include line-height(1);
@include margin-bottom(.75);
}
&__meta {
&-time {
font-size: $typographic-small-font-size;
color: $color-base;
font-weight: 500;
text-transform: uppercase;
}
&-divider {
margin: 0 5px;
}
&-category {
&-link {
font-size: $typographic-small-font-size;
color: $color-secondary;
font-weight: 500;
text-transform: uppercase;
&:hover,
&:focus {
color: $color-primary;
}
}
}
}
&__readmore {
font-size: $typographic-base-font-size;
color: $color-primary;
&:hover,
&:focus {
color: $color-primary;
border-bottom: 1px solid $color-primary;
}
}
}

View File

@@ -0,0 +1,72 @@
import React from 'react';
import PropTypes from 'prop-types';
import Link from 'gatsby-link';
import moment from 'moment';
import './style.scss';
class PostTemplateDetails extends React.Component {
render() {
const { subtitle, author } = this.props.data.site.siteMetadata;
const post = this.props.data.markdownRemark;
const tags = post.fields.tagSlugs;
const homeBlock = (
<div>
<Link className="post-single__home-button" to="/">All Articles</Link>
</div>
);
const tagsBlock = (
<div className="post-single__tags">
<ul className="post-single__tags-list">
{tags.map((tag, i) =>
<li className="post-single__tags-list-item" key={tag}>
<Link to={tag} className="post-single__tags-list-item-link">
{post.frontmatter.tags[i]}
</Link>
</li>
)}
</ul>
</div>
);
return (
<div>
{homeBlock}
<div className="post-single">
<div className="post-single__inner">
<h1 className="post-single__title">{post.frontmatter.title}</h1>
<div className="post-single__body" dangerouslySetInnerHTML={{ __html: post.html }} />
<div className="post-single__date">
<em>Published {moment(post.frontmatter.date).format('D MMM YYYY')}</em>
</div>
</div>
<div className="post-single__footer">
{tagsBlock}
<hr />
<p className="post-single__footer-text">
{subtitle}
<a href={author.twitter} target="_blank" rel="noopener noreferrer">
<br /> <strong>{author.name}</strong> on Twitter
</a>
</p>
</div>
</div>
</div>
);
}
}
PostTemplateDetails.propTypes = {
data: PropTypes.shape({
site: PropTypes.shape({
siteMetadata: PropTypes.shape({
subtitle: PropTypes.string.isRequired,
author: PropTypes.object.isRequired
})
}),
markdownRemark: PropTypes.object.isRequired
})
};
export default PostTemplateDetails;

View File

@@ -0,0 +1,166 @@
@import "../../assets/scss/variables";
@import "../../assets/scss/mixins";
.post-single {
&__inner {
max-width: $layout-post-single-max-width;
padding: 0 15px;
margin: 0 auto;
}
&__title {
font-size: $typographic-base-font-size * 2;
max-width: $layout-post-single-width;
margin-left: auto;
margin-right: auto;
font-weight: 600;
text-align: center;
@include line-height(1.65);
@include margin-top(1);
@include margin-bottom(0);
}
&__body {
& figure {
@include margin-bottom(1);
& blockquote {
font-style: italic;
text-align: center;
margin-top: 0;
@include padding(1, 0);
& p {
max-width: $layout-post-single-width;
font-size: $typographic-base-font-size * 1.6817;
margin-top: 0;
@include margin-bottom(1);
@include line-height(1.5);
}
}
}
& a {
text-decoration: underline;
}
& .gatsby-highlight {
max-width: $layout-post-single-width;
margin-left: 15px;
margin-right: 15px;
@include margin-bottom(1);
}
& :not(div) {
max-width: $layout-post-single-width;
margin-left: auto;
margin-right: auto;
}
}
&__footer {
max-width: $layout-post-single-width;
margin-left: 15px;
margin-right: 15px;
@include line-height(1);
@include margin-top(1);
@include margin-bottom(2);
&-text {
& a {
text-decoration: underline;
}
}
}
&__date {
max-width: $layout-post-single-width;
margin-left: auto;
margin-right: auto;
}
&__tags {
@include margin-bottom(.5);
&-list {
list-style: none;
margin: 0 -5px;
padding: 0;
&-item {
display: inline-block;
margin: 10px 5px;
&-link {
background: $color-gray-bg;
text-decoration: none;
border: 0;
border-radius: 3px;
color: lighten($color-base, 20%);
line-height: $typographic-base-line-height;
padding: 8px 16px;
&:hover,
&:focus {
color: $color-base;
background: darken($color-gray-bg, 5%);
border: 0;
}
}
}
}
}
&__home-button {
display: block;
margin-left: auto;
margin-right: auto;
max-width: 90px;
font-size: $typographic-base-font-size;
padding: 0 16px;
height: 35px;
line-height: 35px;
text-align: center;
color: lighten($color-base, 20%);
background: $color-gray-bg;
font-weight: 400;
border-radius: 3px;
@include margin-top(1);
&:hover,
&:focus {
color: $color-base;
background: darken($color-gray-bg, 5%);
border: 0;
}
}
}
@include breakpoint-sm {
.post-single {
&__footer {
margin-left: auto;
margin-right: auto;
}
&__body {
& .gatsby-highlight {
margin-left: auto;
margin-right: auto;
}
}
}
}
@include breakpoint-md {
.post-single {
&__inner {
padding: 0;
}
&__title {
font-size: $typographic-base-font-size * 3;
@include line-height(2.25);
@include margin-top(2.25);
@include margin-bottom(1.5);
}
&__body {
font-size: $typographic-base-font-size * 1.125;
@include line-height(1.125);
@include margin-bottom(1.125);
& p {
font-size: $typographic-base-font-size * 1.125;
@include line-height(1.125);
@include margin-bottom(1.125);
}
}
&__home-button {
position: fixed;
max-width: auto;
margin: 0;
top: 30px;
left: 30px;
}
}
}

View File

@@ -0,0 +1,74 @@
import React from 'react';
import PropTypes from 'prop-types';
import get from 'lodash/get';
import Link from 'gatsby-link';
import Menu from '../Menu';
import Links from '../Links';
import profilePic from '../../pages/photo.jpg';
import './style.scss';
class Sidebar extends React.Component {
render() {
const { location } = this.props;
const { author, subtitle, copyright, menu } = this.props.data.site.siteMetadata;
const isHomePage = get(location, 'pathname', '/') === '/';
/* eslint-disable jsx-a11y/img-redundant-alt*/
const authorBlock = (
<div>
<Link to="/">
<img
src={profilePic}
className="sidebar__author-photo"
width="75" height="75"
alt={author.name}
/>
</Link>
{ isHomePage ? (
<h1 className="sidebar__author-title">
<Link className="sidebar__author-title-link" to="/">{author.name}</Link>
</h1>
) :
<h2 className="sidebar__author-title">
<Link className="sidebar__author-title-link" to="/">{author.name}</Link>
</h2>
}
<p className="sidebar__author-subtitle">{subtitle}</p>
</div>
);
/* eslint-enable jsx-a11y/img-redundant-alt*/
return (
<div className="sidebar">
<div className="sidebar__inner">
<div className="sidebar__author">
{authorBlock}
</div>
<div>
<Menu data={menu} />
<Links data={author} />
<p className="sidebar__copyright">
{copyright}
</p>
</div>
</div>
</div>
);
}
}
Sidebar.propTypes = {
data: PropTypes.shape({
site: PropTypes.shape({
siteMetadata: PropTypes.shape({
subtitle: PropTypes.string.isRequired,
author: PropTypes.object.isRequired,
copyright: PropTypes.string.isRequired,
menu: PropTypes.array.isRequired
})
})
}),
location: PropTypes.object
};
export default Sidebar;

View File

@@ -0,0 +1,69 @@
@import "../../assets/scss/variables";
@import "../../assets/scss/mixins";
.sidebar {
width: 100%;
&__inner {
position: relative;
padding: 25px 20px 0;
}
&__author {
&-photo {
display: inline-block;
margin-bottom: 0;
border-radius: 50%;
background-clip: padding-box;
}
&-title {
font-size: $typographic-base-font-size * 1.125;
font-weight: 500;
@include line-height(1.125);
@include margin(.5, 0, .5, 0);
&-link {
color: $color-base;
&:hover,
&:focus {
color: $color-base;
}
}
}
&-subtitle {
color: $color-gray;
@include line-height(1);
@include margin-bottom(1);
}
}
&__copyright {
color: lighten($color-gray, 18%);
font-size: $typographic-small-font-size;
}
}
@include breakpoint-sm {
.sidebar {
lost-column: 5/12;
&__inner {
padding: 30px 20px 0;
&:after {
background: $color-gray-border;
background: linear-gradient(to bottom, $color-gray-border 0%, $color-gray-border 48%, $color-white 100%);
position: absolute;
content: "";
width: 1px;
height: 540px;
top: 30px;
right: -10px;
bottom: 0;
}
}
}
}
@include breakpoint-md {
.sidebar {
lost-column: 1/3;
&__inner {
padding: 40px;
}
}
}

View File

@@ -0,0 +1,44 @@
import React from 'react';
import PropTypes from 'prop-types';
import Post from '../Post';
class TagTemplateDetails extends React.Component {
render() {
const items = [];
const tagTitle = this.props.pathContext.tag;
const posts = this.props.data.allMarkdownRemark.edges;
posts.forEach((post) => {
items.push(
<Post data={post} key={post.node.fields.slug} />
);
});
return (
<div className="content">
<div className="content__inner">
<div className="page">
<h1 className="page__title">
All Posts tagget as &quot;{tagTitle}&quot;
</h1>
<div className="page__body">
{items}
</div>
</div>
</div>
</div>
);
}
}
TagTemplateDetails.propTypes = {
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
edges: PropTypes.array.isRequired
})
}),
pathContext: PropTypes.shape({
tag: PropTypes.string.isRequired
})
};
export default TagTemplateDetails;