ZYVOPMulti-Platform Sync
SeriesAI NewsWhy ZyVOPJoin Discord
LoginGet Started
ZYVOPMulti-Platform Sync

The Developer Publishing Hub. Write once, publish everywhere, and make your work citation-ready with built-in SEO, AEO, and GEO discovery support. Zero reader paywalls.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • Why ZyVOP
  • Developer API & CLI
  • Write for Us
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

ยฉ 2026 ZyVOP. Developer Publishing Hub.

Zero paywalls ยท Full content ownership
All systems operational
HomeMantine Rings Progress - A Complete Rewrite Inspired by Apple Watch

Mantine Rings Progress - A Complete Rewrite Inspired by Apple Watch

Giovambattista Fazioli
Giovambattista Fazioli
Senior Full-stack Engineer, Lead DeveloperSupport
September 4, 2026
4 min read
Mantine Rings Progress - A Complete Rewrite Inspired by Apple Watch
#webdev#Programming#JavaScript#react

The concentric ring progress component for Mantine gets a major upgrade: native RingProgress, glow effects, staggered animations, unified tooltips, and full accessibility โ€” all in one release.

Introduction

Version 3.0.0 of @gfazioli/mantine-rings-progress is a ground-up rewrite. The internal fork of Mantine's RingProgress has been completely removed, replaced by the native component from @mantine/core. This eliminates ~600 lines of custom SVG and animation code while adding 10 new features that bring the component closer to the Apple Watch activity rings experience.

Whether you're building fitness dashboards, goal trackers, or compact data visualizations, this release gives you the tools to make your rings shine โ€” literally.

โœจ New Features

Per-ring Customization

Each ring can now override global props individually. Mix thick and thin rings, toggle round caps per ring, or set a custom background track color:

const rings = [{ value: 40, color: 'cyan', thickness: 18 },{ value: 65, color: 'red', thickness: 10, roundCaps: false },{ value: 90, color: '#f90', thickness: 6, rootColor: 'gray' },];

<RingsProgress size={180} rings={rings} />

Enter fullscreen mode Exit fullscreen mode

Supported per-ring overrides: thickness, roundCaps, rootColor, glowIntensity, glowColor, ariaLabel, tooltip.

Staggered Entrance Animation

Instead of all rings appearing at once, use staggerDelay to animate them one after another โ€” outer ring first, inner ring last:

<RingsProgress animate staggerDelay={300} transitionDuration={1000} rings={rings} />

Enter fullscreen mode Exit fullscreen mode

Glow / Neon Effect

Glow

Add a neon-like glow that follows the ring shape using CSS drop-shadow. Set glow={true} for a default 6px blur, or pass a custom radius. Each ring can override the effect with glowIntensity and glowColor:

<RingsProgress glow={8} rings={rings} />

Enter fullscreen mode Exit fullscreen mode

Pulse on Completion

When a ring reaches 100%, trigger a satisfying scale + brightness pulse animation โ€” inspired by the Apple Watch ring closure celebration:

<RingsProgress pulseOnComplete rings={rings} />

Enter fullscreen mode Exit fullscreen mode

The animation respects prefers-reduced-motion and uses a data-pulsing attribute for CSS customization.

onRingComplete Callback

Run custom logic when a ring crosses the 100% threshold:

<RingsProgressonRingComplete={(index, ring) => {
    showNotification({ message: `${ring.color} ring completed!` });}}rings={rings}/>

Enter fullscreen mode Exit fullscreen mode

Start Angle & Direction

Control where rings start filling and in which direction:

<RingsProgress startAngle={90} direction="counterclockwise" rings={rings} />

Enter fullscreen mode Exit fullscreen mode

startAngle={0} is the 12 o'clock position (default). Direction accepts 'clockwise' or 'counterclockwise'.

Unified Tooltip

The new withTooltip prop shows a single, chart-style tooltip with color swatches for all rings โ€” no more overlapping per-ring tooltips:

<RingsProgresswithTooltiprings={[
    { value: 20, color: 'green', tooltip: 'Fitness โ€“ 40 Gb' },
    { value: 80, color: 'blue', tooltip: 'Running โ€“ 50 min' },]}/>

Enter fullscreen mode Exit fullscreen mode

If tooltip is not set on a ring, the percentage value is shown automatically.

Accessibility

The component is now fully accessible out of the box:

  • Root element: role="group" with aria-label="Progress rings" (overridable)

  • Each ring: role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax

  • Per-ring ariaLabel for custom screen reader text

  • Automatic prefers-reduced-motion support via useReducedMotion

๐Ÿ’ฅ Breaking Changes

This is a major release with breaking changes. Here's what you need to update:

Animation props renamed/removed

  <RingsProgress
-   animationDuration={1000}
-   animationSteps={60}
-   animationTimingFunction="ease"
+   transitionDuration={1000}
    animate
    rings={rings}
  />

