GatsbyJSに画像付きカードメニューを作成する
01 28, 2019
GatsbyJSに画像付きカードメニューを作成する
時代は、画像付き投稿一覧だよね?(個人の感想です。) ということで実装してみた。
やったこと
- postlistコンポーネントの変更
- coverImageコンポーネントの実装
- markdownにカバーイメージを追加
postlistを以下の様に変更した。
import React from "react";
import PropTypes from 'prop-types';
import CoverImage from '../../components/CoverImage'
import './postlist.css'
class Postlist extends React.Component {
getPostList() {
const postList = [];
this.props.postEdges.forEach(postEdge => {
postList.push({
title: postEdge.node.frontmatter.title,
date: postEdge.node.frontmatter.date,
cover: postEdge.node.frontmatter.coverImage,
excerpt: postEdge.node.excerpt,
});
});
return postList;
}
render() {
const postList = this.getPostList();
return (
<div className="grid">
{postList.map( post => (
<div key={post.id} className="griditem">
<div className="coverImage">
<CoverImage filename={post.cover}></CoverImage>
</div>
<span>
{post.title}<br/>
{post.date}
</span>
</div>
))}
</div>
);
}
}
export default Postlist;
そして、カードデザインを実装する
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(336px, 1fr));
grid-gap: 16px;
align-items: stretch;
}
.griditem {
max-width: 336px;
border: 1px solid #ccc;
box-shadow: 2px 2px 6px 0px rgba(0,0,0,0.3);
}
.griditem > img {
max-width: 100%;
}
.text {
padding: 0 20px 20px;
}
.text > button {
background: gray;
border: 0;
color: white;
padding: 10px;
width: 100%;
}
カードデザインの幅を336pxに設定しているのには実は理由があって、将来GoogleAdSenseを違和感なくフィットさせることに挑戦したいので、この幅で設定した。
coverImageコンポーネントの実装
import React from 'react'
import { StaticQuery, graphql } from 'gatsby'
import Img from 'gatsby-image'
import "./coverimage.css"
const Image = (props) => (
<StaticQuery
query={graphql`
query {
images: allFile {
edges {
node {
relativePath
name
childImageSharp {
fluid(maxWidth: 336, maxHeight: 280){
...GatsbyImageSharpFluid
}
}
}
}
}
}
`}
render={(data) => {
const image = data.images.edges.find(n => {
return n.node.relativePath.includes(props.filename);
});
if (!image) { return null; }
const imagefluid = image.node.childImageSharp.fluid;
return (
<Img
alt={props.alt}
sizes={imagefluid}
/>
);
}}
/>
)
export default Image
こちらもAdSenseを見越して336×280の画像を生成出来るように実装しておく。
page/index.jsのGraphQLも変更しておく
export const query = graphql`
query {
allMarkdownRemark(filter: {frontmatter: {pagetype: {ne: "category"}}}) {
totalCount
edges {
node {
id
frontmatter {
title
date(formatString: "DD MMMM, YYYY")
category
coverImage
}
excerpt
}
}
}
}
`
できた!