📎

テーブルの行リンクは意外と面倒くさい

2024/06/07に公開

はじめに

Next.js にて下記のようなテーブルを作成する際に、テーブルの各行をリンク化させつつ特定のセルをクリッカブル(例だと編集モードにして編集作業を行うイメージ)にするのが面倒くさかったので愚痴っていきたいと思います。

Image from Gyazo

結論

テーブルにて行リンクが本当に必要か再検討すべし。

どうしても必要なら

  1. 色々と制約ついてしまうけど行リンクをやめてプログラムによる画面遷移にする
  2. div タグを用いて行リンクを実現させつつ(CSS グリッドを用いる)、テーブルを構築する

のどちらかで実装するのが良さそう

1. 行リンク諦めるパターン
'use client'

import { useRouter } from 'next/navigation'

const Table = () => {
  ...
  const router = useRouter()
  const handleRowClick = (row) => {
    router.push(`/use-cases/${row.original.id}`);
  }

  return (
    ...
    <tr onClick={()=> handleRowClick(row)}>
      ...
    </tr>
    ...
  );
}
2. divを用いてテーブルを構築する
import Link from "next/link"

const Table = () => {
  ...

  return (
    ...
    <Link
      key={row.id}
      className="relative grid w-full cursor-pointer grid-cols-5 place-items-center space-x-2 border-b-2 border-gray-200 hover:bg-slate-600"
      href={`/use-cases/${row.original.id}`}
    >
      ...
    </Link>
    ...
  )
}


検証用に使ったリポジトリ
https://github.com/youliangdao/table-row-next-link

そもそも table タグ を使うと行リンクがむずかしい

まず前提として(いろいろなところで言われていますが)table タグ を使うと行リンクは難しいです

table を使わないなら行全体の div をnext/linkなどで囲めばいいだけですが、table になると tr タグを a タグで囲んだり、tr タグの中に a タグを入れるのは不正な構造となってしまいます。

これを解決するためには、たとえば 「各セルに空の a タグを追加しその a タグが全体を覆うように CSS で調整する」 といったハック的な方法がありますが、あまり一般的ではありません。
(詳細は下記を参考にしてください)
https://dev.to/frontenddeveli/make-table-rows-clickable-as-links-with-tanstack-table-and-css-31bl

next/link を用いる場合は stopProgation が効かないことも地味に注意すべき点です。

preventDefaultを用いて伝搬を防がないといけないのもつい忘れがちです。

https://github.com/vercel/next.js/issues/45512

行でいろんなアクションを行うことがある

行でいろんなアクションを行いたい、みたいな要件は割とあります。

例えばサンプルコードに載せてるような編集可能なテーブルというのはその一部です。他にも、行削除や行追加などビジネス要件に応じてさまざまなことが求められます。

以下は Material UI と TanStack Table をベースにした「Material React Table」というライブラリのサンプル集ですが、ライブラリひとつとってもかなり多くのことが実現可能なことがわかるでしょう。

https://www.material-react-table.dev/?path=/story/features-aggregation-examples--aggregation

こういったことをしつつ、行をリンクとして扱おうとすると面倒くさいです。

で、結局なにが言いたいん?

要するにテーブルの行リンク化はどうしても必要なとき以外はしなくてもいいんじゃないかなと思いました。

GitHub のプルリクエスト一覧なんかがいい例ですね。

プルリクエストの一覧テーブルの行全体をクリックできるようにはしていません。詳細ページに移動するには、各行のプルリクエストのタイトルをクリックする必要があります。シンプルでわかりやすいですね。

また下記テーブルの設計リストにも書いてある通り、特定のセルをクリックするとクイックビューやモーダルが開くという形でも充分代替可能だと思います。

https://coyleandrew.medium.com/design-better-data-tables-4ecc99d23356

Image from Gyazo

最後に

行リンクは面倒くさい。

参考資料

https://coyleandrew.medium.com/design-better-data-tables-4ecc99d23356

https://robertcooper.me/post/table-row-links

COUNTERWORKS テックブログ

Discussion