Skip to content
Merged
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
8 changes: 8 additions & 0 deletions first-gen/packages/progress-circle/src/ProgressCircle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
TemplateResult,
} from '@spectrum-web-components/base';
import { ifDefined } from '@spectrum-web-components/base/src/directives.js';
import { property } from '@spectrum-web-components/base/src/decorators.js';
import { ProgressCircleBase } from '@swc/core/components/progress-circle';

import progressCircleStyles from './progress-circle.css.js';
Expand All @@ -28,6 +29,13 @@ export class ProgressCircle extends ProgressCircleBase {
return [progressCircleStyles];
}

/**
* Static color variant for use on different backgrounds.
* When set to 'white', the component uses white styling for images with a dark tinted background.
*/
@property({ reflect: true, attribute: 'static-color' })
public staticColor?: 'white';

protected override render(): TemplateResult {
const styles = [
this.makeRotation(-180 + (180 / 50) * Math.min(this.progress, 50)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ export abstract class ProgressCircleBase extends SizedMixin(SpectrumElement, {
@property({ type: String })
public label = '';

/**
* Static color variant for use on different backgrounds.
* When set to 'white', the component uses white styling for dark backgrounds.
*/
@property({ reflect: true, attribute: 'static-color' })
public staticColor?: 'white';

/**
* Progress value from 0 to 100.
* Only relevant when indeterminate is false.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@
*/

import { CSSResultArray, html, TemplateResult } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { classMap } from 'lit/directives/class-map.js';

import { ProgressCircleBase } from '@swc/core/components/progress-circle';
import { property } from '@spectrum-web-components/base/src/decorators.js';

import progressCircleStyles from './progress-circle.css';

function capitalize(str?: string): string {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of liked this utility living separately but let me know how you want to handle this in the SWC infrastructure.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, what you've done here looks great. Again, we can circle back after Barebones to discuss how we want to handle utilities like this more generally in 2nd-gen.

if (typeof str !== 'string') {
return '';
}
return str.charAt(0).toUpperCase() + str.slice(1);
}
/**
* A progress circle component that visually represents the completion progress of a task.
* Can be used in both determinate (with specific progress value) and indeterminate (loading) states.
Expand All @@ -25,15 +32,16 @@ import progressCircleStyles from './progress-circle.css';
* @since 2.0.0
* @status stable
* @github https://github.com/adobe/spectrum-web-components/tree/main/second-gen/packages/swc/components/progress-circle
* @figma https://spectrum.figma.com/file/progress-circle
*
* @slot - Optional content to display inside the progress circle (e.g., percentage text)
*
* @csspart track - The background track of the progress circle
* @csspart fill - The filled portion of the progress circle
* @figma https://www.figma.com/design/Mngz9H7WZLbrCvGQf3GnsY/S2-%2F-Desktop?node-id=13061-181
*
* @fires progress-change - Dispatched when the progress value changes
*
* @prop {string} static-color - Static color variant for use on different backgrounds.
* @prop {number} progress - Progress value between 0 and 100.
* @prop {boolean} indeterminate - Indeterminate state for loading.
* @prop {string} size - Size of the component.
* @prop {string} label - Label for the component.
*
* @example
* <swc-progress-circle progress="75" label="Loading progress"></swc-progress-circle>
*
Expand All @@ -45,30 +53,61 @@ export class ProgressCircle extends ProgressCircleBase {
return [progressCircleStyles];
}

/**
* Static color variant for use on different backgrounds.
* When set to 'white', the component uses white styling for images with a dark tinted background.
* When set to 'black', the component uses black styling for images with a light tinted background.
*/
@property({ reflect: true, attribute: 'static-color' })
public staticColor?: 'white' | 'black';

protected override render(): TemplateResult {
const styles = [
this.makeRotation(-180 + (180 / 50) * Math.min(this.progress, 50)),
this.makeRotation(
-180 + (180 / 50) * Math.max(this.progress - 50, 0)
),
];
const masks = ['Mask1', 'Mask2'];
const strokeWidth = this.size === 's' ? 2 : this.size === 'l' ? 6 : 4;
// SVG strokes are centered, so subtract half the stroke width from the radius to create an inner stroke.
const radius = `calc(50% - ${strokeWidth / 2}px)`;

return html`
<slot @slotchange=${this.handleSlotchange}></slot>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the sake of simplifying this for S2, I've regressed some of this functionality by removing the slot and leveraging our SVG approach. Would love to have a larger conversation around this for S2 but this seemed sufficient for the base requirement of getting the S2 styles and rendering into the component.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't really see a good reason for us to continue supporting both the slot-based and attribute-based interfaces for providing accessible label text.

That said, I would like to decouple that decision from the initial Barebones component migration, to keep Barebones scoped as minimally as possible.

On the branch where I've been exploring the nuances of our layering / inheritance scheme, I experimentally re-added the slot to the new, SVG-based render() implementation, and it seemed to work fine; just needed to set display: none; on the slot to echo what's done in 1st-gen.

No need to reverse the change on this branch, but I will include the slot re-addition in my follow-up PR, along with a @todo to make a decision on deprecation.

<div class="track"></div>
<div class="fills">
${masks.map(
(mask, index) => html`
<div class="fill${mask}">
<div
class="fillSub${mask}"
style=${ifDefined(styles[index])}
>
<div class="fill"></div>
</div>
</div>
`
)}
<div
class=${classMap({
['spectrum-ProgressCircle']: true,
[`spectrum-ProgressCircle--indeterminate`]:
this.indeterminate,
[`spectrum-ProgressCircle--static${capitalize(this.staticColor)}`]:
typeof this.staticColor !== 'undefined',
[`spectrum-ProgressCircle--size${this.size?.toUpperCase()}`]:
typeof this.size !== 'undefined',
})}
>
<svg
fill="none"
width="100%"
height="100%"
class="spectrum-outerCircle"
>
<circle
class="spectrum-innerCircle"
cx="50%"
cy="50%"
r=${`calc(50% - ${strokeWidth / 1}px)`}
stroke-width=${strokeWidth}
/>
<circle
cx="50%"
cy="50%"
class="spectrum-ProgressCircle-track"
r=${radius}
/>
<circle
cx="50%"
cy="50%"
r=${radius}
class="spectrum-ProgressCircle-fill"
pathLength="100"
stroke-dasharray="100 200"
stroke-dashoffset=${100 - this.progress}
stroke-linecap="round"
/>
</svg>
</div>
`;
}
Expand Down
Loading
Loading