Card

Container for grouping related content.

import { Card } from 'ui-lab-components/card';
Card Title

This is the main content area of the card. You can put any content here.

import { Card } from 'ui-lab-components/card';
 
export default function Example() {
  return (
    <div style={{ width: 360, maxWidth: '100%' }}>
      <Card>
        <Card.Header>
          Card Title
        </Card.Header>
        <Card.Body>
          <p className="text-foreground-300">This is the main content area of the card. You can put any content here.</p>
        </Card.Body>
      </Card>
    </div>
  );
}
 

card/01-notification

A status-driven card with a badge, body copy, and a footer action. Caller controls read state.

Loading interactive preview
"use client";
 
import { useState } from 'react';
import { Card } from 'ui-lab-components/card'
import { Button } from 'ui-lab-components/button'
import { Flex } from 'ui-lab-components/flex'
import { Badge } from 'ui-lab-components/badge';
 
 
export default function Example() {
  const [read, setRead] = useState(false);
 
  return (
    <Card style={{ width: 360, opacity: read ? 0.6 : 1, transition: 'opacity 0.2s' }}>
      <Card.Header>
        <Flex justify-between align-center>
          Deployment failed
          <Badge variant="destructive">Error</Badge>
        </Flex>
      </Card.Header>
      <Card.Body>
        <p className="text-foreground-400" style={{ fontFamily: "var(--font-body)", fontSize: "var(--text-body-size)", fontWeight: "var(--font-weight-body-normal)", lineHeight: "var(--leading-body)" }}>
          The production deploy of <span className="text-foreground-200">api-gateway</span> failed at step "Run tests". Check the logs for details.
        </p>
      </Card.Body>
      <Card.Footer>
        <Flex justify-between align-center>
          <span className="text-foreground-500" style={{ fontFamily: "var(--font-body)", fontSize: "var(--text-xs)", fontWeight: "var(--font-weight-body-normal)", lineHeight: "var(--leading-sm)" }}>2 minutes ago</span>
          <Button size="sm" variant="ghost" onPress={() => setRead(true)}>
            Mark as read
          </Button>
        </Flex>
      </Card.Footer>
    </Card>
  );
}
 

card/02-settings-panel-card

Card used as a settings section with a list of toggle rows and save/cancel actions in the footer.

Loading interactive preview
"use client";
 
import { useState } from 'react';
import { Card } from 'ui-lab-components/card'
import { Button } from 'ui-lab-components/button'
import { Flex } from 'ui-lab-components/flex'
import { List } from 'ui-lab-components/list';
import { Switch } from 'ui-lab-components/switch';
 
 
const items = [
  { label: 'Email alerts', description: 'Receive alerts via email' },
  { label: 'Push notifications', description: 'Browser push notifications' },
  { label: 'Weekly digest', description: 'Summary sent every Monday' },
];
 
export default function Example() {
  const [enabled, setEnabled] = useState<Record<string, boolean>>(() =>
    Object.fromEntries(items.map((item) => [item.label, true]))
  );
 
  return (
    <Card>
      <Card.Header>
        Notifications
      </Card.Header>
      <Card.Body className="py-4">
        <List role="list" aria-label="Notification settings">
          {items.map((item) => (
            <List.Item
              key={item.label}
              role="listitem"
              focusable={false}
              actions={[
                <Switch
                  key="toggle"
                  selected={enabled[item.label]}
                  onChange={(checked) =>
                    setEnabled((previous) => ({ ...previous, [item.label]: checked }))
                  }
                  aria-label={item.label}
                />,
              ]}
            >
              <div>
                <List.Title>{item.label}</List.Title>
                <List.Desc>{item.description}</List.Desc>
              </div>
            </List.Item>
          ))}
        </List>
      </Card.Body>
      <Card.Footer>
        <Flex justify-end gap="xs">
          <Button size="sm" variant="ghost">Cancel</Button>
          <Button size="sm" variant="primary">Save</Button>
        </Flex>
      </Card.Footer>
    </Card>
  );
}
 

card/03-task-progress

Card displaying a checklist with a progress bar in the header to summarize completion state.

Loading interactive preview
import { Card } from 'ui-lab-components/card'
import { Button } from 'ui-lab-components/button'
import { Flex } from 'ui-lab-components/flex'
import { Progress } from 'ui-lab-components/progress';
 
 
const tasks = [
  { label: 'Design review', done: true },
  { label: 'Write changelog', done: true },
  { label: 'Update docs', done: false },
  { label: 'Deploy to staging', done: false },
];
 
const completed = tasks.filter((t) => t.done).length;
 
export default function Example() {
  return (
    <Card>
      <Card.Header>
        <Flex justify-between align-center>
          Release v2.4.0
          <span className="text-xs text-foreground-500">{completed}/{tasks.length}</span>
        </Flex>
        <Progress value={(completed / tasks.length) * 100} className="mt-2" />
      </Card.Header>
      <Card.Body className="py-3">
        <ul className="space-y-2">
          {tasks.map((task) => (
            <li key={task.label} className="flex items-center gap-2 text-sm">
              <span className={task.done ? 'text-foreground-500 line-through' : 'text-foreground-200'}>
                {task.label}
              </span>
            </li>
          ))}
        </ul>
      </Card.Body>
      <Card.Footer>
        <Button size="sm" variant="secondary" className="w-full">View milestone</Button>
      </Card.Footer>
    </Card>
  );
}