Card

Displays a card with header, content, and footer.

No JavaScript Required

Card Title

Card description goes here

This is the main content of the card. You can put any content here.
card/default
<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <div class="flex items-center gap-4">
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "Shadcn",
        size: :lg
      ) %>
      <div>
        <% header.with_title { "Shadcn" } %>
        <% header.with_description { "@shadcn" } %>
      </div>
    </div>
  <% end %>
  <% card.with_content do %>
    <p class="text-sm">Creator of shadcn/ui. Building in public at @shadcn.</p>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline, class_name: "w-full") { "Follow" } %>
  <% end %>
<% end %>

Installation

Add the component to your project:

rails generate shadcn:add card

Usage

<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <div class="flex items-center gap-4">
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "Shadcn",
        size: :lg
      ) %>
      <div>
        <% header.with_title { "Shadcn" } %>
        <% header.with_description { "@shadcn" } %>
      </div>
    </div>
  <% end %>
  <% card.with_content do %>
    <p class="text-sm">Creator of shadcn/ui. Building in public at @shadcn.</p>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline, class_name: "w-full") { "Follow" } %>
  <% end %>
<% end %>

Examples

Simple Card

Card Title

Card Description

Card content goes here.

<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <% header.with_title { "Card Title" } %>
    <% header.with_description { "Card Description" } %>
  <% end %>
  <% card.with_content do %>
    <p>Card content goes here.</p>
  <% end %>
<% end %>

With Footer

Notifications

You have 3 unread messages.

Push Notifications

Send notifications to device.

<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <% header.with_title { "Notifications" } %>
    <% header.with_description { "You have 3 unread messages." } %>
  <% end %>
  <% card.with_content do %>
    <div class="space-y-4">
      <div class="flex items-center gap-4">
        <span class="flex h-2 w-2 rounded-full bg-sky-500"></span>
        <div class="flex-1 space-y-1">
          <p class="text-sm font-medium">Push Notifications</p>
          <p class="text-sm text-muted-foreground">Send notifications to device.</p>
        </div>
        <%= render Shadcn::SwitchComponent.new(checked: true) %>
      </div>
    </div>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(class_name: "w-full") { "Mark all as read" } %>
  <% end %>
<% end %>

Stat Cards

$45,231.89

Total Revenue

+20.1% from last month

+2350

Subscriptions

+180.1% from last month

+573

Active Now

+201 since last hour

<div class="grid gap-4 md:grid-cols-3">
  <%= render Shadcn::CardComponent.new do |card| %>
    <% card.with_header do |header| %>
      <% header.with_description { "Total Revenue" } %>
      <% header.with_title { "$45,231.89" } %>
    <% end %>
    <% card.with_content do %>
      <p class="text-xs text-muted-foreground">+20.1% from last month</p>
    <% end %>
  <% end %>

  <%= render Shadcn::CardComponent.new do |card| %>
    <% card.with_header do |header| %>
      <% header.with_description { "Subscriptions" } %>
      <% header.with_title { "+2350" } %>
    <% end %>
    <% card.with_content do %>
      <p class="text-xs text-muted-foreground">+180.1% from last month</p>
    <% end %>
  <% end %>

  <%= render Shadcn::CardComponent.new do |card| %>
    <% card.with_header do |header| %>
      <% header.with_description { "Active Now" } %>
      <% header.with_title { "+573" } %>
    <% end %>
    <% card.with_content do %>
      <p class="text-xs text-muted-foreground">+201 since last hour</p>
    <% end %>
  <% end %>
</div>

Profile Card

Shadcn

@shadcn

Shadcn

Creator of shadcn/ui. Building in public at @shadcn.

<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <div class="flex items-center gap-4">
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "Shadcn",
        size: :lg
      ) %>
      <div>
        <% header.with_title { "Shadcn" } %>
        <% header.with_description { "@shadcn" } %>
      </div>
    </div>
  <% end %>
  <% card.with_content do %>
    <p class="text-sm">Creator of shadcn/ui. Building in public at @shadcn.</p>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline, class_name: "w-full") { "Follow" } %>
  <% end %>
<% end %>

Simple

A simple card with just content, no header or footer.
card/simple
<%= render(Shadcn::CardComponent.new) do |card| %>
  <% card.with_content_slot do %>
    "A simple card with just content, no header or footer."
  <% end %>
<% end %>

Image Header

Photo

Beautiful Landscape

A stunning view captured in the mountains during golden hour.

card/image_header
<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <div class="flex items-center gap-4">
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "Shadcn",
        size: :lg
      ) %>
      <div>
        <% header.with_title { "Shadcn" } %>
        <% header.with_description { "@shadcn" } %>
      </div>
    </div>
  <% end %>
  <% card.with_content do %>
    <p class="text-sm">Creator of shadcn/ui. Building in public at @shadcn.</p>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline, class_name: "w-full") { "Follow" } %>
  <% end %>
<% end %>

Notification

Notifications

You have 3 unread messages.

Your call has been confirmed.

1 hour ago

You have a new message!

2 hours ago

card/notification
<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <div class="flex items-center gap-4">
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "Shadcn",
        size: :lg
      ) %>
      <div>
        <% header.with_title { "Shadcn" } %>
        <% header.with_description { "@shadcn" } %>
      </div>
    </div>
  <% end %>
  <% card.with_content do %>
    <p class="text-sm">Creator of shadcn/ui. Building in public at @shadcn.</p>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline, class_name: "w-full") { "Follow" } %>
  <% end %>
<% end %>

Form

Create project

Deploy your new project in one-click.

card/form
<%= render Shadcn::CardComponent.new(class_name: "w-[350px]") do |card| %>
  <% card.with_header do |header| %>
    <div class="flex items-center gap-4">
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "Shadcn",
        size: :lg
      ) %>
      <div>
        <% header.with_title { "Shadcn" } %>
        <% header.with_description { "@shadcn" } %>
      </div>
    </div>
  <% end %>
  <% card.with_content do %>
    <p class="text-sm">Creator of shadcn/ui. Building in public at @shadcn.</p>
  <% end %>
  <% card.with_footer do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline, class_name: "w-full") { "Follow" } %>
  <% end %>
<% end %>

API Reference

API Reference

Prop Type Default Description
class_name String nil Additional CSS classes to apply

Slots

Slot Description
with_header Card header section (contains title and description slots)
with_title Card title (inside header or standalone)
with_description Card description text
with_content Main card content area
with_footer Card footer section

Accessibility

  • Card is a visual container and has no inherent semantic meaning
  • Use appropriate heading levels for card titles based on page context
  • Ensure interactive elements within cards are keyboard accessible