チェックリストCheckListExperimental
チェック可能な行、表示専用行、右側の状態表示をまとめて扱う確認リストです。
プレビュー
- 本人確認書類(運転免許証等)確認済
- 転出証明書前住所地の市区町村が発行未確認
- マイナンバーカード / 通知カード未確認
- 印鑑(世帯主分)未確認
必要書類: 1 / 4 確認済
状態とバリエーション
チェック可能
各行のチェック状態を controlled state として扱い、進捗表示へ反映します。
- 本人確認書類(運転免許証等)確認済
- 転出証明書前住所地の市区町村が発行未確認
- マイナンバーカード / 通知カード未確認
- 印鑑(世帯主分)未確認
必要書類: 1 / 4 確認済
表示行を混ぜる
checked を省略した行はチェックボックスなしの情報行として同じリストに混ぜられます。
- 本人確認書類(運転免許証等)確認済
- 転出証明書前住所地の市区町村が発行未確認
- マイナンバーカード / 通知カード未確認
- 印鑑(世帯主分)未確認
- 備考世帯主のみ来庁補足
必要書類: 1 / 4 確認済
無効理由付き
無効行を見せる時は、disabledReason で hover/focus の理由を行に紐づけます。
- 本人確認書類(運転免許証等)確認済
- 転出証明書前住所地の市区町村が発行未確認
- マイナンバーカード / 通知カード未確認
- 印鑑(世帯主分)未確認
必要書類: 1 / 4 確認済
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| items | CheckListItem[] | - | チェック行または表示行の配列です。checked を省略するとチェックボックスなしの表示行になります。 |
| CheckListItem.checked | boolean | undefined | - | チェック状態です。undefined の場合は表示専用行になります。 |
| CheckListItem.disabled | boolean | false | チェック操作を無効化します。 |
| CheckListItem.disabledReason | ReactNode | - | 無効行の hover/focus tooltip に表示する理由です。 |
| CheckListItem.trailing | ReactNode | - | 右側に置くステータスバッジや補助操作です。チェック操作とは独立して描画されます。 |
| onCheckedChange | (id: string, checked: boolean) => void | - | チェック状態が変わった時に行 id と次の状態を通知します。 |
使い方
import * as React from "react";
import { IconAlertTriangle, IconCheck } from "@tabler/icons-react";
import { Badge, CheckList, type CheckListItem } from "@gunjo/ui";
const requiredDocs = [
{ id: "id", label: "本人確認書類(運転免許証等)" },
{ id: "former", label: "転出証明書", description: "前住所地の市区町村が発行" },
{ id: "mynumber", label: "マイナンバーカード / 通知カード" },
{ id: "seal", label: "印鑑(世帯主分)", disabledReason: "オンライン申請では印鑑確認を省略します。" },
];
export function RequiredDocumentCheckList() {
const [checked, setChecked] = React.useState<Record<string, boolean>>({ id: true });
const items: CheckListItem[] = requiredDocs.map((doc) => ({
...doc,
checked: Boolean(checked[doc.id]),
disabled: doc.id === "seal",
disabledReason: doc.id === "seal" ? doc.disabledReason : undefined,
trailing: checked[doc.id] ? (
<Badge variant="success" icon={<IconCheck />}>確認済</Badge>
) : (
<Badge variant="warning" icon={<IconAlertTriangle />}>未確認</Badge>
),
}));
const done = requiredDocs.filter((doc) => checked[doc.id]).length;
return (
<div className="flex w-full max-w-md flex-col gap-2">
<CheckList
items={items}
onCheckedChange={(id, value) => setChecked((current) => ({ ...current, [id]: value }))}
/>
<p className="text-xs text-muted-foreground" aria-live="polite">
必要書類: {done} / {requiredDocs.length} 確認済
</p>
</div>
);
}設計の判断
- チェックの付く行と、付かない行を同じ表に混ぜられる。
checkedを渡さない項目は、チェックボックスの無いただの行として出ます。資料は「複数選択するか」でリストの種類を決めよと書いていますが、実務の確認リストには「確認させる行」と「見せるだけの行」が混ざるので、1つのリストで両方を出せるようにしました。 - チェックボックスの名前は必ず行の文字にした。
labelとdescriptionをCheckboxに渡しているので、名前の無いチェックボックスが生まれません。行の文字を別に置いてlabelをつなぎ忘れる、という壊れ方を型で塞いでいます。 - 右端の要素はチェックの外に置いた。
trailing(バッジ・ボタン・金額)はチェックボックスの外側にあるので、押してもチェックが動きません。行全体を押せるようにしていないのは、この切り分けを守るためです。
一般のリストの設計は UIXHERO の「リスト」にあります。 UIXHERO: リスト(List)