Skip to content

Align meter to architecture goals#186

Merged
lifeiscontent merged 2 commits into
mainfrom
align/meter
Jun 24, 2026
Merged

Align meter to architecture goals#186
lifeiscontent merged 2 commits into
mainfrom
align/meter

Conversation

@lifeiscontent

Copy link
Copy Markdown
Collaborator

Closes #135

What changed

The meter component wasn't reflecting the designer's color-breakpoint spec and had a few architecture gaps. This PR tightens both.

Designer spec recap

Always the same (baked in):

  • Horizontal bar, left-to-right fill, rounded track, fixed track height
  • Color breakpoints: suboptimal low → warning, optimal middle → accent, suboptimal high → success

Adjustable (now exposed as props):

  • value, min, max (already on root via Base UI)
  • low, high, optimum thresholds (new on components-tier Meter)
  • label text (already optional on components-tier)
  • showValue — whether the formatted value text is shown (new)

Architecture changes

ui/meter/variants.ts

  • Replaced the hardcoded bg-accent-primary in meterIndicatorVariants with a tone cva variant: lowbg-warning-primary, mediumbg-accent-primary, highbg-success-primary. No defaultVariants — the caller must supply tone.

ui/meter/meter-indicator.tsx

  • Added a required tone: MeterIndicatorTone prop. Passes it straight to the cva call; no cx in the component file.
  • Exported MeterIndicatorTone from the ui and components indexes.

components/meter/meter.tsx

  • Added low, high, optimum props (mirrors native <meter> semantics).
  • Added showValue prop (default true) — when false, MeterValue is not rendered; aria-valuenow on the root still announces the value to assistive tech.
  • Added deriveIndicatorTone helper that computes which of the three cva tones to use from the current value and thresholds: the optimum position determines which segment is "best", and the indicator fill follows automatically.

Stories

  • UI-tier stories: pass tone="medium" on MeterIndicator (required prop).
  • Components-tier stories: added NoValue (showValue=false) and Thresholds (low/high/optimum with three fill levels) stories.

Notes

Needs design review and approval from @bhaveshraja before merge.

@github-actions

Copy link
Copy Markdown

📚 Storybook preview: https://pr-186-propel-storybook.vamsi-906.workers.dev

- Add tone variant (low/warning · medium/accent · high/success) to
  meterIndicatorVariants; remove the hardcoded bg-accent-primary class.
  No defaultVariants — callers supply tone explicitly.
- Make MeterIndicator accept a required `tone` prop and pass it to the
  cva variant.  Export MeterIndicatorTone from both ui and components
  indexes.
- Components-tier Meter gains low/high/optimum threshold props and a
  deriveIndicatorTone helper that mirrors native <meter> semantics:
  which segment is "best" is driven by optimum; the indicator fill
  follows automatically (warning / accent / success).
- Add showValue prop (default true) so callers can hide the formatted
  value text without losing aria-valuenow on the root.
- Update ui-tier and components-tier stories: pass tone="medium" in ui
  stories; add NoValue and Thresholds stories in the components tier.
…tier

The components-tier composition stacked MeterLabel above the track and
MeterValue below it, relying on the root's flex-col. Per the Meter design
spec the label and value sit together on a row above the bar in a fixed
position relationship, so that row is a missing anatomy part.

Add MeterHeader (an anatomy extension beyond Base UI's parts) that owns the
label/value row layout (flex, justify-between, items-center). The components
tier now composes Header › Label + Value, then Track › Indicator, with no raw
class names. Each ui part still renders exactly one element.
@lifeiscontent lifeiscontent merged commit 7f839f1 into main Jun 24, 2026
2 checks passed
@lifeiscontent lifeiscontent deleted the align/meter branch June 24, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Meter: what should always look the same, and what should be adjustable?

1 participant