diff --git a/packages/web-components/fast-foundation/docs/api-report.md b/packages/web-components/fast-foundation/docs/api-report.md index dd87f8f6af6..38e9e570fad 100644 --- a/packages/web-components/fast-foundation/docs/api-report.md +++ b/packages/web-components/fast-foundation/docs/api-report.md @@ -2526,14 +2526,21 @@ export type PickerOptions = { // @public export function pickerTemplate(options: PickerOptions): ElementViewTemplate; +// @public (undocumented) +export const progressIndicatorTemplate: ViewTemplate; + // @public export type ProgressOptions = { - indeterminateIndicator1?: StaticallyComposableHTML; - indeterminateIndicator2?: StaticallyComposableHTML; + determinateIndicator?: StaticallyComposableHTML; + indeterminateIndicator?: StaticallyComposableHTML; }; +// @public (undocumented) +export const progressRingIndicatorTemplate: ViewTemplate; + // @public export type ProgressRingOptions = { + determinateIndicator?: StaticallyComposableHTML; indeterminateIndicator?: StaticallyComposableHTML; }; diff --git a/packages/web-components/fast-foundation/src/progress-ring/index.ts b/packages/web-components/fast-foundation/src/progress-ring/index.ts index c6eb91da9eb..91b5eec9276 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/index.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/index.ts @@ -1,3 +1,4 @@ +export * from "../progress/base-progress.js"; export * from "./progress-ring.js"; export * from "./progress-ring.options.js"; export * from "./progress-ring.template.js"; diff --git a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.options.ts b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.options.ts index 8b6169ec1e4..a155cdb83d1 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.options.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.options.ts @@ -6,5 +6,6 @@ import type { FASTProgressRing } from "./progress-ring.js"; * @public */ export type ProgressRingOptions = { + determinateIndicator?: StaticallyComposableHTML; indeterminateIndicator?: StaticallyComposableHTML; }; diff --git a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.pw.spec.ts b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.pw.spec.ts index 11822e01975..291adb73ad9 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.pw.spec.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.pw.spec.ts @@ -1,6 +1,7 @@ import { expect, test } from "@playwright/test"; import type { Locator, Page } from "@playwright/test"; import { fixtureURL } from "../__test__/helpers.js"; +import type { FASTProgressRing } from "./progress-ring.js"; test.describe("Progress ring", () => { let page: Page; @@ -61,15 +62,67 @@ test.describe("Progress ring", () => { await expect(element).toHaveAttribute("aria-valuemax", "75"); }); - test("should render an element with a `determinate` slot when a value is provided", async () => { + test("should render an element with a `determinate` class when a value is provided", async () => { await root.evaluate(node => { node.innerHTML = /* html */ ` `; }); - const progress = element.locator(".progress"); + const progress = element.locator(".determinate"); - await expect(progress).toHaveAttribute("slot", "determinate"); + await expect(progress).toHaveCount(1); + }); + + test("should render an element with an `indeterminate` class when no value is provided", async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const progress = element.locator(".indeterminate"); + + await expect(progress).toHaveCount(1); + }); + + test("should return the `percentComplete` property as a value between 0 and 100 when `min` and `max` are unset", async () => { + await page.setContent(/* html */ ` + + `); + + await expect(element).toHaveJSProperty("percentComplete", 50); + }); + + test("should set the `percentComplete` property to match the current `value` in the range of `min` and `max`", async () => { + await page.setContent(/* html */ ` + + `); + + await expect(element).toHaveJSProperty("percentComplete", 0); + + await element.evaluate((node: FASTProgressRing) => { + node.value = 50; + }); + + await expect(element).toHaveJSProperty("percentComplete", 50); + + await element.evaluate((node: FASTProgressRing) => { + node.value = 100; + }); + + await expect(element).toHaveJSProperty("percentComplete", 100); + + await element.evaluate((node: FASTProgressRing) => { + node.max = 200; + }); + + await expect(element).toHaveJSProperty("percentComplete", 50); + + await element.evaluate((node: FASTProgressRing) => { + node.min = 100; + }); + + await expect(element).toHaveJSProperty("percentComplete", 0); }); }); diff --git a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.template.ts b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.template.ts index 05ef4592a35..84d27baa1b2 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.template.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.template.ts @@ -4,7 +4,15 @@ import { staticallyCompose } from "../utilities/template-helpers.js"; import type { FASTProgressRing } from "./progress-ring.js"; import type { ProgressRingOptions } from "./progress-ring.options.js"; -const progressSegments: number = 44; +/** + * @public + */ +export const progressRingIndicatorTemplate = html` + + + + +`; /** * The template for the {@link @microsoft/fast-foundation#FASTProgressRing} component. @@ -23,35 +31,22 @@ export function progressRingTemplate( ${when( x => typeof x.value === "number", html` - - - - + + ${staticallyCompose(options.determinateIndicator)} + + `, html` - - ${staticallyCompose(options.indeterminateIndicator)} - + + + ${staticallyCompose(options.indeterminateIndicator)} + + ` )} diff --git a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.ts b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.ts index f3736588496..5966563b583 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/progress-ring.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/progress-ring.ts @@ -4,11 +4,10 @@ import { FASTBaseProgress } from "../progress/base-progress.js"; * An circular Progress HTML Element. * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#progressbar | ARIA progressbar }. * - * @slot indeterminate - The slot for a custom indeterminate indicator - * @slot determinate - The slot for a custom determinate indicator - * @csspart progress - Represents the progress element + * @slot determinate - The slot for the determinate indicator + * @slot indeterminate - The slot for the indeterminate indicator * @csspart determinate - The determinate indicator - * @csspart background - The background + * @csspart indeterminate - The indeterminate indicator * * @public */ diff --git a/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.register.ts b/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.register.ts index b7a3cd31f8b..69bfe9183d1 100644 --- a/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.register.ts +++ b/packages/web-components/fast-foundation/src/progress-ring/stories/progress-ring.register.ts @@ -1,7 +1,9 @@ -import { html } from "@microsoft/fast-element"; import { css } from "@microsoft/fast-element"; import { FASTProgressRing } from "../progress-ring.js"; -import { progressRingTemplate } from "../progress-ring.template.js"; +import { + progressRingIndicatorTemplate, + progressRingTemplate, +} from "../progress-ring.template.js"; const styles = css` :host { @@ -24,9 +26,14 @@ const styles = css` stroke-width: 2px; } - .determinate { + .determinate .indicator { + --progress-segments: 44; stroke: var(--accent-foreground-rest); fill: none; + stroke-dasharray: calc( + ((var(--progress-segments) * var(--percent-complete)) / 100) * 1px + ) + calc(var(--progress-segments) * 1px); stroke-width: 2px; stroke-linecap: round; transform-origin: 50% 50%; @@ -34,7 +41,7 @@ const styles = css` transition: all 0.2s ease-in-out; } - .indeterminate-indicator-1 { + .indeterminate .indicator { stroke: var(--accent-foreground-rest); fill: none; stroke-width: 2px; @@ -64,24 +71,8 @@ const styles = css` FASTProgressRing.define({ name: "fast-progress-ring", template: progressRingTemplate({ - indeterminateIndicator: /* html */ html` - - - - - `, + determinateIndicator: progressRingIndicatorTemplate, + indeterminateIndicator: progressRingIndicatorTemplate, }), styles, }); diff --git a/packages/web-components/fast-foundation/src/progress/README.md b/packages/web-components/fast-foundation/src/progress/README.md index f34be4523a2..d5567a37843 100644 --- a/packages/web-components/fast-foundation/src/progress/README.md +++ b/packages/web-components/fast-foundation/src/progress/README.md @@ -174,17 +174,17 @@ export const myProgressRing = ProgressRing.compose({ #### CSS Parts -| Name | Description | -| --------------- | ------------------------------- | -| `progress` | Represents the progress element | -| `determinate` | The determinate indicator | -| `indeterminate` | The indeterminate indicator | +| Name | Description | +| --------------- | --------------------------- | +| `determinate` | The determinate indicator | +| `indeterminate` | The indeterminate indicator | #### Slots -| Name | Description | -| --------------- | --------------------------------------------- | -| `indeterminate` | The slot for a custom indeterminate indicator | +| Name | Description | +| --------------- | ---------------------------------------- | +| `determinate` | The slot for the determinate indicator | +| `indeterminate` | The slot for the indeterminate indicator |
diff --git a/packages/web-components/fast-foundation/src/progress/progress.options.ts b/packages/web-components/fast-foundation/src/progress/progress.options.ts index 6abd26ba064..9c8af4a838b 100644 --- a/packages/web-components/fast-foundation/src/progress/progress.options.ts +++ b/packages/web-components/fast-foundation/src/progress/progress.options.ts @@ -6,6 +6,6 @@ import type { FASTProgress } from "./progress.js"; * @public */ export type ProgressOptions = { - indeterminateIndicator1?: StaticallyComposableHTML; - indeterminateIndicator2?: StaticallyComposableHTML; + determinateIndicator?: StaticallyComposableHTML; + indeterminateIndicator?: StaticallyComposableHTML; }; diff --git a/packages/web-components/fast-foundation/src/progress/progress.pw.spec.ts b/packages/web-components/fast-foundation/src/progress/progress.pw.spec.ts index 6e18d38ac55..47be8e1a97a 100644 --- a/packages/web-components/fast-foundation/src/progress/progress.pw.spec.ts +++ b/packages/web-components/fast-foundation/src/progress/progress.pw.spec.ts @@ -3,7 +3,7 @@ import { expect, test } from "@playwright/test"; import { fixtureURL } from "../__test__/helpers.js"; import type { FASTProgress } from "./progress.js"; -test.describe("Progress ring", () => { +test.describe("Progress", () => { let page: Page; let element: Locator; let root: Locator; @@ -56,28 +56,28 @@ test.describe("Progress ring", () => { await expect(element).toHaveAttribute("aria-valuemax", "50"); }); - test("should render an element with a `determinate` slot when a value is provided", async () => { + test("should render an element with a `determinate` class when a value is provided", async () => { await root.evaluate(node => { node.innerHTML = /* html */ ` `; }); - const progress = element.locator(".progress"); + const progress = element.locator(".determinate"); - await expect(progress).toHaveAttribute("slot", "determinate"); + await expect(progress).toHaveCount(1); }); - test("should render an element with an `indeterminate` slot when no value is provided", async () => { + test("should render an element with an `indeterminate` class when no value is provided", async () => { await root.evaluate(node => { node.innerHTML = /* html */ ` `; }); - const progress = element.locator(".progress"); + const progress = element.locator(".indeterminate"); - await expect(progress).toHaveAttribute("slot", "indeterminate"); + await expect(progress).toHaveCount(1); }); test("should return the `percentComplete` property as a value between 0 and 100 when `min` and `max` are unset", async () => { diff --git a/packages/web-components/fast-foundation/src/progress/progress.template.ts b/packages/web-components/fast-foundation/src/progress/progress.template.ts index 281df7e195d..967f7c70709 100644 --- a/packages/web-components/fast-foundation/src/progress/progress.template.ts +++ b/packages/web-components/fast-foundation/src/progress/progress.template.ts @@ -4,6 +4,13 @@ import { staticallyCompose } from "../utilities/template-helpers.js"; import type { FASTProgress } from "./progress.js"; import type { ProgressOptions } from "./progress.options.js"; +/** + * @public + */ +export const progressIndicatorTemplate = html` +
+`; + /** * The template for the {@link @microsoft/fast-foundation#FASTProgress} component. * @public @@ -11,7 +18,7 @@ import type { ProgressOptions } from "./progress.options.js"; export function progressTemplate( options: ProgressOptions = {} ): ElementViewTemplate { - return html` + return html` diff --git a/packages/web-components/fast-foundation/src/progress/progress.ts b/packages/web-components/fast-foundation/src/progress/progress.ts index 661b67cb366..7fc40b10ca8 100644 --- a/packages/web-components/fast-foundation/src/progress/progress.ts +++ b/packages/web-components/fast-foundation/src/progress/progress.ts @@ -4,8 +4,8 @@ import { FASTBaseProgress } from "./base-progress.js"; * An Progress HTML Element. * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#progressbar | ARIA progressbar }. * - * @slot indeterminate - The slot for a custom indeterminate indicator - * @csspart progress - Represents the progress element + * @slot determinate - The slot for the determinate indicator + * @slot indeterminate - The slot for the indeterminate indicator * @csspart determinate - The determinate indicator * @csspart indeterminate - The indeterminate indicator * diff --git a/packages/web-components/fast-foundation/src/progress/stories/progress.register.ts b/packages/web-components/fast-foundation/src/progress/stories/progress.register.ts index 78e4c909bb9..ee77a4e29e3 100644 --- a/packages/web-components/fast-foundation/src/progress/stories/progress.register.ts +++ b/packages/web-components/fast-foundation/src/progress/stories/progress.register.ts @@ -1,7 +1,6 @@ -import { html } from "@microsoft/fast-element"; import { css } from "@microsoft/fast-element"; import { FASTProgress } from "../progress.js"; -import { progressTemplate } from "../progress.template.js"; +import { progressIndicatorTemplate, progressTemplate } from "../progress.template.js"; const styles = css` :host { @@ -11,15 +10,8 @@ const styles = css` outline: none; height: calc(var(--design-unit) * 1px); margin: calc(var(--design-unit) * 1px) 0; - } - - .progress { background-color: var(--neutral-fill-rest); border-radius: calc(var(--design-unit) * 1px); - width: 100%; - height: 100%; - display: flex; - align-items: center; position: relative; } @@ -29,6 +21,7 @@ const styles = css` height: 100%; transition: all 0.2s ease-in-out; display: flex; + width: calc(var(--percent-complete) * 1%); } .indeterminate { @@ -40,8 +33,8 @@ const styles = css` width: 100%; } - .indeterminate-indicator-1 { - animation: indeterminate-1 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; + .indeterminate .indicator { + animation: indeterminate 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; background-color: var(--accent-foreground-rest); border-radius: calc(var(--design-unit) * 1px); height: 100%; @@ -50,17 +43,7 @@ const styles = css` width: 40%; } - .indeterminate-indicator-2 { - position: absolute; - opacity: 0; - height: 100%; - background-color: var(--accent-foreground-rest); - border-radius: calc(var(--design-unit) * 1px); - width: 60%; - animation: indeterminate-2 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; - } - - @keyframes indeterminate-1 { + @keyframes indeterminate { 0% { opacity: 1; transform: translateX(-100%); @@ -77,41 +60,13 @@ const styles = css` transform: translateX(300%); } } - - @keyframes indeterminate-2 { - 0% { - opacity: 0; - transform: translateX(-150%); - } - 29.99% { - opacity: 0; - } - 30% { - opacity: 1; - transform: translateX(-150%); - } - 100% { - transform: translateX(166.66%); - opacity: 1; - } - } `; FASTProgress.define({ name: "fast-progress", template: progressTemplate({ - indeterminateIndicator1: /* html */ html` - - `, - indeterminateIndicator2: /* html */ html` - - `, + determinateIndicator: progressIndicatorTemplate, + indeterminateIndicator: progressIndicatorTemplate, }), styles, });