-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(QTM-489): RingGraph component created
- Loading branch information
1 parent
2c137a2
commit 82d2704
Showing
10 changed files
with
709 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); | ||
}); |
Oops, something went wrong.