Progress

Displays an indicator showing the completion progress of a task.

No JavaScript Required
progress/default
<%= render Shadcn::ProgressComponent.new(value: 60) %>

Installation

Add the component to your project:

rails generate shadcn:add progress

Usage

<%= render Shadcn::ProgressComponent.new(value: 60) %>

Examples

Different Values

0%
25%
50%
75%
100%
<div class="space-y-4 w-full max-w-md">
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span>0%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 0) %>
  </div>
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span>25%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 25) %>
  </div>
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span>50%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 50) %>
  </div>
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span>75%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 75) %>
  </div>
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span>100%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 100) %>
  </div>
</div>

Custom Max Value

Use the max prop to set a custom maximum value.

30 of 50 items 60%
<div class="space-y-4 w-full max-w-md">
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span>30 of 50 items</span>
      <span>60%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 30, max: 50) %>
  </div>
</div>

With Label

Upload Progress 73%
<div class="space-y-4 w-full max-w-md">
  <div class="space-y-2">
    <div class="flex justify-between text-sm font-medium">
      <span>Upload Progress</span>
      <span>73%</span>
    </div>
    <%= render Shadcn::ProgressComponent.new(value: 73) %>
  </div>
</div>

In a Card

Storage Usage

You're using 7.2 GB of 10 GB

2.8 GB available

<%= render Shadcn::CardComponent.new(class_name: "w-full max-w-md") do |card| %>
  <% card.with_header do |header| %>
    <% header.with_title { "Storage Usage" } %>
    <% header.with_description { "You're using 7.2 GB of 10 GB" } %>
  <% end %>
  <% card.with_content do %>
    <%= render Shadcn::ProgressComponent.new(value: 72) %>
  <% end %>
  <% card.with_footer do %>
    <p class="text-sm text-muted-foreground">2.8 GB available</p>
  <% end %>
<% end %>

All Values

progress/values
<%= render Shadcn::ProgressComponent.new(value: value) %>

Zero Percent

progress/zero
<%= render Shadcn::ProgressComponent.new(value: 0) %>

Twenty Five Percent

progress/twenty_five
<%= render Shadcn::ProgressComponent.new(value: 25) %>

Fifty Percent

progress/fifty
<%= render Shadcn::ProgressComponent.new(value: 50) %>

Seventy Five Percent

progress/seventy_five
<%= render Shadcn::ProgressComponent.new(value: 75) %>

Complete

progress/complete
<%= render Shadcn::ProgressComponent.new(value: 100) %>

Indeterminate

progress/indeterminate
<%= render Shadcn::ProgressComponent.new(indeterminate: true) %>

Multiple Steps

Step 1: Basic Information Complete
{:args=>{}, :block=>nil, :component=>#, :locals=>{}, :template=>"view_components/preview"}
Step 2: Contact Details 50%
{:args=>{}, :block=>nil, :component=>#, :locals=>{}, :template=>"view_components/preview"}
Step 3: Preferences Not started
{:args=>{}, :block=>nil, :component=>#, :locals=>{}, :template=>"view_components/preview"}
progress/multiple_steps
<div class="space-y-4">
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span class="text-muted-foreground">Step 1: Basic Information</span>
      <span class="font-medium text-green-600">Complete</span>
    </div>
    <%= render Shadcn::Progress.new(value: 100) %>
  </div>
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span class="text-muted-foreground">Step 2: Contact Details</span>
      <span class="font-medium">50%</span>
    </div>
    <%= render Shadcn::Progress.new(value: 50) %>
  </div>
  <div class="space-y-2">
    <div class="flex justify-between text-sm">
      <span class="text-muted-foreground">Step 3: Preferences</span>
      <span class="font-medium text-gray-400">Not started</span>
    </div>
    <%= render Shadcn::Progress.new(value: 0) %>
  </div>
</div>

File Upload

document.pdf

2.4 MB of 3.2 MB

75%
{:args=>{}, :block=>nil, :component=>#, :locals=>{}, :template=>"view_components/preview"}
progress/file_upload
<div class="space-y-3 rounded-lg border p-4">
  <div class="flex items-center justify-between">
    <div class="flex items-center gap-3">
      <div class="rounded-md bg-primary/10 p-2">
        <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-primary">
          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
          <polyline points="14 2 14 8 20 8" />
        </svg>
      </div>
      <div>
        <p class="text-sm font-medium">document.pdf</p>
        <p class="text-xs text-muted-foreground">2.4 MB of 3.2 MB</p>
      </div>
    </div>
    <span class="text-sm font-medium">75%</span>
  </div>
  <%= render Shadcn::Progress.new(value: 75) %>
</div>

Loading State

Loading your data...

{:args=>{}, :block=>nil, :component=>#, :locals=>{}, :template=>"view_components/preview"}
progress/loading
<div class="space-y-2">
  <p class="text-sm text-muted-foreground">Loading your data...</p>
  <%= render Shadcn::Progress.new(indeterminate: true) %>
</div>

API Reference

API Reference

Prop Type Default Description
value Integer/Float nil Current progress value
max Integer/Float 100 Maximum progress value
indeterminate Boolean false Whether to show indeterminate (loading) state
class_name String nil Additional CSS classes to apply

Accessibility

  • Uses role="progressbar" for proper accessibility
  • Has aria-valuemin, aria-valuemax, and aria-valuenow attributes
  • For indeterminate state, aria-valuenow is omitted
  • Consider adding a visible label or aria-label to describe what the progress represents