Alert dialog
破壊的または重要な操作のための確認ダイアログです。非同期処理を待ち、スマートフォンではボトムシートになります。
pnpm dlx shadcn@latest add https://hextaui.com/r/alert-dialog.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/alert-dialog.tsx components/ui/sheet.tsx components/ui/button.tsx インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
非同期アクション
<AlertDialogAction /> の onClick から Promise を返します。ボタンにスピナーが表示され、Promise が完了するまでダイアログは閉じられません。resolve されると閉じ、reject されると開いたままになるため、やり直すことができます。
メディア
<AlertDialogMedia /> は、デスクトップではタイトルの横に、スマートフォンではタイトルの上にアイコンを配置します。破壊的なアクションには variant="destructive" を使います。
小
size="sm" はコンテンツを中央揃えにし、ボタンを横並びに配置します。短い質問向けです。
分離したトリガー
createAlertDialogHandle() でハンドルを作成すると、1 つのダイアログを複数のトリガーで共有できます。各トリガーは独自の payload を渡し、ダイアログは render 関数を通じてそれを読み取ります。
制御
open と onOpenChange を渡すと、トリガーなしでコードから開けます。フォーカスは引き続きキャンセルに移ります。
入れ子
別のダイアログの内側から開いたダイアログは、手前に重なります。子が開いている間、親は縮小して奥に下がり、子が閉じると手前に戻ります。
長いコンテンツ
画面より高いコンテンツはダイアログ内でスクロールし、ページはロックされたままです。
右から左
コンテンツは RTL コンテナの外側のポータルにレンダリングされるため、コンテンツにも dir を渡してください。フッターの矢印キーは読む方向に従います。
| キー | アクション |
|---|---|
| EnterSpace | トリガーに指定すると、ダイアログを開き、フォーカスをキャンセルに移動します。 |
| TabShift+Tab | コントロール間でフォーカスを移動します。フォーカスはダイアログ内にとどまります。 |
| ←→↑↓ | フッターのボタン間を移動し、端で反対側に回り込みます。左右は読む方向に従います。 |
| Esc | ダイアログを閉じ、フォーカスをトリガーに戻します。非同期アクションの実行中は無視されます。 |
- コンテンツには
role="alertdialog"が付き、タイトルによってラベル付けされ、説明によって補足されます。 - フォーカスは最も破壊的でない選択肢である
<AlertDialogCancel />から始まります。変更するにはinitialFocusを渡します。 - 背景をクリックしても閉じないため、操作の判断が誤って閉じられることはありません。許可するには
disablePointerDismissal={false}を設定します。 - スマートフォンでは、下にスワイプしてキャンセルできるボトムシートになります。アクションの保留中は、スワイプ、Esc、キャンセルがブロックされ、ボタンにはフォーカスできる状態が保たれます。
- モーションの低減が有効な場合は、拡大縮小ではなくフェードになります。
<Sheet /> を通じて、Base UI の drawer をベースにしています。各パーツは、ラップしているプリミティブや要素の props をすべて受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange保留中のアクションによって閉じるのがブロックされた場合は呼ばれません。 | (open: boolean, details) => void | – |
onOpenChangeComplete開閉アニメーションの後に呼ばれます。 | (open: boolean) => void | – |
disablePointerDismissal背景をクリックしてもダイアログを開いたままにします。 | boolean | true |
handle分離したトリガーを接続します。 | AlertDialogHandle<Payload> | – |
actionsRefダイアログをコードから閉じる、またはアンマウントします。 | RefObject<{ close, unmount }> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
handle | AlertDialogHandle<Payload> | – |
payloadダイアログの render 関数に渡されます。 | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-trigger" | CSSでトリガーを指定します。 |
data-popup-open | ダイアログが開いている間、付与されます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
size | "default" | "sm" | "default" |
initialFocus | boolean | RefObject | (openType) => HTMLElement | boolean | Cancel button |
finalFocus | boolean | RefObject | (closeType) => HTMLElement | boolean | The trigger |
dirダイアログを右から左の表示にしたいときに設定します。 | "ltr" | "rtl" | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-content" | CSS でダイアログを指定します。 |
data-size | 現在のサイズ。 |
data-open | 開いている間存在します。 |
data-starting-style | ダイアログが開くアニメーションの間、付与されます。 |
data-ending-style | ダイアログが閉じるアニメーションの間、付与されます。 |
data-nested-drawer-open | ネストしたダイアログが上で開いている間、付与されます。 |
data-swiping | スマートフォンでスワイプしている間、付与されます。 |
--nested-drawers | このダイアログの上で開いているダイアログの数。 |
メディア、タイトル、説明を縦に並べる <div>。
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-header" | CSSでヘッダーを指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
variant | "default" | "destructive" | "default" |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-media" | CSS でメディアを指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-title" | CSSでタイトルを指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render複数の段落を含める場合は render={<div />} を使います。 | ReactElement | (props, state) => ReactElement | <p> |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-description" | CSSで説明を指定します。 |
ボタン用の <div>。スマートフォンではボタンが全幅で縦に積まれ、矢印キーでボタン間を移動できます。
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-footer" | CSS でフッターを指定します。 |
クリックするとダイアログを閉じる <Button />。Button のすべての props を受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
onClickPromise を返すと、スピナーを表示し、完了するまでダイアログを開いたままにします。開いたままにするには event.preventDefault() を呼びます。 | (event) => void | PromiseLike<unknown> | – |
variant | ButtonVariant | "default" |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-action" | CSS でアクションを指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
variant | ButtonVariant | "outline" |
size | ButtonSize | – |
disabledアクションの保留中も無効になります。 | boolean | – |
| 属性 | 説明 |
|---|---|
data-slot="alert-dialog-cancel" | CSS でキャンセルボタンを指定します。最初にフォーカスを受け取ります。 |
data-disabled | 無効な間、付与されます。 |
<AlertDialogContent /> はすでに両方をレンダリングします。カスタムのポップアップを組み立てるときにのみ使ってください。
| プロパティ | 型 | デフォルト |
|---|---|---|
keepMountedポータルに指定すると、閉じている間もダイアログを DOM に残します。 | boolean | false |
ページ上のどこにある <AlertDialogTrigger /> 要素でも、1 つの <AlertDialog /> に接続するハンドルを返します。payload の型はジェネリクスで指定します: createAlertDialogHandle<{ name: string }>()。
- Buttonすべてのバリアントとサイズのボタンです。読み込み、成功、エラーのフローを内蔵し、高速なリクエストではスピナーを省略します。
- Sheet任意の端からスライドインするパネルです。スワイプで閉じる操作、スクロールロック、重なる入れ子に対応します。
- Commandインラインまたは⌘Kパレットとして使える、検索可能な操作リストです。ページ、ショートカット、一致箇所のハイライトに対応します。
- Context menu右クリックまたは長押しで開く操作メニューです。サブメニュー、チェックボックス項目、ラジオ項目に対応し、タッチでは長押しのフィードバックを返します。
- Dialogフォームや集中して行う作業のための、ページ上のウィンドウです。固定のヘッダーとフッター、入れ子に対応し、スマートフォンではスワイプできるボトムシートになります。
- Drawer任意の端からスライドインし、指に追従するパネルです。スナップポイント、実際に使えるハンドル、重なっていく入れ子のドロワーに対応します。
使用しているブロック
Alert dialog の上に構築されるブロック。
- API keysOpenAIやAnthropicのコンソールのような、AIプロダクトのAPIキーのページです。スコープ付きの権限と有効期限を持つキーを作成し、シークレットは一度だけ表示され、コピーで確認でき、取り消しは元に戻せ、その場で名前を変更でき、猶予期間つきでローテーションでき、キーごとの使用量を確認できます。
- BillingCursor、Claude、Vercelのスタイルによる、AIプロダクト向けのプランと使用量です。モデルごとに分かれ、サイクル終了時を予測してクレジット切れの前に警告する使用量メーター、ドラッグで確認できる日別チャート、メーター上でプレビューできるアラートつきの支出上限、正確な日割り計算によるプラン変更、実際のバリデーションを備えたカードフォーム、PDFでダウンロードできる請求書を備えています。
- NotificationsAIプロダクトの設定にある通知セクションです。行、列、すべてを切り替えられるチャンネルとイベントのグリッド、次の静音時間をリアルタイムで示す静音時間、メールダイジェスト、デスクトップ、メール、プッシュ、Slackの実際のテスト送信、ブラウザー権限の処理、Slackの接続フローを備えています。どの設定セクションにも組み込めます。
- SecurityAIプロダクト向けのセッションとセキュリティです。行がアニメーションで消えるサインアウトつきのアクティブなデバイス、リアルタイムの強度メーターつきのパスワード変更、本物のQRコードを使う二要素認証の設定、6桁の確認とダウンロードできるリカバリーコード、WebAuthnによるパスキー、入力による確認が必要なアカウント削除を備えています。