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(HakumiComponents::Card::Component.new) do |card| %>
  <% card.with_header { "Default Size Card" } %>
  <% card.with_extra do %>
    <%= render(HakumiComponents::Typography::Link::Component.new(href: "#")) { "More" } %>
  <% end %>
  <p>Card content</p>
  <p>Card content</p>
  <p>Card content</p>
<% end %>

<div style="margin-top: 16px">
  <%= render(HakumiComponents::Card::Component.new(size: :small)) do |card| %>
    <% card.with_header { "Small Size Card" } %>
    <% card.with_extra do %>
      <%= render(HakumiComponents::Typography::Link::Component.new(href: "#")) { "More" } %>
    <% end %>
    <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(HakumiComponents::Card::Component.new(
    bordered: false,
    style: "width: 300px"
  )) do |card| %>
    <% card.with_header { "Card title" } %>
    <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 HakumiComponents::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(HakumiComponents::Card::Component.new(hoverable: true)) do |card| %>
  <% card.with_cover do %>
    <%= image_tag("https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png", alt: "example") %>
  <% end %>
  <%= render HakumiComponents::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(HakumiComponents::Card::Component.new) do |card| %>
  <% card.with_cover do %>
    <%= image_tag("https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png", alt: "example") %>
  <% end %>
  <% card.with_action do %>
    <%= render(HakumiComponents::Icon::Component.new(name: :setting)) %>
  <% end %>
  <% card.with_action do %>
    <%= render(HakumiComponents::Icon::Component.new(name: :edit)) %>
  <% end %>
  <% card.with_action do %>
    <%= render(HakumiComponents::Icon::Component.new(name: :ellipsis)) %>
  <% end %>
  <%= render HakumiComponents::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(HakumiComponents::Card::Component.new(loading: true)) do |card| %>
  <% card.with_header { "Card title" } %>
  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(HakumiComponents::Card::Component.new) do |card| %>
  <% card.with_header { "Card Title" } %>
  <%= render HakumiComponents::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render HakumiComponents::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render HakumiComponents::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render HakumiComponents::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render HakumiComponents::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render HakumiComponents::Card::Grid::Component.new(style: "width: 25%; text-align: center") do %>
    Content
  <% end %>
  <%= render HakumiComponents::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(HakumiComponents::Card::Component.new(
    bordered: false,
    style: "flex: 1"
  )) do |card| %>
    <% card.with_header { "Card title" } %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>

  <%= render(HakumiComponents::Card::Component.new(
    bordered: false,
    style: "flex: 1"
  )) do |card| %>
    <% card.with_header { "Card title" } %>
    <p>Card content</p>
    <p>Card content</p>
    <p>Card content</p>
  <% end %>

  <%= render(HakumiComponents::Card::Component.new(
    bordered: false,
    style: "flex: 1"
  )) do |card| %>
    <% card.with_header { "Card title" } %>
    <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 content
Code
<%= render(HakumiComponents::Card::Component.new) do |card| %>
  <% card.with_header { "Card title" } %>
  <p style="font-size: 14px; color: rgba(0, 0, 0, 0.85); margin-bottom: 16px; font-weight: 500">
    Group title
  </p>

  <%= render(HakumiComponents::Card::Component.new(type: :inner)) do |inner_card| %>
    <% inner_card.with_header { "Inner Card title" } %>
    <% inner_card.with_extra do %>
      <%= render(HakumiComponents::Typography::Link::Component.new(href: "#")) { "More" } %>
    <% end %>
    Inner Card content
  <% end %>

  <div style="margin-top: 16px">
    <%= render HakumiComponents::Card::Component.new(
      title: "Inner Card title",
      extra: render(HakumiComponents::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