diff --git a/progress/lib/_circular-progress.scss b/progress/lib/_circular-progress.scss
index 8b4fba2c88..b695381b32 100644
--- a/progress/lib/_circular-progress.scss
+++ b/progress/lib/_circular-progress.scss
@@ -67,13 +67,13 @@
content-visibility: auto;
}
- .circular-progress {
+ .progress {
flex: 1;
align-self: stretch;
margin: $container-padding;
}
- .circular-progress,
+ .progress,
.spinner,
.left,
.right,
@@ -110,7 +110,7 @@
stroke: transparent;
}
- .circular-progress.indeterminate {
+ .progress.indeterminate {
will-change: transform;
animation: linear infinite linear-rotate;
animation-duration: $linear-rotate-duration;
diff --git a/progress/lib/_linear-progress.scss b/progress/lib/_linear-progress.scss
index 5dff7baf9e..6119f2a88e 100644
--- a/progress/lib/_linear-progress.scss
+++ b/progress/lib/_linear-progress.scss
@@ -48,9 +48,9 @@ $_track-background: 0 / $_track-background-width 100%
// Generates a list of rtl selectors. This is done so rules can be generated
// separately so they don't get dropped where unsupported.
$rtl-selectors: (
- ':host-context([dir="rtl"]) .linear-progress',
- ':host([dir="rtl"]) .linear-progress',
- '.linear-progress:dir(rtl)'
+ ':host-context([dir="rtl"]) .progress',
+ ':host([dir="rtl"]) .progress',
+ '.progress:dir(rtl)'
);
@mixin styles() {
@@ -72,7 +72,7 @@ $rtl-selectors: (
contain: strict;
}
- .linear-progress,
+ .progress,
.track,
.buffer-bar,
.bar,
@@ -80,7 +80,7 @@ $rtl-selectors: (
position: absolute;
}
- .linear-progress {
+ .progress {
inset: 0;
outline: transparent solid 1px;
border-radius: var(--_track-shape);
@@ -310,13 +310,13 @@ $rtl-selectors: (
}
@media screen and (forced-colors: active) {
- .linear-progress {
+ .progress {
--_active-indicator-color: canvastext;
--_track-color: graytext;
border: 1px solid canvastext;
}
- .indeterminate.linear-progress {
+ .indeterminate.progress {
--_track-color: canvas;
}
}
diff --git a/progress/lib/circular-progress.ts b/progress/lib/circular-progress.ts
index 498ba7d07a..b12b326bfe 100644
--- a/progress/lib/circular-progress.ts
+++ b/progress/lib/circular-progress.ts
@@ -4,58 +4,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import {html, LitElement, nothing} from 'lit';
-import {property} from 'lit/decorators.js';
-import {classMap} from 'lit/directives/class-map.js';
+import {html} from 'lit';
-import {ARIAMixinStrict} from '../../internal/aria/aria.js';
-import {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';
+import {Progress} from './progress.js';
/**
* A circular progress component.
*/
-export class CircularProgress extends LitElement {
- static {
- requestUpdateOnAriaChange(this);
- }
-
- /**
- * Progress to display, a fraction between 0 and 1.
- */
- @property({type: Number}) progress = 0;
-
- /**
- * Whether or not to display an animated spinner representing indeterminate
- * progress.
- */
- @property({type: Boolean}) indeterminate = false;
+export class CircularProgress extends Progress {
+ protected override renderIndicator() {
+ if (this.indeterminate) {
+ return this.renderIndeterminateContainer();
+ }
- /**
- * Whether or not to render indeterminate mode using 4 colors instead of one.
- */
- @property({type: Boolean, attribute: 'four-color'}) fourColor = false;
-
- protected override render() {
- const classes = {
- 'indeterminate': this.indeterminate,
- 'four-color': this.fourColor
- };
-
- // Needed for closure conformance
- const {ariaLabel} = this as ARIAMixinStrict;
- return html`
-
- ${
- this.indeterminate ? this.renderIndeterminateContainer() :
- this.renderDeterminateContainer()}
-
- `;
+ return this.renderDeterminateContainer();
}
// Determinate mode is rendered with an svg so the progress arc can be
diff --git a/progress/lib/linear-progress.ts b/progress/lib/linear-progress.ts
index 4f9d98bf42..0495190f63 100644
--- a/progress/lib/linear-progress.ts
+++ b/progress/lib/linear-progress.ts
@@ -4,58 +4,37 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import {html, LitElement, nothing} from 'lit';
+import {html} from 'lit';
import {property, query, state} from 'lit/decorators.js';
-import {classMap} from 'lit/directives/class-map.js';
import {styleMap} from 'lit/directives/style-map.js';
-import {ARIAMixinStrict} from '../../internal/aria/aria.js';
-import {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';
+import {Progress} from './progress.js';
/**
* A linear progress component.
*/
-export class LinearProgress extends LitElement {
- static {
- requestUpdateOnAriaChange(this);
- }
-
- /**
- * Whether or not to render indeterminate progress in an animated state.
- */
- @property({type: Boolean}) indeterminate = false;
-
- /**
- * Progress to display, a fraction between 0 and 1.
- */
- @property({type: Number}) progress = 0;
-
+export class LinearProgress extends Progress {
/**
* Buffer amount to display, a fraction between 0 and 1.
*/
@property({type: Number}) buffer = 1;
- /**
- * Whether or not to render indeterminate mode using 4 colors instead of one.
- *
- */
- @property({type: Boolean, attribute: 'four-color'}) fourColor = false;
-
- @query('.linear-progress') private readonly rootEl!: HTMLElement|null;
+ @query('.progress') private readonly rootEl!: HTMLElement|null;
@state() private animationReady = true;
private resizeObserver: ResizeObserver|null = null;
- // Note, the indeterminate animation is rendered with transform %'s
- // Previously, this was optimized to use px calculated with the resizeObserver
- // due to a now fixed Chrome bug: crbug.com/389359.
- protected override render() {
- const rootClasses = {
- 'indeterminate': this.indeterminate,
+ protected override getRenderClasses() {
+ return {
+ ...super.getRenderClasses(),
'animation-ready': this.animationReady,
- 'four-color': this.fourColor
};
+ }
+ // Note, the indeterminate animation is rendered with transform %'s
+ // Previously, this was optimized to use px calculated with the resizeObserver
+ // due to a now fixed Chrome bug: crbug.com/389359.
+ protected override renderIndicator() {
const progressStyles = {
transform: `scaleX(${(this.indeterminate ? 1 : this.progress) * 100}%)`
};
@@ -63,25 +42,16 @@ export class LinearProgress extends LitElement {
transform: `scaleX(${(this.indeterminate ? 1 : this.buffer) * 100}%)`
};
- // Needed for closure conformance
- const {ariaLabel} = this as ARIAMixinStrict;
return html`
- `;
+
+
+
+
+ `;
}
override async connectedCallback() {
diff --git a/progress/lib/progress.ts b/progress/lib/progress.ts
new file mode 100644
index 0000000000..091a91d1d2
--- /dev/null
+++ b/progress/lib/progress.ts
@@ -0,0 +1,60 @@
+/**
+ * @license
+ * Copyright 2023 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {html, LitElement, nothing, TemplateResult} from 'lit';
+import {property} from 'lit/decorators.js';
+import {classMap} from 'lit/directives/class-map.js';
+
+import {ARIAMixinStrict} from '../../internal/aria/aria.js';
+import {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';
+
+/**
+ * A progress component.
+ */
+export abstract class Progress extends LitElement {
+ static {
+ requestUpdateOnAriaChange(this);
+ }
+
+ /**
+ * Progress to display, a fraction between 0 and 1.
+ */
+ @property({type: Number}) progress = 0;
+
+ /**
+ * Whether or not to display indeterminate progress, which gives no indication
+ * to how long an activity will take.
+ */
+ @property({type: Boolean}) indeterminate = false;
+
+ /**
+ * Whether or not to render indeterminate mode using 4 colors instead of one.
+ */
+ @property({type: Boolean, attribute: 'four-color'}) fourColor = false;
+
+ protected override render() {
+ // Needed for closure conformance
+ const {ariaLabel} = this as ARIAMixinStrict;
+ return html`
+ ${this.renderIndicator()}
+ `;
+ }
+
+ protected getRenderClasses() {
+ return {
+ 'indeterminate': this.indeterminate,
+ 'four-color': this.fourColor,
+ };
+ }
+
+ protected abstract renderIndicator(): TemplateResult;
+}