Skill
A measure within a known range: that is exactly what the meter role
describes, which the gauge carries. The value is therefore announced, whether it
is shown as a figure or not.
A gauge
Target: 90% on the shipped modules.
<Skill name="Accessibility" level={85} />
<Skill name="Test coverage" level={64}>
Target: 90%.
</Skill>
Content passed as a child becomes a comment under the bar.
As a circle
shape="circle" draws a dial rather than a bar. Useful when the gauges are
few and you want them to stand out.
<Skill name="Accessibility" level={85} shape="circle" />
The circle is a decorative SVG: its wrapper carries the role and the value, so what is announced does not depend on what is drawn.
Its radius gives it a circumference of exactly a hundred units. The level then
goes as is into stroke-dasharray, with no multiplication or rounding — and
the entry animation only has to start from zero.
Size
It is set through --dp-skill-size, on the gauge or on what surrounds it.
<div style={{ '--dp-skill-size': '4rem' }}>
<Skill name="Smaller" level={70} shape="circle" />
</div>
With a comment
Two languages out of five.
Without the figure
There again, the figure leaves the screen but not what the gauge announces.
With an icon and a colour
icon goes before the name — a LogoIcon fits there.
color tints the fill and the icon: both designate the same thing, and
seeing them match helps read a column of gauges at a glance.
<Skill name="Speed" level={92} color="#f59e0b" icon={<LogoIcon src="./icons/lightning.svg" />} />
color accepts any CSS colour. Without it, the theme's accent colour applies.
As a circle too
Tinting a whole group
The tint goes through --dp-skill-color: setting it on a container applies to
every gauge it holds.
<div style={{ '--dp-skill-color': '#0ea5e9' }}>
<Skill name="First" level={70} />
</div>
The bounds
level goes from 0 to 100. Both extremes render with no special case.
Without the figure
<Skill name="Restraint" level={70} showValue={false} />
showValue={false} removes the percentage from the screen only: the gauge
keeps announcing it to screen readers. Hiding a piece of information is not
deleting it.
A dashboard
Several gauges in columns, each in its card.
Two languages out of five.
Styling the gauge
The component classes live below the utilities: a className set at use wins.
The gauge takes its colour from --dp-skill-color, which an arbitrary
property sets:
<Skill className="[--dp-skill-color:#10b981]" name="Green fill" level={78} />A selector written in a class, such as [&_.dp-skill-fill]:…, would not do:
its & reaches the HTML as &, and the stylesheet — compiled from the
rendered pages — never receives the rule.
The fill
It animates as it enters the viewport, through animation-timeline: view(),
over a range wide enough for the movement to be seen rather than flicker.
Where that property is missing, or if the system asks for less motion, the bar
is full from the start — the value stays readable, which is what matters.
What it refuses
A level outside 0–100 stops the build, as does a gauge without a name, a level
that is not a number, or an unknown shape. A silent or overflowing bar goes
unnoticed on review.
DocPensieve