Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Foundation: Update Progress templates #6799

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Foundation: Update Progress templates (see https://github.com/microsoft/fast/pull/6799)",
"packageName": "@microsoft/fast-foundation",
"email": "[email protected]",
"dependentChangeType": "prerelease"
}
11 changes: 9 additions & 2 deletions packages/web-components/fast-foundation/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -2550,14 +2550,21 @@ export type PickerOptions = {
// @public
export function pickerTemplate<T extends FASTPicker>(options: PickerOptions): ElementViewTemplate<T>;

// @public
export const progressIndicatorTemplate: ViewTemplate<any, any>;

// @public
export type ProgressOptions = {
indeterminateIndicator1?: StaticallyComposableHTML<FASTProgress>;
indeterminateIndicator2?: StaticallyComposableHTML<FASTProgress>;
determinateIndicator?: StaticallyComposableHTML<FASTProgress>;
indeterminateIndicator?: StaticallyComposableHTML<FASTProgress>;
};

// @public
export const progressRingIndicatorTemplate: ViewTemplate<any, any>;

// @public
export type ProgressRingOptions = {
determinateIndicator?: StaticallyComposableHTML<FASTProgressRing>;
indeterminateIndicator?: StaticallyComposableHTML<FASTProgressRing>;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export { FASTProgressRing } from "./progress-ring.js";
export { ProgressRingOptions } from "./progress-ring.options.js";
export { progressRingTemplate } from "./progress-ring.template.js";
export {
progressRingIndicatorTemplate,
progressRingTemplate,
} from "./progress-ring.template.js";
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ import type { FASTProgressRing } from "./progress-ring.js";
* @public
*/
export type ProgressRingOptions = {
determinateIndicator?: StaticallyComposableHTML<FASTProgressRing>;
indeterminateIndicator?: StaticallyComposableHTML<FASTProgressRing>;
};
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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 */ `
<fast-progress-ring value="50"></fast-progress-ring>
`;
});

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 */ `
<fast-progress-ring></fast-progress-ring>
`;
});

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 */ `
<fast-progress-ring value="50"></fast-progress-ring>
`);

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 */ `
<fast-progress-ring value="0"></fast-progress-ring>
`);

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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ 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;
/**
* The default template for the indicator element of the {@link @microsoft/fast-foundation#FASTProgressRing} component.
* @public
*/
export const progressRingIndicatorTemplate = html`
<svg viewBox="0 0 16 16" class="progress">
<circle class="background" part="background" cx="8px" cy="8px" r="7px"></circle>
<circle class="indicator" part="indicator" cx="8px" cy="8px" r="7px"></circle>
</svg>
`;

/**
* The template for the {@link @microsoft/fast-foundation#FASTProgressRing} component.
Expand All @@ -23,35 +32,22 @@ export function progressRingTemplate<T extends FASTProgressRing>(
${when(
x => typeof x.value === "number",
html<T>`
<svg
class="progress"
part="progress"
viewBox="0 0 16 16"
slot="determinate"
<span
class="determinate"
part="determinate"
style="--percent-complete: ${x => x.percentComplete}"
>
<circle
class="background"
part="background"
cx="8px"
cy="8px"
r="7px"
></circle>
<circle
class="determinate"
part="determinate"
style="stroke-dasharray: ${x =>
(progressSegments * x.percentComplete) /
100}px ${progressSegments}px"
cx="8px"
cy="8px"
r="7px"
></circle>
</svg>
<slot name="determinate">
${staticallyCompose(options.determinateIndicator)}
</slot>
</span>
`,
html<T>`
<slot name="indeterminate">
${staticallyCompose(options.indeterminateIndicator)}
</slot>
<span class="indeterminate" part="indeterminate">
<slot name="indeterminate">
${staticallyCompose(options.indeterminateIndicator)}
</slot>
</span>
`
)}
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { FASTBaseProgress } from "../progress/base-progress.js";

/**
* An circular Progress HTML Element.
* A 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
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -24,17 +26,22 @@ 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%;
transform: rotate(-90deg);
transition: all 0.2s ease-in-out;
}

.indeterminate-indicator-1 {
.indeterminate .indicator {
stroke: var(--accent-foreground-rest);
fill: none;
stroke-width: 2px;
Expand Down Expand Up @@ -64,24 +71,8 @@ const styles = css`
FASTProgressRing.define({
name: "fast-progress-ring",
template: progressRingTemplate({
indeterminateIndicator: /* html */ html`
<svg class="progress" part="progress" viewBox="0 0 16 16">
<circle
class="background"
part="background"
cx="8px"
cy="8px"
r="7px"
></circle>
<circle
class="indeterminate-indicator-1"
part="indeterminate-indicator-1"
cx="8px"
cy="8px"
r="7px"
></circle>
</svg>
`,
determinateIndicator: progressRingIndicatorTemplate,
indeterminateIndicator: progressRingIndicatorTemplate,
}),
styles,
});
24 changes: 11 additions & 13 deletions packages/web-components/fast-foundation/src/progress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ id: progress
title: fast-progress
sidebar_label: progress
custom_edit_url: https://github.com/microsoft/fast/edit/master/packages/web-components/fast-foundation/src/progress/README.md
description: fast-progress is a web component used to display the length of time a process will take or to visualize percentage value.
description: fast-progress is used to display the length of time a process will take or to visualize percentage value or to represent an unspecified wait time.
---

*Progress* and *progress ring* are used to display the length of time a process will take or to visualize percentage value (referred to as a **determinate** state) and to represent an unspecified wait time (referred to as an **indeterminate** state). *Progress* components are typically visually represented by a circular or linear animation. When the `value` attribute is passed the state is **determinate**, otherwise it is **indeterminate**.
Expand Down Expand Up @@ -40,8 +40,7 @@ import {
provideFASTDesignSystem()
.register(
fastProgress({
indeterminateIndicator1: `...your indeterminate indicator...`,
indeterminateIndicator2: `...your indeterminate indicator...`
indeterminateIndicator: `...your indeterminate indicator...`
}),
fastProgressRing({
indeterminateIndicator: `...your indeterminate indicator...`
Expand Down Expand Up @@ -79,8 +78,7 @@ export const myProgress = Progress.compose<ProgressOptions>({
baseName: "progress",
template,
styles,
indeterminateIndicator1: `...default indeterminate indicator...`,
indeterminateIndicator2: `...default indeterminate indicator...`,
indeterminateIndicator: `...default indeterminate indicator...`,
});
```

Expand Down Expand Up @@ -174,17 +172,17 @@ export const myProgressRing = ProgressRing.compose<ProgressRingOptions>({

#### 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 |

<hr/>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { FASTBaseProgress } from "./base-progress.js";
export { FASTProgress } from "./progress.js";
export { ProgressOptions } from "./progress.options.js";
export { progressTemplate } from "./progress.template.js";
export { progressIndicatorTemplate, progressTemplate } from "./progress.template.js";
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import type { FASTProgress } from "./progress.js";
* @public
*/
export type ProgressOptions = {
indeterminateIndicator1?: StaticallyComposableHTML<FASTProgress>;
indeterminateIndicator2?: StaticallyComposableHTML<FASTProgress>;
determinateIndicator?: StaticallyComposableHTML<FASTProgress>;
indeterminateIndicator?: StaticallyComposableHTML<FASTProgress>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */ `
<fast-progress value="50"></fast-progress>
`;
});

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 */ `
<fast-progress></fast-progress>
`;
});

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 () => {
Expand Down
Loading
Loading