Package-level declarations

Meter displays a numeric value as a circular progress ring with configurable content inside.

When to Use

  • Showing a KPI value or completion percentage at a glance

  • Dashboards, hero stats, or list items requiring compact progress indicators

  • Any measurable value on an arbitrary float range, not just percentages

Variants

VariantSizeContent
Meter.CircularMedium / Large / XLargeContent inside the ring via CircularMeterContent
Meter.CircularSmallSmall (24dp, fixed)Value text rendered outside the ring
CircularCircularSmall
CircularCircularSmall

API

Meter.Circular

fun Meter.Circular(
value: Float,
content: CircularMeterContent,
modifier: Modifier = Modifier,
range: ClosedFloatingPointRange<Float> = MeterDefaults.Range,
intent: MeterIntent = MeterDefaults.Intent,
size: CircleMeterSize = MeterDefaults.Size,
contentDescription: String? = null,
) {}
ParameterDefaultNotes
valueCurrent value within range
contentWhat to render inside the ring; see Content Types
range0f..100fAccepts any float range, e.g. 0f..200f for euros
intentSupportColor intent for indicator and track
sizeLargeMedium, Large, or XLarge
suffixnullAppended to the TalkBack state announcement, suppressing the default "xx percent". E.g. " euros" → "120 euros". null keeps the percentage fallback.

Meter.CircularSmall

fun Meter.CircularSmall(
value: Float,
modifier: Modifier = Modifier,
range: ClosedFloatingPointRange<Float> = MeterDefaults.Range,
intent: MeterIntent = MeterDefaults.Intent,
) {}

CircularSmall is a fixed 24dp ring. It renders the progress value as text outside the ring and exposes no content parameter. Use it in list items, table cells, or sticky bottom bars.

Content Types

Pass a CircularMeterContent instance as the content parameter of Meter.Circular.

TypeRequired fieldsNotes
ValueformatValue: (Float) -> String converts the raw value to a display string; defaults to "${it.toInt()}%"
ValueLabellabelSame formatValue as Value; label is the secondary string below the value
Iconicon, contentDescriptionSparkIcon centred in the ring; tint inherits the intent colour; optional label below
ImagecontentDescription, modelComposable image centred in the ring
CustomcontentFully custom @Composable BoxScope.() -> Unit; attach semantics inside the content block
ValueValueLabelIconImage
ValueValueLabelIconImage

Custom.contentDescription feeds TalkBack directly — no text is derived automatically from arbitrary composable content. Supply it whenever your custom content carries meaning.

Sizes

Small is used internally by Meter.CircularSmall and is not available on Meter.Circular.

SizeDiameterStrokeIcon slotTypical context
Medium64dp5dp24dpKPI cards
Large96dp8dp32dpDashboards or hero KPI (default)
XLarge128dp10dp40dpLarge dashboards or tablets
MediumLargeXLarge
MediumLargeXLarge

Intents

Support (default), Main, Accent, Success, Alert, Danger, Info, Neutral.

The intent colour applies to both the progress arc and the icon tint when using CircularMeterContent.Icon.

Usage Examples

Basic value

Meter.Circular(
value = 70f,
content = CircularMeterContent.Value(),
)

Value with label

Meter.Circular(
value = 70f,
content = CircularMeterContent.ValueLabel(label = "Complete"),
size = CircleMeterSize.Large,
)

Icon content

Meter.Circular(
value = 3f,
range = 0f..5f,
content = CircularMeterContent.Icon(
icon = SparkIcons.StarFill,
contentDescription = "Rating: 3 out of 5",
label = "Rating",
),
intent = MeterIntent.Accent,
)

Non-percentage range with accessible suffix

Meter.Circular(
value = 120f,
range = 0f..200f,
content = CircularMeterContent.Value(formatValue = { "€${it.toInt()}" }),
suffix = " euros",
intent = MeterIntent.Success,
)
// TalkBack announces: "€120 euros" instead of "60 percent"

Custom content

Meter.Circular(
value = 42f,
content = CircularMeterContent.Custom(
contentDescription = "42 new messages",
) {
Text(text = "42", style = SparkTheme.typography.display3)
},
)

CircularSmall

Meter.CircularSmall(
value = 70f,
intent = MeterIntent.Support,
)

Accessibility

  • Meter.Circular exposes ProgressBarRangeInfo with the raw value and range so switch access and other tools can use them. TalkBack announces "48 of 56" for value = 48f, range = 0f..56f when no suffix is set.

  • For Value and ValueLabel content, stateDescription is derived automatically from formatValue so TalkBack announces the formatted string rather than a computed percentage. This prevents doubled announcements (e.g. "89 percent 70") when the range is not 0–100.

  • For Icon, Image, and Custom content, stateDescription is only set when suffix is provided; otherwise TalkBack falls back to its own "xx of yy" or "xx percent" computation.

  • Icon and Image carry a mandatory contentDescription field used as the node's accessible label.

  • Custom callers must attach their own semantics inside the content block.

  • To override the node label, apply Modifier.semantics { contentDescription = "…" } on the call site.

  • Meter.CircularSmall merges its children into a single semantics node.

Customising the state announcement with suffix

For Value/ValueLabel, TalkBack announces formatValue(value) + suffix. The suffix appends a unit to the derived string:

// TalkBack announces: "120 euros"
Meter.Circular(
value = 120f,
range = 0f..200f,
content = CircularMeterContent.Value(formatValue = { "${it.toInt()}" }),
suffix = " euros",
)

// TalkBack announces: "4.5 stars"
Meter.Circular(
value = 4.5f,
range = 0f..5f,
content = CircularMeterContent.Value(formatValue = { it.toString() }),
suffix = " stars",
)

// suffix = null → TalkBack announces "75%" (from formatValue default)
Meter.Circular(
value = 75f,
content = CircularMeterContent.Value(),
)

Design Guidelines

Refer to the design guidelines and Figma specification for visual and spacing guidelines.

  • Choose Medium for card-level KPIs, Large for dashboard heroes, and XLarge where layout space allows (typically tablets).

  • Use CircularSmall in dense lists or table cells where a full ring would dominate the row.

  • Keep value text concise; truncation inside the ring degrades legibility at Medium size.

Types

Link copied to clipboard
object Meter
Link copied to clipboard
Link copied to clipboard