R note

Gatsbyサイトのトップページにカテゴリ一覧を追加してみました

GatsbyJSフロントエンドデザインAirtable

トップページに追加されたカテゴリ一覧

Gatsbyで作っているこのサイトのトップページにカテゴリ一覧を追加しました。これでトップページからも各カテゴリの記事一覧に移動できるようになりました。

実装について

トップページに以下を実装しました。

  1. カテゴリ一覧を引っ張ってくるGraphQLを追加
  2. 表示部分のコードの追加

1. カテゴリ一覧を引っ張ってくるGraphQLを追加

記事一覧用のクエリに加えてカテゴリ一覧用のクエリも必要になったので、postscategoryのエイリアスを追加してそれぞれのクエリを書くようにしました。ハイライトされている部分が追加したカテゴリ一覧用のクエリ部分です。

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>

デザインについて

記事一覧をメインに扱いたいので、カテゴリ一覧は控え目なデザインにしました。それから、カテゴリの数が増えても、この領域が縦に伸びないように、横にスクロールするようにしました。

ただ、問題が一つあって、このままだとマウスで操作できないレイアウトになってしまっていますemoji-sweat_drops

改善のオプションは以下の3つあたりでしょうか?

a. JSでドラッグできるようにする?

トラックパッドやタッチスクリーン、スクリーンリーダーでは問題ないんですけどね。横スクロールのできないマウスだと操作できません。JS使ってドラッグ&スクロールできるようにしないとダメですかね。JSの実装はこの動画がわかりやすくて面白い。こんな仕組みでできるんですね。

b. Moreボタンを表示させる?

それとも、表示できない分については「More」ボタンを表示して、カテゴリ全一覧ページに遷移させるか。。。これもJSでコンテンツの幅を計算して、表示幅と比較して、小さかったら最後のアイテムを「More」ボタンにする的な実装が必要になりそうです。

c. スクロールバーを表示させちゃう?

スクロールバーを表示させちゃえば、操作はできるんですけどね。スペースとるし邪魔だし、見た目がUGLYなんですよねぇ。このコンテキストでは。好みの問題ですけど、僕は嫌いですemoji-grin

実装は複雑にしたくないし。うーん、悩ましいemoji-dizzy_face