サイドバーExperimental

アプリやドキュメントの左側に主要ナビゲーションをまとめ、必要に応じてアイコン幅へ折りたためるサイドナビゲーションです。

プレビュー

メインコンテンツ

状態とバリエーション

折りたたみ初期表示

狭い画面や補助ナビでは、アイコンだけで始めて必要に応じて展開できます。

メインコンテンツ

プロパティ

表は横にスクロールできます
プロパティ初期値説明
Sidebaraside-レールそのもの。フレックス/グリッド親の高さいっぱいに自分で伸びます(240px ⇄ 折りたたみ 60px)。ブロック親に置く場合だけ高さを明示してください。
SidebarProvider.defaultCollapsedbooleanfalse非制御時の初期折りたたみ状態。
SidebarProvider.collapsedboolean-折りたたみ状態を外部 state で制御します。
SidebarProvider.onCollapsedChange(collapsed: boolean) => void-折りたたみ状態が変わった時に呼ばれます。
useSidebar(){ collapsed, setCollapsed, toggleCollapsed }-子孫コンポーネントからサイドバー状態を読み書きします。プロバイダ外で呼ぶと例外になります。
useSidebarCollapsed()boolean | null-最も近い SidebarProvider の折りたたみ状態。プロバイダが無ければ null を返し、例外は投げません。サイドバーの内外どちらでも成立する部品向け。
SidebarTogglebutton-サイドバー境界線上に配置する折りたたみトグル。フッターや本文のレイアウト幅を消費しません。
SidebarToggle.expandLabelReactNode"Expand sidebar"折りたたみ時に表示するツールチップと aria-label。
SidebarToggle.collapseLabelReactNode"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 の記事で解説しています。