Skip to content

Commit cedf067

Browse files
authored
Merge pull request #1200 from dxc-technology/fix-1190
Removed material ui from progress bar component
2 parents d0735cc + 0be4c21 commit cedf067

File tree

4 files changed

+198
-63
lines changed

4 files changed

+198
-63
lines changed

lib/src/progress-bar/ProgressBar.stories.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ export const Chromatic = () => (
1414
<Title title="Without labels" theme="light" level={4} />
1515
<DxcProgressBar value={50} showValue />
1616
<Title title="With helperText" theme="light" level={4} />
17-
<DxcProgressBar helperText="Helper text" value={50} showValue />
17+
<DxcProgressBar helperText="Helper text" value={24} showValue />
1818
<Title title="Without default value" theme="light" level={4} />
1919
<DxcProgressBar label="Loading..." showValue />
20+
<Title title="With full value" theme="light" level={4} />
21+
<DxcProgressBar label="Loading..." value={100} showValue />
2022
</ExampleContainer>
2123
<Title title="Margins" theme="light" level={2} />
2224
<ExampleContainer>

lib/src/progress-bar/ProgressBar.test.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,61 @@ import { render } from "@testing-library/react";
33
import DxcProgressBar from "./ProgressBar";
44

55
describe("ProgressBar component tests", () => {
6-
test("ProgressBar renders with label", () => {
7-
const { getByText } = render(<DxcProgressBar label="test-label"></DxcProgressBar>);
8-
expect(getByText("test-label")).toBeTruthy();
9-
});
10-
11-
test("Overlay progressBar renders with label", () => {
12-
const { getByText } = render(<DxcProgressBar label="test-label" overlay></DxcProgressBar>);
6+
test("ProgressBar renders with label and helperText", () => {
7+
const { getByText } = render(<DxcProgressBar label="test-label" helperText="helper-text"></DxcProgressBar>);
138
expect(getByText("test-label")).toBeTruthy();
9+
expect(getByText("helper-text")).toBeTruthy();
1410
});
1511

1612
test("ProgressBar renders with default value", () => {
17-
const { getByText } = render(<DxcProgressBar showValue></DxcProgressBar>);
13+
const value = 0;
14+
const { getByText, getByRole } = render(<DxcProgressBar showValue></DxcProgressBar>);
15+
const progressBar = getByRole("progressbar");
1816
expect(getByText("0 %")).toBeTruthy();
17+
expect(progressBar.getAttribute("aria-valuenow")).toEqual(value.toString());
1918
});
2019

21-
test("Overlay progressBar renders with default value", () => {
22-
const { getByText } = render(<DxcProgressBar showValue overlay></DxcProgressBar>);
20+
test("ProgressBar renders with value", () => {
21+
const value = 25;
22+
const { getByText, getByRole } = render(<DxcProgressBar showValue value={value}></DxcProgressBar>);
23+
const progressBar = getByRole("progressbar");
24+
expect(getByText("25 %")).toBeTruthy();
25+
expect(progressBar.getAttribute("aria-valuenow")).toEqual(value.toString());
26+
});
27+
28+
test("ProgressBar renders with negative value", () => {
29+
const value = 0;
30+
const { getByText, getByRole } = render(<DxcProgressBar showValue value={-20}></DxcProgressBar>);
31+
const progressBar = getByRole("progressbar");
2332
expect(getByText("0 %")).toBeTruthy();
33+
expect(progressBar.getAttribute("aria-valuenow")).toEqual(value.toString());
2434
});
2535

26-
test("ProgressBar renders with value", () => {
27-
const { getByText } = render(<DxcProgressBar showValue value={25}></DxcProgressBar>);
28-
expect(getByText("25 %")).toBeTruthy();
36+
test("ProgressBar renders as indeterminate", () => {
37+
const { getByRole } = render(<DxcProgressBar></DxcProgressBar>);
38+
const progressBar = getByRole("progressbar");
39+
expect(progressBar.getAttribute("aria-valuenow")).toBe(null);
40+
});
41+
42+
test("Overlay progressBar renders with label and helperText", () => {
43+
const { getByText } = render(<DxcProgressBar label="test-label" helperText="helper-text" overlay></DxcProgressBar>);
44+
expect(getByText("test-label")).toBeTruthy();
45+
expect(getByText("helper-text")).toBeTruthy();
46+
});
47+
48+
test("Overlay progressBar renders with default value", () => {
49+
const value = 0;
50+
const { getByText, getByRole } = render(<DxcProgressBar showValue overlay></DxcProgressBar>);
51+
const progressBar = getByRole("progressbar");
52+
expect(getByText("0 %")).toBeTruthy();
53+
expect(progressBar.getAttribute("aria-valuenow")).toEqual(value.toString());
2954
});
3055

3156
test("Overlay progressBar renders with value", () => {
32-
const { getByText } = render(<DxcProgressBar showValue value={25} overlay></DxcProgressBar>);
57+
const value = 25;
58+
const { getByText, getByRole } = render(<DxcProgressBar showValue value={value} overlay></DxcProgressBar>);
59+
const progressBar = getByRole("progressbar");
3360
expect(getByText("25 %")).toBeTruthy();
61+
expect(progressBar.getAttribute("aria-valuenow")).toEqual(value.toString());
3462
});
3563
});
Lines changed: 150 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
// @ts-nocheck
2-
import React, { useContext } from "react";
1+
import React, { useContext, useEffect, useState } from "react";
32
import styled, { ThemeProvider } from "styled-components";
4-
import LinearProgress from "@material-ui/core/LinearProgress";
5-
63
import { spaces } from "../common/variables.js";
74
import useTheme from "../useTheme";
85
import BackgroundColorContext from "../BackgroundColorContext";
9-
import ProgressBarPropsType from "./types";
6+
import { Size, Props, Space } from "./types";
107

118
const DxcProgressBar = ({
129
label = "",
@@ -15,70 +12,96 @@ const DxcProgressBar = ({
1512
value,
1613
showValue = false,
1714
margin,
18-
}: ProgressBarPropsType): JSX.Element => {
15+
}: Props): JSX.Element => {
1916
const colorsTheme = useTheme();
2017
const backgroundType = useContext(BackgroundColorContext);
18+
const [valueProgressBar, setValueProgressBar] = useState(0);
19+
20+
useEffect(() => {
21+
setValueProgressBar(
22+
value === null || value === undefined || value < 0 ? 0 : value >= 0 && value <= 100 ? value : 100
23+
);
24+
}, [value]);
2125

2226
return (
2327
<ThemeProvider theme={colorsTheme.progressBar}>
2428
<BackgroundProgressBar overlay={overlay}>
25-
<DXCProgressBar overlay={overlay} margin={margin} backgroundType={backgroundType}>
29+
<ProgressBarContainer overlay={overlay} margin={margin}>
2630
<InfoProgressBar>
27-
<ProgressBarLabel overlay={overlay} backgroundType={backgroundType}>
31+
<ProgressBarLabel overlay={overlay} backgroundType={backgroundType} aria-label={label || undefined}>
2832
{label}
2933
</ProgressBarLabel>
30-
<ProgressBarProgress overlay={overlay} showValue={showValue} backgroundType={backgroundType}>
31-
{value === null || value === undefined ? 0 : value >= 0 && value <= 100 ? value : value < 0 ? 0 : 100} %
34+
<ProgressBarProgress
35+
overlay={overlay}
36+
showValue={showValue}
37+
backgroundType={backgroundType}
38+
value={valueProgressBar}
39+
>
40+
{valueProgressBar} %
3241
</ProgressBarProgress>
3342
</InfoProgressBar>
3443
<LinearProgress
35-
variant={showValue ? "determinate" : "indeterminate"}
36-
value={value === null || value === undefined ? 0 : value >= 0 && value <= 100 ? value : value < 0 ? 0 : 100}
37-
/>
44+
role="progressbar"
45+
helperText={helperText}
46+
aria-valuenow={showValue ? valueProgressBar : undefined}
47+
>
48+
<LinearProgressBar
49+
backgroundType={backgroundType}
50+
variant={showValue ? "determinate" : "indeterminate"}
51+
container="first"
52+
value={valueProgressBar}
53+
></LinearProgressBar>
54+
{!showValue && (
55+
<LinearProgressBar
56+
backgroundType={backgroundType}
57+
variant="indeterminate"
58+
container="second"
59+
value={valueProgressBar}
60+
></LinearProgressBar>
61+
)}
62+
</LinearProgress>
3863
{helperText && (
3964
<HelperText overlay={overlay} backgroundType={backgroundType}>
4065
{helperText}
4166
</HelperText>
4267
)}
43-
</DXCProgressBar>
68+
</ProgressBarContainer>
4469
</BackgroundProgressBar>
4570
</ThemeProvider>
4671
);
4772
};
4873

49-
const BackgroundProgressBar = styled.div`
50-
background-color: ${(props) => (props.overlay === true ? `${props.theme.overlayColor}` : "transparent")};
51-
opacity: ${(props) => props.overlay === true && "0.8"};
52-
width: ${(props) => (props.overlay === true ? "100%" : "")};
74+
const BackgroundProgressBar = styled.div<{ overlay?: boolean }>`
75+
${({ overlay, theme }) =>
76+
overlay
77+
? `background-color: ${theme.overlayColor};
78+
opacity: 0.8;
79+
width: 100%;
80+
justify-content: center;
81+
height: 100vh;
82+
align-items: center;
83+
max-width: 100%;
84+
position: fixed;
85+
top: 0;
86+
bottom: 0;
87+
left: 0;
88+
right: 0;
89+
z-index: 1300;`
90+
: `background-color: "transparent";`}
5391
display: flex;
5492
flex-wrap: wrap;
55-
justify-content: ${(props) => (props.overlay === true ? "center" : "")};
56-
height: ${(props) => (props.overlay === true ? "100vh" : "")};
57-
align-items: ${(props) => (props.overlay === true ? "center" : "")};
5893
min-width: 100px;
59-
max-width: ${(props) => (props.overlay === true ? "100%" : "")};
60-
position: ${(props) => (props.overlay === true ? "fixed" : "")};
61-
top: ${(props) => (props.overlay === true ? "0" : "")};
62-
bottom: ${(props) => (props.overlay === true ? "0" : "")};
63-
left: ${(props) => (props.overlay === true ? "0" : "")};
64-
right: ${(props) => (props.overlay === true ? "0" : "")};
65-
z-index: ${(props) => (props.overlay ? 1300 : "")};
6694
width: 100%;
6795
`;
6896

69-
const DXCProgressBar = styled.div`
97+
type ProgressBarContainerProps = {
98+
overlay: boolean;
99+
margin: Size | Space;
100+
};
101+
102+
const ProgressBarContainer = styled.div<ProgressBarContainerProps>`
70103
z-index: ${(props) => (props.overlay === true && "100") || "0"};
71104
width: ${(props) => (props.overlay === true ? "80%" : "100%")};
72-
.MuiLinearProgress-root {
73-
height: ${(props) => props.theme.thickness};
74-
background-color: ${(props) => props.theme.totalLineColor};
75-
border-radius: ${(props) => props.theme.borderRadius};
76-
margin-bottom: ${(props) => props.helperText !== "" && "8px"};
77-
}
78-
.MuiLinearProgress-bar {
79-
background-color: ${(props) =>
80-
props.backgroundType === "dark" ? props.theme.trackLineColorOnDark : props.theme.trackLineColor};
81-
}
82105
margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")};
83106
margin-top: ${(props) =>
84107
props.margin && typeof props.margin === "object" && props.margin.top ? spaces[props.margin.top] : ""};
@@ -101,7 +124,12 @@ const InfoProgressBar = styled.div`
101124
justify-content: space-between;
102125
`;
103126

104-
const ProgressBarLabel = styled.div`
127+
type LabelProps = {
128+
backgroundType: "dark" | "light";
129+
overlay: boolean;
130+
};
131+
132+
const ProgressBarLabel = styled.div<LabelProps>`
105133
font-family: ${(props) => props.theme.labelFontFamily};
106134
font-style: ${(props) => props.theme.labelFontStyle};
107135
font-size: ${(props) => props.theme.labelFontSize};
@@ -119,7 +147,14 @@ const ProgressBarLabel = styled.div`
119147
text-overflow: ellipsis;
120148
`;
121149

122-
const ProgressBarProgress = styled.div`
150+
type ProgressProps = {
151+
backgroundType: "dark" | "light";
152+
overlay: boolean;
153+
showValue: boolean;
154+
value: number;
155+
};
156+
157+
const ProgressBarProgress = styled.div<ProgressProps>`
123158
font-family: ${(props) => props.theme.valueFontFamily};
124159
font-style: ${(props) => props.theme.valueFontStyle};
125160
font-size: ${(props) => props.theme.valueFontSize};
@@ -131,11 +166,17 @@ const ProgressBarProgress = styled.div`
131166
: props.overlay === true
132167
? "#FFFFFF"
133168
: props.theme.valueFontColor};
134-
display: ${(props) => (props.value !== "" && props.showValue === true && "block") || "none"};
169+
display: ${(props) =>
170+
(props.value !== undefined && props.value !== null && props.showValue === true && "block") || "none"};
135171
flex-shrink: 0;
136172
`;
137173

138-
const HelperText = styled.span`
174+
type HelperTextProps = {
175+
backgroundType: "dark" | "light";
176+
overlay: boolean;
177+
};
178+
179+
const HelperText = styled.span<HelperTextProps>`
139180
color: ${(props) =>
140181
props.backgroundType === "dark"
141182
? props.theme.helperTextFontColorOnDark
@@ -149,4 +190,70 @@ const HelperText = styled.span`
149190
line-height: 1.5em;
150191
`;
151192

193+
const LinearProgress = styled.div<{ helperText?: string }>`
194+
height: ${(props) => props.theme.thickness};
195+
background-color: ${(props) => props.theme.totalLineColor};
196+
border-radius: ${(props) => props.theme.borderRadius};
197+
margin-bottom: ${(props) => props.helperText !== "" && "8px"};
198+
overflow: hidden;
199+
position: relative;
200+
`;
201+
202+
type LinearProgressBarProps = {
203+
backgroundType: "dark" | "light";
204+
variant: "determinate" | "indeterminate";
205+
value: number;
206+
container: string;
207+
};
208+
209+
const LinearProgressBar = styled.span<LinearProgressBarProps>`
210+
background-color: ${(props) =>
211+
props.backgroundType === "dark" ? props.theme.trackLineColorOnDark : props.theme.trackLineColor};
212+
transform: ${(props) => `translateX(-${props.variant === "determinate" ? 100 - props.value : 0}%)`};
213+
top: 0;
214+
left: 0;
215+
width: 100%;
216+
bottom: 0;
217+
position: absolute;
218+
transition: ${(props) => (props.variant === "determinate" ? "transform .4s linear" : "transform 0.2s linear")};
219+
transform-origin: left;
220+
${(props) => props.variant === "indeterminate" && "width: auto;"};
221+
${(props) =>
222+
props.variant === "indeterminate"
223+
? props.container === "first"
224+
? "animation: keyframes-indeterminate-first 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;"
225+
: "animation: keyframes-indeterminate-second 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite;"
226+
: ""};
227+
228+
@keyframes keyframes-indeterminate-first {
229+
0% {
230+
left: -35%;
231+
right: 100%;
232+
}
233+
60% {
234+
left: 100%;
235+
right: -90%;
236+
}
237+
100% {
238+
left: 100%;
239+
right: -90%;
240+
}
241+
}
242+
243+
@keyframes keyframes-indeterminate-second {
244+
0% {
245+
left: -200%;
246+
right: 100%;
247+
}
248+
60% {
249+
left: 107%;
250+
right: -8%;
251+
}
252+
100% {
253+
left: 107%;
254+
right: -8%;
255+
}
256+
}
257+
`;
258+
152259
export default DxcProgressBar;

lib/src/progress-bar/types.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge";
2-
type Size = {
1+
export type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge";
2+
export type Size = {
33
top?: Space;
44
bottom?: Space;
55
left?: Space;
66
right?: Space;
77
};
88

9-
type Props = {
9+
export type Props = {
1010
/**
1111
* Text to be placed above the progress bar.
1212
*/
@@ -35,5 +35,3 @@ type Props = {
3535
*/
3636
margin?: Space | Size;
3737
};
38-
39-
export default Props;

0 commit comments

Comments
 (0)