Skip to main content
Version: Next

Progress

A horizontal or vertical fill bar with an optional numeric readout. One value or several, stacked in a single track. Best for quantities that genuinely represent completion or fill fraction.

The Progress component as it renders with its default settings.The Progress component as it renders with its default settings.

Reach for it when you need:

  • Batch progress
  • Tank fill percentage
  • Order completion
  • A disk or capacity bar split into what is using it

Component name: Progress · Category: Display

In the palette: Progress / fill bar — horizontal or vertical, single- or multi-value, with a numeric readout

Properties

Any property can be bound to a tag, another component's property, or a query.

PropertyTypeDefaultDescription
segmentsarray[{"value":65,"color":"hsl(217 91% 60%)","label":"","show":tr… (truncated)The bar's data — one coloured slice per item, stacked in a single track. ONE item = a classic single-value bar; several = a composition. Each item: { value (a MAGNITUDE, not a position on the scale), color, label, show }. Each item's 'value' is separately bindable to a tag. 1.0.1
stackModeenumabsoluteabsolute = each segment is a magnitude in min…max units; they stack and the sum clips at max (keeps 'how full is it', coloured by what's in it). proportional = segments are normalised against their own sum and always fill the track (share-of-total); min/max do not apply. Options: absolute · proportional. 1.0.1
minnumber0
maxnumber100
orientationenumhorizontalOptions: horizontal · vertical.
reversebooleanfalseFlip the edge the bar fills FROM — right→left when horizontal, top→bottom when vertical (default is left→right / bottom→top).
thicknessnumber14Bar HEIGHT when horizontal, bar WIDTH when vertical (px). 0 = fill the widget box.
radiusnumber999Corner radius (px). 999 = fully rounded ends; 0 = square.
trackColorcolorhsl(var(--muted-foreground) / 0.16)The background (unfilled) part. Segment colours live on the segments.
gapnumber0Hairline of track showing between segments (px). 1.0.1
readoutobject{"position":"end","mode":"percent","unit":"","decimals":0,"c… (truncated)The numeric readout — where it sits and how it formats. Not the value itself. 1.0.1
labelobject{"show":true,"text":"Progress","color":"var(--widget-label)"… (truncated)The caption above the bar. 1.0.1
legendobject{"show":true,"position":"bottom","showValue":true,"color":"v… (truncated)Per-segment key. Nothing is drawn for a bar with a single segment — there is nothing to tell apart. 1.0.1
stylestyle{}Custom CSS properties

Events

Attach event actions to these in the Event Manager.

EventLabelGroupPayload
clickClickMouseThe DOM event.
dblclickDouble clickMouseThe DOM event.
contextmenuRight clickMouseThe DOM event.
mouseenterMouse enterMouseThe DOM event.
mouseleaveMouse leaveMouseThe DOM event.
Right-click behaves differently in the Designer

contextmenu fires your configured actions at runtime only — in LiveView and in preview. On the Designer canvas the right-click is captured to open the Event Manager, so testing it there will not run your actions. Test right-click in preview.

Notes

One bar, one or many values

The bar's data is segments — an array, one coloured slice per item, drawn in a single track. One item is an ordinary single-value bar; several are a composition. Each item is { value, color, label, show }, and each item's value is separately bindable, so a three-part bar can take its three numbers from three different tags.

There is no top-level value or fillColor. A single input is the whole point: with two, each one sat inert depending on the other — value drew the bar only while segments was empty, and fillColor painted only the slice that named no colour of its own — which is the "why does this control do nothing?" trap the rest of this schema is arranged to avoid.

absolute or proportional

stackMode decides what a segment's number means, and it is the setting people get wrong:

ModeA segment's value ismin/maxThe track
absolute (default)a magnitude in minmax unitsapplyfills as far as the segments sum to, clipping at max
proportionala share, normalised against the sum of the segmentsignoredalways completely full

Use absolute when "how full is it?" is the question and the colours only say what is in there — a 500 L tank holding 200 L of product and 50 L of water is half empty, and the bar should show that. Use proportional when the question is share-of-total and the parts are the whole of it — the split of today's output across three grades.

A segment carries a magnitude, not a position on the scale. Three segments of 30, 20 and 10 in absolute mode fill to 60 — they are not marks at 30, 20 and 10.

Example — a disk bar in two parts

stackMode: absolute
min / max: 0 / 500 (GB)
gap: 1
segments:
{ value: 180, color: "hsl(217 91% 60%)", label: "History", show: true }
{ value: 40, color: "hsl(43 96% 56%)", label: "Backups", show: true }
readout: { position: "end", mode: "value", unit: " GB", decimals: 0 }

The bar fills to 220 of 500, in two colours, with a key underneath naming each. Bind each value to its own tag and it tracks both independently.

Presentation is grouped

The three text elements are objects rather than a flat list of labelColor / valueSize properties:

  • label — the caption above the bar: { show, text, color, size }.
  • readout — the number itself: { position, mode, unit, decimals, color, size }. mode is percent (progress through minmax) or value (the raw number plus unit).
  • legend — the per-segment key: { show, position, showValue, color, size }. Nothing is drawn for a single-segment bar, because there is nothing to tell apart.

Gotchas

  • show: false removes a segment from the bar, not just from the key. Hiding a slice changes the total in absolute mode and re-normalises the rest in proportional mode.
  • gap is a hairline of track showing between segments, so it eats into the fill. Leave it at 0 for a single-value bar, where the gap has nothing to separate.
  • thickness is height when horizontal and width when vertical, and 0 means "fill the widget box" — which is usually what you want inside a tight container.