複数選択カードCheckboxCardExperimental
Multi-select choice cards with independent checkbox semantics, square check indicators, rich card content slots, form values, and disabled-reason tooltips.
プレビュー
状態とバリエーション
複数選択
RadioCard と違い、複数を同時に選べます。選択はスクエアのチェックで示します。
見出しだけの一片
説明・価格・チップはどれも省けます。絞り込みの条件のように読む言葉が短いときは title だけにして、44px の下限で一片の高さを保ちます。
先頭に印を置く
leading はチェックの右、見出しの左に入ります。設備のように「言葉より印のほうが早く見分けられる」一覧で使います。チェックの位置は動きません。
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| CheckboxCardGroup value / defaultValue | string[] | - | 選択中の値の集合。制御(value)・非制御(defaultValue)どちらも可。 |
| CheckboxCardGroup onValueChange | (value: string[]) => void | - | 選択が変わるたびに新しい配列で呼ばれます。 |
| CheckboxCardGroup name | string | - | 各カードが hidden checkbox を出力し、フォーム送信に載せます。 |
| value | string | - | このカードが選択にトグルする値です。 |
| title | ReactNode | - | 主行(オプション名)。 |
| description | ReactNode | - | 副行(条件・期間など)。 |
| tags / price / highlight / leading | ReactNode | - | チップ列・価格・おトク訴求・先頭アクセサリ(RadioCard と同じ body スロット)。 |
| disabled / disabledReason | boolean / ReactNode | - | 選択不可+理由をツールチップで説明します。 |
使い方
import * as React from "react";
import { Badge, CheckboxCard, CheckboxCardGroup } from "@gunjo/ui";
const addons = [
{ value: "insurance", title: "Travel insurance", description: "Injury & cancellation cover", price: "$5", tag: <Badge variant="info">Popular</Badge> },
{ value: "seat", title: "Seat selection", description: "Choose window or aisle", price: "$3" },
{ value: "meal", title: "In-flight meal", description: "Japanese or Western", price: "$12", highlight: "$2 off when pre-ordered" },
{ value: "lounge", title: "Lounge access", description: "One departure lounge visit", price: "$20", disabled: true, disabledReason: "Not available on this plan." },
];
export function AddonPicker() {
const [selected, setSelected] = React.useState<string[]>(["insurance"]);
return (
<CheckboxCardGroup value={selected} onValueChange={setSelected} aria-label="Add-ons" name="addons">
{addons.map((a) => (
<CheckboxCard
key={a.value}
value={a.value}
title={a.title}
description={a.description}
price={a.price}
tags={a.tag}
highlight={a.highlight}
disabled={a.disabled}
disabledReason={a.disabledReason}
/>
))}
</CheckboxCardGroup>
);
}設計の判断
- カードの見た目でも、中身はチェックボックスにした。一片は
role="checkbox"とaria-checkedを持つ本物のbuttonで、高さは 44px 以上を確保しています。資料の「カード全体を押せるようにする」を、リンクではなくチェックボックスとして実装した形です。 - 矢印キーは付けていない。兄弟の
RadioCardは矢印キーで移動できますが、こちらは1つずつが独立して選べるので、それぞれが自分の Tab 停止位置を持ちます(WAI-ARIA のチェックボックスの型)。同じ見た目でも、キーボードの動きは意味に合わせて変えています。 - 選択の印は四角いチェックで、色に頼らない。選ばれた状態は、枠の色・輪郭・四角いチェックの3つで同時に出ます。選べないカードには
disabledReasonを渡すと、理由がツールチップで読めます。押せない理由を画面に出さずに済ませないためです。
一般のカードの設計は UIXHERO の「カード」にあります。
使用コンポーネント
関連コンポーネント
いつ・なぜ使うか(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。