ProgressBar
Determinate, indeterminate, segmented, and stateful progress feedback.
Usage
Stateful Progress
Loading demo...
Upload progress
:::TuffDemoWrapper{demo="ProgressBarUploadDemo" code-lang="vue" description="The text row sits above the track: the label takes the fill colour and detail is muted behind a separator dot. The default track has no rim, the fill fades in toward the tip, and the tip carries a soft glow. flow-effect=\"stardust\" drifts two depths of white star points over the fill, the near layer twinkling; it sits on a flat colour or on your own gradient alike, and a gradient bar's tip glow turns white to match."}
code: |
<script>
import { ref } from 'vue'
const percentage = ref(65)
</script>
Segments
Hover a segment: it lifts, its neighbours dim, and a tip shows the segment's `label` with its share of `segmentsTotal`. Leave room above the bar for the tip.
Loading demo...
Dashboard Operations Progress
Operations status panel
Progress bars combine with metric cards and status badges to express dashboard health.
Loading demo...
Status Panel
Loading demo...
Best Practices
- Use
percentageonly for known progress. Useloadingorindeterminatewhen duration is unknown. - Do not fake 100% for success states; pass
successwith a message when the operation is complete. - Keep
messageshort because it is also used for the progressbar accessible label. - Use
segmentsTotalto keep segmented bars honest when segments represent a partial total. - Reserve animated effects for high-value progress moments; excessive shimmer/wave/stardust usage makes dashboards noisy.
- Give every segment a
label: the hover tip is the only place a segmented bar explains what each colour stands for. - The default is a flat, rimless track. Pass
maskBackgroundexplicitly (withmaskVariant="solid"for a rim) when you need a blurred or glass track instead of relying on the old default. - For uploads and downloads with a known size, put the "how much so far" copy in
textPlacement="top"+detailrather than inmessage, which doubles as the accessible name.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
loading | boolean | false | Indeterminate loading mode. |
indeterminate | boolean | false | Indeterminate progress mode without implying loading. |
indeterminateVariant | 'classic' | 'sweep' | 'bounce' | 'elastic' | 'split' | 'sweep' | Animation variant for loading/indeterminate states. |
error | boolean | false | Error state. Overrides status. |
success | boolean | false | Success state. Overrides status. |
status | 'success' | 'error' | 'warning' | '' | '' | Visual status tone. |
message | string | '' | Visible/accessible text label. |
detail | string | '' | Secondary copy such as 1.4 MB of 2.3 MB. Rendered only under textPlacement="top"; never part of the accessible name. |
percentage | number | 0 | Determinate progress value before clamping. |
segments | ProgressSegment[] | - | Multi-segment progress data. |
segmentsTotal | number | 100 | Total used to compute filled width when segments are present. |
height | string | '5px' | Progress bar height. |
showText | boolean | false | Show percentage text for determinate progress. |
textPlacement | 'inside' | 'outside' | 'top' | 'inside' | Location for message/percentage text; top renders a text row (with optional detail) above the track. |
format | (percentage: number) => string | - | Custom percentage formatter. |
flowEffect | 'none' | 'shimmer' | 'wave' | 'stardust' | 'particles' | 'none' | Determinate fill overlay effect. stardust drifts two depths of white star points over the fill; particles is its deprecated alias. Ignored for segments. |
indicatorEffect | 'none' | 'sparkle' | 'none' | Endpoint indicator effect when progress is greater than zero. |
hoverEffect | 'none' | 'glow' | 'none' | Wrapper hover effect. |
color | string | - | Custom fill color. Overrides state color. |
maskVariant | 'solid' | 'dashed' | 'plain' | 'plain' | Track rim style; plain draws no rim. |
maskBackground | 'none' | 'blur' | 'glass' | 'mask' | 'none' | Track mask layer; none renders no mask node and leaves the track a flat tint. |
tooltip | boolean | false | Enable tooltip using resolved text. |
tooltipContent | string | - | Tooltip content override. |
tooltipProps | Partial<TooltipProps> | - | Extra props forwarded to TxTooltip. |
ProgressSegment
| Field | Type | Description |
|---|---|---|
value | number | Segment value. Only positive finite values render. |
color | string | Segment fill color. Falls back to progress fill color. |
label | string | Shown in the segment's hover tip ahead of its share (Video · 25%); without it the tip shows the share alone. |
Events
| Event | Payload | Description |
|---|---|---|
complete | - | Emitted once per completion cycle when resolved progress reaches 100. |
Slots
| Slot | Props | Description |
|---|---|---|
| - | - | TxProgressBar does not expose slots. Use message, format, tooltipContent, and tooltipProps for labels and tooltip content. |
Overview
- The track renders
role="progressbar"witharia-valuemin="0"andaria-valuemax="100". - Determinate progress clamps
percentageto0..100and exposes it asaria-valuenow. loadingandindeterminateomitaria-valuenow; usemessageto describe the work.errorandsuccessboolean props take precedence overstatus.- When
successorerrorhas amessageandpercentageis0, the visual width resolves to100%for completion-style labels. messagewins overformat, andformatwins over the default rounded percentage text.- Text renders only when
messageis present orshowText=true; loading/indeterminate states only show text whenmessageis present.textPlacement="top"follows the same rule asoutsideand renders the text row above the track. detailrenders only undertextPlacement="top", after the label and muted behind a separator dot. It is visible text and never enters the progressbar's accessible name (stillariaLabel>message>Progress).- The default track is a flat 10% tint of the text colour: no
.tx-progress-bar__masknode and no rim.maskVariant="solid" | "dashed"draws the rim; the mask layer renders only whenmaskBackgroundis not'none'. - The fill defaults to
linear-gradient(90deg, faded → saturated); acolorthat is already a gradient string is used verbatim..tx-progress-bar__glowis mounted for every determinate bar that is not segmented, sits outside the track's clipping, and is visible only strictly between 0% and 100%. A gradientcolorhas no single hue, so its glow is white and thetoplabel falls back to the text colour (--tx-progress-glow,--tx-progress-accent). flowEffect="stardust"draws two white point fields over the fill (::beforefar, small and slow;::afternear, larger, faster and twinkling), each tiling by whole tile widths so the drift never shows a seam. Points are sized in px, so a 5px and a 14px bar get the same grain.'particles'is a deprecated alias that renders the same layers. No flow effect draws oversegmentsor while indeterminate.- Width changes ease over 480ms on
--tx-ease-out-strong; the five indeterminate sweeps animate composited properties only (transform, plusopacityonsplit), neverleftorwidth, and stop underprefers-reduced-motion. The travelling sweeps (sweep,classic,elastic) run linear and start and end fully off the track, so the loop point is never on screen and the bar never appears to stall. segmentsignore non-positive values. The filled width usessegmentsTotal; segment widths inside the fill normalize by the sum of positive segment values. Each segment paints its colour on an inner.tx-progress-bar__segment-filland carries adata-tipoflabel · share%(share ofsegmentsTotal, or the share alone without a label). On hover the fill scales up, the other segments dim, and the tip rises above the bar; a segmented track setsoverflow: visibleto give the lift room.completeemits once when resolved progress reaches100, and can emit again after progress drops below100and completes again.tooltiportooltipContentwraps the bar inTxTooltip;tooltipPropsare forwarded to that tooltip.
Technologies
- Reviewed against
packages/tuffex/packages/components/src/progress-bar/src/types.ts,TxProgressBar.vue, andprogress-bar.test.ts. - Existing tests cover determinate clamping, progressbar ARIA state, indeterminate
aria-valuenowomission,completeonce-per-cycle emission, and segment normalization by positive segment sum. - Verified coverage (2026-09 redesign): no mask node by default and no
--bg-*wrapper class;--tx-progress-fillislinear-gradient(90deg, …)and a gradientcolorpasses through verbatim; the glow node sits outside the track and is hidden or absent at 0% / 100% / indeterminate / segments; thetoptext row's label / detail rendering and visibility rules; every@keyframes tx-progress-*block is free ofleft/width(with a positive control on the extractor); sweeps stop underprefers-reduced-motion. - Verified coverage (stardust and segment hover):
stardustclasses the fill andparticlesresolves to the same class; no flow class over segments or while indeterminate; a gradientcolorkeeps the glow and sets--tx-progress-glow: #fff; segment tips are built fromlabeland the share ofsegmentsTotal(not of the segment sum) in both templates; the colour sits on the inner fill node; the travelling sweeps areinfinite linearand elastic starts at-100%and ends at454.5%; the stardust layers drift by exactly their tile widths and never read--tx-progress-color; the segmented track isoverflow: visible. - Known and left in place: the
hoverEffect="glow"box-shadow and theindicatorEffect="sparkle"sparks both live inside theoverflow: hiddentrack and get clipped to its height; the source carries comments marking both. - API note:
segmentsuse positive values only. The outer fill width is based onsegmentsTotal, while widths inside the fill normalize by the positive segment sum. - Accessibility note: keep
messageshort and status-specific because it is used as the accessible progress label. - Component source:
packages/tuffex/packages/components/src/progress-bar/src/TxProgressBar.vue. - Types:
packages/tuffex/packages/components/src/progress-bar/src/types.ts. - Verified coverage:
packages/tuffex/packages/components/src/progress-bar/__tests__/progress-bar.test.tsverifies determinate clamping and ARIA state, indeterminatearia-valuenowomission, once-per-cyclecompleteemits, segment normalization by positive segment sum, the redesign (no mask node by default, gradient fill and glow placement, thetoptext row, layout-free keyframes and the reduced-motion stop), the stardust flow (class, alias, white glow for gradients, seamless tile drift) and the segment hover (tips, inner fill, visible overflow, linear sweeps).
查看源码
packages/tuffex/packages/components/src/progress-bar/index.ts