右レールRightRailExperimental

デスクトップで、主コンテンツの右側に補助情報を置くレールです。

プレビュー

状態とバリエーション

ページステータス

公開状態、最終更新、レビュー状況など、右側で常に参照したい情報をまとめます。

本文の流れから外したい関連資料やページ内リンクを右側にまとめます。

レールの中だけをスクロールさせる

RightRail は h-full と min-h-0 を持つ縦並びの箱なので、中の欄に上限と overflow-y-auto を渡すと、そこだけがスクロールします。更新の記録が何十件になっても本文の高さは変わりません。幅は width で狭められます(ここでは w-56)。

仕様ページ

更新の記録が何十件あっても、本文の側は動きません。伸びるのはレールの中だけです。

更新の記録

  • 10:42 白石が公開前確認を通した
  • 10:20 中村が図版を差し替えた
  • 09:58 白石が見出しを直した
  • 09:31 中村が本文を足した
  • 09:04 白石が下書きを作った
  • 前日 18:22 中村が構成を決めた
  • 前日 17:40 白石が担当を割り当てた
  • 前日 16:05 中村が題材を提案した

プロパティ

表は横にスクロールできます
プロパティ初期値説明
widthstring"w-64"デスクトップ時のレール幅を指定する Tailwind クラス。
classNamestring-境界線、背景、高さなどを調整する追加クラス。
childrenReactNode-ページ内リンク、ページステータス、関連リンクなどの補助コンテンツ。

使い方

import { Badge, RightRail } from "@gunjo/ui"

const pageLinks = [
  { id: "overview", label: "概要" },
  { id: "quality", label: "品質指標" },
  { id: "release", label: "公開前確認" },
]

const pageStatuses = [
  { label: "状態", value: "公開前確認", tone: "default" },
  { label: "最終更新", value: "5分前", tone: "secondary" },
  { label: "レビュー", value: "2件対応待ち", tone: "secondary" },
]

function PageLinks() {
  return (
    <section className="space-y-2">
      <h3 className="text-sm font-semibold">ページ内</h3>
      <nav aria-label="ページ内リンク">
        <ul className="space-y-1">
          {pageLinks.map((item) => (
            <li key={item.id}>
              <a className="block rounded-sm px-2 py-1.5 text-sm text-muted-foreground hover:bg-muted hover:text-foreground" href={`#${item.id}`}>
                {item.label}
              </a>
            </li>
          ))}
        </ul>
      </nav>
    </section>
  )
}

function PageStatus() {
  return (
    <section className="space-y-2">
      <h3 className="text-sm font-semibold">ページステータス</h3>
      <dl className="space-y-2">
        {pageStatuses.map((item) => (
          <div key={item.label} className="flex items-center justify-between gap-3 rounded-md border bg-muted/20 px-3 py-2">
            <dt className="text-xs text-muted-foreground">{item.label}</dt>
            <dd className="shrink-0 text-xs font-medium">
              {item.tone === "default" ? <Badge>{item.value}</Badge> : item.value}
            </dd>
          </div>
        ))}
      </dl>
    </section>
  )
}

export function DesktopRightRail() {
  return (
    <div className="flex min-h-[360px] min-w-[680px] overflow-x-auto rounded-md border bg-background">
      <main className="min-w-0 flex-1 space-y-4 bg-muted/30 p-4" aria-label="主コンテンツ">
        <p className="max-w-xl text-sm text-muted-foreground">
          主コンテンツの右側に、参照用の補助情報を固定幅で並べます。
        </p>
      </main>

      <RightRail width="w-72" aria-label="右レールの補助情報">
        <div className="space-y-5 p-4">
          <PageLinks />
          <PageStatus />
        </div>
      </RightRail>
    </div>
  )
}

設計の判断

  • 幅を props で1つだけ持たせた。資料は「Right Rail の幅はメインの3分の1以下」を挙げています。GUNJO は width を Tailwind のクラス文字列として受け取り、既定を w-64(256px)にしました。比率ではなく固定幅にしたのは、レールに載せるもの(目次・関連情報・補足)が横に広がってもほとんど得をしないからです。
  • 貼り付き(sticky)は部品に入れていない。資料は sticky での固定を挙げていますが、貼り付く相手はレールそのものではなく外側のレイアウトです。GUNJO の RightRailh-full の縦並びの箱で、min-h-0 を持つのでこの中だけをスクロールさせられます。貼り付かせるかどうかは、置く側が決めます。
  • 狭い画面での並べ替えは持っていません。資料は「モバイルでは Right Rail を本文の下に移す」を挙げています。GUNJO の RightRail にその切り替えは入っていないので、いまは親側で flex-col lg:flex-row のように組み替えることになります。ここは部品に上げる余地が残っている場所です。

使用コンポーネント

いつ・なぜ使うか(UIXHERO)

「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。