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.
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.
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
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 |