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

Feat: Progress bar Issue#22 #53

Merged
merged 10 commits into from
Feb 27, 2024
58 changes: 58 additions & 0 deletions src/components/ProgressBar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Component } from 'pet-dex-utilities';
import './index.scss';

const events = ['setProgress'];

const html = `
<div class="progress-bar" data-select="progress-bar">
<div class="progress-bar__background"></div>
<div class="progress-bar__foreground" data-select="progress-bar-foreground"></div>
</div>
`;

function isValueValid(value, minimum, maximum) {
return value >= minimum && value <= maximum;
}

function getRatio(value, minimum, maximum) {
return (value - minimum) / (maximum - minimum);
}

function getWidthFormated(value, minimum, maximum) {
const ratio = getRatio(value, minimum, maximum);
return `${ratio * 100}%`;
}
JonySamarelli marked this conversation as resolved.
Show resolved Hide resolved

export default function ProgressBar(minimum, maximum, startValue = minimum) {
Component.call(this, { html, events });
this.minimum = minimum;
this.maximum = maximum;
this.currentProgress = isValueValid(startValue, this.minimum, this.maximum)
? startValue
: this.minimum;

this.setProgress(this.currentProgress);
this.selected.get('progress-bar').ariaValueMin = this.minimum;
this.selected.get('progress-bar').ariaValueMax = this.maximum;
this.selected.get('progress-bar').ariaValueNow = this.currentProgress;
}

ProgressBar.prototype = Object.assign(
ProgressBar.prototype,
Component.prototype,
{
setProgress(value) {
if (!isValueValid(value, this.minimum, this.maximum)) return;
this.currentProgress = value;
this.selected.get('progress-bar-foreground').style.width = getWidthFormated(this.currentProgress, this.minimum, this.maximum);
this.selected.get('progress-bar').ariaValueNow = this.currentProgress;
this.emit('setProgress', this.currentProgress);
},
next() {
this.setProgress(this.currentProgress + 1);
},
prev() {
this.setProgress(this.currentProgress - 1);
},
},
);
37 changes: 37 additions & 0 deletions src/components/ProgressBar/index.scss
JonySamarelli marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@use '~styles/colors.scss' as colors;

.progress-bar {
width: 100%;

display: grid;

&__background {
width: 100%;
height: 50%;

grid-row: 1;
grid-column: 1;

position: relative;
top: 25%;
z-index: 0;

background-color: colors.$grey150;
border-radius: 100000px;
}

&__foreground {
height: 6px;

grid-row: 1;
grid-column: 1;

position: relative;
z-index: 1;

background-color: colors.$yellow500;
border-radius: 100000px;

transition: width 1s ease-in-out;
}
}
50 changes: 50 additions & 0 deletions src/components/ProgressBar/index.spec.js
JonySamarelli marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { describe, expect, it, test } from 'vitest';
import ProgressBar from './index';

describe('ProgressBar', () => {
it('is a Function', () => {
expect(ProgressBar).toBeInstanceOf(Function);
});

it('returns an object', () => {
expect(new ProgressBar()).toBeInstanceOf(Object);
});

test.each([
[-1, 0],
[0, 0],
[1, 1],
[2, 2],
[3, 3],
[4, 4],
[5, 5],
[6, 0],
])('it initializes with a specific valid value set', (value, expected) => {
const progressBar = new ProgressBar(0, 5, value);
expect(progressBar.value).toBe(expected);
});

it('increments value when next is called', () => {
const progressBar = new ProgressBar(0, 5, 10);
progressBar.next();
expect(progressBar.value).toBe(1);
});

it('keeps the maximum value when next is called and it is already at the maximum', () => {
const progressBar = new ProgressBar(0, 5, 5);
progressBar.next();
expect(progressBar.value).toBe(progressBar.maximum);
});

it('decrements value when previous is called', () => {
const progressBar = new ProgressBar(0, 5, 5);
progressBar.previous();
expect(progressBar.value).toBe(4);
});

it('keeps the minimum value when previous is called and it is already at the minimum', () => {
const progressBar = new ProgressBar(0, 5, 10);
progressBar.previous();
expect(progressBar.value).toBe(progressBar.minimum);
});
});
5 changes: 2 additions & 3 deletions src/styles/base.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
@use 'reset-css/sass/reset.scss';

html,
body {
:root {
font-size: 62.5%;
}

.root {
body {
Alecell marked this conversation as resolved.
Show resolved Hide resolved
font-size: 1.6rem;
}
2 changes: 2 additions & 0 deletions src/styles/colors.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
$appColor: rgb(0, 52, 89);
$appContentColor: rgb(255, 255, 255);
$grey150: rgb(236, 239, 242);
$gray800: rgb(57, 67, 79);
$gray600: rgb(128, 139, 154);
$blue500: rgb(27, 133, 243);
$yellow500: rgb(255, 197, 66);