Edit Profile

Dark Mode

Copy config

Copy and paste the following code into your global.css file to apply the styles.

DISCLAIMER: This component is in
Beta
status. That means that it is ready for production, but the API might change.

Card

Displays a card with header, content, and footer.

Installation

Run the following cli command or copy/paste the component code into your project

qwik-ui add card
import { component$, type PropsOf, Slot } from '@builder.io/qwik';
import { cn } from '@qwik-ui/utils';
 
const Root = component$<PropsOf<'div'>>((props) => {
  return (
    <div
      {...props}
      class={cn(
        'rounded-base border bg-card text-card-foreground shadow-sm',
        props.class,
      )}
    >
      <Slot />
    </div>
  );
});
 
const Header = component$<PropsOf<'div'>>((props) => {
  return (
    <div {...props} class={cn('flex flex-col space-y-1.5 p-6', props.class)}>
      <Slot />
    </div>
  );
});
 
const Title = component$<PropsOf<'h3'>>((props) => {
  return (
    <h3 {...props} class={cn('font-medium leading-none tracking-tight', props.class)}>
      <Slot />
    </h3>
  );
});
 
const Description = component$<PropsOf<'p'>>((props) => {
  return (
    <p {...props} class={cn('text-sm text-muted-foreground', props.class)}>
      <Slot />
    </p>
  );
});
 
const Content = component$<PropsOf<'div'>>((props) => {
  return (
    <div {...props} class={cn('p-6 pt-0', props.class)}>
      <Slot />
    </div>
  );
});
 
const Footer = component$<PropsOf<'div'>>(({ ...props }) => {
  return (
    <div {...props} class={cn('flex items-center p-6 pt-0', props.class)}>
      <Slot />
    </div>
  );
});
 
// Experimental API
const Image = component$<PropsOf<'img'>>(({ ...props }) => {
  return <img {...props} class={cn('w-full object-cover', props.class)} />;
});
 
export const Card = {
  Root,
  Header,
  Title,
  Description,
  Content,
  Footer,
  Image,
};

Examples

Color

Notifications

You have 3 unread messages.

Push Notifications

Send notifications to device.

Your call has been confirmed.

1 hour ago

You have a new message!

1 hour ago

Your subscription is expiring soon!

2 hours ago

import { PropsOf, component$ } from '@builder.io/qwik';
import { Button, Card } from '~/components/ui';
import { cn } from '@qwik-ui/utils';
import { LuBell, LuCheck } from '@qwikest/icons/lucide';

const notifications = [
  {
    title: 'Your call has been confirmed.',
    description: '1 hour ago',
  },
  {
    title: 'You have a new message!',
    description: '1 hour ago',
  },
  {
    title: 'Your subscription is expiring soon!',
    description: '2 hours ago',
  },
];

type CardProps = PropsOf<typeof Card.Root>;

export default component$<CardProps>(({ ...props }) => {
  return (
    <Card.Root class={cn('w-[380px]', props.class)} {...props}>
      <Card.Header>
        <Card.Title>Notifications</Card.Title>
        <Card.Description>You have 3 unread messages.</Card.Description>
      </Card.Header>
      <Card.Content class="grid gap-4">
        <div class=" flex items-center space-x-4 rounded-md border p-4">
          <LuBell />
          <div class="flex-1 space-y-1">
            <p class="text-sm font-medium leading-none">Push Notifications</p>
            <p class="text-sm text-muted-foreground">Send notifications to device.</p>
          </div>
          {/* <Switch /> */}
        </div>
        <div>
          {notifications.map((notification, index) => (
            <div
              key={index}
              class="mb-4 grid grid-cols-[25px_1fr] items-start pb-4 last:mb-0 last:pb-0"
            >
              <span class="flex h-2 w-2 translate-y-1 rounded-full bg-primary" />
              <div class="space-y-1">
                <p class="text-sm font-medium leading-none">{notification.title}</p>
                <p class="text-sm text-muted-foreground">{notification.description}</p>
              </div>
            </div>
          ))}
        </div>
      </Card.Content>
      <Card.Footer>
        <Button class="w-full">
          <LuCheck class="mr-2 h-4 w-4" /> Mark all as read
        </Button>
      </Card.Footer>
    </Card.Root>
  );
});