From 664c7bda68044b04c2660d32850b294817010286 Mon Sep 17 00:00:00 2001 From: Richard Helm Date: Thu, 5 Dec 2024 18:01:25 +0000 Subject: [PATCH] Decouple FAST Foundation --- .../lib/progress-ring/progress-ring.spec.ts | 7 ++ .../src/lib/progress-ring/progress-ring.ts | 2 +- .../src/lib/progress/progress.spec.ts | 7 ++ libs/components/src/lib/progress/progress.ts | 2 +- .../foundation/progress/base-progress.ts | 103 ++++++++++++++++++ 5 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 libs/components/src/shared/foundation/progress/base-progress.ts diff --git a/libs/components/src/lib/progress-ring/progress-ring.spec.ts b/libs/components/src/lib/progress-ring/progress-ring.spec.ts index 4e82d12a4b..a0b50d321e 100644 --- a/libs/components/src/lib/progress-ring/progress-ring.spec.ts +++ b/libs/components/src/lib/progress-ring/progress-ring.spec.ts @@ -48,8 +48,15 @@ describe('vwc-progress-ring', () => { await elementUpdated(element); const percentWithSmallRange = element.percentComplete; + element.min = 0; + element.max = 0; + element.value = 0; + await elementUpdated(element); + const percentWithEmptyRange = element.percentComplete; + expect(percentWithBigRange).toEqual(25); expect(percentWithSmallRange).toEqual(50); + expect(percentWithEmptyRange).toEqual(0); }); it('should set the determinate div width to percentComplete', async function () { diff --git a/libs/components/src/lib/progress-ring/progress-ring.ts b/libs/components/src/lib/progress-ring/progress-ring.ts index 26a0a78432..4251a80c91 100644 --- a/libs/components/src/lib/progress-ring/progress-ring.ts +++ b/libs/components/src/lib/progress-ring/progress-ring.ts @@ -1,6 +1,6 @@ -import { BaseProgress } from '@microsoft/fast-foundation'; import { attr } from '@microsoft/fast-element'; import type { Connotation } from '../enums'; +import { BaseProgress } from '../../shared/foundation/progress/base-progress'; export type ProgressRingConnotation = | Connotation.Accent diff --git a/libs/components/src/lib/progress/progress.spec.ts b/libs/components/src/lib/progress/progress.spec.ts index cb1e81fff0..ec61b9b253 100644 --- a/libs/components/src/lib/progress/progress.spec.ts +++ b/libs/components/src/lib/progress/progress.spec.ts @@ -116,8 +116,15 @@ describe('vwc-progress', () => { await elementUpdated(element); const percentWithSmallRange = element.percentComplete; + element.min = 0; + element.max = 0; + element.value = 0; + await elementUpdated(element); + const percentWithEmptyRange = element.percentComplete; + expect(percentWithBigRange).toEqual(25); expect(percentWithSmallRange).toEqual(50); + expect(percentWithEmptyRange).toEqual(0); }); it('should set the determinate div width to percentComplete', async function () { diff --git a/libs/components/src/lib/progress/progress.ts b/libs/components/src/lib/progress/progress.ts index 9b5a35790c..38ec92da4e 100644 --- a/libs/components/src/lib/progress/progress.ts +++ b/libs/components/src/lib/progress/progress.ts @@ -1,6 +1,6 @@ -import { BaseProgress } from '@microsoft/fast-foundation'; import { attr } from '@microsoft/fast-element'; import type { Connotation, ConnotationDecorative, Shape } from '../enums'; +import { BaseProgress } from '../../shared/foundation/progress/base-progress'; export type ProgressConnotation = | Connotation.Accent diff --git a/libs/components/src/shared/foundation/progress/base-progress.ts b/libs/components/src/shared/foundation/progress/base-progress.ts new file mode 100644 index 0000000000..d72584f416 --- /dev/null +++ b/libs/components/src/shared/foundation/progress/base-progress.ts @@ -0,0 +1,103 @@ +import { + attr, + nullableNumberConverter, + observable, +} from '@microsoft/fast-element'; +import { FoundationElement } from '@microsoft/fast-foundation'; + +/** + * An Progress HTML Element. + * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#progressbar | ARIA progressbar }. + * + * @public + */ +export class BaseProgress extends FoundationElement { + /** + * The value of the progress + * @public + * @remarks + * HTML Attribute: value + */ + @attr({ converter: nullableNumberConverter }) + // @ts-expect-error Type is incorrectly non-optional + value: number | null; + /** + * @internal + */ + valueChanged() { + if (this.$fastController.isConnected) { + this.updatePercentComplete(); + } + } + + /** + * The minimum value + * @public + * @remarks + * HTML Attribute: min + */ + @attr({ converter: nullableNumberConverter }) + // @ts-expect-error Type is incorrectly non-optional + min: number; + /** + * @internal + */ + minChanged() { + if (this.$fastController.isConnected) { + this.updatePercentComplete(); + } + } + + /** + * The maximum value + * @public + * @remarks + * HTML Attribute: max + */ + @attr({ converter: nullableNumberConverter }) + // @ts-expect-error Type is incorrectly non-optional + max: number; + /** + * @private + */ + maxChanged() { + if (this.$fastController.isConnected) { + this.updatePercentComplete(); + } + } + + /** + * Indicates the progress is paused + * @public + * @remarks + * HTML Attribute: paused + */ + @attr({ mode: 'boolean' }) + // @ts-expect-error Type is incorrectly non-optional + paused: boolean; + + /** + * Indicates progress in % + * @internal + */ + @observable + percentComplete = 0; + + /** + * @internal + */ + override connectedCallback() { + super.connectedCallback(); + this.updatePercentComplete(); + } + + private updatePercentComplete() { + const min = typeof this.min === 'number' ? this.min : 0; + const max = typeof this.max === 'number' ? this.max : 100; + const value = typeof this.value === 'number' ? this.value : 0; + const range = max - min; + + this.percentComplete = + range === 0 ? 0 : Math.fround(((value - min) / range) * 100); + } +}