Progress
This library is a work-in-progress. We are releasing it early to gather feedback, but it is not ready for production.
A progress component is used to display the progress of a task. It can show determinate progress (with a specific value) or indeterminate progress (loading state without a known duration).
Examples
Live Preview
Indeterminate Progress
When no value is provided, the progress bar is indeterminate.
Progress with Value
Set the value prop to a number to show progress.
Progress with Custom Max
Set the max prop to a number to define the maximum value.
CSS Shadow Parts Customization
Use CSS Shadow Parts to customize the component's appearance.
View Vue Code
<template>
<section>
<div class="mbe4">
<h2>Indeterminate Progress</h2>
<p class="mbs2 mbe3">When no <code>value</code> is provided, the progress bar is indeterminate.</p>
<VueProgress label="Loading..." />
</div>
<div class="mbe4">
<h2>Progress with Value</h2>
<p class="mbs2 mbe3">Set the <code>value</code> prop to a number to show progress.</p>
<VueProgress
:value="50"
label="50% complete"
/>
</div>
<div class="mbe4">
<h2>Progress with Custom Max</h2>
<p class="mbs2 mbe3">Set the <code>max</code> prop to a number to define the maximum value.</p>
<VueProgress
:value="150"
:max="200"
label="150 of 200"
/>
</div>
<div class="mbe4">
<h2>CSS Shadow Parts Customization</h2>
<p class="mbs2 mbe3">Use CSS Shadow Parts to customize the component's appearance.</p>
<VueProgress
:value="75"
label="Customized progress"
class="custom-progress"
/>
</div>
</section>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { VueProgress } from "agnosticui-core/progress/vue";
export default defineComponent({
name: "ProgressExamples",
components: {
VueProgress,
},
});
</script>
<style>
.custom-progress::part(ag-progress-bar) {
background-color: var(--ag-purple-100);
height: 1.5rem;
}
.custom-progress::part(ag-progress-bar)::-webkit-progress-value {
background-color: var(--ag-purple-500);
}
.custom-progress::part(ag-progress-bar)::-moz-progress-bar {
background-color: var(--ag-purple-500);
}
</style>
Live Preview
View Lit / Web Component Code
import { LitElement, html } from 'lit';
import 'agnosticui-core/progress';
export class ProgressLitExamples extends LitElement {
// Render in light DOM to access global utility classes
createRenderRoot() {
return this;
}
render() {
return html`
<section>
<div class="mbe4">
<h2>Indeterminate Progress</h2>
<p class="mbs2 mbe3">When no <code>value</code> is provided, the progress bar is indeterminate.</p>
<ag-progress label="Loading..."></ag-progress>
</div>
<div class="mbe4">
<h2>Progress with Value</h2>
<p class="mbs2 mbe3">Set the <code>value</code> prop to a number to show progress.</p>
<ag-progress
value="50"
label="50% complete"
></ag-progress>
</div>
<div class="mbe4">
<h2>Progress with Custom Max</h2>
<p class="mbs2 mbe3">Set the <code>max</code> prop to a number to define the maximum value.</p>
<ag-progress
value="150"
max="200"
label="150 of 200"
></ag-progress>
</div>
<div class="mbe4">
<h2>CSS Shadow Parts Customization</h2>
<p class="mbs2 mbe3">Use CSS Shadow Parts to customize the component's appearance.</p>
<ag-progress
value="75"
label="Customized progress"
class="custom-progress"
></ag-progress>
</div>
</section>
<style>
.custom-progress::part(ag-progress-bar) {
background-color: var(--ag-purple-100);
height: 1.5rem;
}
.custom-progress::part(ag-progress-bar)::-webkit-progress-value {
background-color: var(--ag-purple-500);
}
.custom-progress::part(ag-progress-bar)::-moz-progress-bar {
background-color: var(--ag-purple-500);
}
</style>
`;
}
}
// Register the custom element
customElements.define('progress-lit-examples', ProgressLitExamples);
Interactive Preview: Click the "Open in StackBlitz" button below to see this example running live in an interactive playground.
View React Code
import { ReactProgress } from "agnosticui-core/progress/react";
export default function ProgressReactExamples() {
return (
<section>
<div className="mbe4">
<h2>Indeterminate Progress</h2>
<p className="mbs2 mbe3">
When no <code>value</code> is provided, the progress bar is indeterminate.
</p>
<ReactProgress label="Loading..." />
</div>
<div className="mbe4">
<h2>Progress with Value</h2>
<p className="mbs2 mbe3">
Set the <code>value</code> prop to a number to show progress.
</p>
<ReactProgress value={50} label="50% complete" />
</div>
<div className="mbe4">
<h2>Progress with Custom Max</h2>
<p className="mbs2 mbe3">
Set the <code>max</code> prop to a number to define the maximum value.
</p>
<ReactProgress value={150} max={200} label="150 of 200" />
</div>
<div className="mbe4">
<h2>CSS Shadow Parts Customization</h2>
<p className="mbs2 mbe3">
Use CSS Shadow Parts to customize the component's appearance.
</p>
<ReactProgress
value={75}
label="Customized progress"
className="custom-progress"
/>
</div>
</section>
);
}
Usage
TIP
The framework examples below import AgnosticUI as an npm package. Alternatively, you can use the CLI for complete control, AI/LLM visibility, and full code ownership:
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add ProgressThe CLI copies source code directly into your project, giving you full visibility and control. After running npx ag add, you'll receive exact import instructions.
Vue
<template>
<VueProgress :value="50" :max="100" label="Loading..." />
<!-- Indeterminate progress (no value) -->
<VueProgress label="Processing..." />
<!-- Custom size -->
<VueProgress :value="75" :max="100" label="Uploading..." size="large" />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { VueProgress } from 'agnosticui-core/Progress/vue/VueProgress';
export default defineComponent({
components: { VueProgress }
});
</script>React
import { ReactProgress } from 'agnosticui-core/Progress/react/ReactProgress';
export default function Example() {
return (
<>
<ReactProgress value={50} max={100} label="Loading..." />
{/* Indeterminate progress (no value) */}
<ReactProgress label="Processing..." />
{/* Custom size */}
<ReactProgress value={75} max={100} label="Uploading..." size="large" />
</>
);
}Lit (Web Components)
<script type="module">
import 'agnosticui-core/Progress/core/Progress';
</script>
<!-- Determinate progress -->
<ag-progress value="50" max="100" label="Loading..."></ag-progress>
<!-- Indeterminate progress (no value attribute) -->
<ag-progress label="Processing..."></ag-progress>
<!-- Custom size -->
<ag-progress value="75" max="100" label="Uploading..." size="large"></ag-progress>Using property binding in Lit templates:
import { html } from 'lit';
import 'agnosticui-core/Progress/core/Progress';
const template = html`
<ag-progress .value=${50} .max=${100} .label=${"Loading..."}></ag-progress>
`;Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | undefined | undefined | The current value of the progress bar. If not provided, the progress bar is indeterminate. |
max | number | 100 | The maximum value of the progress bar. |
label | string | '' | An accessible label for the progress bar. This label is visually hidden but announced by screen readers. |
size | 'small' | 'medium' | 'large' | 'medium' | Size of the progress bar. |
CSS Shadow Parts
| Part | Description |
|---|---|
ag-progress-wrapper | The main container element for the component |
progress-label | The visually hidden label element |
ag-progress-bar | The native <progress> element |
CSS Custom Properties
The Progress component can be customized using CSS custom properties:
| Property | Description | Default |
|---|---|---|
--ag-progress-width | Width of the progress bar | 100% |
--ag-progress-height | Height of the progress bar | Size-dependent |
Customization Example
/* Custom width */
ag-progress {
--ag-progress-width: 300px;
}
/* Custom styling via shadow parts */
ag-progress::part(ag-progress-bar) {
border-radius: 4px;
}
ag-progress::part(ag-progress-bar)::-webkit-progress-value {
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
}
ag-progress::part(ag-progress-bar)::-moz-progress-bar {
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
}Sizes
The Progress component supports three sizes:
small: Compact progress bar (height:var(--ag-space-2))medium(default): Standard progress bar (height:var(--ag-space-3))large: Prominent progress bar (height:var(--ag-space-4))
Determinate vs Indeterminate
Determinate Progress
Shows a specific completion percentage. Use when you know the progress amount:
<VueProgress :value="75" :max="100" label="75% complete" />Indeterminate Progress
Shows an animated loading state. Use when progress duration is unknown:
<VueProgress label="Loading..." />The indeterminate state displays an animated gradient that moves across the progress bar.
Accessibility
The Progress component follows WCAG accessibility guidelines:
- Uses the native HTML5
<progress>element for proper semantics - The
labelprop provides accessible text that is visually hidden but announced by screen readers - The
<progress>element hasaria-labelset to the label value - Indeterminate state is properly indicated to assistive technologies
- The component maintains proper ARIA attributes (
value,max) for determinate progress
Best Practices
- Always provide a meaningful
labelthat describes what is progressing - For determinate progress, update the
valueprop as the task progresses - Use indeterminate progress when you cannot calculate completion percentage
- Consider pairing with text to show actual numbers (e.g., "Uploading 5 of 10 files")
- Ensure adequate color contrast (4.5:1 minimum) for the progress indicator
Browser Support
The Progress component uses the native HTML5 <progress> element with enhanced styling. The indeterminate animation is supported in all modern browsers. Custom styling is applied using browser-specific pseudo-elements:
- Chrome/Safari/Edge:
::-webkit-progress-bar,::-webkit-progress-value - Firefox:
::-moz-progress-bar
Examples
File Upload Progress
<template>
<div>
<VueProgress
:value="uploadProgress"
:max="100"
:label="`Uploading ${fileName}...`"
/>
<p>{{ uploadProgress }}% complete</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { VueProgress } from 'agnosticui-core/Progress/vue/VueProgress';
const uploadProgress = ref(0);
const fileName = ref('document.pdf');
// Simulate upload progress
const interval = setInterval(() => {
uploadProgress.value += 10;
if (uploadProgress.value >= 100) {
clearInterval(interval);
}
}, 500);
</script>Loading State
<template>
<div>
<VueProgress label="Loading content..." />
<p>Please wait...</p>
</div>
</template>