Card

Component

Interactive examples and API documentation

Basic Card
A basic card containing a title, content and an extra corner content. Supports two sizes: default and small.
Default Size Card

Card content

Card content

Card content

Small Size Card

Card content

Card content

Card content

Code
<%= render Hakumi::Card::Component.new(
  title: "Default Size Card",
  extra: render(Hakumi::Typography::Link::Component.new(href: "#")) { "More" }
) do %>
  <p>Card content</p>
  <p>Card content</p>
  <p>Card content</p>
<% end %>

<div style="margin-top: 16px">
  <%= render Hakumi::Card::Component.new(
    title: "Small Size Card",
    extra: render(Hakumi::Typography::Link::Component.new(href: "#")) { "More" },
    size: :small
  ) do %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>
</div>
No Border
A borderless card on a gray background.
Card title

Card content

Card content

Card content

Code
<div style="background: #ececec; padding: 30px">
  <%= render Hakumi::Card::Component.new(
    title: "Card title",
    bordered: false,
    style: "width: 300px"
  ) do %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>
</div>
Simple Card (Hoverable)
A simple card with hover effect.

Card content

Card content

Card content

Code
<%= render Hakumi::Card::Component.new(hoverable: true) do %>
  <p>Card content</p>
  <p>Card content</p>
  <p>Card content</p>
<% end %>
Card with Cover Image
Card with a cover image and meta information.
example
Card title
This is the description
Code
<%= render Hakumi::Card::Component.new(
  hoverable: true,
  cover: image_tag("https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png", alt: "example")
) do %>
  <%= render Hakumi::Card::Meta::Component.new(
    title: "Card title",
    description: "This is the description"
  ) %>
<% end %>
Card with Actions
A card with action buttons at the bottom.
example
Card title
This is the description
Code
<%= render Hakumi::Card::Component.new(
  cover: image_tag("https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png", alt: "example"),
  actions: [
    render(Hakumi::Icon::Component.new(name: :setting)),
    render(Hakumi::Icon::Component.new(name: :edit)),
    render(Hakumi::Icon::Component.new(name: :ellipsis))
  ]
) do %>
  <%= render Hakumi::Card::Meta::Component.new(
    title: "Card title",
    description: "This is the description",
    avatar: image_tag("https://api.dicebear.com/7.x/miniavs/svg?seed=1", style: "width: 32px; height: 32px; border-radius: 50%")
  ) %>
<% end %>
Loading Card
Shows a loading indicator while the contents of the card is being fetched.
Card title

Code
<%= render Hakumi::Card::Component.new(
  loading: true,
  title: "Card title"
) do %>
  Content that won't be shown because loading is true
<% end %>
Grid Card
Grid style card content.
Card Title
Content
Content
Content
Content
Content
Content
Content
Code
<%= render Hakumi::Card::Component.new(title: "Card Title") do %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render Hakumi::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
<% end %>
Cards in Column
Multiple cards displayed in a row layout.
Card title

Card content

Card content

Card content

Card title

Card content

Card content

Card content

Card title

Card content

Card content

Card content

Code
<div style="display: flex; gap: 16px; background: #ececec; padding: 30px">
  <%= render Hakumi::Card::Component.new(
    title: "Card title",
    bordered: false,
    style: "flex: 1"
  ) do %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>

  <%= render Hakumi::Card::Component.new(
    title: "Card title",
    bordered: false,
    style: "flex: 1"
  ) do %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>

  <%= render Hakumi::Card::Component.new(
    title: "Card title",
    bordered: false,
    style: "flex: 1"
  ) do %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>
</div>
Inner Card
Card can be nested inside another Card.
Card title

Group title

Inner Card title
Inner Card content
Inner Card title
Inner Card content
Code
<%= render Hakumi::Card::Component.new(title: "Card title") do %>
  <p style="font-size: 14px; color: rgba(0, 0, 0, 0.85); margin-bottom: 16px; font-weight: 500">
    Group title
  </p>

  <%= render Hakumi::Card::Component.new(
    title: "Inner Card title",
    extra: render(Hakumi::Typography::Link::Component.new(href: "#")) { "More" },
    type: :inner
  ) do %>
    Inner Card content
  <% end %>

  <div style="margin-top: 16px">
    <%= render Hakumi::Card::Component.new(
      title: "Inner Card title",
      extra: render(Hakumi::Typography::Link::Component.new(href: "#")) { "More" },
      type: :inner
    ) do %>
      Inner Card content
    <% end %>
  </div>
<% end %>

Card API

Prop Type Default Description
title String or ViewComponent - Card header title.
extra String or ViewComponent - Content rendered on the right side of the header.
bordered Boolean true Whether the card has a border.
hoverable Boolean false Adds hover effect to the card.
loading Boolean false Show skeleton state instead of content.
size :default or :small :default Card padding/height preset.
type :inner - Inner style for nested cards.
actions Array [] Action items rendered in the footer region.
cover String or ViewComponent - Media displayed above the body.
content slot Slot - Card body content.
**html_options Keyword args - Additional attributes for the wrapper element. Use `class:` for styling (e.g., `class: 'my-card'`, `data: { controller: 'dropdown' }`).