AlertDialog
Dialog の variant。取り消しのきかない操作 (削除・送信など) で、ユーザーに最終確認を求めるモーダルダイアログ。Radix AlertDialog がベースで、Esc やオーバーレイクリックでは閉じない。
プレビュー — 標準
トリガーを押すと最終確認ダイアログが開きます。Cancel / Action の 2 ボタン構成が基本。
実装例 — 標準
import { Button } from "@/components/Button";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
export function Example() {
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="danger" size="m">
削除
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>この顧客を削除しますか?</AlertDialogTitle>
<AlertDialogDescription>
会話履歴や紐づくメモも一緒に削除されます。元に戻せません。
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel variant="secondary" size="m">
キャンセル
</AlertDialogCancel>
<AlertDialogAction variant="danger" size="m">
削除する
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}プレビュー — 入力必須の確認
破壊性が特に高い操作向け。ダイアログ内の入力欄に「削除」と入力しないと Action ボタンが有効化されない。誤タップ・惰性クリックによる事故を防ぐ用途で使う。
実装例 — 入力必須の確認
"use client";
import * as React from "react";
import { Button } from "@/components/Button";
import { Input } from "@/components/ui/input";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
const CONFIRM_TEXT = "削除";
export function Example() {
const [open, setOpen] = React.useState(false);
const [value, setValue] = React.useState("");
const [loading, setLoading] = React.useState(false);
const canConfirm = value === CONFIRM_TEXT;
function handleOpenChange(next: boolean) {
if (loading) return;
setOpen(next);
if (!next) setValue("");
}
function handleConfirm(e: React.MouseEvent) {
// Radix の auto-close を止めて loading を見せる
e.preventDefault();
setLoading(true);
window.setTimeout(() => {
setLoading(false);
setValue("");
setOpen(false);
}, 2000);
}
return (
<AlertDialog open={open} onOpenChange={handleOpenChange}>
<AlertDialogTrigger asChild>
<Button variant="danger" size="m">顧客を削除</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>チェックした顧客を削除しますか?</AlertDialogTitle>
<AlertDialogDescription>
会話履歴や紐づくメモも一緒に削除されます。元に戻せません。
</AlertDialogDescription>
<Input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="「削除」と入力してください"
autoComplete="off"
disabled={loading}
aria-label="削除確認テキスト"
/>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel variant="secondary" size="s" disabled={loading}>
キャンセル
</AlertDialogCancel>
<AlertDialogAction
variant="danger"
size="s"
loading={loading}
disabled={!canConfirm}
onClick={handleConfirm}
>
削除
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}削除操作での使い方
AlertDialog の主な用途は削除確認。以下のルールで文言・構成を統一する。
- タイトルは「〇〇を削除しますか?」 — 削除対象を必ず明示する。「削除しますか?」だけでは何が消えるか分からない。
- 説明文には副作用を書く — 「会話履歴や紐づくメモも一緒に削除されます。元に戻せません。」のように、削除によって起きることを具体的に示す。副作用がない場合は省略してよい。
- ボタン配置はキャンセル左・削除右 — グーテンベルク図に従い、主要 CTA(削除)を右下に置く。キャンセルは左。
- 削除ボタンは
variant="danger"— 破壊的操作であることを色で伝える。primaryは使わない。 - Esc・オーバーレイクリックで閉じない — AlertDialog の仕様通り。誤タップで確認をスキップできないようにする。
- 入力必須型はデータ喪失が大きい操作に限定 — 対象が複数件、または関連データ(会話履歴・メモ等)が同時に消える場合など、影響範囲が大きい削除にのみ使う。通常の 1 件削除では過剰なフリクションになるため標準型を使う。
- 入力必須型では Action ボタン内にスピナーを表示する — Action ボタンにスピナー + disabled を出し、Cancel / Input も disabled にして操作を止める。ラベル文言は変えない(
"削除"のまま)。
仕様
- primitive:
src/components/ui/alert-dialog.tsx(Radix AlertDialog ベース) - 構成:
AlertDialog/AlertDialogTrigger/AlertDialogContent/AlertDialogHeader/AlertDialogTitle/AlertDialogDescription/AlertDialogFooter/AlertDialogCancel/AlertDialogAction - 幅:
--width-dialog-s(424px) / 角丸:--radius-l(12px) / 影:--shadow-layer-4/ Header padding:--spacing-xs(16px) / Footer 上線:--border-default - タイトル:
.tds-text-heading-l(20px / Bold / 125%)、 説明文:.tds-text-body-s(14px / Regular / 150%、--text-secondary) - ボタンは
Buttonprimitive を流用。AlertDialogCancelの default はsecondary/s、AlertDialogActionの default はprimary/s。 破壊的操作のときはvariant="danger"を明示する。