{"slug":"circular-progress","title":"Circular Progress","description":"Using the circular progress machine in your project.","contentType":"component","framework":"react","content":"Circular progress is a circular progress bar that can be used to show the\nprogress of a task such as downloading a file, uploading an image, etc.\n\n## Resources\n\n\n[Latest version: v1.31.0](https://www.npmjs.com/package/@zag-js/progress)\n[Logic Visualizer](https://zag-visualizer.vercel.app/progress)\n[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/progress)\n\n\n\n**Features**\n\n- Support for minimum and maximum values\n- Support for indeterminate progress bars\n\n## Installation\n\nTo use the progress machine in your project, run the following command in your\ncommand line:\n\n```bash\nnpm install @zag-js/progress @zag-js/react\n# or\nyarn add @zag-js/progress @zag-js/react\n```\n\n## Anatomy\n\nTo set up the progress correctly, you'll need to understand its anatomy and how\nwe name its parts.\n\n> Each part includes a `data-part` attribute to help identify them in the DOM.\n\n\n\n## Usage\n\nFirst, import the progress package into your project\n\n```jsx\nimport * as progress from \"@zag-js/progress\"\n```\n\nThe progress package exports two key functions:\n\n- `machine` — The state machine logic for the progress widget.\n- `connect` — The function that translates the machine's state to JSX attributes\n  and event handlers.\n\n> You'll also need to provide a unique `id` to the `useMachine` hook. This is\n> used to ensure that every part has a unique identifier.\n\nNext, import the required hooks and functions for your framework and use the\nprogress machine in your project 🔥\n\n```jsx\nimport * as progress from \"@zag-js/progress\"\nimport { normalizeProps, useMachine } from \"@zag-js/react\"\nimport { useId } from \"react\"\n\nfunction Progress() {\n  const service = useMachine(progress.machine, { id: useId() })\n\n  const api = progress.connect(service, normalizeProps)\n\n  return (\n    <div {...api.getRootProps()}>\n      <div {...api.getLabelProps()}>Upload progress</div>\n      <svg {...api.getCircleProps()}>\n        <circle {...api.getCircleTrackProps()} />\n        <circle {...api.getCircleRangeProps()} />\n      </svg>\n    </div>\n  )\n}\n```\n\n### Setting the value\n\nPass the `defaultValue` or `value` property to the machine function to set the\ninitial value of the progress bar.\n\n```jsx {2}\nconst service = useMachine(progress.machine, {\n  defaultValue: 50,\n})\n```\n\nSubsequently, you can use the `api.setValue` method to set the value of the\nprogress bar.\n\n```jsx\napi.setValue(50)\n```\n\n### Setting the minimum and maximum values\n\nBy default, the progress bar has a minimum value of `0` and a maximum value of\n`100`. You can change these values by passing the `min` and `max` options to the\nmachine.\n\n```jsx {2-3}\nconst service = useMachine(progress.machine, {\n  min: 0,\n  max: 1000,\n})\n```\n\n### Using the indeterminate state\n\nThe progress component is determinate by default, with the value and max set to\n`50` and `100` respectively.\n\nSet `value` to `null` to indicate an indeterminate value for operations whose\nprogress can't be determined (e.g., attempting to reconnect to a server).\n\n```jsx {2}\nconst service = useMachine(progress.machine, {\n  defaultValue: null,\n})\n```\n\n### Showing a value text\n\nProgress bars can only be interpreted by sighted users. To include a text\ndescription to support assistive technologies like screen readers, use the\n`valueText` part.\n\n```jsx\nconst service = useMachine(progress.machine, {\n  translations: {\n    valueText: ({ value, max }) =>\n      value == null ? \"Loading...\" : `${value} of ${max} items loaded`,\n  },\n})\n```\n\n### Setting the size of the progress bar\n\nUse the `--size` CSS variable to set the size of the progress bar.\n\n```css\n[data-scope=\"progress\"][data-part=\"circle\"] {\n  --size: 400px;\n}\n```\n\n### Setting the thickness of the progress bar\n\nUse the `--thickness` CSS variable to set the size of the progress bar.\n\n```css\n[data-scope=\"progress\"][data-part=\"circle\"] {\n  --thickness: 4px;\n}\n```\n\nThen you need to render the `valueText` part in your component.\n\n```jsx\n<div {...api.getValueTextProps()}>{api.valueAsString}</div>\n```\n\n## Styling guide\n\nEarlier, we mentioned that each menu part has a `data-part` attribute added to\nthem to select and style them in the DOM.\n\n```css\n[data-scope=\"progress\"][data-part=\"root\"] {\n  /* Styles for the root part */\n}\n\n[data-scope=\"progress\"][data-part=\"circle-track\"] {\n  /* Styles for the track part */\n}\n\n[data-scope=\"progress\"][data-part=\"circle-range\"] {\n  /* Styles for the range part */\n}\n```\n\n### Indeterminate state\n\nTo style the indeterminate state, you can use the `[data-state=indeterminate]`\nselector.\n\n```css\n[data-scope=\"progress\"][data-part=\"root\"][data-state=\"indeterminate\"] {\n  /* Styles for the root indeterminate state */\n}\n\n[data-scope=\"progress\"][data-part=\"circle-track\"][data-state=\"indeterminate\"] {\n  /* Styles for the root indeterminate state */\n}\n\n[data-scope=\"progress\"][data-part=\"circle-range\"][data-state=\"indeterminate\"] {\n  /* Styles for the root indeterminate state */\n}\n```\n\n## Methods and Properties\n\n### Machine Context\n\nThe progress machine exposes the following context properties:\n\n<ContextTable name=\"progress\" />\n\n### Machine API\n\nThe progress `api` exposes the following methods:\n\n<ApiTable name=\"progress\" />\n\n### Data Attributes\n\n<DataAttrTable name=\"progress\" />","package":"@zag-js/progress","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/components/circular-progress.mdx"}