ഉള്ളടക്കത്തിലേക്ക് പോകുക
ബീറ്റ · പരീക്ഷണാത്മകംReact 19പിയർ ഡിപൻഡൻസികളില്ല

Card

A surface that groups related content, with header, body and footer, plus Stat for a single figure and its trend.

ബീറ്റ കമ്പോണന്റുകൾ മാറാൻ സാധ്യതയുണ്ട്; അവ നിങ്ങളുടെ കോഡ് തകരാറിലാക്കിയേക്കാം. സ്വന്തം ഉത്തരവാദിത്തത്തിൽ ഉപയോഗിക്കുക, ബഗ് ട്രാക്കർ വഴി അഭിപ്രായം അറിയിക്കുക.

ഈ പേജ് ഇതുവരെ വിവർത്തനം ചെയ്തിട്ടില്ല, അതിനാൽ ഇംഗ്ലീഷ് പതിപ്പാണ് താഴെ കാണിക്കുന്നത്.
ഈ പേജിൽ

Installation

bash
npx gbs-add-block@latest -a Card -beta

The block copies the card folder into your project, along with the small shared folder that every component imports. You own the code and can change it freely. There are no peer dependencies other than React.

Requirements

  • React 19 and @types/react 19
  • TypeScript target ES2022 or newer, with "jsx": "react-jsx"
  • Browsers from 2024 or newer (the styles use light-dark() and color-mix())

Import the stylesheet once, for example in your global CSS:

css
@import "../components/card/styles.css";

or in your root layout / entry file:

ts
import "@/components/card/styles.css";

A card groups things that belong together and gives them an edge. Stat is the other half of a dashboard: one figure, its label, and how it has changed.

Set the --gbs-* variables on :root to theme every component at once, the grid included. Each component's own variables fall back to them, and then to the built-in palette, so components look identical out of the box.

Default

Live preview

Quick Start

tsx
import { Card, CardHeader, CardBody, CardFooter, Stat, trendDirection } from "@/components/card";
import "@/components/card/styles.css";
 
<Card>
  <CardHeader
    title={<h3>Revenue</h3>}
    description="Billed this month"
    actions={<Menu trigger={<Button variant="ghost" size="sm">Options</Button>}>…</Menu>}
  />
  <CardBody>
    <Stat
      label="This month"
      value="£48,120"
      trend={{ direction: trendDirection(12.4), label: "12.4%", description: "vs last month" }}
    />
  </CardBody>
  <CardFooter>
    <Button variant="ghost" size="sm">View invoices</Button>
  </CardFooter>
</Card>

Props Table

Card

PropTypeDefaultDescription
variant"outlined" | "elevated" | "plain"outlinedHow the edge is drawn.
padding"none" | "sm" | "md" | "lg"mdApplied to header, body and footer.
href, target, relstringMakes the whole card a link.
interactivebooleanfalseHover and focus styles for a card clickable another way.
className, classNames, styleSlots: root, header, title, description, actions, body, footer.
refRef<HTMLElement>The root element.

CardHeader takes title, description, actions and children. CardBody and CardFooter take children and a className.

Stat

PropTypeDescription
labelReactNodeWhat the figure is. Always shown.
valueReactNodeThe figure, already formatted.
trend{ direction, label, invert?, description? }How it has changed.
helpReactNodeA note under the figure.
iconReactNodeDrawn beside the label.
loadingbooleanPlaceholder bars, announced as "Loading".
className, classNames, styleSlots: root, label, value, trend, help, icon.

Headings belong to the page

CardHeader takes whatever you give it as the title, rather than choosing a heading level for you:

tsx
<CardHeader title={<h3>Revenue</h3>} />

A card can be the main thing on a page or one of twelve tiles in a grid, and the right level is different in each. Passing your own element keeps the document outline yours.

tsx
<Stat
  label="Churn"
  value="2.1%"
  trend={{ direction: trendDirection(0.6), label: "0.6pp", invert: true }}
/>

invert is for figures where down is the good outcome — churn, refunds, error rates, page weight. It changes the colour only: the arrow still points the way the number moved, because the arrow reports the fact and the colour is the judgement.

The direction is also written out for screen readers ("Up", "Down", "No change"), so the meaning never rests on colour alone. direction: "flat" gets no colour at all.

tsx
<Card href="/invoices/1043">
  <CardBody>INV-1043 · £2,400</CardBody>
</Card>

With href the card renders as an <a>. Keep other links and buttons out of it: nesting interactive elements is invalid HTML and makes a mess of the keyboard. When a card needs both a main link and its own buttons, use interactive with your own handler, or put the link on the title.

Styling and Theming

All rules are in the CSS components layer, so utility classes passed through className / classNames override them.

CSS variables

VariableUsed for
--cd-bg, --cd-fgCard surface and text.
--cd-mutedDescriptions, labels, help text.
--cd-borderThe outline and the footer rule.
--cd-hoverInteractive cards, and the Stat placeholder bars.
--cd-focusFocus ring on an interactive card.
--cd-success, --cd-dangerTrend colours.
--cd-shadow, --cd-radius, --cd-font-sizeCard shape.
--cd-pxPadding, set by the padding prop.

Override them on .cd-root, on :root, or through style. Each variable falls back to the shared --gbs-* of the same name, then to the DataGrid's --dg-* when that stylesheet is loaded, and finally to the built-in palette.

Data attributes

ElementAttributes
Root (.cd-root)data-variant, data-padding, data-interactive
Stat (.st-root)data-loading
Trend (.st-trend)data-direction, data-positive

Headless Use

core/trend.ts is framework-free:

ts
import { trendDirection, isPositive, percentChange } from "@/components/card";
 
trendDirection(12.4);          // "up"
trendDirection(0.4, 0.5);      // "flat" — under the threshold
isPositive("down", true);      // true  — down is good for churn
percentChange(200, 250);       // 25
percentChange(0, 10);          // null — growth from zero is not a percentage

Next.js

Card and Stat are marked "use client" because they accept event handlers and refs. Nothing stops you rendering them from a server component — pass the data in as props.

Notes

  • The card is a plain surface with no elevation tricks: one border, one optional shadow.
  • Stat's figures use tabular numerals, so a column of them lines up.