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
7 changes: 7 additions & 0 deletions .changeset/floppy-tigers-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@sl-design-system/progress-bar': minor
---

- Refactored to use new contextual tokens
- Moved sub label (in main slot) above the progress bar
- The text in the main slot in `error` variant is no longer the danger color. To communicate errors you can use the new `error` slot. That is placed underneath the progressbar and shown in a contrasting colour.
86 changes: 25 additions & 61 deletions packages/components/progress-bar/src/progress-bar.scss
Original file line number Diff line number Diff line change
@@ -1,54 +1,26 @@
$variants: success, warning, error;

:host {
--_bar-background: var(--sl-color-progressbar-background);
--_bar-thickness: var(--sl-size-progressbar);
--_border-radius: var(--sl-border-radius-full);
--_gap: var(--sl-space-progressbar-vertical-gap);
--_helper-color: var(--sl-color-input-helper-text-default);
--_helper-color-error: var(--sl-color-progressbar-error-track);
--_helper-font: var(--sl-text-input-field-label-hint-md);
--_indeterminate-duration: 20s;
--_label-color: var(--sl-color-input-field-label-text-default);
--_label-font: var(--sl-text-input-field-label-label-md);
--_label-gap: var(--sl-space-progressbar-horizontal-gap);
--_progress-background: var(--sl-color-progressbar-active-track);
--_icon-fill: var(--sl-color-progressbar-active-track);
--_fill-color: var(--sl-color-border-selected);

@media (prefers-reduced-motion: no-preference) {
--_indeterminate-duration: 1.2s;
}

color: var(--_helper-color);
display: flex;
flex-direction: column;
font: var(--_helper-font);
gap: var(--_gap);
gap: var(--sl-space-050);
}

