tsimport {XDSCard} from '@xds/core/Card'
| Guidance | Practices |
|---|---|
| Do | Try a section first — only use a card when you need the visual separation of a border and elevated background. |
| Do | Keep padding consistent across sibling cards so they align visually in a grid or list. |
| Do | Use the muted variant for secondary content like tips, callouts, or background information. |
| Do | Pair a card with XDSLayout when you need a structured header, scrollable content, and footer with actions. |
| Don't | Nest cards inside other cards — flatten the hierarchy or use a section instead. |
| Don't | Use color variants for status — use Banner or Badge for that. Color cards are for categorization. |
tsx'use client';import {XDSCard} from '@xds/core/Card';import {XDSStack} from '@xds/core/Layout';import {XDSHeading, XDSText} from '@xds/core/Text';export default function CardCallout() {return (<XDSStack direction="horizontal" gap={4}><XDSCard width={270} variant="muted"><XDSStack direction="vertical" gap={2}><XDSHeading level={3}>Tip</XDSHeading><XDSText type="body" color="secondary">Use the muted variant for callouts or supplementary information.</XDSText></XDSStack></XDSCard><XDSCard width={270} variant="muted"><XDSStack direction="vertical" gap={2}><XDSHeading level={3}>Note</XDSHeading><XDSText type="body" color="secondary">Muted cards work well in sidebars or help panels.</XDSText></XDSStack></XDSCard></XDSStack>);}
tsx'use client';import {XDSCard} from '@xds/core/Card';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutFooter,XDSHStack,} from '@xds/core/Layout';import {XDSButton} from '@xds/core/Button';import {XDSHeading, XDSText} from '@xds/core/Text';export default function CardWithInnerLayout() {return (<XDSCard width={380}><XDSLayoutheader={<XDSLayoutHeader hasDivider><XDSHeading level={3}>Edit Profile</XDSHeading></XDSLayoutHeader>}content={<XDSLayoutContent><XDSText type="body" color="secondary">Update your display name, bio, and profile photo. Changes aresaved immediately.</XDSText></XDSLayoutContent>}footer={<XDSLayoutFooter hasDivider><XDSHStack gap={2} hAlign="end"><XDSButton label="Cancel" variant="ghost" /><XDSButton label="Save changes" variant="primary" /></XDSHStack></XDSLayoutFooter>}/></XDSCard>);}
tsx'use client';import {XDSCard} from '@xds/core/Card';import {XDSStack} from '@xds/core/Layout';import {XDSHeading, XDSText} from '@xds/core/Text';export default function CardWithSimpleContent() {return (<XDSCard width={360}><XDSStack direction="vertical" gap={2}><XDSHeading level={3}>Project Overview</XDSHeading><XDSText type="body" color="secondary">This project tracks the redesign of the onboarding flow. The goal isto reduce drop-off by 15% in Q2.</XDSText><XDSText type="supporting" color="secondary">Last updated 2 hours ago</XDSText></XDSStack></XDSCard>);}
tsx'use client';import {XDSCard} from '@xds/core/Card';import {XDSStack} from '@xds/core/Layout';import {XDSText} from '@xds/core/Text';const VARIANTS = [{variant: 'default' as const, label: 'General', note: '4 tasks due today'},{variant: 'muted' as const,label: 'Archived',note: 'No activity in 30 days',},{variant: 'blue' as const, label: 'Engineering', note: '12 open issues'},{variant: 'green' as const, label: 'Marketing', note: '3 campaigns active'},{variant: 'orange' as const, label: 'Urgent', note: '2 items need review'},{variant: 'purple' as const, label: 'Design', note: '5 drafts in progress'},];export default function CardVariants() {return (<XDSStack direction="horizontal" gap={3} style={{flexWrap: 'wrap'}}>{VARIANTS.map(({variant, label, note}) => (<XDSCard key={variant} variant={variant} width={160}><XDSStack direction="vertical" gap={1}><XDSText type="body" weight="bold">{label}</XDSText><XDSText type="supporting" color="secondary">{note}</XDSText></XDSStack></XDSCard>))}</XDSStack>);}
tsx'use client';import {XDSClickableCard} from '@xds/core/ClickableCard';import {XDSStack} from '@xds/core/Layout';import {XDSText, XDSHeading} from '@xds/core/Text';import {XDSButton} from '@xds/core/Button';export default function ClickableCardWithNestedButton() {return (<XDSClickableCard label="Product" href="/product/123" width={320}><XDSStack direction="vertical" gap={3}><XDSStack direction="vertical" gap={1}><XDSHeading level={4}>Wireless Headphones</XDSHeading><XDSText type="body" color="secondary">$79.99</XDSText></XDSStack><XDSButton label="Add to cart" onClick={() => {}} variant="primary" /></XDSStack></XDSClickableCard>);}
tsx'use client';import {useState} from 'react';import {XDSSelectableCard} from '@xds/core/SelectableCard';import {XDSStack} from '@xds/core/Layout';import {XDSText} from '@xds/core/Text';const tags = [{id: 'react', name: 'React', variant: 'blue' as const},{id: 'typescript', name: 'TypeScript', variant: 'cyan' as const},{id: 'node', name: 'Node.js', variant: 'green' as const},{id: 'python', name: 'Python', variant: 'yellow' as const},{id: 'rust', name: 'Rust', variant: 'orange' as const},{id: 'go', name: 'Go', variant: 'teal' as const},];export default function SelectableCardMulti() {const [selected, setSelected] = useState(new Set(['react', 'typescript']));return (<XDSStack direction="horizontal" gap={2} wrap="wrap">{tags.map(tag => (<XDSSelectableCardkey={tag.id}label={tag.name}isSelected={selected.has(tag.id)}variant={tag.variant}onChange={isNow => {setSelected(prev => {const next = new Set(prev);if (isNow) {next.add(tag.id);} else {next.delete(tag.id);}return next;});}}width={130}><XDSText type="body" weight="bold">{tag.name}</XDSText></XDSSelectableCard>))}</XDSStack>);}
tsx'use client';import {XDSCard} from '@xds/core/Card';import {XDSStack} from '@xds/core/Layout';import {XDSText, XDSHeading} from '@xds/core/Text';export default function CardShowcase() {return (<XDSCard width={320}><XDSStack direction="vertical" gap={2}><XDSHeading level={4}>Card title</XDSHeading><XDSText type="body" color="secondary">Cards group related content with a border and background. Use them forprofiles, settings panels, or data summaries.</XDSText></XDSStack></XDSCard>);}