Skip to content

Commit

Permalink
Merge pull request #1 from DaPulse/feature/dorsh/linear-progresss-bar
Browse files Browse the repository at this point in the history
feat: linear progress bar
  • Loading branch information
DorShakedMonday authored Oct 7, 2020
2 parents 81d5bb8 + 9ac10c5 commit 946716f
Show file tree
Hide file tree
Showing 15 changed files with 622 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/components/FormattedNumber/FormattedNumber.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { customPropTypes, validateValue } from "./FormattedNumberHelpers";
import "./FormattedNumber.scss";

const { MAX_PRECISION, MIN_PRECISION, DEFAULT_LOCAL } = formatNumberConsts;
const { MAX_PRECISION, MIN_PRECISION } = formatNumberConsts;

const FormattedNumber = ({
value,
Expand Down Expand Up @@ -64,7 +64,7 @@ const FormattedNumber = ({
};

FormattedNumber.formatNumber = formatNumber;
FormattedNumber.localFallBack = DEFAULT_LOCAL;
FormattedNumber.localFallBack = formatNumberConsts.DEFAULT_LOCAL;

const { range } = customPropTypes;

Expand Down Expand Up @@ -111,7 +111,7 @@ FormattedNumber.defaultProps = {
emptyPlaceHolder: "N/A",
decimalPrecision: 2,
compact: true,
local: DEFAULT_LOCAL,
local: FormattedNumber.localFallBack,
rtl: false
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/FormattedNumber/FormattedNumberHelpers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const validateValue = value => {
const isNullOrUndefined = value == null;
const isNullOrUndefined = value === null || value === undefined;
const isEmptyStringWithSpaces =
typeof value === "string" && !value.replace(" ", "").length;
return isNullOrUndefined || isNaN(value) || isEmptyStringWithSpaces;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ import { text, number, select, boolean } from "@storybook/addon-knobs";
import "./formattedNumber.stories.scss";

export const Sandbox = () => (
<div style={{ width: "100%", margin: "40px" }}>
<div style={{ width: "40px", heigt: "40px" }}>
<FormattedNumber
className={select("With custom class", ["custom-class", ""], "")}
value={number("Value", 50000)}
prefix={text("Prefix", "$")}
suffix={text("Suffix", "Human")}
decimalPrecision={number("Precision", 2)}
emptyPlaceHolder={text("Place Holder", "N/A")}
local={text("Local", "en-US")}
compact={boolean("Is compact", true)}
rtl={boolean("Right to Left", false)}
/>
<div style={{ width: "100%", margin: "40px" }}>
<div style={{ width: "40px", height: "40px" }}>
<FormattedNumber
className={select(
"With custom class",
["formatted-number--custom-class", ""],
""
)}
value={number("Value", 50000)}
prefix={text("Prefix", "$")}
suffix={text("Suffix", "Human")}
decimalPrecision={number("Precision", 2)}
emptyPlaceHolder={text("Place Holder", "N/A")}
local={text("Local", "en-US")}
compact={boolean("Is compact", true)}
rtl={boolean("Right to Left", false)}
/>
</div>
</div>
</div>
);

export default {
title: "Components/FormattedNumber",
component: FormattedNumber
title: "Components/FormattedNumber",
component: FormattedNumber
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.custom-class {
.formatted-number--custom-class {
color: var(--color-success);
font-size: 24px;
}
35 changes: 35 additions & 0 deletions src/components/ProgressBars/LinearProgressBar/Bar/Bar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useMemo } from "react";
import cx from "classnames";
import { calculatePercentage } from "../LinearProgressBarHelpers";

const Bar = ({ value, baseClass, barStyle, animated, min, max, color }) => {
const classNames = useMemo(() => {
const classNames = cx(baseClass, `${baseClass}--${barStyle}`, {
[`${baseClass}--animate`]: animated
});
return classNames;
}, [barStyle, animated, animated]);

const valuePercentage = useMemo(() => {
if (value === null || value === undefined) return 0;
return calculatePercentage(value, min, max);
}, [value, min, max]);

if (!value) return null;

return (
<div
role={"progressbar"}
aria-valuenow={valuePercentage}
aria-valuemin={0}
aria-valuemax={100}
className={classNames}
style={{
width: `${valuePercentage}%`,
...(color && { backgroundColor: color })
}}
/>
);
};

export default Bar;
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import React from "react";
import { expect, sinon } from "../../../test/test-helpers";
import LinearProgressBar from "./LinearProgressBar";
import { render, cleanup, act, screen } from "@testing-library/react";

describe("ProgressBars Tests", () => {
let component;

beforeEach(() => {
cleanup();
act(() => {
component = render(<LinearProgressBar id="test" />);
});
});

afterEach(() => {
cleanup();
});

describe("rendering of bars", () => {
it("should not render progress bars if no values provided", () => {
expect(screen.queryAllByRole("progressbar").length).to.eq(0);
});

it("should render progress bars if values are provided", () => {
const { rerender } = component;
act(() => {
component = rerender(<LinearProgressBar value={13} id="test" />);
});
expect(
screen.queryAllByRole("progressbar").length,
"should render only main progress bar"
).to.eq(1);

act(() => {
component = rerender(
<LinearProgressBar value={14} valueSecondary={15} id="test" />
);
});
expect(
screen.queryAllByRole("progressbar").length,
"should render both progress bars"
).to.eq(2);
});
});

describe("indicate progress", () => {
it("should not render progress indication if not set", () => {
const { rerender } = component;
act(() => {
component = rerender(
<LinearProgressBar value={13} max={100} id="test" />
);
});
expect(screen.queryAllByText("13%").length).to.eq(0);
});

it("should render progress indication if set", () => {
const { rerender } = component;
act(() => {
component = rerender(
<LinearProgressBar
value={13}
max={100}
id="test"
indicateProgress={true}
/>
);
});

expect(screen.getByText("13%")).to.be.ok;
});

it("should change progress indication for value changes", () => {
const { rerender } = component;
const value = 13;
for (let i = 0; i < 2; i++) {
act(() => {
component = rerender(
<LinearProgressBar
value={value + i}
max={100}
id="test"
indicateProgress={true}
/>
);
});

expect(screen.getByText(`${value + i}%`)).to.be.ok;
}
});
});

describe("multi progress bars", () => {
const multiValues = [
{ value: 10, color: "rgb(255, 0, 0)" },
{ value: 20, color: "rgb(0, 255, 0)" },
{ value: 30, color: "rgb(0, 0, 255)" }
];
let multiBarsComponent;

beforeEach(() => {
multiBarsComponent = render(
<LinearProgressBar max={100} id="test" multi />
);
});

it("should not render multiple bars if multi is not set", () => {
const { rerender } = component;
act(() => {
component = rerender(
<LinearProgressBar max={100} id="test" multiValues={multiValues} />
);
});

expect(screen.queryAllByRole("progressbar").length).to.eq(0);
});

it("should render all the given bars with the correct values", () => {
const { rerender } = multiBarsComponent;
rerender(
<LinearProgressBar
max={100}
id="test"
multi
multiValues={multiValues}
/>
);

const progressBarElements = screen.queryAllByRole("progressbar");
expect(progressBarElements.length).to.equal(3);
const style = window.getComputedStyle(progressBarElements[1]);
expect(style.backgroundColor).to.equal(`${multiValues[1].color}`);
});

it("should propagate value changes to bars", () => {
const multiValuesWithChange = [
{ value: 100, color: "rgb(255, 255, 255)" },
multiValues[1],
multiValues[2]
];
const { rerender } = multiBarsComponent;
rerender(
<LinearProgressBar
max={100}
id="test"
multi
multiValues={multiValues}
/>
);

let progressBarElements = screen.queryAllByRole("progressbar");
let style = window.getComputedStyle(progressBarElements[0]);
const widthBeforeChange = style.width;

rerender(
<LinearProgressBar
max={100}
id="test"
multi
multiValues={multiValuesWithChange}
/>
);

console.log(multiValuesWithChange);

progressBarElements = screen.queryAllByRole("progressbar");
style = window.getComputedStyle(progressBarElements[2]);
expect(Number(style.width.replace("px", ""))).to.greaterThan(
Number(widthBeforeChange.replace("px", ""))
);
expect(style.backgroundColor).to.equal(multiValuesWithChange[0].color);
});
});
});
Loading

0 comments on commit 946716f

Please sign in to comment.