Progress
How far along something is. Give it a value from 0 to max, or leave the value out when the length of the wait is not known.
The preview needs JavaScript. The code is in the Code tab.
<template>
<div>
<Progress value="40" label="Uploading photo" />
<Progress value="80" tone="neutral" size="sm" label="Storage used" />
<Progress label="Waiting for the server" />
</div>
</template>
Installation
npx @pixelscriptio/tessera add Progresspnpm exec tessera add Progressyarn tessera add Progressbunx @pixelscriptio/tessera add Progress- Works with Tessera 0.9.0 or newer.
Copy and paste the code into your project
Put it in
system/components.system/components/Progress.tess <contract> { "name": "Progress", "role": "progressbar", "description": "How far along something is. Give it a value from 0 to max, or leave the value out when the length of the wait is not known.", "since": "0.8.0", "parts": ["root", "bar"], "variants": { "size": ["md", "sm"], // first value is the default "tone": ["primary", "neutral", "danger"] }, "preview": { "props": { "value": 60, "label": "Uploading photo" } } } </contract> <script> const { value, max, label } = props({ value: null, max: 100, label: 'Progress' }) const percent = derived(() => { if (value.value === null) return 0 return Math.round(Math.min(Math.max(value.value / max.value, 0), 1) * 100) }) </script> <template> <div class="root" role="progressbar" :aria-label="label" aria-valuemin="0" :aria-valuemax="max" :aria-valuenow="value === null ? null : value" :data-indeterminate="value === null ? 'true' : null" > <div class="bar" :style="value === null ? null : 'width: ' + percent + '%'"></div> </div> </template> <style> .root { position: relative; width: 100%; height: $space.2; overflow: hidden; border-radius: $radius.full; background: $color.surface.hover; &[data-size='sm'] { height: $space.1; } } .bar { height: 100%; border-radius: $radius.full; background: $color.action.primary.bg; transition-duration: $motion.duration.fast; } .root[data-tone='neutral'] .bar { background: $color.text.muted; } .root[data-tone='danger'] .bar { background: $color.action.danger.bg; } .root[data-indeterminate='true'] .bar { width: 40%; animation: slide 1.2s ease-in-out infinite; } @keyframes slide { from { transform: translateX(-100%); } to { transform: translateX(250%); } } @media (prefers-reduced-motion: reduce) { .root[data-indeterminate='true'] .bar { animation: none; width: 100%; opacity: $opacity.disabled; } } </style>Check your design tokens
Your design system needs these.
tessera addreports the ones that are missing; by hand, runnpx @pixelscriptio/tessera check.color.action.danger.bgcolor.action.primary.bgcolor.surface.hovercolor.text.mutedmotion.duration.fastopacity.disabledradius.fullspace.1space.2
Usage
Using Progress
How far along something is.
valueruns from 0 tomax(100 unless you set it). The bar's width and what a screen reader hears are both set from it.- Leave
valueout when you do not know how long it will take: the bar moves back and forth, and the progress bar is announced without a value. - Give it a
labelthat says what is progressing, such asUploading photo. The default isProgress. tone="danger"is for a failed upload that stays on screen.size="sm"is a thinner bar.
The preview needs JavaScript. The code is in the Code tab.
<template>
<div>
<Progress value="40" label="Uploading photo" />
<Progress value="80" tone="neutral" size="sm" label="Storage used" />
<Progress label="Waiting for the server" />
</div>
</template>
API reference
Variants
| Variant | Values |
|---|---|
size | md default sm |
tone | primary default neutral danger |
Anatomy
| Role | progressbar |
| Parts | root bar |
| Since | 0.8.0 |
Design tokens it uses
Your design system needs these. tessera add checks that it has them, and can add the ones it lacks.
color.action.danger.bg color.action.primary.bg color.surface.hover color.text.muted motion.duration.fast opacity.disabled radius.full space.1 space.2
Checksum
6f6fe2f23130a727357aac86bedb1e6334ef1a045474051dd604fed57bd6455f