Clarity: core: progress/circular progress component API proposal / button css refactor

Created on 22 Nov 2019  路  8Comments  路  Source: vmware/clarity

  • [x] Implement cds-progress component could potentially be a single standard cds-progress component with a circular flag or two separate elements cds-progress/cds-circular-progress.
  • [x] replace inline SVG/CSS spinner icon in the cds-button component

cds-progress API Proposal

<cds-progress min="0" max="100" value="50" status="warning">50%</cds-progress>
<cds-progress type="circular" indeterminate>Loading...</cds-progress>

Internally the component can add the appropriate aria labels to the host element.

role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"

This will allow a stand alone label to be used to describe the progress when more custom layouts are need like https://github.com/vmware/clarity/issues/2245#issuecomment-490980445

<label id="custom-label">custom label stuff</label>
<cds-progress min="0" max="100" value="50" aria-describedby="custom-label" layout="nolabel">50%</cds-progress>

Props

  • min: used to set minimum value
  • max: used to set maximum value
  • value: display value
  • type: bar (default) | circular
  • status: info (default) | success | warning | danger
  • layout: vertical (default) | horizontal | nolabel
  • indeterminate: used to set indeterminate animation
  • displayValue: boolean (show percentage value inline)

Slots

  • default slot for text content describing progress action
@cdcore progress new component v5

All 8 comments

@coryrylan
What relation would this proposal have to #2245 ?

A spinner is/should be an indeterminate circular progress.

I don't know if we need to call it cwc-spinner

Yeah seems like it would be better if #2245 design is complete before continuing. Marking blocked on design. I'll work on the API some more to reflect a progress style component.

related to #2245

Revisiting this work and giving it more thought and research, here is where I landed.

Two Elements

While there may be some utilities/helpers that these progress elements share, I think the APIs vary significantly enough in execution that they should be two separate components: cds-progress-bar and cds-progress-circle

Additionally, it opens up the possibility of different progress visualizations in the future like "segmented" and "gauge" which could be cds-progress-segment and cds-progress-gauge, the latter of which is discussed in #2245

cds-progress-bar

