サイドバーExperimental
アプリやドキュメントの左側に主要ナビゲーションをまとめ、必要に応じてアイコン幅へ折りたためるサイドナビゲーションです。
プレビュー
状態とバリエーション
折りたたみ初期表示
狭い画面や補助ナビでは、アイコンだけで始めて必要に応じて展開できます。
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| Sidebar | aside | - | レールそのもの。フレックス/グリッド親の高さいっぱいに自分で伸びます(240px ⇄ 折りたたみ 60px)。ブロック親に置く場合だけ高さを明示してください。 |
| SidebarProvider.defaultCollapsed | boolean | false | 非制御時の初期折りたたみ状態。 |
| SidebarProvider.collapsed | boolean | - | 折りたたみ状態を外部 state で制御します。 |
| SidebarProvider.onCollapsedChange | (collapsed: boolean) => void | - | 折りたたみ状態が変わった時に呼ばれます。 |
| useSidebar() | { collapsed, setCollapsed, toggleCollapsed } | - | 子孫コンポーネントからサイドバー状態を読み書きします。プロバイダ外で呼ぶと例外になります。 |
| useSidebarCollapsed() | boolean | null | - | 最も近い SidebarProvider の折りたたみ状態。プロバイダが無ければ null を返し、例外は投げません。サイドバーの内外どちらでも成立する部品向け。 |
| SidebarToggle | button | - | サイドバー境界線上に配置する折りたたみトグル。フッターや本文のレイアウト幅を消費しません。 |
| SidebarToggle.expandLabel | ReactNode | "Expand sidebar" | 折りたたみ時に表示するツールチップと aria-label。 |
| SidebarToggle.collapseLabel | ReactNode | "Collapse sidebar" | 展開時に表示するツールチップと aria-label。 |
| SidebarToggle.placement | "center" | "header" | "footer" | "footer" | トグルを置く境界線位置。既定ではフッター上端と右境界線の交点に置きます。 |
使い方
import * as React from "react"
import { Avatar, AvatarFallback, Sidebar, SidebarBody, SidebarFooter, SidebarHeader, SidebarItem, SidebarProvider, SidebarToggle, useSidebar } from "@gunjo/ui"
import { IconChartBar as BarChart3, IconHome as Home, IconLayoutKanban as FolderKanban, IconSettings as Settings } from "@tabler/icons-react"
const navItems = [
{ id: "home", label: "ホーム", icon: Home },
{ id: "projects", label: "プロジェクト", icon: FolderKanban },
{ id: "reports", label: "レポート", icon: BarChart3 },
{ id: "settings", label: "設定", icon: Settings },
]
function SidebarContent() {
const { collapsed } = useSidebar()
const [activeId, setActiveId] = React.useState("projects")
return (
<Sidebar className="min-h-[360px]">
<SidebarHeader>
<div className="grid h-7 w-7 shrink-0 place-items-center rounded-md bg-primary text-xs font-semibold text-primary-foreground">G</div>
{!collapsed ? <span className="truncate text-sm font-semibold">Gunjo UI</span> : null}
</SidebarHeader>
<SidebarBody>
{/* SidebarItem reads the collapse from the provider: the row goes
icon-only and its label moves into a tooltip on its own. */}
{navItems.map((item) => {
const Icon = item.icon
return (
<SidebarItem
key={item.id}
id={item.id}
icon={<Icon className="h-4 w-4 shrink-0" />}
label={item.label}
isActive={activeId === item.id}
onClick={() => setActiveId(item.id)}
reserveChevronSpace={false}
/>
)
})}
</SidebarBody>
<SidebarFooter>
<Avatar className="h-7 w-7 shrink-0"><AvatarFallback>UI</AvatarFallback></Avatar>
{!collapsed ? <span className="min-w-0 flex-1 truncate text-sm">デザインチーム</span> : null}
</SidebarFooter>
<SidebarToggle
expandLabel="サイドバーを展開"
collapseLabel="サイドバーを折りたたむ"
/>
</Sidebar>
)
}
export function SidebarLayout() {
return (
<div className="flex overflow-hidden rounded-md border bg-background">
<SidebarProvider>
<SidebarContent />
</SidebarProvider>
<main className="flex min-w-0 flex-1 items-center justify-center bg-muted/30 p-6 text-sm text-muted-foreground">
メインコンテンツ
</main>
</div>
)
}使用コンポーネント
関連コンポーネント
設計の判断(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。