Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 2a7fb16

Browse files
Merge pull request #65 from topcoder-platform/dev
[PROD] Release 1.0.2
2 parents 6462a06 + d8ed637 commit 2a7fb16

File tree

83 files changed

+2669
-684
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+2669
-684
lines changed
Loading
+30
Loading

src/components/Button/index.jsx

+15-10
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import styles from "./styles.module.scss";
99
* @param {Object} props component properties
1010
* @param {Object} props.children button text
1111
* @param {string} [props.className] class name added to root element
12-
* @param {'primary'|'primary-dark'|'primary-light'} [props.color] button color
12+
* @param {'primary'|'primary-dark'|'primary-light'|'error'|'warning'} [props.color]
13+
* button color
1314
* @param {boolean} [props.isDisabled] if button is disabled
1415
* @param {boolean} [props.isSelected] if button is selected
1516
* @param {string} [props.name] button name
16-
* @param {(e: any) => void} props.onClick function called when button is clicked
17+
* @param {(e: any) => void} [props.onClick] function called when button is clicked
1718
* @param {'medium'|'small'} [props.size] button size
1819
* @param {'circle'|'rounded'} [props.style] button style
1920
* @param {'button'|'submit'|'reset'} [props.type] button type
@@ -42,13 +43,11 @@ const Button = ({
4243
type={type}
4344
className={cn(
4445
styles.button,
45-
{
46-
[styles.selected]: isSelected,
47-
[styles[color]]: true,
48-
[styles[size]]: true,
49-
[styles[style]]: true,
50-
[styles[variant]]: true,
51-
},
46+
styles[color],
47+
styles[size],
48+
styles[style],
49+
styles[variant],
50+
{ [styles.selected]: isSelected },
5251
className
5352
)}
5453
onClick={onClick}
@@ -60,7 +59,13 @@ const Button = ({
6059
Button.propTypes = {
6160
children: PT.node,
6261
className: PT.string,
63-
color: PT.oneOf(["primary"]),
62+
color: PT.oneOf([
63+
"primary",
64+
"primary-dark",
65+
"primary-light",
66+
"error",
67+
"warning",
68+
]),
6469
isDisabled: PT.bool,
6570
isSelected: PT.bool,
6671
name: PT.string,

src/components/Button/styles.module.scss

+21
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
align-items: center;
88
@include roboto-bold;
99
letter-spacing: 0.8px;
10+
white-space: nowrap;
1011
text-transform: uppercase;
1112
outline: none;
1213
cursor: pointer;
@@ -61,6 +62,16 @@
6162
color: $primary-dark-text-color;
6263
}
6364

65+
&.error {
66+
border-color: $error-color;
67+
color: $error-text-color;
68+
}
69+
70+
&.warning {
71+
border-color: $warning-color;
72+
color: $warning-text-color;
73+
}
74+
6475
&:disabled {
6576
border-color: $control-disabled-border-color;
6677
background-color: $control-disabled-bg-color;
@@ -88,6 +99,16 @@
8899
background-color: $primary-dark-color;
89100
}
90101

102+
&.error {
103+
border-color: $error-color;
104+
background-color: $error-color;
105+
}
106+
107+
&.warning {
108+
border-color: $warning-color;
109+
background-color: $warning-color;
110+
}
111+
91112
&:disabled {
92113
border-color: $control-disabled-border-color;
93114
background-color: $control-disabled-bg-color;

src/components/Checkbox/index.jsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import styles from "./styles.module.scss";
1010
* @param {Object} props component properties
1111
* @param {boolean} props.checked whether checkbox is checked
1212
* @param {string} [props.className] class name added to root element
13+
* @param {string} [props.impostorClassName] class name added to checkbox impostor
1314
* @param {boolean} [props.isDisabled] if checkbox is disabled
1415
* @param {string} props.name name for input element
1516
* @param {() => void} props.onChange function called when checkbox changes state
@@ -21,6 +22,7 @@ import styles from "./styles.module.scss";
2122
const Checkbox = ({
2223
checked,
2324
className,
25+
impostorClassName,
2426
isDisabled = false,
2527
name,
2628
onChange,
@@ -47,7 +49,7 @@ const Checkbox = ({
4749
checked={checked}
4850
value={option ? option.value : ""}
4951
/>
50-
<span className={styles.impostor} />
52+
<span className={cn(styles.impostor, impostorClassName)} />
5153
{option && option.label && (
5254
<span className={styles.label}>{option.label}</span>
5355
)}
@@ -57,6 +59,7 @@ const Checkbox = ({
5759
Checkbox.propTypes = {
5860
checked: PT.bool,
5961
className: PT.string,
62+
impostorClassName: PT.string,
6063
isDisabled: PT.bool,
6164
name: PT.string.isRequired,
6265
size: PT.oneOf(["medium", "small"]),

src/components/Checkbox/styles.module.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ input.checkbox {
9696
z-index: 2;
9797
position: relative;
9898
display: inline-block;
99-
vertical-align: -2px;
99+
vertical-align: -3px;
100100
width: 15px;
101101
height: 15px;
102102
line-height: 13px;

src/components/Content/styles.module.scss

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
padding: 0 10px;
55

66
@include desktop {
7-
flex: 1 1 auto;
7+
flex: 1 1 0;
88
padding: 0 35px;
9+
min-width: 0;
910
}
1011
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React, { useEffect, useState } from "react";
2+
import PT from "prop-types";
3+
import cn from "classnames";
4+
import Icon from "../../../assets/images/icon-checkmark-circled.svg";
5+
import styles from "./styles.module.scss";
6+
7+
/**
8+
* Displays an animated checkmark inside circle. After the specified timeout
9+
* the checkmark is faded out and after fade transition ends the onTimeout
10+
* is called.
11+
*
12+
* @param {Object} props component properties
13+
* @param {string} [props.className] class name to be added to root element
14+
* @param {() => void} props.onTimeout
15+
* @param {number} props.timeout timeout milliseconds
16+
* @returns {JSX.Element}
17+
*/
18+
const CheckmarkCircled = ({ className, onTimeout, timeout = 2000 }) => {
19+
const [isAnimated, setIsAnimated] = useState(false);
20+
const [isTimedOut, setIsTimedOut] = useState(false);
21+
22+
useEffect(() => {
23+
setIsAnimated(true);
24+
}, []);
25+
26+
useEffect(() => {
27+
setIsTimedOut(false);
28+
let timeoutId = setTimeout(() => {
29+
timeoutId = 0;
30+
setIsTimedOut(true);
31+
}, Math.max(timeout, /* total CSS animation duration */ 1200));
32+
return () => {
33+
if (timeoutId) {
34+
clearTimeout(timeoutId);
35+
}
36+
};
37+
}, [timeout]);
38+
39+
return (
40+
<span
41+
className={cn(
42+
styles.container,
43+
{ [styles.fadeOut]: isTimedOut },
44+
className
45+
)}
46+
onTransitionEnd={isTimedOut ? onTimeout : null}
47+
>
48+
<Icon
49+
className={cn(styles.checkmark, { [styles.animated]: isAnimated })}
50+
/>
51+
</span>
52+
);
53+
};
54+
55+
CheckmarkCircled.propTypes = {
56+
className: PT.string,
57+
onTimeout: PT.func.isRequired,
58+
timeout: PT.number,
59+
};
60+
61+
export default CheckmarkCircled;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
@import "styles/variables";
2+
3+
.container {
4+
display: inline-block;
5+
width: 30px;
6+
height: 30px;
7+
opacity: 1;
8+
transition: opacity 0.2s ease;
9+
}
10+
11+
.checkmark {
12+
display: block;
13+
width: auto;
14+
height: 100%;
15+
border-radius: 999px;
16+
stroke-width: 2;
17+
stroke: $primary-color;
18+
stroke-miterlimit: 10;
19+
box-shadow: inset 0px 0px 0px $primary-color;
20+
animation-play-state: paused;
21+
animation: /*checkmark-circled-fill 0.4s ease-in-out 0.4s forwards,*/ checkmark-circled-scale
22+
0.3s ease-in-out 0.9s both;
23+
24+
:global(.checkmark__circle) {
25+
stroke-dasharray: 166;
26+
stroke-dashoffset: 166;
27+
stroke-width: 2;
28+
stroke-miterlimit: 10;
29+
stroke: $primary-color;
30+
fill: rgba(255, 255, 255, 0);
31+
animation-play-state: paused;
32+
animation: checkmark-circled-stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1)
33+
forwards;
34+
}
35+
36+
:global(.checkmark__check) {
37+
transform-origin: 50% 50%;
38+
stroke-dasharray: 48;
39+
stroke-dashoffset: 48;
40+
animation-play-state: paused;
41+
animation: checkmark-circled-stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s
42+
forwards;
43+
}
44+
}
45+
46+
.animated {
47+
animation-play-state: running;
48+
49+
:global(.checkmark__circle),
50+
:global(.checkmark__check) {
51+
animation-play-state: running;
52+
}
53+
}
54+
55+
.fadeOut {
56+
opacity: 0;
57+
}
58+
59+
@keyframes checkmark-circled-stroke {
60+
100% {
61+
stroke-dashoffset: 0;
62+
}
63+
}
64+
65+
@keyframes checkmark-circled-scale {
66+
0%,
67+
100% {
68+
transform: none;
69+
}
70+
50% {
71+
transform: scale3d(1.1, 1.1, 1);
72+
}
73+
}
74+
75+
@keyframes checkmark-circled-fill {
76+
100% {
77+
box-shadow: inset 0px 0px 0px 10px $primary-color;
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from "react";
2+
import PT from "prop-types";
3+
import cn from "classnames";
4+
import styles from "./styles.module.scss";
5+
6+
/**
7+
* Displays a white exclamation mark inside red circle.
8+
*
9+
* @param {Object} props component properties
10+
* @returns {JSX.Element}
11+
*/
12+
const ExclamationMarkCircled = (props) => (
13+
<span {...props} className={cn(styles.icon, props.className)} />
14+
);
15+
16+
ExclamationMarkCircled.propTypes = {
17+
className: PT.string,
18+
};
19+
20+
export default ExclamationMarkCircled;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@import "styles/mixins";
2+
@import "styles/variables";
3+
4+
.icon {
5+
display: inline-block;
6+
padding: 2px 0 0;
7+
font-size: 12px;
8+
width: 16px;
9+
height: 16px;
10+
border-radius: 8px;
11+
line-height: 14px;
12+
@include roboto-bold;
13+
text-align: center;
14+
background: $error-color;
15+
color: #fff;
16+
cursor: pointer;
17+
18+
&::before {
19+
content: "!";
20+
display: inline;
21+
}
22+
}

src/components/JobName/index.jsx

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React, { memo, useContext, useEffect } from "react";
2+
import PT from "prop-types";
3+
import cn from "classnames";
4+
import { JobNameContext } from "components/JobNameProvider";
5+
import { JOB_NAME_LOADING } from "constants/workPeriods";
6+
import styles from "./styles.module.scss";
7+
8+
const JobName = ({ className, jobId }) => {
9+
const [getName, fetchName] = useContext(JobNameContext);
10+
const [jobName, error] = getName(jobId);
11+
12+
useEffect(() => {
13+
fetchName(jobId);
14+
}, [fetchName, jobId]);
15+
16+
return (
17+
<span
18+
className={cn(styles.container, { [styles.error]: !!error }, className)}
19+
>
20+
{jobName || JOB_NAME_LOADING}
21+
</span>
22+
);
23+
};
24+
25+
JobName.propTypes = {
26+
className: PT.string,
27+
jobId: PT.oneOfType([PT.number, PT.string]).isRequired,
28+
};
29+
30+
export default memo(JobName);

0 commit comments

Comments
 (0)