Page MenuHomePhabricator

Create a determinate progress bar variant in Codex
Closed, ResolvedPublic

Description

Background

We need to introduce a static version of the ProgressBar component in Codex to support use cases where the progress represents measurable completion - rather than a system process or loading state. This variant would allow designers and developers to display goal progression consistently across products, using the same Codex component structure while maintaining a style that communicates growth/progress/completion/achievement.

Description

The determinate ProgressBar shows that an operation is in progress when the amount of progress can’t be measured (for example, loading or processing with an unknown duration).

User stories

As a designer, I want the progress bar component to support a static, goal-oriented variant, so I can visually communicate progress toward completion rather than system activity.

As a developer, I want a single progress bar component that can handle both indeterminate (loading) and determinate (goal-based) states, so I can reuse the same component with different variants across multiple contexts.

Design specifications

  • bar has a height of 12px (size-75 token)
  • bar container uses border-color-progressive and a fill background-color-base
  • progress element uses a fill background-color-progressive
  • both bar container and progress element use a corner radius of 2px (border-radius-base)
  • labels use 14px font size and color-subtle
  • labels show at 4px from progress bar
  • this variant allows for labels at both sides of the progress bar - codex user can choose whether they want to have only left-side label, only right-side label, or both.

Design

progress-determinate (6).png (144×1 px, 5 KB)

Captura de pantalla 2026-02-26 a la(s) 8.06.45 p. m..png (466×1 px, 48 KB)

Codex implementation

Some notes from Slack thread (see full thread here).

Recommendation would be to add a new optional prop called progress or percentCompleted that takes a numerical value. Maybe the cleanest way to do it would be to accept a float value from 0 to 1, but you could also represent things as 2-digit integers (or any way you want to do it really)

I think that reasonable behavior for the component would be: if the progress prop is not supplied, show the indeterminate loading bar. If the prop is supplied, show the bar filled up by that amount instead

Since this is a Vue component, it would be easy for the bar to dynamically animate as the progress value increments

Final thing – in some ways the trickiest part will be whether you also want to support a CSS-only version of this component variant. I think you could probably write some clever CSS using some kind of [data-progress] attribute that directly informs the styles in terms of how much of the bar to fill up. But this would take a little bit of research to figure out. For implementation I would probably suggest figuring out the CSS-only way to do this first (assuming we want to support that use-case) and then work backwards to make the Vue version easy to use but compatible with the CSS-only approach.

Component task owners


Event Timeline

DTorsani-WMF moved this task from Backlog to Ready for Design/Dev on the Codex board.
JFernandez-WMF renamed this task from Create a static progress bar variant in Codex to Create a determinate progress bar variant in Codex.Feb 26 2026, 11:00 PM
JFernandez-WMF updated the task description. (Show Details)

Discussion from Slack with @Catrope and @DTorsani-WMF

Michelle Horsey
That’s awesome, thank you!! Just to be sure, would you expect a separate component or an > extension of the existing progressBar

Derek Torsani
I'm imagining a new prop for ProgressBar for determinate or indeterminate, with indeterminate being the default so to not disrupt any current uses. But curious what @Roan thinks.

Michelle Horsey
That’s how I pictured it, with a value prop and a maxvalue so we can calc the percentage

Roan Kattouw 
I was thinking a prop with a percentage, but what Michelle just said is probably better
To accommodate percentages, maxValue could default to 100
And maybe indeterminate-ness can be implicit from the value not being set?

To summarise:

New props -
MaxValue, default 100
Value, nullable

If Value is unset, current indeterminate behaviour remains.

Thank you, looks good to me. Is this task ready for development now?

i think this is ready for dev yes, i just moved it on our sprint board

ifried changed the task status from Open to In Progress.Mar 2 2026, 5:10 PM
ifried assigned this task to MHorsey-WMF.

Notes from team call on March 2 2026:

  • For the MVP release of goal-setting, we just need to support JS users for goal-setting. This is because it is an MVP that is focused on a first, quick release and the progress bar is not necessary in order to organize an event (i.e., enable event registration) or participate in an event (i.e., being able to register, being able to associate an edit with an event, etc). We also looked at the number of no JS users we had in the past, and the numbers were quite low & lower than we expected. For this reason, the CSS version should come later in a separate release that does not block the main release, if we go with the new progress bar.

Change #1245325 had a related patch set uploaded (by Mhorsey; author: Mhorsey):

[design/codex@main] [WIP] determinate progress bar

https://gerrit.wikimedia.org/r/1245325

Coming to the designs first time when reviewing the patch, we've added the non-inline progress bar as a drop in replacement for OOUI's. Which is a single page application similar use case – visible when loading VisualEditor.
The new design does move away from such ability of positioning it seamlessly. Has this use case been incorporated into the design process?

Thanks @Volker_E! I need to add back the background color for the bar, so that the page is not visible through the progress bar.

Change #1245325 merged by jenkins-bot:

[design/codex@main] ProgressBar: Add determinate variation with updated styles and guidance

https://gerrit.wikimedia.org/r/1245325

Change #1270166 had a related patch set uploaded (by VolkerE; author: Mhorsey):

