Progress

Progress bar shows the progression of a task. Supports reactive values and multiple colors.

Basic Example

Progress bars with different colors

await import('/components/data-display/progress.js');
const { tags, $ } = Lightview;
const { div, Progress } = tags;

const colors = ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'];

const progressBars = div({ style: 'display: flex; flex-direction: column; gap: 1rem; width: 16rem;' },
    ...colors.map((color, i) => 
        Progress({ 
            value: 30 + i * 10, 
            max: 100, 
            color
        })
    )
);

$('#example').content(progressBars);
await import('/components/data-display/progress.js');
const { $, tags } = Lightview;
const { Progress, div } = tags;

const colors = ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'];

const progressBars = {
    tag: div,
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem; width: 16rem;' },
    children: colors.map((color, i) => ({
        tag: Progress,
        attributes: {
            value: 30 + i * 10,
            max: 100,
            color
        }
    }))
};

$('#example').content(progressBars);
await import('/components/data-display/progress.js');
const { $ } = Lightview;

const colors = ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'];

const progressBars = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem; width: 16rem;',
        children: colors.map((color, i) => ({
            Progress: {
                value: 30 + i * 10,
                max: 100,
                color
            }
        }))
    }
};

$('#example').content(progressBars);
<!-- Import the component (registers lv-progress) -->
<script type="module" src="/components/data-display/progress.js"></script>

<div style="display: flex; flex-direction: column; gap: 1rem; width: 16rem;">
    <lv-progress value="30" color="primary"></lv-progress>
    <lv-progress value="40" color="secondary"></lv-progress>
    <lv-progress value="50" color="accent"></lv-progress>
    <lv-progress value="60" color="info"></lv-progress>
    <lv-progress value="70" color="success"></lv-progress>
    <lv-progress value="80" color="warning"></lv-progress>
    <lv-progress value="90" color="error"></lv-progress>
</div>

Animated Progress

Reactive progress with live updates

await import('/components/data-display/progress.js');
await import('/components/actions/button.js');

const { signal, tags, $ } = Lightview;
const { div, p, Progress, Button } = tags;

const progress = signal(0);
const isRunning = signal(false);
let interval = null;

const startDownload = () => {
    if (isRunning.value) return;
    progress.value = 0;
    isRunning.value = true;
    interval = setInterval(() => {
        progress.value += Math.random() * 15;
        if (progress.value >= 100) {
            progress.value = 100;
            isRunning.value = false;
            clearInterval(interval);
        }
    }, 200);
};

const demo = div({ style: 'display: flex; flex-direction: column; gap: 1rem; width: 18rem;' },
    Progress({ 
        value: () => progress.value, 
        max: 100, 
        color: 'success',
        style: 'width: 100%;'
    }),
    p({ style: 'font-family: monospace; font-size: 0.875rem;' }, 
        () => progress.value >= 100 
            ? '✓ Complete!' 
            : `Downloading: ${Math.round(progress.value)}%`
    ),
    Button({ 
        color: 'primary',
        size: 'sm',
        disabled: () => isRunning.value,
        onclick: startDownload
    }, () => isRunning.value ? 'Downloading...' : 'Start Download')
);

$('#example').content(demo);
await import('/components/data-display/progress.js');
await import('/components/actions/button.js');
const { signal, $, tags } = Lightview;
const { Progress, Button, div, p } = tags;

const progress = signal(0);
const isRunning = signal(false);
let interval = null;

const startDownload = () => {
    if (isRunning.value) return;
    progress.value = 0;
    isRunning.value = true;
    interval = setInterval(() => {
        progress.value += Math.random() * 15;
        if (progress.value >= 100) {
            progress.value = 100;
            isRunning.value = false;
            clearInterval(interval);
        }
    }, 200);
};

const demo = {
    tag: div,
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem; width: 18rem;' },
    children: [
        {
            tag: Progress,
            attributes: {
                value: () => progress.value,
                max: 100,
                color: 'success',
                style: 'width: 100%;'
            }
        },
        {
            tag: p,
            attributes: { style: 'font-family: monospace; font-size: 0.875rem;' },
            children: [
                () => progress.value >= 100
                    ? '✓ Complete!'
                    : `Downloading: ${Math.round(progress.value)}%`
            ]
        },
        {
            tag: Button,
            attributes: {
                color: 'primary',
                size: 'sm',
                disabled: () => isRunning.value,
                onclick: startDownload
            },
            children: [() => isRunning.value ? 'Downloading...' : 'Start Download']
        }
    ]
};

$('#example').content(demo);
await import('/components/data-display/progress.js');
await import('/components/actions/button.js');
const { signal, $ } = Lightview;

const progress = signal(0);
const isRunning = signal(false);
let interval = null;

const startDownload = () => {
    if (isRunning.value) return;
    progress.value = 0;
    isRunning.value = true;
    interval = setInterval(() => {
        progress.value += Math.random() * 15;
        if (progress.value >= 100) {
            progress.value = 100;
            isRunning.value = false;
            clearInterval(interval);
        }
    }, 200);
};

const demo = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem; width: 18rem;',
        children: [
            {
                Progress: {
                    value: () => progress.value,
                    max: 100,
                    color: 'success',
                    style: 'width: 100%;'
                }
            },
            {
                p: {
                    style: 'font-family: monospace; font-size: 0.875rem;',
                    children: [
                        () => progress.value >= 100
                            ? '✓ Complete!'
                            : `Downloading: ${Math.round(progress.value)}%`
                    ]
                }
            },
            {
                Button: {
                    color: 'primary',
                    size: 'sm',
                    disabled: () => isRunning.value,
                    onclick: startDownload,
                    children: [() => isRunning.value ? 'Downloading...' : 'Start Download']
                }
            }
        ]
    }
};

$('#example').content(demo);

Props

Prop Type Default Description
value number | function 0 Current progress value (reactive)
max number 100 Maximum value
color string - 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'info' | 'error'

Colors

Indeterminate

Omit the value attribute for indeterminate state

>

Custom Element Gallery

Live examples using <lv-progress> custom elements.

All Colors

Different Values

Indeterminate (No Value)