Gatsbyサイトのトップページにカテゴリ一覧を追加してみました
2019年1月25日2019年1月26日
Gatsbyで作っているこのサイトのトップページにカテゴリ一覧を追加しました。これでトップページからも各カテゴリの記事一覧に移動できるようになりました。
実装について
トップページに以下を実装しました。
- カテゴリ一覧を引っ張ってくるGraphQLを追加
- 表示部分のコードの追加
1. カテゴリ一覧を引っ張ってくるGraphQLを追加
記事一覧用のクエリに加えてカテゴリ一覧用のクエリも必要になったので、posts
とcategory
のエイリアスを追加してそれぞれのクエリを書くようにしました。ハイライトされている部分が追加したカテゴリ一覧用のクエリ部分です。
export const query = graphql`
query {
posts: allAirtable(
sort: { fields: [data___date], order: DESC },
filter: { table: {eq: "entry"}},
) {
totalCount
edges {
node {
data {
slug
title
date(formatString: "YYYY年M月D日")
image {
id
url
}
}
}
}
}
category: allAirtable( filter: { table: {eq: "category"}, data: {entry: {ne: null}} } ) { edges { node { data { catname slug entry } } } }
... 省略 ...
}
`
2. 表示部分のコードの追加
記事の数が多いカテゴリから表示したかったので、sort()
メソッドを使ってオブジェクト内のデータの順番を変更しました。GraphQLでどうにか解決できないかと思いググったりして模索してみたんですけど諦めました。
const category = this.props.data.category
const catOrdered = category.edges.sort((a,b) => { let x = a.node.data.entry.length; let y = b.node.data.entry.length; let res = 0; if (x > y){ res = -1; } if (x < y){ res = 1; } return res; });
このノートサイトのデータはAirtableを使って管理しているんですが、他のテーブルにリンクしたフィールドはリンクされた項目の数をnode.data.entry.length
のようにオブジェクトのプロパティの長さから取得できます。
上のJavaScriptでは取得した項目の数をsort()
メソッドで比較して、順番を並び替えています。
Mapを使ってカテゴリを表示
あとはmap()
メソッドを使って一覧を表示させました。
<div className={styles.catlist}>
<ul>
{catOrdered.map(({ node }, index) => (
<li key={index}>
<Link
to={`category/${node.data.slug}/`}
>{node.data.catname}
</Link>
</li>
))}
</ul>
</div>
デザインについて
記事一覧をメインに扱いたいので、カテゴリ一覧は控え目なデザインにしました。それから、カテゴリの数が増えても、この領域が縦に伸びないように、横にスクロールするようにしました。
ただ、問題が一つあって、このままだとマウスで操作できないレイアウトになってしまっています
改善のオプションは以下の3つあたりでしょうか?
a. JSでドラッグできるようにする?
トラックパッドやタッチスクリーン、スクリーンリーダーでは問題ないんですけどね。横スクロールのできないマウスだと操作できません。JS使ってドラッグ&スクロールできるようにしないとダメですかね。JSの実装はこの動画がわかりやすくて面白い。こんな仕組みでできるんですね。
b. Moreボタンを表示させる?
それとも、表示できない分については「More」ボタンを表示して、カテゴリ全一覧ページに遷移させるか。。。これもJSでコンテンツの幅を計算して、表示幅と比較して、小さかったら最後のアイテムを「More」ボタンにする的な実装が必要になりそうです。
c. スクロールバーを表示させちゃう?
スクロールバーを表示させちゃえば、操作はできるんですけどね。スペースとるし邪魔だし、見た目がUGLYなんですよねぇ。このコンテキストでは。好みの問題ですけど、僕は嫌いです
実装は複雑にしたくないし。うーん、悩ましい