@each $variant in $variants {
:host([variant='#{$variant}']:not([indeterminate])) {
--_progress-background: var(--sl-color-progressbar-#{$variant}-track);
--_icon-fill: var(--sl-color-progressbar-#{$variant}-track);
}

:host([variant='#{$variant}'][indeterminate]) .progress {
--_progress-background: var(--sl-color-progressbar-#{$variant}-track);
--_icon-fill: var(--sl-color-progressbar-#{$variant}-track);

animation: none;
inline-size: 100%;
}
:host([variant='success']) {
--_fill-color: var(--sl-color-border-positive-plain);
}

:host([variant='#{$variant}'][indeterminate]) {
.label sl-icon {
--sl-icon-fill-default: var(--sl-color-progressbar-#{$variant}-track);
}
:host([variant='warning']) {
--_fill-color: var(--sl-color-border-caution-plain);
}

.helper sl-icon {
--sl-icon-fill-default: var(--sl-color-progressbar-#{$variant}-track);
}
}
:host([variant='error']) {
--_fill-color: var(--sl-color-border-negative-plain);
}

:host([indeterminate]) .progress {
Expand All @@ -60,51 +32,43 @@ $variants: success, warning, error;
inline-size: 100%;
}

:host([variant='error']) ::slotted(*) {
color: var(--_helper-color-error);
}

.label {
color: var(--_label-color);
color: var(--sl-color-foreground-bold);
display: flex;
font: var(--_label-font);
gap: var(--_label-gap);
font: var(--sl-text-new-heading-sm);
gap: var(--sl-space-100);
justify-content: space-between;
}

sl-icon {
--sl-icon-fill-default: var(--_icon-fill);
}
sl-icon {
--sl-icon-fill-default: var(--_fill-color);
}

.helper {
color: var(--sl-color-foreground-subtlest);
display: flex;
gap: var(--_label-gap);
gap: var(--sl-space-100);
justify-content: space-between;

sl-icon {
--sl-icon-fill-default: var(--_icon-fill);
}
}

::slotted(*) {
color: var(--_helper-color);
font: var(--_helper-font);
slot[name='error'] {
color: var(--sl-color-foreground-negative-plain);
}

.container {
align-items: stretch;
background: var(--_bar-background);
block-size: var(--_bar-thickness);
border-radius: var(--_border-radius);
background: var(--sl-color-border-plain);
block-size: var(--sl-size-050);
border-radius: var(--sl-border-radius-full);
display: flex;
inline-size: 100%;
overflow: hidden;
position: relative;
}

.progress {
background: var(--_progress-background);
border-radius: var(--_border-radius);
background: var(--_fill-color);
border-radius: var(--sl-border-radius-full);
transform-origin: left;
transition:
400ms transform,
Expand Down
27 changes: 12 additions & 15 deletions packages/components/progress-bar/src/progress-bar.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default {
render: ({ indeterminate, variant, value, label, slot }) => {
return html`
<sl-progress-bar ?indeterminate=${indeterminate} .value=${value} .label=${label} .variant=${variant}>
${slot?.() ?? html`<span>Uploaded ${value}% of 100%</span>`}
${slot?.() ?? html`Uploaded ${value}% of 100%`}
</sl-progress-bar>
`;
}
Expand Down Expand Up @@ -201,36 +201,33 @@ export const All: StoryObj = {
}
</style>
<h2>With label</h2>
<sl-progress-bar value="20" label="Progress bar label in the default variant">
<span>20% of 100%</span>
</sl-progress-bar>
<sl-progress-bar value="20" label="Progress bar label in the default variant"> 20% of 100% </sl-progress-bar>
<sl-progress-bar value="100" label="Progress bar label in the success variant" variant="success">
<span>File downloaded</span>
File downloaded
</sl-progress-bar>
<sl-progress-bar value="40" label="Progress bar label in the warning variant" variant="warning">
<span>40% of 100%</span>
40% of 100%
</sl-progress-bar>
<sl-progress-bar value="50" label="Progress bar label in the error variant" variant="error">
<span>50% of 100%</span>
50% of 100%
</sl-progress-bar>
<sl-progress-bar indeterminate label="Progress bar label in the indeterminate state">
<span>Preparing download</span>
Preparing download
</sl-progress-bar>
<h2>No label</h2>
<sl-progress-bar value="20" aria-label="Progress bar label in the default variant">
<span>20% of 100%</span>
</sl-progress-bar>
<sl-progress-bar value="20" aria-label="Progress bar label in the default variant"> 20% of 100% </sl-progress-bar>
<sl-progress-bar value="100" variant="success" aria-label="Progress bar label in the success variant">
<span>File uploaded</span>
File uploaded
</sl-progress-bar>
<sl-progress-bar value="40" variant="warning" aria-label="Progress bar label in the warning variant">
<span>40% of 100%</span>
40% of 100%
</sl-progress-bar>
<sl-progress-bar value="50" variant="error" aria-label="Progress bar label in the error variant">
<span>50% of 100%</span>
50% of 100%
<span slot="error">This is a <strong>custom</strong> error</span>
</sl-progress-bar>
<sl-progress-bar indeterminate aria-label="Progress bar label in the indeterminate state">
<span>Preparing download</span>
Preparing download
</sl-progress-bar>
`
};
33 changes: 18 additions & 15 deletions packages/components/progress-bar/src/progress-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,22 @@ export class ProgressBar extends ScopedElementsMixin(LitElement) {

override render(): TemplateResult {
return html`
${this.label
? html`
<div id="label" class="label">
${this.label} ${this.variant ? html`<sl-icon .name=${this.iconName} size="md"></sl-icon>` : nothing}
</div>
`
: nothing}
<div>
${this.label
? html`
<div id="label" class="label">
${this.label} ${this.variant ? html`<sl-icon .name=${this.iconName} size="md"></sl-icon>` : nothing}
</div>
`
: nothing}
<div id="helper" class="helper">
<slot></slot>
<span id="live" aria-busy=${ifDefined(this.indeterminate)}>
${msg('state')}: ${this.variant ? html`${this.#getLocalizedVariant()}` : html`${msg('active')}`}
</span>
${this.variant && !this.label ? html`<sl-icon .name=${this.iconName} size="md"></sl-icon>` : nothing}
</div>
</div>
<div
aria-labelledby=${ifDefined(this.label ? 'label' : undefined)}
aria-describedby="helper"
Expand All @@ -104,16 +113,10 @@ export class ProgressBar extends ScopedElementsMixin(LitElement) {
>
<div
class="progress"
style=${styleMap({ transform: !this.indeterminate || this.variant ? `scaleX(${this.value / 100})` : '' })}
style=${styleMap({ width: !this.indeterminate || this.variant ? `${this.value}%` : '' })}
></div>
</div>
<div id="helper" class="helper">
<slot></slot>
<span id="live" aria-busy=${ifDefined(this.indeterminate)}>
${msg('state')}: ${this.variant ? html`${this.#getLocalizedVariant()}` : html`${msg('active')}`}
</span>
${this.variant && !this.label ? html`<sl-icon .name=${this.iconName} size="md"></sl-icon>` : nothing}
</div>
<slot name="error"></slot>
`;
}

Expand Down