cds-progress-bars have a lot in common with the form elements. most of the layout permutations mirror those we see in form elements (a label, a message, success/error icons shown.

Therefore, the proposal is to break the linear progress bar into two deliverables: cds-progress-bar which is just the actual BAR and nothing else (except a11y considerations and an option to display the current percent value) and cds-form-progress which will integrate the progress bar with regular form components.

In user template...

<cds-progress-bar value="50" status="warning" line-thickness="8" progress-text="Something loading now at 50%" announce-text="polite"></cds-progress-bar>
<cds-form-progress>
    <label>Something here</label>
    <cds-progress-bar value="50" progress-text="Something loading now at 50%" announce-text="polite"></cds-progress-bar>
    <cds-control-message status="warning">message text</cds-control-message>
</cds-form-progress>

API for the progress bar

name: type _(default value)_ => description

  • progressText: required property _(undefined)_ => provides text for aria-label applied to the progress-bar. warns if not defined
  • announceText: property _(undefined)_ => sets aria-live for progress-bar element; if undefined no aria-live value will be applied to the progress bar
  • value: property _(undefined)_ => a number between 0 and 100. sets the percent completed. if not set, becomes an indeterminate bar
  • layout: property _('nolabel')_ => displays the percent complete textually to the left of the bar; needs to support RTL|
    |inverse|boolean property|false|displays white-on-white progress similar to what we see in buttons
  • line-thickness: property _(TBD)_ => sets height/thickness of the bar; because we will be generating SVG internally in the bar we can't really get a consistent way to size this across progress bars; while we could do this in CSS for the linear bar, the circular bar is calculated in radians; so while technically this could be a CSS variable here, i'm proposing making it a property for consistency across all progress types; also should support size token (t-shirt) values...

Notes

  • no events necessary as the application is providing our values
  • have the application do the math for percent completed; reduces landscapes for errors/bugs on our end and keeps us out of fuzzy float issues that can arise from JS math;

CSS var _(default value)_ => description
--color _(action-blue)_ => sets color of the fill bar
--background _(neutral)_ => sets color of the bar in the background being filled
--padding _(TBD)_ => establishes padding around the bar (above, below, etc.) note: this may be overkill...

API for form bar

Same as other form controls.

Note: we may be able to just put a progress bar inside a generic form control and provide an example of how to do that...

cds-progress-circle

In user template...

<cds-progress-circle size="md" line-thickness="3" value="50" status="danger" progress-text="Something loading now at 50%" announce-text="polite"></cds-progress-circle>

In user template with icon...

Including an icon in the progress circle will display that icon sized inside the circle and centered...

<cds-progress-circle value="50" status="warning" progress-text="Something loading now at 50%" announce-text="polite">
    <cds-icon shape="home" solid></cds-icon>
</cds-progress-circle>

Indeterminate...

Giving the progress circle no value will turn it into a "spinner"

<cds-progress-bar progress-text="Something is loading"></cds-progress-bar>

API for the progress circle

name: type _(default value)_ => description

  • progressText: required property _(undefined)_ => provides text for aria-label applied to the progress-bar. warns if not defined
  • announceText: property _(undefined)_ => sets aria-live for progress-bar element; if undefined no aria-live value will be applied to the progress bar
  • value: property _(undefined)_ => a number between 0 and 100. sets the percent completed. if not set, becomes an indeterminate bar
  • line-thickness: property _(TBD)_ => sets thickness of the circle's line; because we will be generating SVG internally and calculating it with radians; should support size token (t-shirt) values...
  • icon: slot _(nil)_ => a slot where the icon is placed if an icon is inside the progress element

CSS var _(default value)_ => description
--color _(action-blue)_ => sets color of the fill bar; any inner icon should inherit this color
--background _(neutral)_ => sets color of the bar in the background being filled

Using circular progress in other elements

Circular progress should be able to be used anywhere you would use an icon...

Scope of work

The current scope of work for core only covers cds-progress-circle but the work there lays the groundwork for cds-progress-bar (which would be a good onboarding component).

CC: @coryrylan @jeeyun

I like the integration of progress bar as a form control! Would circular progress have the same? I think we could accomplish the same without requiring a new form control by leveraging the generic cds-control.

  <!-- you can do this with the today current API with the native progress -->
  <cds-control layout="horizontal">
    <label>label text</label>
    <progress value="75" min="0" max="100"></progress>
    <cds-control-message>message text</cds-control-message>
  </cds-control>

Should be able to do this as well with new components

  <cds-control layout="horizontal">
    <label>label text</label>
    <cds-progress-bar value="75" min="0" max="100"></cds-progress-bar>
    <cds-control-message>message text</cds-control-message>
  </cds-control>

  <cds-control layout="horizontal">
    <label>label text</label>
    <cds-progress-circle value="75" min="0" max="100"></cds-progress-circle>
    <cds-control-message>message text</cds-control-message>
  </cds-control>

My thinking was that circular progress would go wherever someone could conceivably put an icon. It's similar to a linear progress bar in API but very different in that regard.

I agree on the idea of just using the generic cds-control. Likewise if someone _wanted_ to put a circular progress in a form control, there's no reason it wouldn't work.

Note in your examples, however, I'm proposing dropping min and max. Users just tell us a value between 0 and 100.

If I remember (I could be mistaken) min/max is for a11y so if the native progress can be used to describe a series of tasks (4/5 tasks completed) vs describing a percentage. The aria attrs can default 0/100 and if there is a use case to override we can always add min/max on later to the API and it wouldn't be a breaking change.

I think you might be able to omit announceText and progressText and have aria-live/aria-label be applied by the developer directly on the component.

<!-- developer would write -->
<cds-progress-bar value="75" aria-live="polite" aria-label="Something loading now at 75%"></cds-progress-bar>

The component would apply the proper role progress attrs to the host for a11y. Then rendered output which would ensure the a11y role and label describe the same element.

<!-- component renders this -->
<cds-progress-bar
  value="75"
  aria-live="polite"
  aria-label="Something loading now at 75%" 

  role="progressbar"
  aria-valuenow="75"
  aria-valuemin="0"
  aria-valuemax="100"></cds-progress-bar>

Hi there 馃憢, this is an automated message. To help Clarity keep track of discussions, we automatically lock closed issues after 14 days. Please look for another open issue or open a new issue with updated details and reference this one as necessary.

Was this page helpful?
0 / 5 - 0 ratings