ComponentsThemes
Palette
Default
Stone
Rose
Blue
Green
Violet
Yellow
Orange
6

← Components

Progress

Value-driven progress bar with progressbar a11y semantics. Static, no JS.

Installation

bin/rails g wabi:add progress

Example

Labeled progress

Pass a contextual aria_label: so screen readers announce what is progressing. max: defaults to 100 but can be set to any scale.

Source

app/components/ui/progress.rb

# frozen_string_literal: true

module Components
  module UI
    class Progress < Wabi::Base
      variants do
        base "relative h-4 w-full overflow-hidden rounded-full bg-secondary"
      end

      def initialize(value: 0, max: 100, aria_label: "Progress", **attrs)
        @value      = value
        @max        = max
        @aria_label = aria_label
        @attrs      = attrs
      end

      def view_template
        user_class = @attrs.delete(:class)
        pct = (@value.to_f / @max * 100).clamp(0, 100)
        div(
          role: "progressbar",
          "aria-label": @aria_label,
          "aria-valuemin": "0",
          "aria-valuemax": @max.to_s,
          "aria-valuenow": @value.to_s,
          **@attrs,
          class: merge_class(tokens, user_class)
        ) do
          div(
            class: "h-full w-full flex-1 bg-primary transition-all motion-reduce:transition-none",
            style: "transform: translateX(-#{100 - pct}%)"
          )
        end
      end
    end
  end
end

Accessibility

  • Renders a <div> with role="progressbar", aria-valuemin, aria-valuemax, and aria-valuenow.
  • Pass a descriptive label via aria_label: or aria_labelledby: for screen reader context.