ui · Primitive
Card
@devalok/shilp-sutra/ui/cardView in Storybook Preview
Latest release
v0.42.1 is live. BREAKING.json manifest, recipe polish, and the usual Devalok improvements.
Three phases land together: theming foundation, /theming editor, and /components detail pages.
On track
Variants
Minimal
Just a heading and a description.
With content
Headers gain weight from short, specific copy.
Three sentences max in card body. Keep the user moving.
Project: Karm
Devalok's product. Built with shilp-sutra.
Cards compose. Add a header row, a body, a footer, or just one of the three. Each piece is optional and uses the same spacing tokens, so density is consistent across the app.
Reference
Props
variant: "default" | "elevated" | "outline" | "flat"
color: "default" | "accent" | "error" | "success" | "warning" | "info" | "neutral" (border accent color)
size: "sm" | "md" | "lg" (padding — propagated to CardHeader/CardContent/CardFooter via context)
interactive: boolean (enables hover shadow lift + pointer cursor)
accent: "left" | "top" | "right" | "bottom" (render a colored accent bar on the specified edge)
accentColor: "default" | "accent" | "error" | "success" | "warning" | "info" (color of the accent bar; default maps to accent-9)
Compound Components
Card (root)
CardHeader ← inherits size from Card context
CardTitle
CardDescription
CardContent ← inherits size from Card context
CardFooter ← inherits size from Card context
Defaults
variant="default", color="default", size="md"
Example
<Card variant="elevated" interactive onClick={() => navigate(url)}>
<CardHeader>
<CardTitle>Project</CardTitle>
<CardDescription>Last updated 2h ago</CardDescription>
</CardHeader>
<CardContent><p>Content here</p></CardContent>
</Card>
Composability
- Size cascades through context — Card's
sizeprop sets padding on CardHeader, CardContent, and CardFooter viaCardSizeContext. Don't set padding classes on sub-components directly; override viaclassNameif needed. - Not a compound state machine — Card, CardHeader, CardTitle, etc. are purely structural. No open/close state.
- Accent bar is independent: The
accent/accentColorprops render a decorative colored edge bar (absolutely positioned,aria-hidden). Works alongsidecolor(which tints the border) — the two can stack for layered emphasis. - Interactive cards: Set
interactive={true}+onClickfor clickable cards (entire surface becomes the button). Addaria-labelon the Card root when there's no visible heading. For complex multi-action cards, prefer standard Card with explicit buttons inside. - ContentCard (composed) is a higher-level wrapper with built-in header/footer slots and title/actions — use it for list-row-style cards; use Card directly for custom layouts.
Gotchas
- Use
interactiveprop for clickable cards — adds hover lift and pointer cursor - Don't override CardHeader/CardContent/CardFooter padding via className if you want the size cascade to work — set size on Card instead
Changes
v0.31.0
- Added
colorprop: semantic border color (accent, error, success, warning, info, neutral) - Added
sizeprop:sm | md | lg— padding propagated to sub-components via React context
v0.18.0
- Changed Interactive card hover lift animation migrated to Framer Motion
v0.4.2
- Changed (BREAKING)
variant="outlined"renamed tovariant="outline" - Added
cardVariantsexport
v0.1.1
- Fixed
leading-none tracking-tightchanged toleading-ds-none tracking-ds-tightfor token compliance
v0.1.0
- Added Initial release