sashigane
コンポーネント

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 は 署名に現れないので、表に出すと「引数のデフォルトが書かれているものだけ」になり、嘘になります。

On this page