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
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<progress
class="tedi-progress__bar"
[id]="progressId()"
[max]="100"
[value]="value()"
[attr.aria-describedby]="feedbackTextId()"
></progress>

<span tedi-label size="small" class="tedi-progress__indicator"
>{{ value() }}%</span
>

@if (feedbackText(); as feedback) {
<tedi-feedback-text
[attr.id]="feedbackTextId()"
[text]="feedback.text"
[type]="feedback.type"
[position]="feedback.position"
/>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@use "@tedi-design-system/core/bootstrap-utility/breakpoints";

.tedi-progress {
--_bar-height: var(--progress-bar-height, 8px);
--_bar-radius: var(--progress-bar-radius, 4px);
--_bar-background: var(--progress-bar-background-passive, #f9f9f9);
--_bar-border: var(--progress-bar-border-default, #838494);
--_progress-background: var(--progress-bar-background-active, #005aa3);

display: grid;
grid-template-areas: "bar bar" ". indicator";
grid-template-rows: 24px;
grid-template-columns: 1fr auto;
column-gap: var(--layout-grid-gutters-08, 8px);

&__bar {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
grid-area: bar;
height: var(--_bar-height);
border-radius: var(--_bar-radius);
border: 1px solid var(--_bar-border);
width: 100%;
align-self: center;

&::-webkit-progress-bar {
background: var(--_bar-background);
border-radius: var(--_bar-radius);
}

&::-webkit-progress-value {
background: var(--_progress-background);
border-radius: var(--_bar-radius);
}

&::-moz-progress-bar {
background: var(--_progress-background);
border-radius: var(--_bar-radius);
}
}

&__indicator {
grid-area: indicator;
}

&--small {
--_bar-height: var(--progress-bar-height-sm, 4px);
}

&--horizontal {
@include breakpoints.media-breakpoint-up(sm) {
grid-template-areas: "bar indicator";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { booleanAttribute, ChangeDetectionStrategy, Component, computed, input, ViewEncapsulation } from "@angular/core";
import { ComponentInputs, FeedbackTextComponent, generateUUID, LabelComponent } from "@tedi-design-system/angular/tedi";

@Component({
selector: "tedi-progress-bar",
imports: [FeedbackTextComponent, LabelComponent],
templateUrl: "./progress-bar.component.html",
styleUrl: "./progress-bar.component.scss",
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
"[class.tedi-progress]": "true",
"[class.tedi-progress--small]": "small()",
"[class.tedi-progress--horizontal]": "direction() === 'horizontal'",
},
})
export class ProgressBarComponent {
progressId = input<string>();
value = input<number>(0);
direction = input<'horizontal' | 'vertical'>("horizontal");
small = input(false, { transform: booleanAttribute });
feedbackText = input<ComponentInputs<FeedbackTextComponent>>();

feedbackTextId = computed(() => {
if (this.feedbackText()) {
return generateUUID();
}
return;
});
}
86 changes: 86 additions & 0 deletions community/components/helpers/progress-bar/progress-bar.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Meta, moduleMetadata, StoryObj } from "@storybook/angular";
import { ProgressBarComponent } from "./progress-bar.component";

export default {
title: "Community/Helpers/ProgressBar",
component: ProgressBarComponent,
decorators: [
moduleMetadata({
imports: [ProgressBarComponent],
}),
],
argTypes: {
progressId: {
description:
"Optional id for the progress element to bind with label etc.",
control: "text",
table: {
type: { summary: "string" },
},
},
value: {
description: "Progress value between 0 and 100",
control: { type: "number", min: 0, max: 100, step: 1 },
table: {
type: { summary: "number" },
defaultValue: { summary: "0" },
},
},
direction: {
description: "Orientation of the progress bar",
control: { type: "radio" },
options: ["horizontal", "vertical"],
table: {
type: { summary: "'horizontal' | 'vertical'" },
defaultValue: { summary: "horizontal" },
},
},
small: {
description: "Whether it's the small variant",
control: "boolean",
table: {
type: { summary: "boolean" },
defaultValue: { summary: "false" },
},
},
feedbackText: {
description:
"Optional feedback text displayed alongside the progress bar. Accepts `FeedbackTextComponent` inputs.",
control: "object",
table: {
type: { summary: "ComponentInputs<FeedbackTextComponent>" },
},
},
},
} as Meta<ProgressBarComponent>;

export const Default: StoryObj<ProgressBarComponent> = {
args: {
value: 50,
direction: "horizontal",
small: false,
},
};

export const Small: StoryObj<ProgressBarComponent> = {
args: {
value: 50,
direction: "horizontal",
small: true,
},
};

export const WithFeedback: StoryObj<ProgressBarComponent> = {
args: {
value: 50,
feedbackText: { text: "Uploading…", type: "hint", position: "left" },
},
};

export const Vertical: StoryObj<ProgressBarComponent> = {
args: {
value: 50,
feedbackText: { text: "Uploading…", type: "hint", position: "left" },
direction: "vertical",
},
};
Loading