Sheet
任意の端からスライドインするパネルです。スワイプで閉じる操作、スクロールロック、重なる入れ子に対応します。
pnpm dlx shadcn@latest add https://hextaui.com/r/sheet.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/sheet.tsx components/ui/button.tsx インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
サイド
side を設定すると、任意の端からスライドインします。各 sheet はそれぞれの端に向かってスワイプして戻せ、閉じるジェスチャーは慣性を伴って指に追従します。
長いコンテンツ
<SheetBody /> は単独でスクロールするため、コンテンツがどれだけ長くなっても、ヘッダーとフッターは固定されたままです。
閉じるボタンなし
フッターにすでに閉じる手段がある場合は、showCloseButton={false} を設定します。Escape、背景、スワイプでは引き続き閉じられます。
入れ子
sheet から開いた sheet や alert dialog は上に重なります。親はわずかに縮小し、重なるごとにより薄い背景が加わるので、スタックは読み取りやすいままです。Escape は最上位のレイヤーだけを閉じます。
制御
open と onOpenChange を渡すと、トリガーなしでどこからでも開けます。
分離したトリガー
createSheetHandle で、1つの sheet を複数のトリガーで共有します。各トリガーは payload を渡し、sheet は関数の子要素を通じてそれを描画します。
右から左
dir="rtl" では、右側は左端に反転し、そこからスライドインして、同じ向きにスワイプして閉じます。
| キー | アクション |
|---|---|
| EnterSpace | トリガー上では sheet を開き、フォーカスを内側に移します。 |
| TabShift + Tab | フォーカス可能な要素の間を移動します。フォーカスは sheet の内側に留まります。 |
| Esc | 最上位の sheet を閉じ、そのトリガーにフォーカスを戻します。 |
- sheet はモーダルダイアログです。
<SheetTitle />がラベルを、<SheetDescription />が説明を提供するので、必ずタイトルを含めてください。 - 開いている間、ページのスクロールはロックされ、背後のコンテンツは支援技術から隠されます。
- 閉じるボタンには「Close」というラベルが付きます。内側の端にあるハンドルは sheet をドラッグできることを示し、支援技術からは隠されます。
- 視差効果の軽減が有効な場合、sheet はスライドせずにフェードで出入りします。
Base UI の drawer をベースにしています。各パーツは、ラップしているプリミティブの props を受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
defaultOpen | boolean | false |
open | boolean | – |
onOpenChange | (open: boolean, details) => void | – |
onOpenChangeComplete開閉アニメーションの終了後に呼ばれます。 | (open: boolean) => void | – |
modal | boolean | "trap-focus" | true |
disablePointerDismissal背景がクリックされても開いたままにします。 | boolean | false |
swipeDirectionコンテンツの側と方向から自動で設定されます。 | "up" | "down" | "left" | "right" | – |
handle | SheetHandle<Payload> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
handle | SheetHandle<Payload> | – |
payload | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="sheet-trigger" | CSSでトリガーを指定します。 |
data-popup-open | その sheet が開いている間付きます。 |
ポータル、背景、ビューポート、ポップアップに加え、ドラッグハンドルと閉じるボタンを描画します。
| プロパティ | 型 | デフォルト |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "right" |
showCloseButton | boolean | true |
dirsheet の方向を設定します。right と left は rtl で反転します。 | "ltr" | "rtl" | – |
initialFocus | boolean | RefObject | (type) => HTMLElement | boolean | – |
finalFocus | boolean | RefObject | (type) => HTMLElement | boolean | – |
classNameサイド sheet の幅は75%で、sm ブレークポイント以上では最大24remです。 | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| 属性 | 説明 |
|---|---|
data-slot="sheet-content" | sheet のパネル。 |
data-side | 開く側。 |
data-open | sheet が開いている間付きます。 |
data-starting-style | 表示アニメーションの間存在します。 |
data-ending-style | 非表示アニメーションの間存在します。 |
data-swiping | ドラッグされている間、付与されます。 |
data-swipe-direction | 閉じる方向。 |
data-nested-drawer-open | ネストされた sheet が上に開いている間付きます。 |
data-slot="sheet-handle" | 内側の端にあるドラッグハンドル。 |
data-slot="sheet-close-button" | 組み込みの閉じるボタン。 |
--drawer-swipe-movement-x | 水平方向のドラッグ距離。-y の変数もあります。 |
--nested-drawers | 上に開いているネストされた sheet の数。 |
<SheetContent /> によって描画されます。ネストされたレイヤーにはより薄い背景が付きます。
| 属性 | 説明 |
|---|---|
data-slot="sheet-overlay" | バックドロップ。 |
data-nested | ネストされたレイヤーの背景に付きます。 |
sheet をレイアウトするプレーンな <div> 要素。ヘッダーは閉じるボタンの余白を確保し、ボディはスクロールして残りの高さを占め、フッターは小さい画面ではアクションを縦に積み、sm ブレークポイント以上では末尾に並べます。
| 属性 | 説明 |
|---|---|
data-slot="sheet-header" | タイトルと説明。 |
data-slot="sheet-body" | スクロール可能なコンテンツ。 |
data-slot="sheet-footer" | アクション。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| 属性 | 説明 |
|---|---|
data-slot="sheet-title" | sheet にラベルを付けます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <p> |
| 属性 | 説明 |
|---|---|
data-slot="sheet-description" | sheet を説明します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="sheet-close" | 押すと sheet を閉じます。 |
createSheetHandle<Payload>() は、別の場所にレンダリングされたトリガーと <Sheet /> をつなぐハンドルを返します。コンポーネントの外で一度だけ作成してください。
- Buttonすべてのバリアントとサイズのボタンです。読み込み、成功、エラーのフローを内蔵し、高速なリクエストではスピナーを省略します。
- Alert dialog破壊的または重要な操作のための確認ダイアログです。非同期処理を待ち、スマートフォンではボトムシートになります。
- Commandインラインまたは⌘Kパレットとして使える、検索可能な操作リストです。ページ、ショートカット、一致箇所のハイライトに対応します。
- Context menu右クリックまたは長押しで開く操作メニューです。サブメニュー、チェックボックス項目、ラジオ項目に対応し、タッチでは長押しのフィードバックを返します。
- Dialogフォームや集中して行う作業のための、ページ上のウィンドウです。固定のヘッダーとフッター、入れ子に対応し、スマートフォンではスワイプできるボトムシートになります。
- Drawer任意の端からスライドインし、指に追従するパネルです。スナップポイント、実際に使えるハンドル、重なっていく入れ子のドロワーに対応します。
使用しているブロック
Sheet の上に構築されるブロック。