Skip to content
ARC UI ARC Reactive Components
Docs Components Tokens Synthesizer
v2.1.0
Getting Started Frameworks Design Tokens Theming Theme Synthesizer Accessibility Browser Support Changelog Contributing All Components App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageInfinite ScrollMarqueeScroll AreaSeparatorSkeletonSpinnerStackVirtual List Animated NumberBadgeComparisonCountdown TimerData TableDescription ListDiffKey ValueListMeterSparklineStatStepperTableTagTimelineValue Card BlockquoteCode BlockGradient TextHighlightKbdMarkdownNumber FormatProseTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerFieldsetFile UploadFormHotkeyIcon ButtonInputInput GroupLabelMulti SelectNumber InputOTP InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSliderSortable ListSwitch GroupTextareaTheme ToggleTime PickerToggle AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
Components Progress
feedback static
<arc-progress>

Overview

Guidelines

When to use

  • Use the bar variant when you can report a numeric percentage (e.g. file uploads, multi-step forms)
  • Switch from indeterminate to determinate as soon as the total work is known
  • Always provide a label prop so screen readers can announce the purpose of the indicator
  • Use the spinner variant inside buttons or inline contexts where a bar would be too wide
  • Pair with descriptive text nearby (e.g. "Uploading project files...") to add context beyond the bar alone
  • Use the sm size for inline or table-cell indicators and lg for full-width page loaders

When not to use

  • Show a determinate bar stuck at 0% — use indeterminate until real progress data is available
  • Use a spinner when you have percentage data; bars are more informative for known-length tasks
  • Omit the label prop — without it the progress indicator is invisible to assistive technology
  • Animate progress backwards; if the total changes, reset to indeterminate rather than decreasing the value
  • Stack multiple progress bars in view simultaneously — consolidate into a single indicator or use a stepper
  • Use progress for instant actions that complete in under 300ms; a brief delay feels faster without a loader

Features

  • Bar variant with horizontal fill track for determinate completion
  • Spinner variant with circular animation for compact contexts
  • Indeterminate mode for unknown-duration operations
  • Three size presets (sm, md, lg) for different layout contexts
  • Accessible label text announced by screen readers via aria-label
  • ARIA progressbar role with aria-valuenow, aria-valuemin, and aria-valuemax
  • Respects prefers-reduced-motion by disabling animations
  • Smooth fill transition when value updates for determinate bar

Preview

Usage

<script type="module" src="@arclux/arc-ui"></script>

<div style="display: flex; flex-direction: column; width: 100%; gap: var(--space-lg);">
  <arc-progress value="65" label="Uploading project files..."></arc-progress>
  <arc-progress variant="spinner" indeterminate label="Processing upload"></arc-progress>
</div>
import { Progress } from '@arclux/arc-ui-react';

export function FileUploadStatus() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', width: '100%', gap: 'var(--space-lg)' }}>
      <Progress value={65} label="Uploading project files..." />
      <Progress variant="spinner" indeterminate label="Processing upload" />
    </div>
  );
}
<script setup>
import { Progress } from '@arclux/arc-ui-vue';
</script>

<template>
  <div style="display: flex; flex-direction: column; width: 100%; gap: var(--space-lg);">
    <Progress :value="65" label="Uploading project files..." />
    <Progress variant="spinner" indeterminate label="Processing upload" />
  </div>
</template>
<script>
  import { Progress } from '@arclux/arc-ui-svelte';
</script>

<div style="display: flex; flex-direction: column; width: 100%; gap: var(--space-lg);">
  <Progress value={65} label="Uploading project files..." />
  <Progress variant="spinner" indeterminate label="Processing upload" />
</div>
import { Component } from '@angular/core';
import { Progress } from '@arclux/arc-ui-angular';

@Component({
  imports: [Progress],
  template: `
    <div style="display: flex; flex-direction: column; width: 100%; gap: var(--space-lg);">
      <Progress [value]="65" label="Uploading project files..." />
      <Progress variant="spinner" indeterminate label="Processing upload" />
    </div>
  `,
})
export class FileUploadStatusComponent {}
import { Progress } from '@arclux/arc-ui-solid';

export function FileUploadStatus() {
  return (
    <div style={{ display: 'flex', 'flex-direction': 'column', width: '100%', gap: 'var(--space-lg)' }}>
      <Progress value={65} label="Uploading project files..." />
      <Progress variant="spinner" indeterminate label="Processing upload" />
    </div>
  );
}
import { Progress } from '@arclux/arc-ui-preact';

export function FileUploadStatus() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', width: '100%', gap: 'var(--space-lg)' }}>
      <Progress value={65} label="Uploading project files..." />
      <Progress variant="spinner" indeterminate label="Processing upload" />
    </div>
  );
}
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-progress — requires progress.css + base.css (or arc-ui.css) -->
<div class="arc-progress">
  <div>
   Label
   <div
   class="progress__spinner"
   role="progressbar"
   aria-valuenow="Indeterminate"
   aria-valuemin="0"
   aria-valuemax="100"
   aria-label="Label"
   >
   <svg viewBox="0 0 44 44">
   <circle class="progress__spinner-track" cx="22" cy="22" r="20"></circle>
   <circle class="progress__spinner-fill" cx="22" cy="22" r="20"></circle>
   </svg>
   </div>
   </div>
</div>
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-progress — self-contained, no external CSS needed -->
<style>
  @media (prefers-reduced-motion: reduce) {
    .arc-progress .progress__fill,
        .arc-progress .progress__spinner svg,
        .arc-progress .progress__spinner-fill { animation: none; }
  }
</style>
<div class="arc-progress" style="display: block">
  <div>
   Label
   <div
   class="progress__spinner" style="display: inline-block"
   role="progressbar"
   aria-valuenow="Indeterminate"
   aria-valuemin="0"
   aria-valuemax="100"
   aria-label="Label"
   >
   <svg viewBox="0 0 44 44">
   <circle style="fill: none; stroke: rgb(24, 24, 30); stroke-width: 3" cx="22" cy="22" r="20"></circle>
   <circle class="progress__spinner-fill" style="fill: none; stroke: rgb(77, 126, 247); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 80, 200; stroke-dashoffset: 0; animation: spinner-dash 1.4s ease-in-out infinite" cx="22" cy="22" r="20"></circle>
   </svg>
   </div>
   </div>
</div>

API

Prop Type Default Description
value number 0 Current completion percentage from 0 to 100. Only meaningful in determinate mode. The bar fills proportionally and aria-valuenow updates to match, giving screen readers a live reading.
variant 'bar' | 'spinner' 'bar' Selects the visual shape. Bar renders a horizontal track with a fill that grows from left to right — best for wide containers and known percentages. Spinner renders a circular indicator suited to compact inline or button contexts.
size 'sm' | 'md' | 'lg' 'md' Controls the thickness of the bar track or the diameter of the spinner. Small (sm) fits inside table cells and tight layouts. Medium (md) is the standard default. Large (lg) is appropriate for page-level or hero loading states.
indeterminate boolean false When true, the bar pulses or the spinner loops without a fixed endpoint. Use this when the total work is unknown. Switch to determinate (indeterminate=false) and set a value as soon as real progress data becomes available.
label string Accessible label text applied as aria-label on the underlying progressbar role element. This is the only way screen readers can convey the purpose of the indicator. Always provide a meaningful label such as "Uploading report.pdf" rather than a generic "Loading".
show-value boolean false Displays the current percentage value next to the label.

See Also