Skip to content

feat(Progress): add circular variant#6747

Open
aovee wants to merge 10 commits into
nuxt:v4from
aovee:feat/circular-progress
Open

feat(Progress): add circular variant#6747
aovee wants to merge 10 commits into
nuxt:v4from
aovee:feat/circular-progress

Conversation

@aovee

@aovee aovee commented Jul 17, 2026

Copy link
Copy Markdown

🔗 Linked issue

Resolves #6151

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Adds circular progress support to UProgress as a variant rather than a separate UCircularProgress component, as suggested in the issue. This keeps a single API surface and lets the existing color, size, animation, inverted, status and orientation props carry over.

<UProgress variant="circular" :model-value="75" status />

What's included

  • variant proplinear (default) or circular. Defaults preserve current behaviour, so this is non-breaking.
  • SVG-based rendering — the circular variant renders a <circle> track plus a ProgressIndicator circle with pathLength="100", driven by stroke-dasharray. A new track slot is exposed for the background circle.
  • thickness propauto (default) derives the stroke width from size, or pass a number of pixels. Both go through the --ui-progress-thickness CSS variable, which also drives the radius (r: calc(50px - thickness / 2)) so the stroke never overflows the viewBox.
  • Sizes2xs2xl map to both a diameter and a default thickness.
  • Status — for the circular variant the status slot is rendered centered inside the circle instead of above/beside the bar.
  • Indeterminate — all four animation values (carousel, carousel-inverse, swing, elastic) have circular equivalents, added as new keyframes in keyframes.css.
  • inverted — flips the sweep direction of the circle.

Theme refactor

The progress theme has been reorganised so most existing orientation/size/animation compound variants are now scoped under variant: 'linear', with variant: 'circular' counterparts added. Some slot classes moved from slots into the linear variant (e.g. overflow-hidden rounded-full bg-accented on base). Rendered output for the default linear variant is unchanged apart from class ordering — snapshots were updated accordingly (Progress, and Toast which embeds a progress bar).

Playground

playgrounds/nuxt/app/pages/components/progress.vue now exercises the circular variant across sizes, colors, animations and a custom thickness.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@pkg-pr-new

pkg-pr-new Bot commented Jul 18, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/@nuxt/ui@6747

commit: b714c5d

@aovee
aovee marked this pull request as ready for review July 21, 2026 13:54
@aovee
aovee requested a review from benjamincanac as a code owner July 21, 2026 13:54
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7fafcd19-bc7c-4b32-b74c-8967c72d584a

📥 Commits

Reviewing files that changed from the base of the PR and between a795aea and b714c5d.

⛔ Files ignored due to path filters (2)
  • test/components/__snapshots__/Progress-vue.spec.ts.snap is excluded by !**/*.snap
  • test/components/__snapshots__/Progress.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • src/runtime/components/Progress.vue
  • src/runtime/keyframes.css
  • src/theme/progress.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/runtime/keyframes.css
  • src/runtime/components/Progress.vue
  • src/theme/progress.ts

📝 Walkthrough

Walkthrough

The Progress component now supports linear and circular variants with explicit thickness configuration. Circular rendering uses SVG stroke styling, while linear rendering retains orientation, direction, and inversion transforms. The theme adds circular layout, color, status, and animation classes, alongside five circular keyframe animations. The playground and documentation expose the new options, and tests cover all configured variants.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a circular variant to Progress.
Description check ✅ Passed The description is directly related to the circular Progress feature and its implementation.
Linked Issues check ✅ Passed The changes add circular progress support with variant, SVG rendering, thickness, centered status, animations, and inversion as requested.
Out of Scope Changes check ✅ Passed The changes stay within the circular Progress feature, with docs, playground, tests, theme, runtime, and keyframes all in scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/runtime/components/Progress.vue`:
- Around line 217-224: Update the circular branch in Progress.vue around the SVG
element to apply the component’s sizing class to the <svg>, ensuring it fills
the intended square container and preserves the circle’s aspect ratio.
Coordinate this with the circular variant sizing definitions in the progress
theme so the root size propagates through the SVG; leave non-circular rendering
unchanged.
- Around line 217-232: Add data-slot="indicator" to the circular variant’s
indicator <circle> in the Progress component, the same element using
ui.indicator({ class: props.ui?.indicator }). Leave the linear ProgressIndicator
and other markup unchanged.

In `@src/runtime/keyframes.css`:
- Around line 568-572: Update the circular-rotate keyframes to explicitly define
a from state matching the indicator’s static -90deg transform, while preserving
the existing 360deg to state, so each animation loop restarts continuously
without a visible jump.

In `@src/theme/progress.ts`:
- Around line 94-98: Update the circular variant configuration in the theme
definition to provide an explicit base sizing override, matching the sizing
behavior required by the root’s fixed dimensions and centered alignment. Add the
appropriate circular base classes alongside its existing track, indicator, and
status classes, while leaving the linear variant and other circular styling
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ddbd35d0-bbed-4e38-ae10-a61442b9bd49

📥 Commits

Reviewing files that changed from the base of the PR and between 0a1803d and a795aea.

⛔ Files ignored due to path filters (4)
  • test/components/__snapshots__/Progress-vue.spec.ts.snap is excluded by !**/*.snap
  • test/components/__snapshots__/Progress.spec.ts.snap is excluded by !**/*.snap
  • test/components/__snapshots__/Toast-vue.spec.ts.snap is excluded by !**/*.snap
  • test/components/__snapshots__/Toast.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • docs/content/docs/2.components/progress.md
  • playgrounds/nuxt/app/pages/components/progress.vue
  • src/runtime/components/Progress.vue
  • src/runtime/keyframes.css
  • src/theme/progress.ts
  • test/components/Progress.spec.ts

Comment thread src/runtime/components/Progress.vue
Comment thread src/runtime/components/Progress.vue
Comment thread src/runtime/keyframes.css
Comment thread src/theme/progress.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Circular Progress Component

1 participant