display
Card
A surface with header, content and footer parts for grouping related content.
Examples
Anatomy
Production
HealthyDeployed 12 minutes ago from main.
- Region
- eu-west-1
- Instances
- 6
- p99 latency
- 84 ms
Variants
Four surfaces, from raised to no chrome at all.
elevated
The surface changes; the parts inside do not.
outline
The surface changes; the parts inside do not.
subtle
The surface changes; the parts inside do not.
ghost
The surface changes; the parts inside do not.
Own the source
Noksha ships as a package and as copy-paste source. Take the files and they are yours to change. These are read from the generated registry, so they are exactly what the library ships — never a paraphrase of it.
Self-contained apart from @noksha-ui/core. Or let the CLI do it: npx @noksha-ui/cli add card writes them, follows the same dependency graph, and fixes up the imports.
import { Slot } from '@noksha-ui/core';
import * as React from 'react';
import type { CardPartProps, CardProps, CardTitleProps } from './card.types.js';
import {
cardContentVariants,
cardDescriptionVariants,
cardFooterVariants,
cardHeaderVariants,
cardTitleVariants,
cardVariants,
} from './card.variants.js';
/**
* A surface that groups related content.
*
* ```tsx
* <Card.Root>
* <Card.Header>
* <Card.Title>Usage</Card.Title>
* <Card.Description>Billing period to date</Card.Description>
* </Card.Header>
* <Card.Content>…</Card.Content>
* <Card.Footer><Button>Upgrade</Button></Card.Footer>
* </Card.Root>
* ```
*/
export const CardRoot = React.forwardRef<HTMLDivElement, CardProps>(function CardRoot(
{
variant = 'elevated',
padding = 'md',
interactive = false,
asChild = false,
className,
...rest
},
ref,
) {
const Comp = asChild ? Slot : 'div';
return (
<Comp
ref={ref}
data-interactive={interactive || undefined}
className={cardVariants({ variant, padding, interactive, className })}
{...rest}
/>
);
});
CardRoot.displayName = 'Card.Root';
export const CardHeader = React.forwardRef<HTMLDivElement, CardPartProps>(function CardHeader(
{ asChild = false, className, ...rest },
ref,
) {
const Comp = asChild ? Slot : 'div';
return <Comp ref={ref} className={cardHeaderVariants({ className })} {...rest} />;
});
CardHeader.displayName = 'Card.Header';
/**
* Defaults to `<h3>` but takes any level through `as`.
*
* There is no correct default heading level for a component that does not know
* its page, so this exposes the choice rather than hard-coding one and quietly
* breaking the document outline.
*/
export const CardTitle = React.forwardRef<HTMLHeadingElement, CardTitleProps>(function CardTitle(
{ as: Tag = 'h3', asChild = false, className, ...rest },
ref,
) {
const Comp = asChild ? Slot : Tag;
return <Comp ref={ref} className={cardTitleVariants({ className })} {...rest} />;
});
CardTitle.displayName = 'Card.Title';
export const CardDescription = React.forwardRef<HTMLParagraphElement, CardPartProps>(
function CardDescription({ asChild = false, className, ...rest }, ref) {
const Comp = asChild ? Slot : 'p';
return <Comp ref={ref} className={cardDescriptionVariants({ className })} {...rest} />;
},
);
CardDescription.displayName = 'Card.Description';
export const CardContent = React.forwardRef<HTMLDivElement, CardPartProps>(function CardContent(
{ asChild = false, className, ...rest },
ref,
) {
const Comp = asChild ? Slot : 'div';
return <Comp ref={ref} className={cardContentVariants({ className })} {...rest} />;
});
CardContent.displayName = 'Card.Content';
export const CardFooter = React.forwardRef<HTMLDivElement, CardPartProps>(function CardFooter(
{ asChild = false, className, ...rest },
ref,
) {
const Comp = asChild ? Slot : 'div';
return <Comp ref={ref} className={cardFooterVariants({ className })} {...rest} />;
});
CardFooter.displayName = 'Card.Footer';
/**
* The namespace is a plain object of the same components exported individually
* above, so `import { CardTitle }` tree-shakes even where `Card.Title` reads
* better in application code.
*/
export const Card = {
Root: CardRoot,
Header: CardHeader,
Title: CardTitle,
Description: CardDescription,
Content: CardContent,
Footer: CardFooter,
};
export { cardVariants };API reference
Accepted values
- CardVariant
elevatedoutlinesubtleghost- CardPadding
nonesmmdlg
CardProps
Also accepts everything from React.HTMLAttributes<HTMLDivElement>.
| Prop | Type | Description |
|---|---|---|
| variant | CardVariant | — |
| padding | CardPadding | Applied to the header, content and footer parts — not to the root. |
| interactive | boolean | Adds hover and press affordances. Does **not** make the card focusable on its own: use `asChild` with an `<a>` or a `<button>` for that, so the whole card carries real semantics instead of a click handler on a `<div>`. |
| asChild | boolean | — |
CardPartProps
Also accepts everything from React.HTMLAttributes<HTMLDivElement>.
| Prop | Type | Description |
|---|---|---|
| asChild | boolean | — |
CardTitleProps
Also accepts everything from React.HTMLAttributes<HTMLHeadingElement>.
| Prop | Type | Description |
|---|---|---|
| as | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | The heading level. Pick the one that fits the page outline. |
| asChild | boolean | — |