Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3 ProgressRing always displays 100% on iOS for values greater than 0 #3222

Open
3xplosiv3-official opened this issue Feb 16, 2025 · 11 comments
Labels
bug Something isn't working
Milestone

Comments

@3xplosiv3-official
Copy link

Current Behavior

On iOS (Safari), the ProgressRing component does not display progress correctly:

  • If value = 0, it displays correctly as 0% progress.

  • If value > 0 (even 1), it immediately jumps to 100% progress, ignoring the actual value.

  • The issue occurs only in iOS browsers, the component works correctly on desktop browsers.

Expected Behavior

  • ProgressRing should display the correct progress value on iOS just like it does on desktop.

  • The ring should scale between 0% and 100%, rather than jumping to fully completed for any nonzero value.

  • It should maintain smooth transitions on iOS devices.

Steps To Reproduce

  1. Use ProgressRing on an iOS device with the following setup:
<script>
let value= $state(0)
</script>

<ProgressRing value={value} size="size-14" />
<button onclick={() => value = 0}>set 0</button>
<button onclick={() => value = 25}>set 25</button>
<button onclick={() => value = 75}>set 75</button>
  1. Open the page on Safari on iOS.
  2. Click the buttons to change value.
  3. Notice that any value greater than 0 causes the ring to display 100% progress, instead of the expected percentage.

Link to Reproduction / Stackblitz

No response

Environment Information

No response

More Information

No response

@3xplosiv3-official 3xplosiv3-official added the bug Something isn't working label Feb 16, 2025
@endigo9740 endigo9740 added this to the v3.0 (Next) milestone Feb 16, 2025
@nullpointerexceptionkek
Copy link
Contributor

This issue also exist in macOS sarfari

@endigo9740
Copy link
Contributor

endigo9740 commented Feb 19, 2025

I was curious about that, thanks for confirming Null. Here's a screenshot on Safari. It's the same on both Svelte and React.

Image

However Zag's example is working, so this is an implementation issue on our end:

Image

If I was to guess, I'd assume the way we're passing the prop values to the CSS custom properties isn't compatible on Safari. We have a few components that got outside of normal values and use CSS custom properties, so we should evaluate a universal solution for these.

@nullpointerexceptionkek
Copy link
Contributor

nullpointerexceptionkek commented Feb 19, 2025

@endigo9740

Based on the Zag documentation, pixel values are used for calculations—even though percentage values are not explicitly prohibited. However, since the Skeleton framework relies on percentages, Safari might have rendered inconsistencies with this approach.

I did some testing, and the following seems to fix the issue. Although using this will result the progress ring being rendered slightly thicker than before
Original Code:

	<svg
		{...api.getCircleProps()}
		class="{svgBase} {svgClasses} {rxAnimCircle}"
		style="--size:100%;--thickness:{strokeWidth};"
		data-testid="progress-ring-svg"
	>

Revised Code:

	<svg
		viewBox="0 0 100 100"
		{...api.getCircleProps()}
		class="{svgBase} {svgClasses} {rxAnimCircle}"
		style="--size:100px;--thickness:{strokeWidth};"
		data-testid="progress-ring-svg"
	>

@endigo9740
Copy link
Contributor

@nullpointerexceptionkek can you share a screenshot of before vs after?

@nullpointerexceptionkek
Copy link
Contributor

@nullpointerexceptionkek can you share a screenshot of before vs after?

Before:
Image

After:
Image

@endigo9740
Copy link
Contributor

endigo9740 commented Feb 19, 2025

Ok that's not bad at all - I was worried it would be super dramatic. Looks good to me. I'd welcome a PR with this change!

@nullpointerexceptionkek
Copy link
Contributor

Yeah, I'll do some testing to ensure it doesn't add some additional styling issues.

@endigo9740
Copy link
Contributor

Cool. Make sure to check the indeterminate state - which includes the animations!

@nullpointerexceptionkek
Copy link
Contributor

nullpointerexceptionkek commented Feb 20, 2025

Hi @endigo9740,

I spent some more time investigating this issue and can confirm that it's caused by passing a percentage (%) value instead of a pixel value. The problem persists even in this minimal Zag example:

<script lang="ts">
  import * as progress from "@zag-js/progress";
  import { normalizeProps, useMachine } from "@zag-js/svelte";

  const [snapshot, send] = useMachine(progress.machine({ id: "1" }));

  const api = $derived(progress.connect(snapshot, send, normalizeProps));
</script>

<div style="height: 120px; width: 120px">
  <div {...api.getRootProps()}>
    <div {...api.getLabelProps()}>Upload progress</div>
    <svg {...api.getCircleProps()}>
      <circle {...api.getCircleTrackProps()} />
      <circle {...api.getCircleRangeProps()} />
    </svg>
  </div>
</div>

<style>
  [data-scope="progress"] {
    --size: 100%;
    --thickness: 10px;
  }
</style>

Using a viewBox with pixel values, as I mentioned earlier, works, but this causes the stroke width to scale relative to the SVG size. For example, a 10px stroke will render differently depending on the SVG’s dimensions. Unfortunately, adding vector-effect="non-scaling-stroke" breaks Zag. Are you fine with stroke width being relative to the SVG dimension?

Additionally, I noticed another issue: when the progress ring size increases(EX: size-64), the indeterminate progress renders incorrectly, showing a break in the track ring. I'm not sure if this is a Zag issue or something else.

@endigo9740
Copy link
Contributor

Thanks for sharing this info. Yeah I'm aware of the size breaking the animation. We have another issue tracking that issue.

For now, given the scope of these changes, leave this to me. I need to dig in and try this myself. I'll follow up as needed though.

@nullpointerexceptionkek
Copy link
Contributor

It's always Safari that refuses to work with the web 😒

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants