Skip to content

Commit

Permalink
feat(QTM-489): RingGraph component created
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcosViniciusPC committed Aug 2, 2023
1 parent 2c137a2 commit 82d2704
Show file tree
Hide file tree
Showing 10 changed files with 709 additions and 0 deletions.
143 changes: 143 additions & 0 deletions components/RingGraph/RingGraph.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Generated with scripts/create-component.js
import PropTypes from 'prop-types';
import { useEffect, useState } from 'react';
import styled, { css } from 'styled-components';
import { colors, baseFontSize as defaultBaseFontSize } from '../shared/theme';
import { shadow } from '../shared';
import { percentToDegrees } from '../Stepper/helper';

const Wrapper = styled.div`
display: inline-flex;
align-items: center;
`;

const Circle = styled.div`
display: flex;
align-items: center;
justify-content: center;
width: 24px;
min-width: 24px;
height: 24px;
min-height: 24px;
${({
degrees: { 0: reference, 1: position },
skin,
theme: {
colors: {
neutral: { 300: neutralColor },
[skin]: { 900: color },
},
},
}) =>
reference > 0
? css`
background-image: linear-gradient(
${reference}deg,
${neutralColor} 50%,
transparent 50%
),
linear-gradient(${position}deg, ${neutralColor} 50%, ${color} 50%);
`
: css`
background-image: linear-gradient(
${reference}deg,
${color} 50%,
transparent 50%
),
linear-gradient(${position}deg, ${color} 50%, ${neutralColor} 50%);
`}
border-radius: 50%;
${shadow(2)}
`;
const CircleOverlay = styled.div`
width: 16px;
height: 16px;
border-radius: 50%;
background-color: ${({
theme: {
colors: {
neutral: { 0: neutralColor },
},
},
}) => neutralColor};
`;

const ProgressWrapper = styled.div`
margin-left: 12px;
${({
theme: {
baseFontSize,
colors: {
primary: { 900: primaryColor },
},
},
}) => `
color: ${primaryColor};
font-size: ${baseFontSize}px;
`}
`;
const formatInPercentage = (number) =>
number.toLocaleString('pt-br', {
style: 'percent',
maximumFractionDigits: 2,
});

const RingGraph = ({ percentage, round, skin, theme }) => {
const [compatibilityPercentage, setCompatibilityPercentage] = useState(
formatInPercentage(0),
);

useEffect(() => {
if (percentage >= 0 && percentage <= 100) {
let percentageValue = percentage;
if (round) {
percentageValue = Math.round(percentageValue);
}
const formattedPercentageValue = formatInPercentage(
percentageValue / 100,
);
setCompatibilityPercentage(formattedPercentageValue);
}
}, [percentage]);

return (
<Wrapper>
<Circle degrees={percentToDegrees(percentage)} theme={theme} skin={skin}>
<CircleOverlay theme={theme} />
</Circle>
<ProgressWrapper
theme={theme}
>{`${compatibilityPercentage} compatível`}</ProgressWrapper>
</Wrapper>
);
};

RingGraph.propTypes = {
percentage: PropTypes.number,
round: PropTypes.bool,
skin: PropTypes.oneOf([
'primary',
'secondary',
'success',
'warning',
'error',
'neutral',
]),
theme: PropTypes.shape({
colors: PropTypes.object,
baseFontSize: PropTypes.number,
}),
};

RingGraph.defaultProps = {
percentage: 0,
round: true,
skin: 'primary',
theme: {
colors,
baseFontSize: defaultBaseFontSize,
},
};

export default RingGraph;
66 changes: 66 additions & 0 deletions components/RingGraph/RingGraph.unit.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Generated with scripts/create-component.js
import { render, screen } from '@testing-library/react';

import RingGraph from './RingGraph';

describe('<RingGraph />', () => {
it('should match the snapshots', () => {
expect(render(<RingGraph percentage={0} />).asFragment()).toMatchSnapshot();

expect(
render(<RingGraph percentage={25} />).asFragment(),
).toMatchSnapshot();

expect(
render(<RingGraph percentage={50} />).asFragment(),
).toMatchSnapshot();

expect(
render(<RingGraph percentage={75} />).asFragment(),
).toMatchSnapshot();

expect(
render(<RingGraph percentage={100} />).asFragment(),
).toMatchSnapshot();

expect(
render(<RingGraph percentage={100} skin="secondary" />).asFragment(),
).toMatchSnapshot();
});

it('should round percentage when value is float', () => {
render(<RingGraph percentage={50.5} />);

expect(screen.getByText(/51% compatível/)).toBeInTheDocument();
});

it('should display percentage 0 when prop "percentage" is less than 100', () => {
render(<RingGraph percentage={-1} />);

expect(screen.getByText(/0% compatível/)).toBeInTheDocument();
});

it('should display percentage 0 when prop "percentage" is greater than 100', () => {
render(<RingGraph percentage={110} />);

expect(screen.getByText(/0% compatível/)).toBeInTheDocument();
});

it('should round percentage when value is float', () => {
render(<RingGraph percentage={50.5} />);

expect(screen.getByText(/51% compatível/)).toBeInTheDocument();
});

it('should display actual percentage value when not an integer and when value of prop "round" is false', () => {
render(<RingGraph percentage={50.5} round={false} />);

expect(screen.getByText(/50,5% compatível/)).toBeInTheDocument();
});

it('must show maximum two digits after comma when percentage is float and has more than 2 digits after dot and prop "round" is false', () => {
render(<RingGraph percentage={50.555} round={false} />);

expect(screen.getByText(/50,55% compatível/)).toBeInTheDocument();
});
});
Loading

0 comments on commit 82d2704

Please sign in to comment.