ナビゲーションの概要
ページ移動、階層、現在地、前後関係、主要導線を扱うコンポーネント群です。移動先の範囲と、ユーザーが今どこにいるかを示す必要性で選びます。
カテゴリ概要コンポーネント一覧
各コンポーネントの詳細ページへ移動して、プレビュー、コード、プロパティを確認できます。
アプリレール
AppRail左側の細いプライマリナビゲーションです。
ボトムアクションバー
BottomActionBarモバイル画面下部にサマリと主要CTAを固定するアクションバーです。
パンくず
Breadcrumb階層リンクで現在のリソースへのパスを表示します。
コマンド
Command検索入力、候補リスト、ショートカットを組み合わせて、コマンド選択 UI を構成します。
コマンドパレット
CommandPaletteナビゲーションやアクション用のグローバルコマンドパレットです。
デスクトップページヘッダー
DesktopPageHeaderこのカテゴリに含まれるコンポーネントです。
ドキュメントページャー
DocumentPager前後のドキュメントへ移動するためのナビゲーションです。
フッター
Footerブランド、リンクグループ、著作権表記をページ下部にまとめて表示します。
ヘッダー
Headerロゴ、主要ナビゲーション、右側の操作をページ上部にまとめて表示します。
メニューバー
Menubarデスクトップアプリでよくある常時表示のメニューバーです。
ナビゲーション
NavigationMenuこのカテゴリに含まれるコンポーネントです。
ナビ行
NavRow設定画面やマイページで使う、ラベル、説明、現在値、末尾操作を持つ行です。
ページ補助
PageAsideページ内リンク、ページステータス、関連リンクなどの補助情報を、広い画面では右レール、狭い画面では本文内の折りたたみ領域へ配置します。
ページヘッダー
PageHeaderモバイル画面の上部に、戻る、タイトル、補足、末尾操作を配置するページヘッダーです。
ページネーション
Pagination複数ページに分かれた一覧や検索結果を移動するためのナビゲーションです。ページ番号、省略記号、前後移動に加えて、件数サマリーや表示件数の選択と組み合わせて使います。
右レール
RightRailデスクトップで、主コンテンツの右側に補助情報を置くレールです。
サイドバー
Sidebarこのカテゴリに含まれるコンポーネントです。
サイドバー項目
SidebarItemサイドバー内で使う選択行です。アイコン、ラベル、件数、階層、開閉、削除操作を同じ行幅で揃えて表示します。
タブ
Tabs一度に1つだけ表示されるタブパネル群です。
テキストリンク
TextLink本文中のリンクを表示し、新しいタブで開くリンクには外部リンクアイコンを自動で併記します。
補足情報
一覧でコンポーネントを選んだあとに確認する、カテゴリ全体の責務、共通ルール、使い分けです。
このカテゴリの責務
画面、階層、ページ内の位置、前後関係を整理し、ユーザーが迷わず移動できるようにします。
このページの使い方
まずカテゴリの責務を確認し、迷いやすい使い分けから該当コンポーネントへ移動します。
パターンで確認する場面
ドキュメントサイト、メディアライブラリ、ダッシュボードのような複数領域を持つ画面で、現在地と移動導線を確認します。
ナビゲーション系の共通ルール
カテゴリ内で共通して守るべき判断基準です。
現在地、移動先、無効な移動理由を見た目だけでなくテキストや aria 属性でも伝えます。
プレビュー内のリンクは意図しないページ遷移を起こさず、遷移確認のフィードバックを返します。
迷いやすい使い分け
似ているコンポーネントを選ぶ時の入口です。
階層の現在地は Breadcrumb、横断的なページ移動は NavigationMenu、補助的な前後移動は DocumentPager を使います。
アプリ全体の領域移動は AppRail や Sidebar、ページ内の視点切り替えは Tabs を使います。
最初に確認するページ
どの範囲を移動させるのかで、最初に見るページが変わります。
避ける使い方
ナビゲーションは移動できることだけでなく、現在地と戻り方を失わないことが重要です。
現在地の表示を色や背景だけに頼る。
ページ内の切り替えにグローバルナビゲーションを使う。
docs プレビュー内で、リンククリックにより実際にページ遷移させる。
まとめて使う見本
この分類のコンポーネントをまとめて、いまどこにいて次にどこへ行けるかを示す1画面を組んだ例です。そのまま貼り付けて動きます。
import { useState } from "react";
import {
IconArchive,
IconInbox,
IconSettings,
IconUsers,
} from "@tabler/icons-react";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
SidebarItem,
Tabs,
TabsContent,
TabsList,
TabsTrigger,
TextLink,
} from "@gunjo/ui";
const SECTIONS = [
{ id: "inbox", label: "受信箱", icon: <IconInbox className="h-4 w-4" />, count: 4 },
{ id: "people", label: "メンバー", icon: <IconUsers className="h-4 w-4" /> },
{ id: "archive", label: "保管庫", icon: <IconArchive className="h-4 w-4" /> },
{ id: "settings", label: "設定", icon: <IconSettings className="h-4 w-4" /> },
];
const TABS = [
{ value: "open", label: "未対応", body: "レビュー担当が決まっていない依頼です。" },
{ value: "mine", label: "自分の担当", body: "自分が引き受けた依頼です。" },
{ value: "done", label: "対応済み", body: "この30日で片付いた依頼です。" },
];
const PAGES = [1, 2, 3];
export function ReviewNavigation() {
const [section, setSection] = useState("inbox");
const [page, setPage] = useState(1);
return (
<div className="grid gap-6 md:grid-cols-[13rem_minmax(0,1fr)]">
<nav aria-label="区分" className="space-y-1">
{SECTIONS.map((item) => (
<SidebarItem
key={item.id}
id={item.id}
icon={item.icon}
label={item.label}
count={item.count}
countLabel={(count) => count + " 件の未読"}
isActive={section === item.id}
onClick={() => setSection(item.id)}
/>
))}
</nav>
<div className="space-y-5">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#">ワークスペース</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="#">レビュー</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>受信箱</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<Tabs defaultValue="open">
<TabsList>
{TABS.map((tab) => (
<TabsTrigger key={tab.value} value={tab.value}>
{tab.label}
</TabsTrigger>
))}
</TabsList>
{TABS.map((tab) => (
<TabsContent key={tab.value} value={tab.value}>
<p className="text-sm text-muted-foreground">{tab.body}</p>
</TabsContent>
))}
</Tabs>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
onClick={() => setPage(Math.max(1, page - 1))}
/>
</PaginationItem>
{PAGES.map((number) => (
<PaginationItem key={number}>
<PaginationLink
isActive={page === number}
onClick={() => setPage(number)}
>
{number}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationNext
onClick={() => setPage(Math.min(PAGES.length, page + 1))}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
<p className="text-sm text-muted-foreground">
見つからないときは <TextLink href="#">一覧をすべて開く</TextLink>
</p>
</div>
</div>
);
}設計の判断
ナビゲーションのコンポーネントをいつ使い、いつ使わないかは、UIXHERO の「UIコンポーネント完全ガイド」にある「カテゴリ 02|ナビゲーション」の節にまとめています。今どこにいるかを示すのか、別の場所へ移動させるのかで、選ぶコンポーネントが変わります。
UIXHERO: UIコンポーネント完全ガイド(カテゴリ 02|ナビゲーション)(新しいタブで開きます)