Card
カード。内容をひとまとまりに見せる
面の宣言(data-sg-surface)の使い方を決めるコンポーネントです。
面は data-sg-surface で宣言します
Card は背景色を1つも書きません。背景も文字色も境界色も、面の宣言から来ます。
<Card>内容</Card>背景だけを塗る方法を用意していないのは、塗れてしまうと前景が親の面のまま残り、 読みにくい組み合わせができてもエラーにならないためです。
hover も塗りではなく宣言で切り替えます
interactive は面の文脈を1段深くするだけで、背景を直接塗りません。
背景だけを深くすると前景が置き去りになるので、塗る道は用意していません。
overlay には影が要ります
overlay は通常の面と同じ深さに置いてあります。そのため影が無いとダークモードで下地と同化します。
surface="overlay" を選ぶと影が自動で付きます——「付けられる」ではなく
「無しでは組み立てられない」形にしてあります。
中に置けるセクション
見出しと操作はセクションで分けます。セクションは面も色も持ちません—— 面を宣言するのは枠だけです。
<Card>
<CardHeader>
<CardTitle>見出し</CardTitle>
<CardDescription>補足</CardDescription>
</CardHeader>
<p>本文</p>
<CardFooter>
<Button>進む</Button>
</CardFooter>
</Card>セクションは必須ではありません。 要るセクションだけ置けば足ります。 枠は中身を縦に並べて間を空けるだけなので、セクションを使わずに直接書いても崩れません。
本文のセクションはありません
本文は枠の直下に置きます。 一度 CardBody を用意しましたが、
クラスを1つも持たない div でした——書かなくても崩れず、書いても何も起きません。
枠が縦に並べて間を空けるので、それで足ります。
見出しのレベルは変えられます
CardTitle は既定で h3 になります。カードをページのどこに置くかで正しいレベルは変わる
ので、asChild で差し替えられます。
<CardTitle asChild>
<h2>ページ直下に置くとき</h2>
</CardTitle>操作は下端に寄ります
CardFooter は下端に寄ります。高さの揃った並びに置いたとき、
カードごとに本文の長さが違っても操作の位置が揃います。
画像のセクションは持っていません
画像はそのまま中身として置けます。枠の余白いっぱいまで広げるセクションは用意していません—— 広げ方(縦横比、角の丸め、上端だけか両端か)を決めていないためです。 決めずに口だけ用意すると、利用側ごとに違う広げ方が生まれます。
外側の要素は div 以外にもできます
記事なら article、セクションなら section、カード全体がリンクなら a にできます。
asChild を付けると、Card は要素を1つも作らず、クラスと属性を子へ移して子だけを描きます。
<Card asChild>
<article>
<h3>見出し</h3>
<p>本文</p>
</article>
</Card>面の宣言も hover の宣言もそのまま子へ移ります。 リンクになっても、背景と前景は同時に切り替わります。
子は要素1つだけです。
3つの状態
通常・空・エッジケースの3つは、どのコンポーネントにも必ずあります。
通常default.tsx
通常。面を宣言しているだけで、色は1つも書いていない。 背景・文字色・境界色は `data-sg-surface="surface"` から来る。
面は宣言する
背景も文字色も境界色も、面の宣言から来ます。
この枠は背景色を1つも書いていません。
浮かせた面
ライトモードでは影が、ダークモードでは1段深い輪郭が出ます。
空empty.tsx
空。中身が無くても面として成立すること。
エッジケースedge.tsx
エッジケース。面が重なるとき。
面の中の面
Supercalifragilisticexpialidocious/長い識別子でも枠は破れません。
重なる面。hover すると面が1段深くなります。
使い方
3つの状態とは別に、説明のために置いている例です。
要素の差し替えas-child.tsx
枠が `div` とは限らない。
記事として組む
見出しと本文を持つ塊なので、`article` で描いています。
カード全体がリンク
hover すると面の文脈が1段深くなります。
中の区画parts.tsx
セクションの使い分け。
見出しの深さを変える
ページ直下に置くなら h2 が正しいこともあります。
本文がここに入ります。
本文が短い側
props
Prop
Type
型と説明はコンポーネントのソースから抽出しています。既定値は出していません——cva の defaultVariants は 署名に現れないので、表に出すと「引数のデフォルトが書かれているものだけ」になり、嘘になります。