Enter fullscreen mode Exit fullscreen mode

  • animationDuration โ†’ transitionDuration (default changed from 1000 to 0)

  • animationSteps โ€” removed (CSS transitions replaced JS setInterval)

  • animationTimingFunction โ€” removed (CSS uses ease by default)

Tip: If you only use animate for entrance animation, you can omit transitionDuration entirely โ€” the component auto-applies 1000ms during the entrance phase.

Ring type changed

- import { RingProgressSection } from '@gfazioli/mantine-rings-progress';
- const rings: RingProgressSection[] = [...]
+ import { RingsProgressRing } from '@gfazioli/mantine-rings-progress';
+ const rings: RingsProgressRing[] = [...]

Enter fullscreen mode Exit fullscreen mode

The base properties (value, color, tooltip) remain the same, so existing code that only uses those will work without changes.

Props interface

RingsProgressProps now extends BoxProps + StylesApiProps + ElementProps<'div'> (standard Mantine pattern) instead of the forked RingProgressProps. All common props (size, thickness, roundCaps, label, animate) are still available.

Styles API

A new 'label' style name was added. Style names are now 'root' | 'ring' | 'label'.

๐Ÿ”ง Improvements

Drastically simplified internals

The entire forked RingProgress/ directory (~600 lines) has been deleted. The component now delegates entirely to Mantine's native RingProgress, ensuring better compatibility with future Mantine releases and smaller bundle size.

Smart entrance animation

The component auto-applies 1000ms transition during the entrance phase only. After all rings mount, transitionDuration reverts to 0 โ€” preventing geometry changes (like resizing) from triggering unwanted CSS transitions.

Interactive demos

The documentation now includes replay buttons for animation demos, interactive sliders for the pulse demo, and a configurator with all new props.

๐Ÿ› Bug Fixes

  • Label centering: Fixed the label being offset from center โ€” now rendered as a separate overlay

  • Debug styles: Removed hardcoded color: 'red' on the label

  • Theme overrides: Fixed useProps('Rings', ...) โ†’ useProps('RingsProgress', ...)

  • Countdown demo: Added transitionDuration={0} to prevent CSS transitions from interfering with rapid updates

Getting Started

npm install @gfazioli/mantine-rings-progress@3

Enter fullscreen mode Exit fullscreen mode

Import styles at the root of your application:

import '@gfazioli/mantine-rings-progress/styles.css';

Enter fullscreen mode Exit fullscreen mode

Basic usage with the new features:

import { RingsProgress } from '@gfazioli/mantine-rings-progress';

function ActivityRings() {const rings = [
    { value: 75, color: 'green', tooltip: 'Move' },
    { value: 50, color: 'blue', tooltip: 'Exercise' },
    { value: 90, color: 'orange', tooltip: 'Stand' },];

  return (
    <RingsProgress
      size={180}
      rings={rings}
      animate
      staggerDelay={300}
      glow={6}
      withTooltip
      pulseOnComplete
      onRingComplete={(i) => console.log(`Ring ${i} done!`)}
    />);}

Enter fullscreen mode Exit fullscreen mode

Links

  • ๐Ÿ“ฆ npm package

  • ๐Ÿ“– Documentation & Demos

  • ๐Ÿ”— GitHub Repository

  • ๐Ÿงฉ Mantine Extensions Hub

Comments (0)

Login to post a comment.

Giovambattista Fazioli
Giovambattista Fazioli

Senior Full-stack Engineer, Lead Developer

Italian Senior Full-stack Engineer and Lead Developer on the Cloud team at Namecheap. I build developer tools, React/Mantine UI components and native macOS apps โ€” mostly open source. I work across TypeScript, Next.js, Go and SwiftUI, and I've been coding since the Commodore/Assembly days. Creator of WP Bones and 25+ Mantine extensions, and maintainer of the Undolog open-source studio.

Support
Subscribe to Giovambattista Fazioli's Newsletter

More from Giovambattista Fazioli

View profile

FinderGit 0.29.0 โ€” open a commit like a folder

Thereโ€™s a moment, reading a commit list, where you want to know one small thing: which files did that one touch?

3 minSep 4

Netfox 0.18.0 โ€” is it my connection, or the internet?

There is a question that comes up every time something feels slow, and until now Netfox could not...

3 minSep 4

Mantine Book โ€” Grab Any Edge, Turn Any Page

A realistic iBooks-style book for React built on Mantine: stack two-sided pages and turn them by...

5 minSep 4

Netfox โ€” The macOS app that never loses track of your network

I built Netfox because every existing answer to "what's actually on my network?" annoyed me. The...

5 minSep 4

Audio That Sees Itself

A Mantine-native audio player for React with waveform visualisation and a live spectrum analyser,...

5 minSep 4