Components
Progress
See also: Spinner.
Indeterminate
<script setup lang="ts">import { Progress } from "opui-css/vue"</script>
<template> <Progress aria-busy="true" /></template><div class="ui-progress"> <progress><!--[--><!--]--></progress></div>Determinate
<script setup lang="ts">import { onMounted } from "vue"import { Progress } from "opui-css/vue"
onMounted(() => { const progress = document.querySelector("#determinate-progress") if (progress) { setInterval(() => { if (progress.value >= 100) { progress.value = 10 } else { progress.value += 10 } }, 3000) }})</script>
<template> <Progress id="determinate-progress" max="100" value="10" /></template><div class="ui-progress"> <progress id="determinate-progress" max="100" value="10"> <!--[--><!--]--> </progress></div>Variants
Use the variant prop to swap the progress bar track surface for
better contrast on different backgrounds.
<script setup lang="ts">import { Progress } from "opui-css/vue"</script>
<template> <Progress value="25" max="100" variant="default" /> <Progress value="50" max="100" variant="filled" /> <Progress value="75" max="100" variant="tonal" /></template><!--[--><div class="ui-progress ui-default"> <progress max="100" value="25"><!--[--><!--]--></progress></div><div class="ui-progress ui-filled"> <progress max="100" value="50"><!--[--><!--]--></progress></div><div class="ui-progress ui-tonal"> <progress max="100" value="75"><!--[--><!--]--></progress></div><!--]-->Accessibility
If the <progress> element is describing the loading progress
of a section of a page:
- use
aria-describedbyto point to the status -
set
aria-busy="true"on the section that is being updated, removing it when loading is finished.
Source: MDN
Content here is loading.
API
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | string | - | The current value of the progress bar. |
max | number | string | - | The maximum value of the progress bar. |
aria-busy | "true" | "false" | boolean | - | Indicates that the element or its content is being modified. |
aria-label | string | - | Accessible label for the progress bar. |
variant | 'filled' | 'default' | 'tonal' | 'default' | Adjusts the progress bar background color for better contrast on different surfaces. |
Installation
@layer components.root { :where(.ui-progress) { --_motion: var(--motion, 1); --_accent-color: var(--primary); --_bg-color: var(--surface-tonal);
background-color: var(--_bg-color); block-size: var(--size-1); border-radius: var(--border-radius, 0.25rem); display: inline-block; inline-size: 100%; overflow: hidden; position: relative; vertical-align: baseline;
/* Color */ &.ui-filled { --_bg-color: var(--surface-filled); }
&.ui-default { --_bg-color: var(--surface-default); }
&.ui-tonal { --_bg-color: var(--surface-tonal); }
& > progress { appearance: none; background: none; block-size: 100%; border: 0; display: block; inline-size: 100%;
&::-webkit-progress-bar { background: none; border-radius: var(--border-radius, 0.25rem); }
&[value]::-webkit-progress-value { background-color: var(--_accent-color); transition: inline-size calc(0.2s * var(--_motion)) var(--ease-out-4, cubic-bezier(0, 0, 0.1, 1)); }
&::-moz-progress-bar { background-color: var(--_accent-color); } } }
:where(.ui-progress):has(> progress:indeterminate) { &::after { animation: indeterminate calc(2s * var(--motion, 1)) linear infinite; background-color: var(--_accent-color); content: ""; inset: 0 auto 0 0; position: absolute; will-change: inset-inline-start, inset-inline-end; }
& > progress { &::-webkit-progress-value { background-color: transparent; }
&::-moz-progress-bar { background-color: transparent; } } }
[dir="rtl"] { :where(.ui-progress):has(> progress:indeterminate) { &::after { animation-direction: reverse; } } }
@keyframes indeterminate { 0% { inset-inline-start: -200%; inset-inline-end: 100%; }
60% { inset-inline-start: 107%; inset-inline-end: -8%; }
100% { inset-inline-start: 107%; inset-inline-end: -8%; } }}