Progress
Progress is a simple progress bar that can be used to show the progress of a task such as downloading a file, uploading an image, etc.
Features
- Support for linear and circular progress bars.
- Support for minimum and maximum values.
- Support for indeterminate progress bars.
Installation
To use the progress machine in your project, run the following command in your command line:
npm install @zag-js/progress @zag-js/react # or yarn add @zag-js/progress @zag-js/react
npm install @zag-js/progress @zag-js/solid # or yarn add @zag-js/progress @zag-js/solid
npm install @zag-js/progress @zag-js/vue # or yarn add @zag-js/progress @zag-js/vue
npm install @zag-js/progress @zag-js/vue # or yarn add @zag-js/progress @zag-js/vue
This command will install the framework agnostic progress logic and the reactive utilities for your framework of choice.
Anatomy
To set up the progress correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute to help identify them in the DOM.
Usage
First, import the progress package into your project
import * as progress from "@zag-js/progress"
The progress package exports two key functions:
machine— The state machine logic for the progress widget.connect— The function that translates the machine's state to JSX attributes and event handlers.
You'll also need to provide a unique
idto theuseMachinehook. This is used to ensure that every part has a unique identifier.
Next, import the required hooks and functions for your framework and use the progress machine in your project 🔥
import * as progress from "@zag-js/progress" import { normalizeProps, useMachine } from "@zag-js/react" import { useId } from "react" function Progress() { const [state, send] = useMachine(progress.machine({ id: useId() })) const api = progress.connect(state, send, normalizeProps) return ( <div {...api.rootProps}> <div {...api.labelProps}>Upload progress</div> <div {...api.trackProps}> <div {...api.rangeProps} /> </div> </div> ) }
import * as progress from "@zag-js/progress" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId } from "solid-js" function Progress() { const [state, send] = useMachine(progress.machine({ id: useId() })) const api = createMemo(() => progress.connect(state, send, normalizeProps)) return ( <div {...api().rootProps}> <div {...api().labelProps}>Upload progress</div> <div {...api().trackProps}> <div {...api().rangeProps} /> </div> </div> ) }
import * as progress from "@zag-js/progress" import { normalizeProps, useMachine } from "@zag-js/vue" import { defineComponent, h, Fragment, computed } from "vue" export default defineComponent({ name: "Progress", setup() { const [state, send] = useMachine(progress.machine({ id: "1" })) const apiRef = computed(() => progress.connect(state.value, send, normalizeProps), ) return () => { const api = apiRef.value return ( <div {...api.rootProps}> <div {...api.labelProps}>Upload progress</div> <div {...api.trackProps}> <div {...api.rangeProps} /> </div> </div> ) } }, })
<script setup> import * as progress from "@zag-js/progress" import { normalizeProps, useMachine } from "@zag-js/vue" import { computed } from "vue" const [state, send] = useMachine(progress.machine({ id: "1" })) const api = computed(() => progress.connect(state.value, send, normalizeProps), ) </script> <template> <div v-bind="api.rootProps"> <div v-bind="api.labelProps">Upload progress</div> <div v-bind="api.trackProps"> <div v-bind="api.rangeProps" /> </div> </div> </template>
Setting the value
Use the api.setValue method to set the value of the progress bar.
const [state, send] = useMachine( progress.machine({ value: 50, }), )
Setting the minimum and maximum values
By default, the progress bar has a minimum value of 0 and a maximum value of
100. You can change these values by passing the min and max options to the
machine.
const [state, send] = useMachine( progress.machine({ min: 0, max: 1000, }), )
Using the indeterminate state
The progress component is determinate by default, with the value and max set to
50 and 100 respectively.
Set value to null to indicate an indeterminate value for operations whose
progress can't be determined (e.g., attempting to reconnect to a server).
const [state, send] = useMachine( progress.machine({ value: null, }), )
Showing a value text
Progress bars can only be interpreted by sighted users. To include a text
description to support assistive technologies like screen readers, use the
valueText part.
const [state, send] = useMachine( progress.machine({ translations: { valueText: ({ value, max }) => value == null ? "Loading..." : `${value} of ${max} items loaded`, }, }), )
Then you need to render the valueText part in your component.
<div {...api.valueText}>{api.valueText}</div>
Styling guide
Earlier, we mentioned that each menu part has a data-part attribute added to
them to select and style them in the DOM.
[data-scope="progress"][data-part="root"] { /* Styles for the root part */ } [data-scope="progress"][data-part="track"] { /* Styles for the track part */ } [data-scope="progress"][data-part="range"] { /* Styles for the range part */ }
Indeterminate state
To style the indeterminate state, you can use the [data-state=indeterminate]
selector.
[data-scope="progress"][data-part="root"][data-state="indeterminate"] { /* Styles for the root indeterminate state */ } [data-scope="progress"][data-part="track"][data-state="indeterminate"] { /* Styles for the root indeterminate state */ } [data-scope="progress"][data-part="range"][data-state="indeterminate"] { /* Styles for the root indeterminate state */ }
Methods and Properties
Machine Context
The progress machine exposes the following context properties:
valuenumberThe current value of the progress bar.minnumberThe minimum allowed value of the progress bar.maxnumberThe maximum allowed value of the progress bar.translationsIntlTranslationsThe localized messages to use.dir"ltr" | "rtl"The document's text/writing direction.idstringThe unique identifier of the machine.getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.orientationOrientationThe orientation of the element.
Machine API
The progress api exposes the following methods:
valuenumberThe current value of the progress bar.valueAsStringstringThe current value of the progress bar as a string.setValue(value: number) => voidSets the current value of the progress bar.setToMax() => voidSets the current value of the progress bar to the max value.
Edit this page on GitHub