Sidebar
アイコンのみ、またはオフキャンバスに折りたたまれ、ヘッダーの下に固定され、スマートフォンではスワイプできるシートになるアプリのサイドバーです。
pnpm dlx shadcn@latest add https://hextaui.com/r/sidebar.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/sidebar.tsx components/ui/button.tsx components/ui/input.tsx components/ui/sheet.tsx components/ui/skeleton.tsx components/ui/tooltip.tsx hooks/use-composed-ref.ts lib/hotkey.ts インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
レイアウトを <SidebarProvider /> で囲み、ページはサイドバーの後に <SidebarInset /> の中へ置きます。
SidebarProviderは、開閉の状態、キーボードショートカット、幅を保持します。Sidebarは、ページがスクロールしても固定されたままの列です。768px未満では sheet になります。SidebarHeaderとSidebarFooterは固定されたままです。SidebarContentはそれらの間でスクロールします。SidebarGroupは、ラベルとアクションを任意で持てるセクションです。SidebarMenuはリンクを保持します。SidebarInsetは、サイドバーの隣にあるページです。
バリアント
variant は見た目を設定します。全高の sidebar、floating パネル、またはページがサイドバーの色の上でカードになる inset です。切り替えると、レイアウトがアニメーションするのを確認できます。
Collapsible
offcanvas はサイドバーを画面外へスライドさせ、icon はアイコンに縮めて各ラベルを tooltip に表示し、none は開いたままにします。⌘B または Ctrl+B で、作業中のサイドバーを切り替えます。
折りたたみ可能なグループとサブメニュー
SidebarGroup または SidebarMenuItem を Collapsible で囲み、ラベルまたはボタンをトリガーとして描画し、SidebarMenuSub をネストします。
右側
side="right" を設定し、SidebarInset の後にサイドバーを置きます。レールとモバイルの sheet もその側に従います。
ヘッダーの下
サイドバーは sticky なので、上にあるものの下から始まります。sticky なヘッダーがある場合は、--sidebar-top にその高さを設定すると、サイドバーはその下に固定され、残りの画面に収まります。
制御
open と onOpenChange を渡します。トリガー、レール、ショートカットはすべて onOpenChange を通ります。
読み込み中
SidebarMenuSkeleton は、読み込み中のメニューを埋めます。幅は行ごとに異なり、サーバーとクライアントで一致します。
右から左
dir="rtl" と side="right" を設定します。余白、サブメニューの線、tooltip、トリガーのアイコンが反転します。
サイドバーの幅は16rem、スマートフォンでは18rem、アイコンに折りたたむと3remです。プロバイダーで --sidebar-width、--sidebar-width-mobile、--sidebar-width-icon を上書きします。
サイドバーには副作用がありません。開いていたかどうかを記憶するには、onOpenChange で保存し、サーバーで描画するときに defaultOpen へ読み戻します。
| キー | アクション |
|---|---|
| ⌘ + BCtrl + B | サイドバーを切り替えます。ページに複数のサイドバーがある場合は、フォーカスを持つものが応答し、なければ最初のものが応答します。リッチテキストエディターで入力中は無視されます。 |
| TabShift + Tab | リンク間を移動します。キャンバス外に折りたたまれたサイドバーはスキップされます。 |
| EnterSpace | フォーカスされているリンク、ボタン、トリガーを実行します。 |
| Esc | スマートフォンでサイドバーを閉じます。 |
SidebarTriggerには「Toggle Sidebar」というラベルが付き、aria-expandedとaria-controlsを公開します。isActiveはaria-current="page"を設定します。- キャンバス外へ折りたたむと、コンテンツはキーボードとスクリーンリーダーから隠されます。フォーカスが内側にあった場合は、トリガーに移ります。
- アイコンに折りたたまれていても、ラベルは各リンクのアクセシブルな名前として残り、ホバーとキーボードフォーカス時に tooltip として表示されます。グループのラベル、アクション、バッジは非表示になります。
- スマートフォンでは、サイドバーはモーダルの sheet になります。フォーカスはトラップされ、スワイプまたは Esc で閉じ、リンクをたどっても閉じます。新しいタブで開くリンク、ダウンロード、修飾キー付きのクリックでは開いたままです。
- 視差効果の軽減が有効な場合、折りたたみは即座に行われます。
| プロパティ | 型 | デフォルト |
|---|---|---|
defaultOpen | boolean | true |
open | boolean | – |
onOpenChange | (open: boolean) => void | – |
keyboardShortcutmod は Apple のプラットフォームでは ⌘、それ以外では Ctrl です。null でオフになります。 | string | null | "mod+b" |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-wrapper" | レイアウトのラッパー。 |
--sidebar-width | 展開時の幅。デフォルトは16remです。 |
--sidebar-width-mobile | スマートフォン用 sheet の幅。デフォルトは18remです。 |
--sidebar-width-icon | アイコンに折りたたんだときの幅。デフォルトは3remです。 |
--sidebar-top | sticky なヘッダーの下など、スクロール中にサイドバーが固定される位置。デフォルトは0pxです。 |
className などの props はサイドバーのコンテナーに渡されます。
| プロパティ | 型 | デフォルト |
|---|---|---|
side | "left" | "right" | "left" |
variantplain は、面、端の線、スクロールバー、メニュー項目間の gap を取り除き、ページ上に置くサイドバー向けにします。 | "sidebar" | "floating" | "inset" | "plain" | "sidebar" |
collapsible | "offcanvas" | "icon" | "none" | "offcanvas" |
mobileスマートフォンでの開き方。側面からの sheet か、チャットアプリのように画面全体を埋めるスライドインです。 | "sheet" | "fullscreen" | "sheet" |
dirスマートフォン用 sheet の方向も設定します。 | "ltr" | "rtl" | – |
| 属性 | 説明 |
|---|---|
data-slot="sidebar" | サイドバー、またはスマートフォンでは sheet。 |
data-state | "expanded" または "collapsed"。 |
data-collapsible | 折りたたまれている間は collapsible のモード、それ以外は ""。子要素には group-data-[collapsible=icon]: でスタイルを付けます。 |
data-variant | バリアント。 |
data-side | 側。 |
data-mobile | スマートフォン用 sheet に付きます。 |
data-slot="sidebar-container" | スライドしてリサイズするパネル。 |
data-slot="sidebar-inner" | コンテンツを保持する面。 |
toggleSidebar を呼ぶ、ゴースト型のアイコン Button。止めるには onClick で event.preventDefault() を呼びます。アイコンを置き換えるには子要素を渡します。
| 属性 | 説明 |
|---|---|
data-slot="sidebar-trigger" | トリガー。 |
aria-expanded | サイドバーが開いているかどうか。 |
サイドバーの端にある細いヒット領域で、クリックで切り替えます。キーボードユーザーにはトリガーとショートカットがあるため、タブ順からは外されています。サイドバーがキャンバス外にあるときも、レールは画面の端に残ります。
| 属性 | 説明 |
|---|---|
data-slot="sidebar-rail" | レール。 |
残りの幅を占める <main>。inset サイドバーの隣では、角丸のカードになります。
| プロパティ | 型 | デフォルト |
|---|---|---|
render別の要素を描画します。ページにすでに <main> ランドマークがある場合は <div /> を渡します。 | React.ReactElement | (props) => React.ReactElement | – |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-inset" | ページ領域。 |
プレーンな <div> 要素。コンテンツは細いスクロールバーと柔らかい端のフェードでスクロールします。
| 属性 | 説明 |
|---|---|
data-slot="sidebar-header" | 上部のセクション。 |
data-slot="sidebar-content" | スクロールする中央部。 |
data-slot="sidebar-footer" | 下部のセクション。 |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-group" | サイドバーのセクション。 |
data-slot="sidebar-group-content" | グループのコンテンツ。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <div> |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-group-label" | アイコンに折りたたまれると、上にスライドしてフェードします。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-group-action" | アクセシブルなラベルが必要です。 |
<ul> とその <li> 項目。チャット履歴のように行を詰めて並べる密なリストには、gap="none" を設定します。
| プロパティ | 型 | デフォルト |
|---|---|---|
gap項目間の間隔。SidebarMenuSub にもあります。 | "default" | "none" | "default" |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-menu" | リスト。 |
data-slot="sidebar-menu-item" | 項目。ホバー用スタイルには group/menu-item。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
isActiveハイライトして aria-current="page" を設定します。 | boolean | false |
variant | "default" | "outline" | "default" |
size | "default" | "sm" | "lg" | "default" |
tooltipアイコンに折りたたまれている間表示されます。メニューに沿って動くと、項目間でコンテンツがスライドします。 | ReactNode | TooltipContentProps | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-menu-button" | 兄弟要素向けのスタイルには peer/menu-button。 |
data-active | isActive の間付きます。 |
data-size | サイズ。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
showOnHover項目がホバーまたはフォーカスされている間、またはそのメニューが開いている間だけ表示します。タッチスクリーンでは常に表示されます。 | boolean | false |
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-menu-action" | アクセシブルなラベルが必要です。 |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-menu-badge" | 項目の末尾のカウント。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
showIcon | boolean | false |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-menu-skeleton" | 支援技術から隠されます。 |
先頭側の端に線があるネストされたリスト。サイドバーがアイコンに折りたたまれると畳まれます。
| プロパティ | 型 | デフォルト |
|---|---|---|
isActiveSidebarMenuSubButton 上で。 | boolean | false |
sizeSidebarMenuSubButton 上で。 | "sm" | "md" | "md" |
renderSidebarMenuSubButton 上で。 | ReactElement | (props, state) => ReactElement | <a> |
| 属性 | 説明 |
|---|---|
data-slot="sidebar-menu-sub" | ネストされたリスト。 |
data-slot="sidebar-menu-sub-button" | ネストされたリンク。 |
data-active | isActive の間付きます。 |
ページ背景上の小さな Input と、細い区切り線。
| 属性 | 説明 |
|---|---|
data-slot="sidebar-input" | 入力欄。 |
data-slot="sidebar-separator" | セパレーター。 |
最も近いサイドバーを読み取り、制御します。SidebarProvider の外ではエラーを投げます。
| プロパティ | 型 | デフォルト |
|---|---|---|
state | "expanded" | "collapsed" | – |
open | boolean | – |
setOpen | (open: boolean) => void | – |
openMobile | boolean | – |
setOpenMobile | (open: boolean) => void | – |
isMobile | boolean | – |
toggleSidebarスマートフォンでは sheet を、それ以外ではサイドバーを切り替えます。 | () => void | – |
- Buttonすべてのバリアントとサイズのボタンです。読み込み、成功、エラーのフローを内蔵し、高速なリクエストではスピナーを省略します。
- Hotkeyキーボードショートカットの解析、ラベル付け、読み上げ、一致判定を行います。Appleプラットフォームでは⌘、それ以外ではCtrlを使います。
- Input3つのサイズ、無効状態と読み取り専用状態、ネイティブのバリデーションスタイル、スマートフォンでズームされない16pxのタッチ用フォントを備えたテキスト入力です。
- Sheet任意の端からスライドインするパネルです。スワイプで閉じる操作、スクロールロック、重なる入れ子に対応します。
- Skeleton150ms待ってから表示され、包んだコンテンツと同じサイズになり、何も動かさずにコンテンツをフェードインさせるプレースホルダーです。
- Tooltipホバーまたはキーボードフォーカスで、少し待ってから開く短いヒントです。隣り合う要素の間では即座に切り替わり、ショートカットも表示できます。
使用しているブロック
Sidebar の上に構築されるブロック。
- Chat Sidebarチャットアプリ向けのサイドバーです。上部にロゴ、検索、New chat、その下に独自のリンク、ピン留めされたチャット、チャットを表示するために展開するプロジェクト、日ごとにグループ化された最近のチャットを配置します。行にはホバーメニューと右クリックメニュー、インラインでの名前変更、取り消しできる削除、リアルタイムの返信状態があります。
- HextaAIHextaUIのすべてのAIブロックで作られた、完全なAIチャットアプリです。サイドバーのチャット、出典つきの思考、差分と承認つきのツール呼び出し、エージェントの実行前に確認するプラン、ストリーミングされるMarkdownとコード、無音の音声モードを備え、すべてAI SDKのメッセージパーツで動作します。