feat(progress): add max property

PiperOrigin-RevId: 549673538
This commit is contained in:
Elizabeth Mitchell 2023-07-20 10:34:31 -07:00 committed by Copybara-Service
parent 2dabbdc142
commit 02a509b480
5 changed files with 29 additions and 15 deletions

View File

@ -23,6 +23,7 @@ function cssWire<T = string>(prop: string, unit = '') {
const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>( const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>(
'Progress indicators', [ 'Progress indicators', [
new Knob('value', {ui: numberInput({step: 0.1}), defaultValue: 0.5}), new Knob('value', {ui: numberInput({step: 0.1}), defaultValue: 0.5}),
new Knob('max', {ui: numberInput(), defaultValue: 1}),
new Knob('indeterminate', {ui: boolInput(), defaultValue: false}), new Knob('indeterminate', {ui: boolInput(), defaultValue: false}),
new Knob('fourColor', {ui: boolInput(), defaultValue: false}), new Knob('fourColor', {ui: boolInput(), defaultValue: false}),
new Knob( new Knob(

View File

@ -20,6 +20,7 @@ import {classMap} from 'lit/directives/class-map.js';
/** Knob types for linear progress stories. */ /** Knob types for linear progress stories. */
export interface StoryKnobs { export interface StoryKnobs {
value: number; value: number;
max: number;
'buffer (linear)': number; 'buffer (linear)': number;
indeterminate: boolean; indeterminate: boolean;
fourColor: boolean; fourColor: boolean;
@ -47,7 +48,7 @@ const standard: MaterialStoryInit<StoryKnobs> = {
} }
`, `,
render(knobs) { render(knobs) {
const {value, indeterminate, fourColor} = knobs; const {value, max, indeterminate, fourColor} = knobs;
const buffer = knobs['buffer (linear)']; const buffer = knobs['buffer (linear)'];
const classes = {'custom': knobs['custom theme (linear)']}; const classes = {'custom': knobs['custom theme (linear)']};
@ -55,6 +56,7 @@ const standard: MaterialStoryInit<StoryKnobs> = {
<md-linear-progress <md-linear-progress
class=${classMap(classes)} class=${classMap(classes)}
.value=${value} .value=${value}
.max=${max}
.buffer=${buffer} .buffer=${buffer}
.indeterminate=${indeterminate} .indeterminate=${indeterminate}
.fourColor=${fourColor} .fourColor=${fourColor}
@ -65,10 +67,11 @@ const standard: MaterialStoryInit<StoryKnobs> = {
const standardCircular: MaterialStoryInit<StoryKnobs> = { const standardCircular: MaterialStoryInit<StoryKnobs> = {
name: 'Circular progress', name: 'Circular progress',
render({value, indeterminate, fourColor}) { render({value, max, indeterminate, fourColor}) {
return html` return html`
<md-circular-progress <md-circular-progress
.value=${value} .value=${value}
.max=${max}
.indeterminate=${indeterminate} .indeterminate=${indeterminate}
.fourColor=${fourColor} .fourColor=${fourColor}
></md-circular-progress>`; ></md-circular-progress>`;
@ -87,7 +90,7 @@ const iconButton: MaterialStoryInit<StoryKnobs> = {
position: absolute; position: absolute;
} }
`, `,
render({value, indeterminate, fourColor}) { render({value, max, indeterminate, fourColor}) {
const toggle = ({target}: Event) => { const toggle = ({target}: Event) => {
const spinner = const spinner =
((target as HTMLElement).parentElement as MdCircularProgress); ((target as HTMLElement).parentElement as MdCircularProgress);
@ -98,6 +101,7 @@ const iconButton: MaterialStoryInit<StoryKnobs> = {
<div class="around-icon"> <div class="around-icon">
<md-circular-progress <md-circular-progress
.value=${value} .value=${value}
.max=${max}
.indeterminate=${indeterminate} .indeterminate=${indeterminate}
.fourColor=${fourColor} .fourColor=${fourColor}
></md-circular-progress> ></md-circular-progress>
@ -116,7 +120,7 @@ const insideButton: MaterialStoryInit<StoryKnobs> = {
--md-tonal-button-with-icon-spacing-trailing: 8px; --md-tonal-button-with-icon-spacing-trailing: 8px;
width: 80px; width: 80px;
}`, }`,
render({value, indeterminate, fourColor}) { render({value, max, indeterminate, fourColor}) {
const loadTime = 2500; const loadTime = 2500;
let loadTimeout = -1; let loadTimeout = -1;
const toggleLoad = (target: MdTonalButton) => { const toggleLoad = (target: MdTonalButton) => {
@ -141,6 +145,7 @@ const insideButton: MaterialStoryInit<StoryKnobs> = {
}}> }}>
<md-circular-progress slot="nothing" <md-circular-progress slot="nothing"
.value=${value} .value=${value}
.max=${max}
.indeterminate=${indeterminate} .indeterminate=${indeterminate}
.fourColor=${fourColor} .fourColor=${fourColor}
></md-circular-progress> ></md-circular-progress>

View File

@ -23,15 +23,16 @@ export class CircularProgress extends Progress {
// Determinate mode is rendered with an svg so the progress arc can be // Determinate mode is rendered with an svg so the progress arc can be
// easily animated via stroke-dashoffset. // easily animated via stroke-dashoffset.
private renderDeterminateContainer() { private renderDeterminateContainer() {
const dashOffset = (1 - this.value) * 100; const dashOffset = (1 - this.value / this.max) * 100;
// note, dash-array/offset are relative to Setting `pathLength` but // note, dash-array/offset are relative to Setting `pathLength` but
// Chrome seems to render this inaccurately and using a large viewbox helps. // Chrome seems to render this inaccurately and using a large viewbox helps.
const pathLength = 100; return html`
return html`<svg viewBox="0 0 4800 4800"> <svg viewBox="0 0 4800 4800">
<circle class="track" pathLength="${pathLength}"></circle> <circle class="track" pathLength="100"></circle>
<circle class="progress" pathLength="${pathLength}" stroke-dashoffset="${ <circle class="progress" pathLength="100"
dashOffset}"></circle> stroke-dashoffset=${dashOffset}></circle>
</svg>`; </svg>
`;
} }
// Indeterminate mode rendered with 2 bordered-divs. The borders are // Indeterminate mode rendered with 2 bordered-divs. The borders are

View File

@ -36,10 +36,12 @@ export class LinearProgress extends Progress {
// due to a now fixed Chrome bug: crbug.com/389359. // due to a now fixed Chrome bug: crbug.com/389359.
protected override renderIndicator() { protected override renderIndicator() {
const progressStyles = { const progressStyles = {
transform: `scaleX(${(this.indeterminate ? 1 : this.value) * 100}%)` transform:
`scaleX(${(this.indeterminate ? 1 : this.value / this.max) * 100}%)`
}; };
const bufferStyles = { const bufferStyles = {
transform: `scaleX(${(this.indeterminate ? 1 : this.buffer) * 100}%)` transform:
`scaleX(${(this.indeterminate ? 1 : this.buffer / this.max) * 100}%)`
}; };
return html` return html`

View File

@ -20,10 +20,15 @@ export abstract class Progress extends LitElement {
} }
/** /**
* Progress to display, a fraction between 0 and 1. * Progress to display, a fraction between 0 and `max`.
*/ */
@property({type: Number}) value = 0; @property({type: Number}) value = 0;
/**
* Maximum progress to display, defaults to 1.
*/
@property({type: Number}) max = 1;
/** /**
* Whether or not to display indeterminate progress, which gives no indication * Whether or not to display indeterminate progress, which gives no indication
* to how long an activity will take. * to how long an activity will take.
@ -43,7 +48,7 @@ export abstract class Progress extends LitElement {
role="progressbar" role="progressbar"
aria-label="${ariaLabel || nothing}" aria-label="${ariaLabel || nothing}"
aria-valuemin="0" aria-valuemin="0"
aria-valuemax="1" aria-valuemax=${this.max}
aria-valuenow=${this.indeterminate ? nothing : this.value} aria-valuenow=${this.indeterminate ? nothing : this.value}
>${this.renderIndicator()}</div> >${this.renderIndicator()}</div>
`; `;