Item

A flexible flex container for displaying titles, descriptions, and actions.

No JavaScript Required
Project brief

Updated just now

item/default
<%= render Shadcn::Item.new(variant: :outline, class_name: "w-[360px]") do |item| %>
  <% item.with_media(variant: :icon) do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
      <path d="M14 2v6h6" />
      <path d="M16 13H8" />
      <path d="M16 17H8" />
      <path d="M10 9H8" />
    </svg>
  <% end %>
  <% item.with_content do |content| %>
    <% content.with_title { "Project brief" } %>
    <% content.with_description { "Updated just now" } %>
  <% end %>
  <% item.with_actions do %>
    <%= render Shadcn::Button.new(size: :sm, variant: :outline) { "Open" } %>
  <% end %>
<% end %>

Installation

Add the component to your project:

rails generate shadcn:add item

Usage

<%= render Shadcn::Item.new(variant: :outline, class_name: "w-[360px]") do |item| %>
  <% item.with_media(variant: :icon) do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
      <path d="M14 2v6h6" />
      <path d="M16 13H8" />
      <path d="M16 17H8" />
      <path d="M10 9H8" />
    </svg>
  <% end %>
  <% item.with_content do |content| %>
    <% content.with_title { "Project brief" } %>
    <% content.with_description { "Updated just now" } %>
  <% end %>
  <% item.with_actions do %>
    <%= render Shadcn::Button.new(size: :sm, variant: :outline) { "Open" } %>
  <% end %>
<% end %>

Examples

Outline Variant

Use the outline variant for bordered items.

Documents

View and edit your documents

<div class="w-full max-w-md">
  <%= render Shadcn::ItemComponent.new(variant: :outline) do |item| %>
    <% item.with_media(variant: :icon) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-2 2Zm0 0a2 2 0 0 1-2-2v-9c0-1.1.9-2 2-2h2"/></svg>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "Documents" } %>
      <% content.with_description { "View and edit your documents" } %>
    <% end %>
  <% end %>
</div>

Muted Variant

Use the muted variant for subtle backgrounds.

Blocked

This feature is currently unavailable

<div class="w-full max-w-md">
  <%= render Shadcn::ItemComponent.new(variant: :muted) do |item| %>
    <% item.with_media(variant: :icon) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m4.93 4.93 14.14 14.14"/></svg>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "Blocked" } %>
      <% content.with_description { "This feature is currently unavailable" } %>
    <% end %>
  <% end %>
</div>

As Link

Use the href prop to render as a clickable link.

<div class="w-full max-w-md">
  <%= render Shadcn::ItemComponent.new(href: "#", class_name: "hover:bg-accent rounded-lg cursor-pointer transition-colors") do |item| %>
    <% item.with_media(variant: :icon) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "Settings" } %>
      <% content.with_description { "Manage your account settings" } %>
    <% end %>
  <% end %>
</div>

With Avatar

Use with avatars for user lists.

John Doe
John Doe

john@example.com

<div class="w-full max-w-md">
  <%= render Shadcn::ItemComponent.new do |item| %>
    <% item.with_media do %>
      <%= render Shadcn::AvatarComponent.new(
        src: "https://github.com/shadcn.png",
        alt: "John Doe"
      ) %>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "John Doe" } %>
      <% content.with_description { "john@example.com" } %>
    <% end %>
    <% item.with_actions do %>
      <%= render Shadcn::ButtonComponent.new(variant: :ghost, size: :sm) { "Message" } %>
    <% end %>
  <% end %>
</div>

Item List

Combine multiple items with separators.

Payments

Manage payment methods

Notifications

Configure notification settings

Security

Manage security preferences

<div class="w-full max-w-md border rounded-lg divide-y">
  <%= render Shadcn::ItemComponent.new do |item| %>
    <% item.with_media(variant: :icon) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/></svg>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "Payments" } %>
      <% content.with_description { "Manage payment methods" } %>
    <% end %>
  <% end %>
  <%= render Shadcn::ItemComponent.new do |item| %>
    <% item.with_media(variant: :icon) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "Notifications" } %>
      <% content.with_description { "Configure notification settings" } %>
    <% end %>
  <% end %>
  <%= render Shadcn::ItemComponent.new do |item| %>
    <% item.with_media(variant: :icon) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
    <% end %>
    <% item.with_content do |content| %>
      <% content.with_title { "Security" } %>
      <% content.with_description { "Manage security preferences" } %>
    <% end %>
  <% end %>
</div>

API Reference

ItemComponent

API Reference

Prop Type Default Description
variant Symbol :default Visual style - :default, :outline, or :muted
size Symbol :default Size variant - :default or :sm
tag Symbol :div HTML tag to render (:div, :li, etc.)
href String nil URL for link items (automatically uses :a tag)
class_name String nil Additional CSS classes to apply

ItemMediaComponent

API Reference

Prop Type Default Description
variant Symbol :default Media variant - :default, :icon, or :image

Slots

Slot Description
with_media(variant:) Media slot for icons, images, or avatars
with_content Content wrapper containing title and description slots
with_title Title text (inside content slot)
with_description Description text (inside content slot)
with_actions Container for action buttons
with_header Header content above main content
with_footer Footer content below main content

Accessibility

  • Use the tag: :li prop when rendering inside a list
  • Interactive items should have visible focus states
  • When using href, the component automatically renders as an anchor tag
  • Use separators with role="separator" between items