ProgressRing
Description
A circular progress indicator
ProgressRing displays progress in a circular donut style. Use it alongside a metric value, in a dashboard card header, or to track quota/usage.
It supports determinate values (0–100), an indeterminate spinning state, and an optional text label in the centre.
Samples
Determinate Rings
progress-ring-determinate-sample.js
using H5.Core;
using Tesserae;
using static H5.Core.dom;
using static Tesserae.UI;
namespace Tesserae.Tests
{
internal static class App
{
private static void Main()
{
var component = HStack().Gap(24.px()).AlignItems(ItemAlign.End).Children(
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(64, 6).Progress(25, 100).Label("25%"), TextBlock("25%").Small().MT(8)),
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(64, 6).Progress(50, 100).Label("50%"), TextBlock("50%").Small().MT(8)),
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(64, 6).Progress(75, 100).Label("75%"), TextBlock("75%").Small().MT(8)),
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(64, 6).Progress(100, 100).Label("100%"), TextBlock("100%").Small().MT(8))
);
document.body.style.overflow = "hidden";
MountCenteredToBody(component);
}
}
}
Sizes
progress-ring-sizes-sample.js
using H5.Core;
using Tesserae;
using static H5.Core.dom;
using static Tesserae.UI;
namespace Tesserae.Tests
{
internal static class App
{
private static void Main()
{
var component = HStack().Gap(24.px()).AlignItems(ItemAlign.End).Children(
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(32, 3).Progress(60, 100), TextBlock("Small").XSmall().MT(8)),
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(48, 4).Progress(60, 100), TextBlock("Medium").XSmall().MT(8)),
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(64, 6).Progress(60, 100), TextBlock("Large").XSmall().MT(8)),
VStack().AlignItems(ItemAlign.Center).Children(ProgressRing(96, 8).Progress(60, 100).Label("60%"), TextBlock("XLarge").XSmall().MT(8))
);
document.body.style.overflow = "hidden";
MountCenteredToBody(component);
}
}
}
Indeterminate (Loading)
progress-ring-indeterminate-sample.js
using H5.Core;
using Tesserae;
using static H5.Core.dom;
using static Tesserae.UI;
namespace Tesserae.Tests
{
internal static class App
{
private static void Main()
{
var component = HStack().Gap(24.px()).AlignItems(ItemAlign.Center).Children(
ProgressRing(48, 4).Indeterminate(),
ProgressRing(64, 6).Indeterminate(),
ProgressRing(96, 8).Indeterminate().Label("…")
);
document.body.style.overflow = "hidden";
MountCenteredToBody(component);
}
}
}
Animated Fill
progress-ring-animated-sample.js
using System.Threading.Tasks;
using H5.Core;
using Tesserae;
using static H5.Core.dom;
using static Tesserae.UI;
namespace Tesserae.Tests
{
internal static class App
{
private static void Main()
{
var component = Button("Start 5s countdown").Primary().Var(out var animBtn).OnClick(async () =>
{
animBtn.Disabled();
var liveRing = ProgressRing(64, 6).Label("0%");
var container = HStack().AlignItems(ItemAlign.Center).Gap(12.px()).Children(liveRing, TextBlock("Processing…").Small());
Toast().Information(container).Duration(System.TimeSpan.FromSeconds(7));
for (int i = 1; i <= 5; i++)
{
await Task.Delay(1000);
liveRing.Progress(i, 5).Label($"{i * 20}%");
}
animBtn.Disabled(false);
});
document.body.style.overflow = "hidden";
MountCenteredToBody(component);
}
}
}