[design/codex@build-eslint-config-wikimedia-upgrade-T414401] ProgressBar: Add determinate variation with updated styles and guidance

https://gerrit.wikimedia.org/r/1270166

Change #1270166 abandoned by VolkerE:

[design/codex@build-eslint-config-wikimedia-upgrade-T414401] ProgressBar: Add determinate variation with updated styles and guidance

https://gerrit.wikimedia.org/r/1270166

Change #1275555 had a related patch set uploaded (by Catrope; author: Catrope):

[mediawiki/core@master] Update Codex from v2.4.0 to v2.5.0

https://gerrit.wikimedia.org/r/1275555

Change #1275555 merged by jenkins-bot:

[mediawiki/core@master] Update Codex from v2.4.0 to v2.5.1

https://gerrit.wikimedia.org/r/1275555

FYI: This change applies to MediaViewer and currently causes a white flash (live on the Beta Cluster, riding the train this week).

Before
before.png (1×2 px, 209 KB)
After
after.png (1×2 px, 217 KB)

Previously the progress bar was transparent (with a 9999px border-radius) and so looked "right" in the dark design of MMV, regardless of the skin/article being in the default lightmode behind it.

Thanks @Krinkle for bringing this to our awareness! The border-radius update is intentional, so I won't go into detail there. As for the background color, we made it white (in light mode) for pages where it appears on an overlay over the content of the page. Otherwise the content would have shown through in this instance. I'm unsure why the transparent background before didn't have this issue. Possibly a local override. @JFernandez-WMF any ideas here?

Can you help me understand why the page is dark, assuming this is in light mode?

I could see a few potential solutions:

  1. Have a local override here, which would change the background color of the progress bar to background-color-transparent. I would only do this if this is a rare occurrence, and if progress bars don't typically show up on dark backgrounds in light mode.
  2. Apply the dark mode color theme class on the progress bar element itself, which would use the dark mode colors for this element. I'm not sure we do this anywhere else, so I would be wary of this solution.
  3. Amend the progress bar background in Codex to use background-color-transparent and guide to create a local override in any instances where it appears over content and needs a solid background color.

Can you help me understand why the page is dark, assuming this is in light mode?

Otherwise the content would have shown through in this instance. I'm unsure why the transparent background before didn't have this issue.

This is MediaViewer. This is the image viewer (aka lightbox) on Wikipedia. You get to it from any article, e.g. https://en.wikipedia.org/wiki/Boston, and clicking on a thumbnail. There is no content to show through. The page is made black and blank on purpose. The only "content" on-screen, here, is the progress bar (until the image is loaded, after that the image takes its place). These aspects haven't changed, and aren't at issue.

Looking at other photo applications and preview modals in operating systems, where a black veil is involved, these generally do not toggle dark mode within their context. The MediaViewer indeed is not generally in dark mode. It just has a black background, is all. There are other UI elements (buttons) we'd want to keep consistent with the rest of the UI. As well nested panels with regular content, which are likewise in light mode.

Thanks @Volker_E! I need to add back the background color for the bar, so that the page is not visible through the progress bar.

I don't understand this part. Which page, and what part of the page does this refer to?

Is there really a case where we position a progress bar directly over other content? Without being contained by something that has its own background? I can't imagine it, but maybe it's in a place I'm not familiar with. I imagine such scenario would not be very readable, even with a solid background in the progress bar.

@JFernandez-WMF Can you help shine some light on the example where the progress bar appears over the page content, and your thoughts around changing the background color of the progress bar to transparent?

sorry for the delay and thanks for flagging!
the example that we thought of to inform the decision on whether we wanted a white background or no background was if, for example, the progress bar appears in an article or above written content, e.g.:

Captura de pantalla 2026-02-25 a la(s) 3.17.55 p. m..png (1×1 px, 641 KB)

if we think this use case/use cases like these aren't enought to support the white background decision, i'm happy to drop that and change to transparent!

RE: MediaViewer, I think shipping an opaque background color in ProgressBar would be fine as long as we had a corresponding dark mode style for this component (which I assume we would anyway). @DTorsani-WMF or @JFernandez-WMF, can you show a dark mode example of the new design?

MediaViewer (which always has a dark color scheme) uses Codex tokens, so we could force any Codex components we use there to always show up in their dark variants via the .cdx-mode-dark() mixin from Codex. We're already doing that in mmv.bootstrap.less.

I think opaque background is fine, but we need to ensure MMV's initial progress bar doesn't show a white background. As long as the component is set up for dark mode, we can add a small patch to MMV to correct this.

Change #1285447 had a related patch set uploaded (by Eric Gardner; author: Eric Gardner):

[mediawiki/extensions/MultimediaViewer@master] mmv.bootstrap: Force dark mode for cdx-progress-bar

https://gerrit.wikimedia.org/r/1285447

Change #1285447 merged by jenkins-bot:

[mediawiki/extensions/MultimediaViewer@master] mmv.bootstrap: Force dark mode for cdx-progress-bar

https://gerrit.wikimedia.org/r/1285447

@egardner If we used a transparent background, wouldn't that just be transparent in dark mode as well? What additional design for that are you looking for or what do you think would need to change?