Biji UI

Progress

Displays an indicator showing the completion progress of a task.

25%

60%

Complete

Installation

biji-ui = { version = "0.5.0", features = ["progress"] }

Usage

use leptos::prelude::*;
use biji_ui::components::progress;

#[component]
pub fn MyProgress() -> impl IntoView {
    view! {
        <progress::Root
            class="overflow-hidden relative w-full h-2 rounded-full bg-secondary"
            value=Some(75.0_f64)
            max=100.0
        >
            <progress::Indicator class="h-full transition-all bg-primary" />
        </progress::Root>
    }
}

Example

Drive the progress bar reactively with a signal. Place a reactive <div> inside the root as the indicator and update its width via an inline style closure.

use leptos::prelude::*;
use biji_ui::components::progress;

#[component]
pub fn ReactiveProgress() -> impl IntoView {
    let value = RwSignal::new(Some(50.0_f64));
    let steps: &[f64] = &[0.0, 25.0, 50.0, 75.0, 100.0];

    view! {
        <div class="space-y-6">
            <progress::Root
                class="overflow-hidden relative w-full h-3 rounded-full bg-secondary"
                value=value
                max=100.0
            >
                <progress::Indicator class="h-full transition-all duration-500 ease-in-out bg-primary" />
            </progress::Root>
            <div class="flex gap-2 justify-between">
                {steps
                    .iter()
                    .map(|&s| view! {
                        <button
                            class="py-1.5 px-3 text-sm rounded-md border transition-colors outline-none focus:ring-2 border-border data-[active]:bg-muted data-[active]:font-medium hover:bg-muted focus:ring-ring"
                            data-active={move || value.get() == Some(s)}
                            on:click={move |_| value.set(Some(s))}
                        >
                            {format!("{}%", s as u32)}
                        </button>
                    })
                    .collect::<Vec<_>>()}
            </div>
        </div>
    }
}

RootWith

Use <RootWith> when you need direct access to ProgressState inside the children. The let:p binding exposes derived signals like p.percentage and p.data_state for custom rendering.

Progress50%
use leptos::prelude::*;
use biji_ui::components::progress;

#[component]
pub fn LabeledProgress() -> impl IntoView {
    let value = RwSignal::new(Some(50.0_f64));

    view! {
        <progress::RootWith
            class="w-full"
            value=value
            max=100.0
            let:p
        >
            <div class="flex justify-between items-center mb-1.5 text-xs">
                <span class="text-muted-foreground">"Progress"</span>
                <span class="font-medium tabular-nums">
                    {move || {
                        p.percentage.get()
                            .map(|pct| format!("{}%", pct as u32))
                            .unwrap_or_else(|| "–".to_string())
                    }}
                </span>
            </div>
            <div class="overflow-hidden w-full h-3 rounded-full bg-secondary">
                <progress::Indicator class="h-full transition-all duration-500 ease-in-out bg-primary" />
            </div>
        </progress::RootWith>
    }
}

API Reference

Root / RootWith

NameTypeDefaultDescription
classString""CSS class applied to the root element.
valueSignal<Option<f64>>NoneThe current progress value. Accepts a static Some(f64) or a reactive signal. When None, the progress is indeterminate.
maxf64100.0The maximum progress value.

Indicator

NameTypeDefaultDescription
classString""CSS class applied to the indicator element.

Data Attributes

AttributeDescription
data-state"indeterminate" when value is None; "loading" while in progress; "complete" when value is greater than or equal to max. Present on Root and Indicator.
data-valueThe current numeric value. Present on Root and Indicator when value is set.
data-maxThe maximum value. Present on Root and Indicator.